From: Terry Greeniaus <hidden> Date: 2003-06-20 05:53:41
On Thu, 19 Jun 2003, Chris Studholme wrote:
On Fri, 13 Jun 2003, Terry Greeniaus wrote:
quoted
The PowerLogix 900 MHz bluechips are 750FX CPUs, however they have been
strapped so that the PVR reports itself as 0x0008nnnn instead of
0x7000nnnn, so that Apple's OpenFirmware can better support them (in
particular, to automatically enable the L2 cache). The correct way (on
these boards, anyhow) to determine if this is a 750FX is by writing to
the HID1 register and seeing if it changed. I have a code snippet to do
this if anyone wants it, although it isn't LinuxPPC-specific. This is
backwards-compatible with normal 750 CPUs, they don't take an exception
if you try to write to the HID1 register.
I would like to see the code snippet. Do you know how the bluechip G4
upgrade for the pismo works? Is it also reported as 0x0008nnnn? If so,
how does your code snippet handle that case?
All of the G4 bluechips are either 7400 (in the older models, not
anymore though) or 7410 CPUs strapped normally (PVR = 0x000Cnnnn [7400]
or 0x800Cnnnn [7410]). Since these are strapped normally, nothing
special needs to be done to handle that case. Here's the code snippet
we use in our software to determine if you are on a 750 or 750FX:
UInt32 getRealPVR()
{
UInt32 pvr = getSPR(287);
UInt32 realPVR = pvr;
if((pvr & 0xFFFF0000) == 0x00080000)
{
// This could be a 750FX strapped as a 750 PVR
UInt32 hid1 = getHID1();
if(hid1 & 0x00010000)
{
// PLL1 is in use, fiddle with PLL0
setHID1(hid1 ^ 0x00000200);
if(getHID1() != hid1)
{
// HID1 changed, this is a 750FX
realPVR = (0x70000000 |
(pvr & 0x0000FFFF));
setHID1(hid1);
}
}
else
{
// PLL0 is in use, fiddle with PLL1
setHID1(hid1 ^ 0x00000002);
if(getHID1() != hid1)
{
// HID1 changed, this is a 750FX
realPVR = (0x70000000 |
(pvr & 0x0000FFFF));
setHID1(hid1);
}
}
}
return realPVR;
}
Basically this just checks to see if we have a 750 PVR, and if we do it
tries writing to the PLL bits of the PLL that isn't in use in HID1. If
HID1 changes, then we have a 750FX rather than a 750. Finally, we reset
HID1 back to whatever it was before we changed it.
This is a bit annoying because it means you can't always rely on a mfpvr
instruction in some assembly code. We run this routine once when our
software starts up and store the result in a global variable which we
use in the rest of the code. Also, note that the lower 16 bits of the
PVR remain unchanged regardless of how the CPU is strapped, so we mask
off the top 16 bits only and replace them with 0x7000nnnn.
BTW I am only subscribed to the list digest, so if you want more timely
replies (i.e. more than once a day :P ) CC me with the list message.
TG
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-21 15:58:05
Terry,
Thanks for the code snippet and all the info. I hope to add this check
immediately after the device-tree is copied to ram and then I'll modify
the in ram version to reflect the properties of a 750fx. I'll post a
patch here when I get something working.
Chris.
On Fri, 20 Jun 2003, Terry Greeniaus wrote:
On Thu, 19 Jun 2003, Chris Studholme wrote:
quoted
On Fri, 13 Jun 2003, Terry Greeniaus wrote:
quoted
The PowerLogix 900 MHz bluechips are 750FX CPUs, however they have been
strapped so that the PVR reports itself as 0x0008nnnn instead of
0x7000nnnn, so that Apple's OpenFirmware can better support them (in
particular, to automatically enable the L2 cache). The correct way (on
these boards, anyhow) to determine if this is a 750FX is by writing to
the HID1 register and seeing if it changed. I have a code snippet to do
this if anyone wants it, although it isn't LinuxPPC-specific. This is
backwards-compatible with normal 750 CPUs, they don't take an exception
if you try to write to the HID1 register.
I would like to see the code snippet. Do you know how the bluechip G4
upgrade for the pismo works? Is it also reported as 0x0008nnnn? If so,
how does your code snippet handle that case?
All of the G4 bluechips are either 7400 (in the older models, not
anymore though) or 7410 CPUs strapped normally (PVR = 0x000Cnnnn [7400]
or 0x800Cnnnn [7410]). Since these are strapped normally, nothing
special needs to be done to handle that case. Here's the code snippet
we use in our software to determine if you are on a 750 or 750FX:
UInt32 getRealPVR()
{
UInt32 pvr = getSPR(287);
UInt32 realPVR = pvr;
if((pvr & 0xFFFF0000) == 0x00080000)
{
// This could be a 750FX strapped as a 750 PVR
UInt32 hid1 = getHID1();
if(hid1 & 0x00010000)
{
// PLL1 is in use, fiddle with PLL0
setHID1(hid1 ^ 0x00000200);
if(getHID1() != hid1)
{
// HID1 changed, this is a 750FX
realPVR = (0x70000000 |
(pvr & 0x0000FFFF));
setHID1(hid1);
}
}
else
{
// PLL0 is in use, fiddle with PLL1
setHID1(hid1 ^ 0x00000002);
if(getHID1() != hid1)
{
// HID1 changed, this is a 750FX
realPVR = (0x70000000 |
(pvr & 0x0000FFFF));
setHID1(hid1);
}
}
}
return realPVR;
}
Basically this just checks to see if we have a 750 PVR, and if we do it
tries writing to the PLL bits of the PLL that isn't in use in HID1. If
HID1 changes, then we have a 750FX rather than a 750. Finally, we reset
HID1 back to whatever it was before we changed it.
This is a bit annoying because it means you can't always rely on a mfpvr
instruction in some assembly code. We run this routine once when our
software starts up and store the result in a global variable which we
use in the rest of the code. Also, note that the lower 16 bits of the
PVR remain unchanged regardless of how the CPU is strapped, so we mask
off the top 16 bits only and replace them with 0x7000nnnn.
BTW I am only subscribed to the list digest, so if you want more timely
replies (i.e. more than once a day :P ) CC me with the list message.
TG
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2003-06-22 09:49:25
On Sat, 2003-06-21 at 17:58, Chris Studholme wrote:
Terry,
Thanks for the code snippet and all the info. I hope to add this check
immediately after the device-tree is copied to ram and then I'll modify
the in ram version to reflect the properties of a 750fx. I'll post a
patch here when I get something working.
Note that the kernel doesn't use the device tree to detect the
CPU type. It rather runs the PVR through a table in
arch/ppc/kernel/cputable.c. There is currently no hook you could
use to 'fix' that. Ideally, you should make sure the CPU is properly
detected before the fixups are done or you may "lose" some 750fx
specific code.
Terry: do you setup PLL1 ? I assume it's set to a low freq by
the firmware and switch to it during idle among others...
If PLL1 isn't set, you should probably not set powersave_lowspeed
in arch/ppc/platforms/pmac_feature.c.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Terry Greeniaus <hidden> Date: 2003-06-22 21:58:49
On 22 Jun 2003, Benjamin Herrenschmidt wrote:
Note that the kernel doesn't use the device tree to detect the
CPU type. It rather runs the PVR through a table in
arch/ppc/kernel/cputable.c. There is currently no hook you could
use to 'fix' that. Ideally, you should make sure the CPU is properly
detected before the fixups are done or you may "lose" some 750fx
specific code.
Terry: do you setup PLL1 ? I assume it's set to a low freq by
the firmware and switch to it during idle among others...
If PLL1 isn't set, you should probably not set powersave_lowspeed
in arch/ppc/platforms/pmac_feature.c.
Currently we don't ship any LinuxPPC software with the upgrades. The
hardware is strapped so that its built-in PLL comes up at the maximum
speed of the upgrade (usually 900 MHz). This allows software to
determine the range of allowed PLL settings. The user can attempt to
overclock by running the software in "advanced" mode, but that isn't
documented or supported really. The software we ship allows the user to
manually configure the CPU speed by switching the PLLs, if that's what
you're asking I can post some code to do that, but I thought LinuxPPC
already had something similar. We don't downclock the CPU when it is
idle, but that would probably be a nice power saver.
TG
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-23 04:47:56
On Sun, 22 Jun 2003, Benjamin Herrenschmidt wrote:
Note that the kernel doesn't use the device tree to detect the
CPU type. It rather runs the PVR through a table in
arch/ppc/kernel/cputable.c. There is currently no hook you could
use to 'fix' that. Ideally, you should make sure the CPU is properly
detected before the fixups are done or you may "lose" some 750fx
specific code.
Ok, so to properly detect the cpu, I ported Terry's code to assembler and
added it to identify_cpu in arch/ppc/kernel/misc.S. See the attached diff
below. This code does the following:
- detects 750FX strapped as 750 in identify_cpu
- stores the real pvr is a new global called 'real_pvr'
- updates the cache and clock_frequency values in the device tree at the
end of finish_device_tree() in prom.c
- makes use of real_pvr instead of mfspr(PVR) in show_cpuinfo() in setup.c
Note that I currently hardcode the clock frequency to 900MHz (speed of my
pismo). I'll fix that as soon as I learn how to detect the true processor
speed.
For a complete solution, I believe all that needs to be done is to change
all instances of 'mfspr(PVR)' to 'real_pvr', except the one in prom.c.
Also, I just learned ppc assembler today while doing this so please let me
know if you see a more efficient/eloquent way to do the cpu detection, or
if you find a bug in what I have. I've only tested this on my upgraded
pismo and it seems to work. Here's my /proc/cpuinfo now:
cpu : 750FX
temperature : 18-20 C (uncalibrated)
clock : 900MHz
revision : 2.2 (pvr 7000 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 512K unified
memory : 256MB
pmac-generation : NewWorld
Chris.
diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/cputable.c linux-2.4.21-ac1/arch/ppc/kernel/cputable.c
*** linux-2.4.21-ac1.orig/arch/ppc/kernel/cputable.c Fri Jun 13 10:51:31 2003
--- linux-2.4.21-ac1/arch/ppc/kernel/cputable.c Sun Jun 22 21:10:37 2003
***************
*** 18,23 ****
--- 18,25 ----
struct cpu_spec* cur_cpu_spec[NR_CPUS];
+ unsigned int real_pvr;
+
extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2003-06-23 06:01:10
Currently we don't ship any LinuxPPC software with the upgrades. The
hardware is strapped so that its built-in PLL comes up at the maximum
speed of the upgrade (usually 900 MHz). This allows software to
determine the range of allowed PLL settings. The user can attempt to
overclock by running the software in "advanced" mode, but that isn't
documented or supported really. The software we ship allows the user to
manually configure the CPU speed by switching the PLLs, if that's what
you're asking I can post some code to do that, but I thought LinuxPPC
already had something similar. We don't downclock the CPU when it is
idle, but that would probably be a nice power saver.
We do have code to switch between PLL0 and PLL1, but that code assumes
that PLL1 was already set to an arbitrary "low speed", typically 400Mhz,
by the firmware (we could also lower the core voltage when switching
to low speed on some ibooks but I haven't implemented that yet).
So unless we have some code to detect that PLL1 isn't initialized and
then set it up properly, the user should disable that powersave_lowspeed
code or the kernel will try to switch to PLL1
Ben
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Gabriel Paubert <hidden> Date: 2003-06-23 08:27:51
On Mon, Jun 23, 2003 at 12:47:56AM -0400, Chris Studholme wrote:
quoted hunk
On Sun, 22 Jun 2003, Benjamin Herrenschmidt wrote:
quoted
Note that the kernel doesn't use the device tree to detect the
CPU type. It rather runs the PVR through a table in
arch/ppc/kernel/cputable.c. There is currently no hook you could
use to 'fix' that. Ideally, you should make sure the CPU is properly
detected before the fixups are done or you may "lose" some 750fx
specific code.
Ok, so to properly detect the cpu, I ported Terry's code to assembler and
added it to identify_cpu in arch/ppc/kernel/misc.S. See the attached diff
below. This code does the following:
- detects 750FX strapped as 750 in identify_cpu
- stores the real pvr is a new global called 'real_pvr'
- updates the cache and clock_frequency values in the device tree at the
end of finish_device_tree() in prom.c
- makes use of real_pvr instead of mfspr(PVR) in show_cpuinfo() in setup.c
Note that I currently hardcode the clock frequency to 900MHz (speed of my
pismo). I'll fix that as soon as I learn how to detect the true processor
speed.
For a complete solution, I believe all that needs to be done is to change
all instances of 'mfspr(PVR)' to 'real_pvr', except the one in prom.c.
Also, I just learned ppc assembler today while doing this so please let me
know if you see a more efficient/eloquent way to do the cpu detection, or
if you find a bug in what I have. I've only tested this on my upgraded
pismo and it seems to work. Here's my /proc/cpuinfo now:
cpu : 750FX
temperature : 18-20 C (uncalibrated)
clock : 900MHz
revision : 2.2 (pvr 7000 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 512K unified
memory : 256MB
pmac-generation : NewWorld
Chris.
diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/cputable.c linux-2.4.21-ac1/arch/ppc/kernel/cputable.c
*** linux-2.4.21-ac1.orig/arch/ppc/kernel/cputable.c Fri Jun 13 10:51:31 2003
--- linux-2.4.21-ac1/arch/ppc/kernel/cputable.c Sun Jun 22 21:10:37 2003
***************
*** 18,23 ****
--- 18,25 ----
struct cpu_spec* cur_cpu_spec[NR_CPUS];
+ unsigned int real_pvr;
+
extern void __setup_cpu_601(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_603(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
Are you sure you want to test the summary overflow bit
in this branch ? This bit is not related to the result
of the preceding srwi. instruction, so this looks
strange to say the least.
A bit convoluted no? r3 is supposed to be zero, so
the standard way of performing this is:
lis r6,real_pvr@ha
stw r7,real_pvr@l(r6)
+
blr
The rest looks fine, but I can't test it and did not check
the details of the boring C code.
Regards,
Gabriel
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Are you sure you want to test the summary overflow bit
in this branch ? This bit is not related to the result
of the preceding srwi. instruction, so this looks
strange to say the least.
What I was trying to do is test the last bit shifted out by the srwi., but
I still don't know how to do that, so how about this instead:
mfspr r5,0x3F1
andis. r6,r5,0x0001
bne 2f
A bit convoluted no? r3 is supposed to be zero, so
the standard way of performing this is:
lis r6,real_pvr@ha
stw r7,real_pvr@l(r6)
I believe when this method is called, there is some concern over where
data is. The method comments are:
/*
* identify_cpu,
* called with r3 = data offset and r4 = CPU number
* doesn't change r3
*/
and all of the other references to global data involve r3, like:
addis r8,r3,cpu_specs@ha
addi r8,r8,cpu_specs@l
and
addis r6,r3,cur_cpu_spec@ha
addi r6,r6,cur_cpu_spec@l
slwi r4,r4,2
sub r8,r8,r3
stwx r8,r4,r6
so I figured I should do the same. But perhaps I could still simplify my
code with:
addis r6,r3,real_pvr@ha
stwx r7,real_pvr@l(r6)
A bit convoluted no? r3 is supposed to be zero, so
the standard way of performing this is:
Well... he may be called while the kernel hasn't been relocated
yet, so he should take r3 into account at this point.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Are you sure you want to test the summary overflow bit
in this branch ? This bit is not related to the result
of the preceding srwi. instruction, so this looks
strange to say the least.
What I was trying to do is test the last bit shifted out by the srwi., but
I still don't know how to do that, so how about this instead:
mfspr r5,0x3F1
andis. r6,r5,0x0001
bne 2f
This looks much better, and is the standard way
of testing a bit on PPC.
A bit convoluted no? r3 is supposed to be zero, so
Argh, disregard this. I've been lately working too much with
an assembler in which the result is the last operand and
believed that sub r8,r8,r3 was a convoluted way of clearung r3.
quoted
the standard way of performing this is:
lis r6,real_pvr@ha
stw r7,real_pvr@l(r6)
I believe when this method is called, there is some concern over where
data is. The method comments are:
/*
* identify_cpu,
* called with r3 = data offset and r4 = CPU number
* doesn't change r3
*/
and all of the other references to global data involve r3, like:
addis r8,r3,cpu_specs@ha
addi r8,r8,cpu_specs@l
and
addis r6,r3,cur_cpu_spec@ha
addi r6,r6,cur_cpu_spec@l
slwi r4,r4,2
sub r8,r8,r3
stwx r8,r4,r6
so I figured I should do the same. But perhaps I could still simplify my
code with:
addis r6,r3,real_pvr@ha
stwx r7,real_pvr@l(r6)
Correct, provided the last instruction is stw instead of stwx, and
unless I miss again something.
Gabriel
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-26 17:02:04
I'm trying to set PLL1 on my 750FX to a multiplier of 4 (for a clock speed
of 400MHz) so I can eventually use cpufreq, but the machine keeps locking
up.
I know HID1 is 0x92000000 after boot and except for my twiddling of a bit
to detect the 750FX, it is not changed. This value is slightly confusing.
It indicates that PLL0 is in use, and its config is external. PLL_CFG is
18 (decimal) which indicates a multiplier of 9x. That's fine as my cpu
speed is 900MHz on a 100MHz bus. But PLL_RNG appears to be 01 (binary),
which is labeled as a reserved value in the IBM docs. What is the purpose
of PLL_RNG (range bits) anyway?
I'm trying to set PLL1 to 4x using the code:
mtspr(HID1,(mfspr(HID1)&~0xFE)|0x44);
This should set PLL_CFG to a value of 8 (for a multiplier of 4x) and
PLL_RNG to 10 (binary) which the IBM docs say should be used when the
frequency is below 600MHz. Note that I've also tried 00 and 01 as values
of PLL_RNG and they all fail. I've tried this both with and without a
delay afterwards. My delay is simply:
for (i=0; i<100000000; ++i) j+=i;
Since I never switch the processor to PLL1, the delay shouldn't matter.
The machine doesn't seem to lockup the moment HID1 is changed (ie. in
finish_device_tree()). It always locks up during the detection of the IDE
devices. From dmesg output:
Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4
ide: Assuming 33MHz system bus speed for PIO modes; override with
idebus=xx
ide0: Found Apple KeyLargo ATA-4 controller, bus ID 2
ide1: Found Apple KeyLargo ATA-3 controller, bus ID 1
ide2: Found Apple KeyLargo ATA-3 controller, bus ID 0 (mediabay)
Probing IDE interface ide0...
hda: FUJITSU MHR2020AT D, ATA DISK drive
hda: Enabling Ultra DMA 4
Probing IDE interface ide1...
ide0 at 0xd1806000-0xd1806007,0xd1806160 on irq 19
hda: attached ide-disk driver.
-> lockup is always here regardless of delay or not and particular setting <-
hda: host protected area => 1
hda: 39070080 sectors (20004 MB) w/2048KiB Cache, CHS=2432/255/63,
UDMA(66)
Partition check:
/dev/ide/host0/bus0/target0/lun0: [mac] p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13
usb.c: registered new driver usbdevfs
Is there something else I need to do to set PLL1?
Chris.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Terry Greeniaus <hidden> Date: 2003-06-26 17:33:02
On Thu, 26 Jun 2003, Chris Studholme wrote:
I know HID1 is 0x92000000 after boot and except for my twiddling of a bit
to detect the 750FX, it is not changed. This value is slightly confusing.
It indicates that PLL0 is in use, and its config is external. PLL_CFG is
18 (decimal) which indicates a multiplier of 9x. That's fine as my cpu
speed is 900MHz on a 100MHz bus. But PLL_RNG appears to be 01 (binary),
which is labeled as a reserved value in the IBM docs. What is the purpose
of PLL_RNG (range bits) anyway?
In our code we use the following:
PLL_RNG CPU freq
------------------------------------------
0b10 less than 600 MHz
0b00 between 600 and 750 MHz
0b01 above 750 MHz
------------------------------------------
I don't recall exactly where I got that last PLL_RNG setting from, it
may have been from an email from an IBM engineer or something. Last
time I checked it indeed wasn't documented anywhere.
I'm trying to set PLL1 to 4x using the code:
mtspr(HID1,(mfspr(HID1)&~0xFE)|0x44);
This should set PLL_CFG to a value of 8 (for a multiplier of 4x) and
PLL_RNG to 10 (binary) which the IBM docs say should be used when the
frequency is below 600MHz. Note that I've also tried 00 and 01 as values
of PLL_RNG and they all fail. I've tried this both with and without a
delay afterwards. My delay is simply:
This code all looks fine to me. You do need to put in a delay so that
the PLL can stabilize before using it. We use a 0.5 second delay, which
is probably waaaay overkill.
Also, switching between two half-integer ratios is considered a
programming error, but you don't seem to be doing that and AFAICT this
code should not cause you to hang, especially if you aren't even
switching over to PLL1 yet.
TG
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-26 20:47:28
Ok, I've got PLL1 setup correctly now. It seems that there is a switch to
PLL1 in power_save_6xx. Also, a copy of HID1 is saved in init_idle_6xx
and restored in power_save_6xx_restore. Ben mentioned something about
this earlier with the clue:
If PLL1 isn't set, you should probably not set powersave_lowspeed
in arch/ppc/platforms/pmac_feature.c.
I don't understand how it is that my machine didn't lockup when PLL1 was
in the off state.
Anyway, I decided to set PLL1 in identify_cpu in misc.S. Actually, I put
the code to detect the 750fx and set PLL1 in a seperate method. Here's
what I have:
/*
* identify_cpu,
* called with r3 = data offset and r4 = CPU number
* doesn't change r3
*/
_GLOBAL(identify_cpu)
mfpvr r7
/* if pvr reports 750, check for 750fx */
srwi r6,r7,16
cmpli 0,r6,8
bne 2f
mflr r8
bl identify_cpu_750fx
mtlr r8
2:
addis r8,r3,cpu_specs@ha
addi r8,r8,cpu_specs@l
1:
lwz r5,CPU_SPEC_PVR_MASK(r8)
and r5,r5,r7
lwz r6,CPU_SPEC_PVR_VALUE(r8)
cmplw 0,r6,r5
beq 1f
addi r8,r8,CPU_SPEC_ENTRY_SIZE
b 1b
1:
addis r6,r3,cur_cpu_spec@ha
addi r6,r6,cur_cpu_spec@l
slwi r4,r4,2
sub r8,r8,r3
stwx r8,r4,r6
addis r6,r3,real_pvr@ha
stw r7,real_pvr@l(r6)
blr
/* Check for 750fx cpu strapped on as a 750. Also, if 750fx and PLL1 is
* not in use, set PLL1 to 4x and delay as needed to lock pll.
* Called with pvr in r7 (assumed to be 0x0008nnnn).
* Returns new pvr in r7.
* r5,r6 are changed.
*/
identify_cpu_750fx:
mfspr r5,SPRN_HID1
andis. r6,r5,0x0001
xori r6,r5,0x0002
beq 1f
xori r6,r5,0x0200
1:
mtspr SPRN_HID1,r6
mfspr r6,SPRN_HID1
cmplw 0,r5,r6
beqlr
/* pvr is actually 0x7000nnnn, not 0x0008nnnn */
xoris r7,r7,0x7008
mtspr SPRN_HID1,r5
andis. r6,r5,0x0001
bnelr
li r6,0x00FE
andc r5,r5,r6
ori r5,r5,0x0044
mtspr SPRN_HID1,r5
/* delay for at least 0.5sec (on 1GHz or slower cpu) */
lis r6,0x1DCE
mtctr r6
2: bdnz 2b
blr
I know HID1 is being set correctly as I modified cpuinfo to output a few
SPR's:
$ cat /proc/cpuinfo
cpu : 750FX
temperature : 19-21 C (uncalibrated)
clock : 898MHz
revision : 2.2 (pvr 7000 0202)
HID0 : 0xC010C0AC
HID1 : 0x92000044
L2CR : 0xBB000000
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 512K unified
memory : 256MB
pmac-generation : NewWorld
Comments/critique? I haven't tried cpufreq yet. That's next.
Chris.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2003-06-27 11:37:30
I don't understand how it is that my machine didn't lockup when PLL1 was
in the off state.
Well... I may have a bug making my low-speed-during-idle code not work
... Or maybe the PLL1 beeing off means the CPU will just continue
locking on PLL0...
Anyway, I decided to set PLL1 in identify_cpu in misc.S. Actually, I put
the code to detect the 750fx and set PLL1 in a seperate method. Here's
what I have:
That looks fine overall but I didn't look at the assembly in details yet,
I'll try to take some time to review your code in more detail & eventually
commit to the linuxppc trees.
Another place where you want the real PVR is the CPU save/restore state
code in cpu_setup_6xx.S. That code is used for example to save the CPU
state before sleep and restore it on wakeup.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-28 03:05:57
On Fri, 27 Jun 2003, Benjamin Herrenschmidt wrote:
Well... I may have a bug making my low-speed-during-idle code not work
... Or maybe the PLL1 beeing off means the CPU will just continue
locking on PLL0...
Maybe the latter. When I first started playing with this, I had hacked
cpufreq to change to low speed when PLL1 wasn't set. It neither changed
the frequency (obviously), nor locked up the machine.
Another place where you want the real PVR is the CPU save/restore state
code in cpu_setup_6xx.S. That code is used for example to save the CPU
state before sleep and restore it on wakeup.
I'll look into this a little more.
My patch is now working quite well for me. I've got cpufreq working and
I've verified that the cpu speed actually drops to about half when low
speed is selected. I've also modified the patch so the bulk of the code
is selectable by a config option (CONFIG_BLUECHIP_750FX). I've included
the full patch below. Let me know if you would like any changes to make
this patch more acceptable for the main linuxppc trees. Thanks for all
the help getting this working.
Chris.
diff -b -c -r linux-2.4-benh.orig/Documentation/Configure.help linux-2.4-benh/Documentation/Configure.help
*** linux-2.4-benh.orig/Documentation/Configure.help Mon Jun 16 04:32:31 2003
--- linux-2.4-benh/Documentation/Configure.help Thu Jun 26 22:15:43 2003
***************
*** 22440,22445 ****
--- 22440,22456 ----
If in doubt, say N.
+ BlueChip 750FX Support
+ CONFIG_BLUECHIP_750FX
+ If you have purchased a PowerLogix BlueChip G3 processor upgarde
+ for your machine, enabling this option will allow your IBM 750FX
+ processor to be correctly detected and allows you to use the
+ advanced features of your processor (namely, the variable clock
+ speed feature). If you don't have this type of upgrade, this
+ option has no effect.
+
+ If in doubt, say N.
+
# Choice: ppc4xxtype
Oak
CONFIG_OAK
--- linux-2.4-benh/arch/ppc/configs/pmac_defconfig Thu Jun 26 22:05:46 2003
***************
*** 29,34 ****
--- 29,35 ----
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
# CONFIG_8260 is not set
+ # CONFIG_BLUECHIP_750FX is not set
CONFIG_PPC_STD_MMU=y
CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_24_API is not set
--- linux-2.4-benh/arch/ppc/defconfig Thu Jun 26 22:06:51 2003
***************
*** 29,34 ****
--- 29,35 ----
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
# CONFIG_8260 is not set
+ # CONFIG_BLUECHIP_750FX is not set
CONFIG_PPC_STD_MMU=y
CONFIG_ALL_PPC=y
# CONFIG_APUS is not set
!
1:
lwz r5,CPU_SPEC_PVR_MASK(r8)
and r5,r5,r7
***************
*** 127,133 ****
--- 140,186 ----
slwi r4,r4,2
sub r8,r8,r3
stwx r8,r4,r6
+ addis r6,r3,real_pvr@ha
+ stw r7,real_pvr@l(r6)
+ blr
+
+ #ifdef CONFIG_BLUECHIP_750FX
+ /* Check for 750fx cpu strapped on as a 750. Also, if 750fx and PLL1 is not
+ * in use, set PLL1 to 4x and delay as needed to lock pll.
+ * Called with pvr in r7 (assumed to be 0x0008nnnn).
+ * Returns new pvr in r7.
+ * r5,r6 are changed.
+ */
+ identify_cpu_750fx:
+ mfspr r5,SPRN_HID1
+ andis. r6,r5,0x0001
+ xori r6,r5,0x0002
+ beq 1f
+ xori r6,r5,0x0200
+ 1:
+ mtspr SPRN_HID1,r6
+ mfspr r6,SPRN_HID1
+ cmplw 0,r5,r6
+ beqlr
+
+ /* pvr is actually 0x7000nnnn, not 0x0008nnnn */
+ xoris r7,r7,0x7008
+ mtspr SPRN_HID1,r5
+
+ andis. r6,r5,0x0001
+ bnelr
+
+ li r6,0x00FE
+ andc r5,r5,r6
+ ori r5,r5,4+(DEFAULT_PLL1_CONFIG<<3)
+ mtspr SPRN_HID1,r5
+
+ /* delay for at least 0.5sec (on 1GHz or slower cpu) */
+ lis r6,0x1DCE
+ mtctr r6
+ 2: bdnz 2b
blr
+ #endif /* CONFIG_BLUECHIP_750FX */
/*
* do_cpu_ftr_fixups - goes through the list of CPU feature fixups
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2003-06-28 08:23:01
On Sat, 2003-06-28 at 05:05, Chris Studholme wrote:
My patch is now working quite well for me. I've got cpufreq working and
I've verified that the cpu speed actually drops to about half when low
speed is selected. I've also modified the patch so the bulk of the code
is selectable by a config option (CONFIG_BLUECHIP_750FX). I've included
the full patch below. Let me know if you would like any changes to make
this patch more acceptable for the main linuxppc trees. Thanks for all
the help getting this working.
Looks good. Just fix the cpu_setup_6xx.S code so that sleep mode
works properly and it should be ok to merge upstream.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Chris Studholme <hidden> Date: 2003-06-30 18:57:02
On Sat, 28 Jun 2003, Benjamin Herrenschmidt wrote:
Looks good. Just fix the cpu_setup_6xx.S code so that sleep mode
works properly and it should be ok to merge upstream.
Oddly enough, sleep mode was working without HID1 and HID2 being saved;
however, I was occationally getting non-reproducable hangs on resume.
I've changed __save_cpu_setup and __restore_cpu_setup in cpu_setup_6xx.S
to use real_pvr now. Sleep/resume works fine from both high speed and low
speed. Also, I moved the setup of PLL1 to setup_750fx in cpu_setup_6xx.S.
Chris.
diff -b -c -r linux-2.4-benh.orig/Documentation/Configure.help linux-2.4-benh/Documentation/Configure.help
*** linux-2.4-benh.orig/Documentation/Configure.help Mon Jun 16 04:32:31 2003
--- linux-2.4-benh/Documentation/Configure.help Thu Jun 26 22:15:43 2003
***************
*** 22440,22445 ****
--- 22440,22456 ----
If in doubt, say N.
+ BlueChip 750FX Support
+ CONFIG_BLUECHIP_750FX
+ If you have purchased a PowerLogix BlueChip G3 processor upgarde
+ for your machine, enabling this option will allow your IBM 750FX
+ processor to be correctly detected and allows you to use the
+ advanced features of your processor (namely, the variable clock
+ speed feature). If you don't have this type of upgrade, this
+ option has no effect.
+
+ If in doubt, say N.
+
# Choice: ppc4xxtype
Oak
CONFIG_OAK
--- linux-2.4-benh/arch/ppc/configs/pmac_defconfig Thu Jun 26 22:05:46 2003
***************
*** 29,34 ****
--- 29,35 ----
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
# CONFIG_8260 is not set
+ # CONFIG_BLUECHIP_750FX is not set
CONFIG_PPC_STD_MMU=y
CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_24_API is not set
--- linux-2.4-benh/arch/ppc/defconfig Thu Jun 26 22:06:51 2003
***************
*** 29,34 ****
--- 29,35 ----
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
# CONFIG_8260 is not set
+ # CONFIG_BLUECHIP_750FX is not set
CONFIG_PPC_STD_MMU=y
CONFIG_ALL_PPC=y
# CONFIG_APUS is not set
diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/cpu_setup_6xx.S linux-2.4-benh/arch/ppc/kernel/cpu_setup_6xx.S
*** linux-2.4-benh.orig/arch/ppc/kernel/cpu_setup_6xx.S Sat May 3 14:47:07 2003
--- linux-2.4-benh/arch/ppc/kernel/cpu_setup_6xx.S Mon Jun 30 14:41:48 2003
***************
*** 185,192 ****
--- 185,210 ----
blr
/* 750fx specific
+ * If PLL1 is not active, it is set to DEFAULT_PLL1_CONFIG.
*/
setup_750fx:
+ #ifdef CONFIG_BLUECHIP_750FX
+ mfspr r10,SPRN_HID1
+ andi. r6,r10,0x00FE
+ bnelr
+ andis. r6,r10,0x0001
+ bnelr
+
+ ori r10,r10,DEFAULT_PLL1_CONFIG
+ mtspr SPRN_HID1,r10
+
+ /* wait for PLL to stabilize (approx 0.4ms) */
+ mftbl r7
+ 1: mftbl r6
+ sub r6,r6,r7
+ cmpli cr0,r6,10000
+ ble 1b
+ #endif /* CONFIG_BLUECHIP_750FX */
blr
/* MPC 745x
***************
*** 282,288 ****
stw r3,CS_HID0(r5)
/* Now deal with CPU type dependent registers */
! mfspr r3,PVR
srwi r3,r3,16
cmpli cr0,r3,0x8000 /* 7450 */
cmpli cr1,r3,0x000c /* 7400 */
--- 300,307 ----
stw r3,CS_HID0(r5)
/* Now deal with CPU type dependent registers */
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2003-07-01 09:52:49
On Mon, 2003-06-30 at 20:57, Chris Studholme wrote:
On Sat, 28 Jun 2003, Benjamin Herrenschmidt wrote:
quoted
Looks good. Just fix the cpu_setup_6xx.S code so that sleep mode
works properly and it should be ok to merge upstream.
Oddly enough, sleep mode was working without HID1 and HID2 being saved;
however, I was occationally getting non-reproducable hangs on resume.
I've changed __save_cpu_setup and __restore_cpu_setup in cpu_setup_6xx.S
to use real_pvr now. Sleep/resume works fine from both high speed and low
speed. Also, I moved the setup of PLL1 to setup_750fx in cpu_setup_6xx.S.
There are small bits of non-unified diffs in there, can you resend with
only unified (-u) diffs ? Thanks !
I'll apply to my next release and maybe to 2.4.22
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/