Page Type: Article
Edit this page (last editedMarch 6, 2008)
Bookmarks1: Bitsum | Wiki | Frontpage | RecentChanges | TitleIndex | CategoryIndex | UserPreferences | FindPage | HelpPage | SandBox

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.


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).


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):

/* 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 }

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):

nvram set clkfreq=250
nvram commit

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.

{ 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 }

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.

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

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.

[Download modified WRT54Gv4 CFE]

The End

Misc. Notes

  • 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.

  • Factor6
stored actual
0x02 2
0x03 3
0x05 4
0x09 5
0x11 6
0x21 7

Summary : Overclocking the BCM3302 0.8 (WRT54G/GS v4, WRT54GL v1, WRT54GL v1.1)
Bookmarks1: Bitsum | Wiki | Frontpage | RecentChanges | TitleIndex | CategoryIndex | UserPreferences | FindPage | HelpPage | SandBox
Edit this page | Rename this page | View other revisions | Attachments (0) | Print this page | View XML | Page views: 81229
Find page by browsing, searching or an index | Page Revisions: 2
Last Edited March 6, 2008 by Jc | (diff)

Valid XHTML 1.0!Valid CSS!