| 1 | /* |
|---|
| 2 | * overclock_atheros.c |
|---|
| 3 | * |
|---|
| 4 | * Copyright (C) 2008 Sebastian Gottschall <gottschall@dd-wrt.com> |
|---|
| 5 | * |
|---|
| 6 | * This program is free software; you can redistribute it and/or |
|---|
| 7 | * modify it under the terms of the GNU General Public License |
|---|
| 8 | * as published by the Free Software Foundation; either version 2 |
|---|
| 9 | * of the License, or (at your option) any later version. |
|---|
| 10 | * |
|---|
| 11 | * This program is distributed in the hope that it will be useful, |
|---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | * GNU General Public License for more details. |
|---|
| 15 | * |
|---|
| 16 | * You should have received a copy of the GNU General Public License |
|---|
| 17 | * along with this program; if not, write to the Free Software |
|---|
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 19 | * |
|---|
| 20 | * desc: |
|---|
| 21 | * overclocks 2313 and 2316/17 or compatible wisoc boards with redboot or wistron zLoader to any 200 - 240 mhz (you must select it by i.e. nvram set cpuclk=220) |
|---|
| 22 | * just a dirty hack i found while playing with code |
|---|
| 23 | */ |
|---|
| 24 | #include <unistd.h> |
|---|
| 25 | #include <sys/types.h> |
|---|
| 26 | #include <stdio.h> |
|---|
| 27 | #include <string.h> |
|---|
| 28 | #include <stdlib.h> |
|---|
| 29 | #include <fcntl.h> |
|---|
| 30 | #include <shutils.h> |
|---|
| 31 | #include <bcmnvram.h> |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | /* |
|---|
| 35 | to prevent bricks and other troubles you should use this tool only manually. it will not be implemented in the webgui |
|---|
| 36 | */ |
|---|
| 37 | |
|---|
| 38 | void start_overclock (void) // hidden feature. must be called with "startservice overlock". then reboot the unit |
|---|
| 39 | { |
|---|
| 40 | long len; |
|---|
| 41 | long i; |
|---|
| 42 | #ifdef HAVE_CA8 |
|---|
| 43 | FILE *in = fopen ("/dev/mtdblock/2", "rb"); // zLoader Board Data access. the board data section contains also the cpu programming code |
|---|
| 44 | #else |
|---|
| 45 | FILE *in = fopen ("/dev/mtdblock/0", "rb"); |
|---|
| 46 | #endif |
|---|
| 47 | FILE *out = fopen ("/tmp/boot", "wb"); |
|---|
| 48 | fseek (in, 0, SEEK_END); |
|---|
| 49 | len = ftell (in); |
|---|
| 50 | fseek (in, 0, SEEK_SET); |
|---|
| 51 | for (i = 0; i < len; i++) |
|---|
| 52 | putc (getc (in), out); |
|---|
| 53 | fclose (in); |
|---|
| 54 | fclose (out); |
|---|
| 55 | int clk = atoi (nvram_default_get ("cpuclk", "180")); |
|---|
| 56 | |
|---|
| 57 | in = fopen ("/tmp/boot", "r+b"); |
|---|
| 58 | fseek (in, 0xe64b, SEEK_SET); |
|---|
| 59 | int zmul = getc (in); |
|---|
| 60 | fseek (in, 0xcb, SEEK_SET); |
|---|
| 61 | int vipermul = getc (in); |
|---|
| 62 | fseek (in, 0x1e3, SEEK_SET); |
|---|
| 63 | int div = getc (in); |
|---|
| 64 | fseek (in, 0x1ef, SEEK_SET); |
|---|
| 65 | int mul = getc (in); |
|---|
| 66 | // fprintf(stderr,"vipermul %X, div %X, mul %X\n",vipermul,div,mul); |
|---|
| 67 | if (div == 0x3 && mul == 0x5c) |
|---|
| 68 | { |
|---|
| 69 | fprintf (stderr, "ap51/ap61 (ar2315 or ar2317) found\n"); |
|---|
| 70 | fseek (in, 0x1e3, SEEK_SET); |
|---|
| 71 | putc (0x1, in); |
|---|
| 72 | fseek (in, 0x1ef, SEEK_SET); |
|---|
| 73 | if (clk == 200) |
|---|
| 74 | putc (0x28, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 75 | else if (clk == 220) |
|---|
| 76 | putc (0x2c, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 77 | else if (clk == 240) |
|---|
| 78 | putc (0x30, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 79 | else |
|---|
| 80 | { |
|---|
| 81 | nvram_set ("cpuclk", "200"); |
|---|
| 82 | clk = atoi (nvram_default_get ("cpuclk", "180")); |
|---|
| 83 | nvram_commit (); |
|---|
| 84 | putc (0x28, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | fclose (in); |
|---|
| 88 | eval ("mtd", "-f", "write", "/tmp/boot", "RedBoot"); |
|---|
| 89 | }else |
|---|
| 90 | if (div == 0x1 && (mul == 0x28 || mul == 0x2c || mul == 0x30)) |
|---|
| 91 | { |
|---|
| 92 | fprintf (stderr, "ap51/ap61 (ar2315 or ar2317) found\n"); |
|---|
| 93 | if (clk == 200 && mul == 0x28) |
|---|
| 94 | { |
|---|
| 95 | fprintf (stderr, "board already clocked to 200mhz\n"); |
|---|
| 96 | fclose (in); |
|---|
| 97 | return; |
|---|
| 98 | } |
|---|
| 99 | if (clk == 220 && mul == 0x2c) |
|---|
| 100 | { |
|---|
| 101 | fprintf (stderr, "board already clocked to 220mhz\n"); |
|---|
| 102 | fclose (in); |
|---|
| 103 | return; |
|---|
| 104 | } |
|---|
| 105 | if (clk == 240 && mul == 0x30) |
|---|
| 106 | { |
|---|
| 107 | fprintf (stderr, "board already clocked to 240mhz\n"); |
|---|
| 108 | fclose (in); |
|---|
| 109 | return; |
|---|
| 110 | } |
|---|
| 111 | fseek (in, 0x1e3, SEEK_SET); |
|---|
| 112 | putc (0x1, in); |
|---|
| 113 | fseek (in, 0x1ef, SEEK_SET); |
|---|
| 114 | if (clk == 200) |
|---|
| 115 | putc (0x28, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 116 | else if (clk == 220) |
|---|
| 117 | putc (0x2c, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 118 | else if (clk == 240) |
|---|
| 119 | putc (0x30, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 120 | else |
|---|
| 121 | { |
|---|
| 122 | nvram_set ("cpuclk", "200"); |
|---|
| 123 | nvram_commit (); |
|---|
| 124 | putc (0x28, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 125 | } |
|---|
| 126 | fclose (in); |
|---|
| 127 | eval ("mtd", "-f", "write", "/tmp/boot", "RedBoot"); |
|---|
| 128 | } |
|---|
| 129 | else if (vipermul == 0x9 || vipermul == 0xa || vipermul == 0xb |
|---|
| 130 | || vipermul == 0xc) |
|---|
| 131 | { |
|---|
| 132 | fprintf (stderr, "viper (ar2313) found\n"); |
|---|
| 133 | if (clk == 180 && vipermul == 0x9) |
|---|
| 134 | { |
|---|
| 135 | fprintf (stderr, "board already clocked to 180mhz\n"); |
|---|
| 136 | fclose (in); |
|---|
| 137 | return; |
|---|
| 138 | } |
|---|
| 139 | if (clk == 200 && vipermul == 0xa) |
|---|
| 140 | { |
|---|
| 141 | fprintf (stderr, "board already clocked to 200mhz\n"); |
|---|
| 142 | fclose (in); |
|---|
| 143 | return; |
|---|
| 144 | } |
|---|
| 145 | if (clk == 220 && vipermul == 0xb) |
|---|
| 146 | { |
|---|
| 147 | fprintf (stderr, "board already clocked to 220mhz\n"); |
|---|
| 148 | fclose (in); |
|---|
| 149 | return; |
|---|
| 150 | } |
|---|
| 151 | if (clk == 240 && vipermul == 0xc) |
|---|
| 152 | { |
|---|
| 153 | fprintf (stderr, "board already clocked to 240mhz\n"); |
|---|
| 154 | fclose (in); |
|---|
| 155 | return; |
|---|
| 156 | } |
|---|
| 157 | fseek (in, 0xcb, SEEK_SET); |
|---|
| 158 | if (clk == 200) |
|---|
| 159 | putc (0xa, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 160 | else if (clk == 220) |
|---|
| 161 | putc (0xb, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 162 | else if (clk == 240) |
|---|
| 163 | putc (0xc, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 164 | else |
|---|
| 165 | { |
|---|
| 166 | nvram_set ("cpuclk", "220"); |
|---|
| 167 | clk = atoi (nvram_default_get ("cpuclk", "180")); |
|---|
| 168 | nvram_commit (); |
|---|
| 169 | putc (0xb, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 170 | } |
|---|
| 171 | fclose (in); |
|---|
| 172 | eval ("mtd", "-f", "write", "/tmp/boot", "RedBoot"); |
|---|
| 173 | } |
|---|
| 174 | else if (zmul == 0x9 || zmul == 0xa || zmul == 0xb || zmul == 0xc) // special handling for zLoader based boards |
|---|
| 175 | { |
|---|
| 176 | fprintf (stderr, "viper (ar2313) found (zLoader)\n"); |
|---|
| 177 | if (clk == 180 && zmul == 0x9) |
|---|
| 178 | { |
|---|
| 179 | fprintf (stderr, "board already clocked to 180mhz\n"); |
|---|
| 180 | fclose (in); |
|---|
| 181 | return; |
|---|
| 182 | } |
|---|
| 183 | if (clk == 200 && zmul == 0xa) |
|---|
| 184 | { |
|---|
| 185 | fprintf (stderr, "board already clocked to 200mhz\n"); |
|---|
| 186 | fclose (in); |
|---|
| 187 | return; |
|---|
| 188 | } |
|---|
| 189 | if (clk == 220 && zmul == 0xb) |
|---|
| 190 | { |
|---|
| 191 | fprintf (stderr, "board already clocked to 220mhz\n"); |
|---|
| 192 | fclose (in); |
|---|
| 193 | return; |
|---|
| 194 | } |
|---|
| 195 | if (clk == 240 && zmul == 0xc) |
|---|
| 196 | { |
|---|
| 197 | fprintf (stderr, "board already clocked to 240mhz\n"); |
|---|
| 198 | fclose (in); |
|---|
| 199 | return; |
|---|
| 200 | } |
|---|
| 201 | fseek (in, 0xe64b, SEEK_SET); |
|---|
| 202 | if (clk == 200) |
|---|
| 203 | putc (0xa, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 204 | else if (clk == 220) |
|---|
| 205 | putc (0xb, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 206 | else if (clk == 240) |
|---|
| 207 | putc (0xc, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 208 | else |
|---|
| 209 | { |
|---|
| 210 | nvram_set ("cpuclk", "220"); |
|---|
| 211 | clk = atoi (nvram_default_get ("cpuclk", "180")); |
|---|
| 212 | nvram_commit (); |
|---|
| 213 | putc (0xb, in); //0x2c for 220 mhz 0x30 for 240 mhz |
|---|
| 214 | } |
|---|
| 215 | fclose (in); |
|---|
| 216 | eval ("mtd", "-f", "write", "/tmp/boot", "bdata"); |
|---|
| 217 | } |
|---|
| 218 | else |
|---|
| 219 | { |
|---|
| 220 | fprintf (stderr, "unknown board or no redboot found\n"); |
|---|
| 221 | fclose (in); |
|---|
| 222 | } |
|---|
| 223 | fprintf (stderr, "board is now clocked at %d mhz, please reboot\n",clk); |
|---|
| 224 | } |
|---|