OpenWikiBookmarks1: Bitsum | Wiki | Frontpage | RecentChanges | TitleIndex | CategoryIndex | UserPreferences | FindPage | HelpPage | SandBox
Difference from revision 37 to the current revision.
major diff minor diff author diff hide diff

= Overclocking the WRT54G/GS v4, WRT54GL v1, WRT54GL v1.1 =
  
**WARNING:** Although the the versions of the WRT54G discussed here are safer 
to attempt to overclock than previous versions since their CFE does not allow 
the possibility of bricking via a bad clkfreq setting, I do not recommend 
overclocking unless you have built a JTAG cable to allow for recovery in case 
things somehow do go horribly wrong.
  
**DISCLAIMER:** The author of this text makes no warranties, express or implied 
and assumes no liability for damages, tangible or intangible, resulting from 
the use or misuse of information or software presented here, or derived from 
information presented here. It is possible you will ruin your router by 
attempting to overclock it, so understand and accept that risk or do not 
continue. The reader or user assumes liability for all risk involved.
  
== Introduction ==
  
This page presents findings about overclocking the WRT54G v4 BCM3302 0.8 
platform that were not previously known to the WRT54G community. It explains 
why you are likely mistaken if you think you have overclocked above 250mhz, and 
why 250mhz is the limit with the default CFE on this model (and other WRT54G 
units with the BCM3302 0.8, like the WRT54GL).
  
Older versions of the WRT54G/GS have a CFE that does support up to 300mhz, if 
they'll boot successfully at those speeds. This page is not applicable to them.
  
This page goes on to explain how to increase the clock frequency above the CFE 
imposed limit of 250mhz by modifying the CFE (requires JTAG for safe CFE 
flashing). At present, my **modified CFE supports CPU clock frequencies of up 
to 275mhz** (backplane 137).
  
== Discovery ==
  
=== You mean I'm not running at 300mhz?!?! ===
  
When I installed my first third party firmware on my WRT54Gv4, DD-WRT, I was 
happy to see an option to overclock. 
  
I eagerly toyed around with it and thought for a while I had overclocked its 
200mhz processor to 300mhz, since the DD-WRT web UI reported this to be the 
clock speed. Life was good.
  
Then I happened to look closer and noticed the clock frequency hadn't actually 
changed! The clock was running only at its default frequency of 200mhz, despite 
what the nvram ''clkfreq'' variable was set to. 
  
I experimented and soon discovered that in the list of valid frequencies DD-WRT 
was aware of, none above 240mhz actually caused the processor clock to change. 
The next known 
valid frequency above 240mhz was 252mhz, and this is where overclocking quit 
working.
  
(''UPDATE: Brainslayer has reported that future builds of DD-WRT (post v23 SP1) 
will have proper CPU frequencies for the BCM3302 0.8.'')
  
I knew that for previous versions of the WRT54G/GS the clock frequencies of 
252mhz and greater worked fine. I decided to investigate.
  
=== A different set of frequencies for this CPU ===
  
I looked around in the Broadcom source code to see if there was any indication 
of what was setting the clock frequency. I found in the common source code a 
file, ''sbmips.c''. that seemed to set the architecture clock frequencies and 
perform initialization tasks. 
  
Apparently the CFE uses this same code, or at least the frequency tables within 
it. Although the linux kernel itself doesn't make use of the 
''sb_mips_setclock'' function, the capability to set the clock frequency is 
there, should anyone decide to use it.
  
I discovered that beginning with the WRT54G v4, a different clock frequency 
table was being selected, likely due to the processor revision being 0.8 
instead of 0.7.
  
Specifically, the BCM3302 v0.7 uses the PLL_TYPE4 table, while the BCM3302 v0.8 
uses the PLL_TYPE7 table. They are similar in nature, but have a different set 
of frequencies.
  
These tables are lists of valid frequencies for the processor. Basically, the 
nvram ''clkfreq'' variable is compared to the frequencies in the table to find 
appropriate clock settings for the CPU frequency equal to, or less than, that 
specified.
  
If ''clkfreq'' exceeds the highest value in the table, the clock frequency is 
not changed. I noted that this behavior was in contrast to documented behavior 
of previous models.
  
I tested to make sure my findings were correct and specifically noted these 
differences in the WRT54Gv4 and above from the previous models:
  
  1. The CPU/backplane clock frequency is always a 2:1 ratio, so the second 
parameter of the clkfreq variable is ignored and can be omitted. The platform 
may support the same ratios as the BCM3302 0.7, but no other ratios are used or 
have been experimented yet to date.
  2. If no frequency match is found in the table, the next closest match of 
less than or equal value is used. Previous CFE versions had a problem that 
would cause them to just fail.
  3. If a a frequency above the maximum is attempted, the clock is set to its 
default speed. Previous CFE versions would simply lock up.
  4. The ''clkfreq'' variable is reset to 200 on a hard reset of the nvram. 
Previous CFE versions were reported to not do this.
  
=== BCM3302 0.8 frequencies known by the CFE ===
  
I documented the list of valid frequencies and wrote up an overclocking page in 
the OpenWRT Wiki. I also reported my findings to the author of DD-WRT via the 
DD-WRT forum, so that he could modify DD-WRT to properly handle these models 
(he hasn't got around to it as of DD v23 SP1).
  
The maximum CPU frequency in the table is 250mhz, a backplane of 125mhz.
  
The actual clock table pertaining to r0.8 is defined below, pulled out of 
sbmips.c (copyright Broadcom, Inc):
  
<code>
/* PLL configuration: type 2, 4, 7 */
typedef struct {
uint32 mipsclock;
uint32 sbclock;
uint16 n;
uint32 sb;
uint32 pci33;
uint32 m2;
uint32 m3;
uint32 ratio_cfg;
uint32 ratio_parm;
uint32 d11_r1;
uint32 d11_r2;
} n4m_table_t;
  
static n4m_table_t BCMINITDATA(type7_table)[] = {
{ 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 
11, 0x0aaa0555 },
{ 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 
11, 0x0aaa0555 },
{ 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 
11, 0x0aaa0555 },
{ 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 
11, 0x0aaa0555 },
{ 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 
11, 0x0aaa0555 },
{ 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 
11, 0x0aaa0555 },
{ 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 
11, 0x0aaa0555 },
{ 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 
11, 0x0aaa0555 },
{ 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 
11, 0x0aaa0555 },
{ 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 
11, 0x0aaa0555 },
{ 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 
11, 0x0aaa0555 },
{ 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 
11, 0x0aaa0555 },
{ 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 
11, 0x0aaa0555 },
{ 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 
11, 0x0aaa0555 }
</code>
  
Therefore, the set of valid clkfreq values known by the CFE are:
  
|| **MIPS/CPU** || **Backplane** || **Comment** ||
|| 183 || 91 || || 
|| 188 || 94 || ||
|| 197 || 98 || ||
|| 200 || 100 || default ||
|| 206 || 103 || ||
|| 212 || 106 || ||
|| 216 || 108 || ||
|| 217 || 109 || ||
|| 225 || 113 || ||
|| 238 || 119 || ||
|| 240 || 120 || ||
|| 250 || 125 || ||
  
To overclock to the maximum of 250mhz one would simply execute (in linux):
  
<code>
nvram set clkfreq=250
nvram commit
reboot
</code>
  
Of course, the clkfreq variable can also be set at the CFE> prompt if a 
serial console is available to you.
  
My unit, although equipped with a heatsink and fan, has run for weeks now at 
250mhz with no problems. The unit benchmarks considerably faster and for the 
many I/O tasks that are dependent on CPU speed, throughput increases in 
proportion to the clock increase.
  
== Hacking the CFE. Taking it higher! ==
 
I couldn't leave well enough alone, so I decided to see if the 'soft' limit 
imposed by the CFE could be overcome by modifying the frequency table. Of 
course, since I don't have the CFE code to rebuild it, I would need to make 
changes directly to the CFE binary.
  
There are a few possible ways to do this:
  
  * Patch the code so that BCM3302 0.7 table is used for the BCM3302 0.8. 
  : This may or may not work. Its unknown if the 0.7 table is valid for 0.8.
  * Add members to the BCM3302 0.8 frequency table.
  : This is the best idea, as there is extra space, but it requires extending 
the table size by patching the code.
  * Replace members of the BCM3302 0.8 frequency table.
  : By removing a few of the frequencies (like those < 200mhz), you can 
shift the table rows up and add new frequencies.
  
=== Adding new frequencies ===
  
This chore wasn't as simple as replacing one frequency with another, since the 
clock frequencies are actually a result of a relationship between the other 
variables. Some of the variables were obvious, but the critical ones, 
"n" and "m", required some analysis to determine the 
appropriate values. I quickly discovered that random guesses sure weren't going 
to work :).
  
After a couple hours of digging through the applicable source code, I figured 
out the relationship. I won't document every little thing here, but an overview 
follows:
  
  * N contains two 6-bit fields, N1 and N2. 
    * N1 is bits 0-6, translated by factor6 (see bottom of page).
    * N2 is bits 8-14, with a value of 5 as the implicit first value 
(subtracted)
  * M contains four 4-bit fields, MC, M3, M2, and M1, in that order (MC is 
highest 4 bits).
    * MC specifies how the clock is affected by M1 through M3, basically which 
ones it is divided by.
             
After extracting and translating N1, N2, MC, M1, M2, and M3, calculation of the 
clock frequency is performed.
  
The base frequency used for the BCM3302 0.8 is determined by the crystal in use 
on the PCB, and is 12.5mhz. We'll call this CC_BASE2, since this is similar to 
the definition in the source code. Oddly, clock frequencies don't seem to 
necessarily have to be divisible by this base, e.g. 240mhz.
  
In the case of the BCM3302 0.8 (PLL_TYPE7), the forumala when MC = 04 is:
   
  MIPS_CLOCK = (CC_BASE2 * N1 * N2) / M3
   
Therefore, one must find a valid combination of N1, N2, and M3 that results in 
the CPU clock frequency desired. If MC is a differen value, then M2 and M1 may 
be divided into the clock, instead of, or in addition to, M3.
  
I ended up with valid 262.5 and 275 mhz clock frequencies. 
  
<code>
{ 262500000, 131250000, 0x1003, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 
11, 0x0aaa0555 }
{ 275000000, 137500000, 0x1103, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 
11, 0x0aaa0555 }
{ 287500000, 143750000, 0x1203, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 
11, 0x0aaa0555 }
</code>
  
The 288mhz frequency has a problem, though I'm not yet certain what it is. The 
backplane at 288 is a very high 144mhz, so it may be that I need to try using a 
different CPU/SB ratio. However, all of the documented frequencies use a 2:1 
ratio so whether or not this processor supports other ratios I am not sure of. 
I believe it will, as the BCM3302 0.7 does, and all indications in the source 
code are that the 0.8 also supports 4 different ratios. 
  
I don't anticipate making any new developments due to the great amount of trial 
and error involved, and the fact that 275mhz is more than I hoped for to start 
with. 
  
=== Download my modified CFE ===
  
You too can have the performance of a 275mhz CPU clock by installing my 
modified CFE.
  
<code>
root@OpenWrt:/# cat /proc/cpuinfo
system type             : Broadcom BCM947XX
processor               : 0
cpu model               : BCM3302 V0.8
BogoMIPS                : 274.43
wait instruction        : no
microsecond timers      : yes
tlb_entries             : 32
extra interrupt vector  : no
hardware watchpoint     : no
VCED exceptions         : not available
VCEI exceptions         : not available
</code>
  
WARNING: I highly recommend installing at least passive cooling (heatsink) 
before running your board at this high a frequency for any sustained duration.
  
This CFE handles gracefully any clkfreq setting and has a maximum allowed 
setting of 275/137 CPU/backplane. My tests show a properly cooled router is 
stable at this speed. The default starting MAC address have been changed, so be 
sure to set it to whatever you desire after installation.
  
Supported frequencies:
  
|| **MIPS/CPU** || **Backplane** || **CFE memtest** *1 || **Comment** ||
|| 200 || 100 || not perfomed || default ||
|| 206 || 103 || not perfomed || stable (presumed) ||
|| 212 || 106 || not perfomed || stable (presumed) ||
|| 216 || 108 || not perfomed || stable ||
|| 217 || 109 || not perfomed || stable || 
|| 225 || 113 || not perfomed || stable (presumed) ||
|| 238 || 119 || not perfomed || stable (presumed) ||
|| 240 || 120 || not perfomed || stable (passive cooling) ||
|| 250 || 125 || not perfomed || stable (active cooling) ||
|| 263 || 131 || not perfomed || stable (active cooling) ||
|| 275 || 137 || passed on 552 iterations || unstable: reboots periodically 
(overheating?) ||
|| 288 || 144 || n/a || not yet working ||
  
*1 ''CFE> memtest -loop 80000000 200000''
  
My modified CFE has been tested on the WRT54G v4 only. It probably works fine 
on the WRT54GL v1.x, but I do not know this for certain.
  
To install the CFE, use a JTAG cable and HairyDairyMaid's debricking tool. 
Alternatively, you can install it without a JTAG by using the mtd utility, but 
I'm hesistant to suggest this since if there is a problem with the flash your 
router will be recoverable by JTAG only.
  
[[http://www.bitsum.com/files/cfe.288.zip Download modified WRT54Gv4 CFE]]
   
<br>The End<br>
----
  
<br>
**Misc. Notes**
   
<Anchor(@this#anchor1)/> 
  * I've noticed different behavior in how clock frequencies above the maximum 
valid are handled by a DD-WRT and an OpenWrt installation that I can't 
immediately explain. With DD-WRT the clock frequency ends up set at the default 
of 200mhz, as I state above, but with OpenWrt it ends up not being changed from 
its last frequency. The developers of OpenWrt and DD-WRT swear to me that the 
clock frequency is set only by the CFE, and not also by the linux kernel driver 
for the BCM processor. I investigated and indeed can't find any place where the 
sb_mips_setclock procedure is invoked by the any part of the kernel. This 
behavior is still a mystery, but may involve some difference in how the 
processor is initialized by the linux kernel.
  
<Anchor(@this#factor6)/>
  * Factor6
|| **stored** || **actual** ||
|| 0x02 || 2 ||
|| 0x03 || 3 ||
|| 0x05 || 4 ||
|| 0x09 || 5 ||
|| 0x11 || 6 ||
|| 0x21 || 7 ||
  
  

Bookmarks1: Bitsum | Wiki | Frontpage | RecentChanges | TitleIndex | CategoryIndex | UserPreferences | FindPage | HelpPage | SandBox
Edit this page | View other revisions
Print this page | View XML
Find page by browsing, searching or an index
Edited March 6, 2008 (hide diff)