Subject: PowerPC 750GX (FX?) PLL Settings - Getting it running at 1GHz!
To: None <firstname.lastname@example.org, email@example.com>
From: Francis Koclas <firstname.lastname@example.org>
Date: 10/29/2005 00:31:42
A couple months ago I posted to see if anyone has been able to run the
PowerLogix 1GHz 750GX processor at 1GHz (defaults to 500MHz).
Posts by John Klos on port-macppc were the first I had found on the same
topic, so I promptly contacted him. I also found posts by Matthias
Kretschmer on the same topic again on port-powerpc this time. So I
contacted him as well and started working on this.
As recently as yesterday I was linked by a kind person on #netbsd to a
patch submitted for the linux kernel 2.4.30 by Kevin Diggs. I contacted
him and he gave me some valuable input on the work I had done until then.
It's too bad we mostly had conducted seperate efforts for the same task.
However, I'm glad to report that I have managed to get mine running at 1GHz!
cpu0 at mainbus0: 750 (Revision 2.3), ID 0 (primary)
cpu0: HID0 8290c0a4<EMCP,ECLK,DOZE,DPM,ICE,DCE,SGE,BTIC,BHT>
cpu0: 1000.00 MHz, no-parity 1MB WB L2 cache (PB SRAM) at 1:1 ratio
A little php script which calculates 2,500,000 decimals of Pi runs twice
as fast with this setting, so the CPU is indeed running at 1GHz.
Here is useful information on how to get this done :
Details about the HID1 register (IBM):
Procedure to use to set the processor PLLs (IBM):
Masks needed to set the HID1 register (myself):
I got the "result" (last line of that last link) with a very simple C
program I made.
These are the changes I have done:
What: everything inside the two boxes :-)
struct device *self;
struct cpu_info *ci;
u_int hid0, pvr, vers;
char *bitmask, hidbuf;
* BEGIN PLL SETTINGS *
/* set HID1[PR1] */
hid1 = mfspr(SPR_HID1);
hid1 = hid1 | 0x00000002;
/* set HID1[PC1] */
hid1 = hid1 | 0x000000F0;
/* set HID1[PS] */
hid1 = hid1 | 0x00010000;
* END PLL SETTINGS *
John on his end started working on a way to control this using sysctl.
My code works, but its dirty right now. By this I mean I make no check
to see if the CPU is of the right kind or anything. I just change the
PLL1 bits and switch over to it (750FX and GX has two PLLs, PLL0 and
PLL1, and both processors share the exact same HID1 register). I did
some tests 2 days ago and the type of CPU (variable "vers" in cpu_setup)
is reported as 8, so it technically it would work if it was treated in
the MPC750 block, although I'm not exactly sure this is reported right
in the first place as it is not a Motorola (Freescale) G3.
The code does not seem too big but it took a big effort of my part to
get it right. I had zero powerpc assembler background, and never did any
kernel work before. So use this at your own risk, and please be kind =)
Surprisingly, the code works without any sync or wait calls. When I did
my initial testing I had some __asm__volatile("sync"); and some
delay(1000); calls, but the code worked as well without them..
What remains to be done:
- checks for the CPU type
- tests on 750FX (and more 750GX!) processors
- determine if some sync/wait calls should be added
- a some function which would translate the clock multiplier to the
corresponding PC1 code, and then generate a valid mask.
- control via sysctl, or via the kernel config, kind of like the L2CR
settings right now. example:
- verifications on how this affects power saving settings, etc.