* Re: pismo upgraded to 750fx not detected correctly [not found] <200306200459.XAA31217@lists.linuxppc.org> @ 2003-06-20 5:53 ` Terry Greeniaus 2003-06-21 15:58 ` Chris Studholme 0 siblings, 1 reply; 21+ messages in thread From: Terry Greeniaus @ 2003-06-20 5:53 UTC (permalink / raw) To: linuxppc-dev On Thu, 19 Jun 2003, Chris Studholme wrote: > On Fri, 13 Jun 2003, Terry Greeniaus wrote: > > > 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-20 5:53 ` pismo upgraded to 750fx not detected correctly Terry Greeniaus @ 2003-06-21 15:58 ` Chris Studholme 2003-06-22 9:49 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-21 15:58 UTC (permalink / raw) To: Terry Greeniaus; +Cc: linuxppc-dev 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: > > > On Fri, 13 Jun 2003, Terry Greeniaus wrote: > > > > > 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-21 15:58 ` Chris Studholme @ 2003-06-22 9:49 ` Benjamin Herrenschmidt 2003-06-22 21:58 ` Terry Greeniaus ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-06-22 9:49 UTC (permalink / raw) To: Chris Studholme; +Cc: Terry Greeniaus, linuxppc-dev 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-22 9:49 ` Benjamin Herrenschmidt @ 2003-06-22 21:58 ` Terry Greeniaus 2003-06-23 6:01 ` Benjamin Herrenschmidt 2003-06-23 4:47 ` Chris Studholme 2003-06-26 17:02 ` how to setup PLL1 on 750FX Chris Studholme 2 siblings, 1 reply; 21+ messages in thread From: Terry Greeniaus @ 2003-06-22 21:58 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: Chris Studholme, linuxppc-dev 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-22 21:58 ` Terry Greeniaus @ 2003-06-23 6:01 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-06-23 6:01 UTC (permalink / raw) To: Terry Greeniaus; +Cc: Chris Studholme, linuxppc-dev > > 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-22 9:49 ` Benjamin Herrenschmidt 2003-06-22 21:58 ` Terry Greeniaus @ 2003-06-23 4:47 ` Chris Studholme 2003-06-23 8:27 ` Gabriel Paubert 2003-06-26 17:02 ` how to setup PLL1 on 750FX Chris Studholme 2 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-23 4:47 UTC (permalink / raw) To: linuxppc-dev; +Cc: Terry Greeniaus, Benjamin Herrenschmidt 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); diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S linux-2.4.21-ac1/arch/ppc/kernel/misc.S *** linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S Fri Jun 13 10:51:31 2003 --- linux-2.4.21-ac1/arch/ppc/kernel/misc.S Sun Jun 22 21:25:32 2003 *************** *** 113,118 **** --- 113,139 ---- addis r8,r3,cpu_specs@ha addi r8,r8,cpu_specs@l mfpvr r7 + + /* check for 750fx strapped on as 750 */ + srwi r6,r7,16 + cmpli 0,r6,8 + bne 1f + mfspr r5,0x3F1 + srwi. r6,r5,17 + bso 2f + xori r6,r5,0x0200 + b 3f + 2: + xori r6,r5,0x0002 + 3: + mtspr 0x3F1,r6 + mfspr r6,0x3F1 + cmplw 0,r5,r6 + beq 1f + + /* pvr is actually 0x7000nnnn, not 0x0008nnnn */ + xoris r7,r7,0x7008 + 1: lwz r5,CPU_SPEC_PVR_MASK(r8) and r5,r5,r7 *************** *** 127,132 **** --- 148,158 ---- slwi r4,r4,2 sub r8,r8,r3 stwx r8,r4,r6 + + addis r6,r3,real_pvr@ha + addi r6,r6,real_pvr@l + stwx r7,0,r6 + blr /* diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/prom.c linux-2.4.21-ac1/arch/ppc/kernel/prom.c *** linux-2.4.21-ac1.orig/arch/ppc/kernel/prom.c Fri Jun 13 10:51:31 2003 --- linux-2.4.21-ac1/arch/ppc/kernel/prom.c Sun Jun 22 21:31:14 2003 *************** *** 101,106 **** --- 101,176 ---- rtas(&u, rtas_data); } + /* Fix device tree for misrepresented 750FX. + */ + static void __init + prom_fixup_for_750fx(void) + { + unsigned int cpufreq; + struct device_node *cpunode, *cachenode; + u32 *value; + + /* need to calculate this somehow */ + cpufreq = 900000000; + + /* assume only one CPU */ + cpunode = find_type_devices("cpu"); + if (!cpunode) + goto out; + + value = (u32*)get_property(cpunode, "cpu-version", NULL); + if (!value) + goto out; + *value = real_pvr; + + value = (u32*)get_property(cpunode, "clock-frequency", NULL); + if (!value) + goto out; + *value = cpufreq; + + /* cache size is really 512kB */ + value = (u32*)get_property(cpunode, "d-cache-size", NULL); + if (!value) + goto out; + *value = 0x00080000 / 0x20; + + value = (u32*)get_property(cpunode, "d-cache-block-size", NULL); + if (!value) + goto out; + *value = 0x20; + + value = (u32*)get_property(cpunode, "i-cache-size", NULL); + if (!value) + goto out; + *value = 0x00080000 / 0x20; + + value = (u32*)get_property(cpunode, "i-cache-block-size", NULL); + if (!value) + goto out; + *value = 0x20; + + cachenode = find_type_devices("cache"); + if (!cachenode) + goto out; + + value = (u32*)get_property(cachenode, "d-cache-size", NULL); + if (!value) + goto out; + *value = 0x00080000; + + value = (u32*)get_property(cachenode, "i-cache-size", NULL); + if (!value) + goto out; + *value = 0x00080000; + + value = (u32*)get_property(cachenode, "clock-frequency", NULL); + if (!value) + goto out; + *value = cpufreq; + + out: + } + /* * finish_device_tree is called once things are running normally * (i.e. with text and data mapped to the address they were linked at). *************** *** 161,166 **** --- 231,239 ---- mem = finish_node(allnodes, mem, NULL, 1, 1); dev_tree_size = mem - (unsigned long) allnodes; klimit = (char *) mem; + + if ((PVR_VER(real_pvr)==0x7000) && (PVR_VER(mfspr(PVR))==8)) + prom_fixup_for_750fx(); } static unsigned long __init diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/setup.c linux-2.4.21-ac1/arch/ppc/kernel/setup.c *** linux-2.4.21-ac1.orig/arch/ppc/kernel/setup.c Fri Jun 13 10:51:31 2003 --- linux-2.4.21-ac1/arch/ppc/kernel/setup.c Sun Jun 22 20:52:25 2003 *************** *** 154,160 **** lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %lu\n", i); #else ! pvr = mfspr(PVR); lpj = loops_per_jiffy; #endif --- 154,161 ---- lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %lu\n", i); #else ! /*pvr = mfspr(PVR);*/ ! pvr = real_pvr; lpj = loops_per_jiffy; #endif diff -c -r linux-2.4.21-ac1.orig/include/asm-ppc/processor.h linux-2.4.21-ac1/include/asm-ppc/processor.h *** linux-2.4.21-ac1.orig/include/asm-ppc/processor.h Fri Jun 13 10:51:38 2003 --- linux-2.4.21-ac1/include/asm-ppc/processor.h Sun Jun 22 19:28:16 2003 *************** *** 615,620 **** --- 615,625 ---- #define _machine 0 #endif /* CONFIG_ALL_PPC */ + /* Some machines report incorrect version with mfspr(PVR). Use this global + * instead. + */ + extern unsigned int real_pvr; + struct task_struct; void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void release_thread(struct task_struct *); ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-23 4:47 ` Chris Studholme @ 2003-06-23 8:27 ` Gabriel Paubert 2003-06-23 17:16 ` Chris Studholme 2003-06-23 17:46 ` Benjamin Herrenschmidt 0 siblings, 2 replies; 21+ messages in thread From: Gabriel Paubert @ 2003-06-23 8:27 UTC (permalink / raw) To: Chris Studholme; +Cc: linuxppc-dev, Terry Greeniaus, Benjamin Herrenschmidt On Mon, Jun 23, 2003 at 12:47:56AM -0400, Chris Studholme wrote: > > 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); > diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S linux-2.4.21-ac1/arch/ppc/kernel/misc.S > *** linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S Fri Jun 13 10:51:31 2003 > --- linux-2.4.21-ac1/arch/ppc/kernel/misc.S Sun Jun 22 21:25:32 2003 > *************** > *** 113,118 **** > --- 113,139 ---- > addis r8,r3,cpu_specs@ha > addi r8,r8,cpu_specs@l > mfpvr r7 > + > + /* check for 750fx strapped on as 750 */ > + srwi r6,r7,16 > + cmpli 0,r6,8 > + bne 1f > + mfspr r5,0x3F1 > + srwi. r6,r5,17 > + bso 2f 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. > + xori r6,r5,0x0200 > + b 3f > + 2: > + xori r6,r5,0x0002 > + 3: > + mtspr 0x3F1,r6 > + mfspr r6,0x3F1 > + cmplw 0,r5,r6 > + beq 1f > + > + /* pvr is actually 0x7000nnnn, not 0x0008nnnn */ > + xoris r7,r7,0x7008 > + > 1: > lwz r5,CPU_SPEC_PVR_MASK(r8) > and r5,r5,r7 > *************** > *** 127,132 **** > --- 148,158 ---- > slwi r4,r4,2 > sub r8,r8,r3 > stwx r8,r4,r6 > + > + addis r6,r3,real_pvr@ha > + addi r6,r6,real_pvr@l > + stwx r7,0,r6 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-23 8:27 ` Gabriel Paubert @ 2003-06-23 17:16 ` Chris Studholme 2003-06-24 8:18 ` Gabriel Paubert 2003-06-23 17:46 ` Benjamin Herrenschmidt 1 sibling, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-23 17:16 UTC (permalink / raw) To: Gabriel Paubert; +Cc: linuxppc-dev, Terry Greeniaus, Benjamin Herrenschmidt On Mon, 23 Jun 2003, Gabriel Paubert wrote: > > diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S linux-2.4.21-ac1/arch/ppc/kernel/misc.S > > *** linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S Fri Jun 13 10:51:31 2003 > > --- linux-2.4.21-ac1/arch/ppc/kernel/misc.S Sun Jun 22 21:25:32 2003 > > *************** > > *** 113,118 **** > > --- 113,139 ---- > > addis r8,r3,cpu_specs@ha > > addi r8,r8,cpu_specs@l > > mfpvr r7 > > + > > + /* check for 750fx strapped on as 750 */ > > + srwi r6,r7,16 > > + cmpli 0,r6,8 > > + bne 1f > > + mfspr r5,0x3F1 > > + srwi. r6,r5,17 > > + bso 2f > > 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 > > + xori r6,r5,0x0200 > > + b 3f > > + 2: > > + xori r6,r5,0x0002 > > + 3: > > + mtspr 0x3F1,r6 > > + mfspr r6,0x3F1 > > + cmplw 0,r5,r6 > > + beq 1f > > + > > + /* pvr is actually 0x7000nnnn, not 0x0008nnnn */ > > + xoris r7,r7,0x7008 > > + > > 1: > > lwz r5,CPU_SPEC_PVR_MASK(r8) > > and r5,r5,r7 > > *************** > > *** 127,132 **** > > --- 148,158 ---- > > slwi r4,r4,2 > > sub r8,r8,r3 > > stwx r8,r4,r6 > > + > > + addis r6,r3,real_pvr@ha > > + addi r6,r6,real_pvr@l > > + stwx r7,0,r6 > > 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) > > + > > blr > > Chris. ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-23 17:16 ` Chris Studholme @ 2003-06-24 8:18 ` Gabriel Paubert 0 siblings, 0 replies; 21+ messages in thread From: Gabriel Paubert @ 2003-06-24 8:18 UTC (permalink / raw) To: Chris Studholme; +Cc: linuxppc-dev, Terry Greeniaus, Benjamin Herrenschmidt On Mon, Jun 23, 2003 at 01:16:41PM -0400, Chris Studholme wrote: > On Mon, 23 Jun 2003, Gabriel Paubert wrote: > > > diff -c -r linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S linux-2.4.21-ac1/arch/ppc/kernel/misc.S > > > *** linux-2.4.21-ac1.orig/arch/ppc/kernel/misc.S Fri Jun 13 10:51:31 2003 > > > --- linux-2.4.21-ac1/arch/ppc/kernel/misc.S Sun Jun 22 21:25:32 2003 > > > *************** > > > *** 113,118 **** > > > --- 113,139 ---- > > > addis r8,r3,cpu_specs@ha > > > addi r8,r8,cpu_specs@l > > > mfpvr r7 > > > + > > > + /* check for 750fx strapped on as 750 */ > > > + srwi r6,r7,16 > > > + cmpli 0,r6,8 > > > + bne 1f > > > + mfspr r5,0x3F1 > > > + srwi. r6,r5,17 > > > + bso 2f > > > > 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. > > > slwi r4,r4,2 > > > sub r8,r8,r3 > > > stwx r8,r4,r6 > > > + > > > + addis r6,r3,real_pvr@ha > > > + addi r6,r6,real_pvr@l > > > + stwx r7,0,r6 > > > > 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. > > 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-23 8:27 ` Gabriel Paubert 2003-06-23 17:16 ` Chris Studholme @ 2003-06-23 17:46 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-06-23 17:46 UTC (permalink / raw) To: Gabriel Paubert; +Cc: Chris Studholme, linuxppc-dev, Terry Greeniaus > > *************** > > *** 127,132 **** > > --- 148,158 ---- > > slwi r4,r4,2 > > sub r8,r8,r3 > > stwx r8,r4,r6 > > + > > + addis r6,r3,real_pvr@ha > > + addi r6,r6,real_pvr@l > > + stwx r7,0,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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* how to setup PLL1 on 750FX 2003-06-22 9:49 ` Benjamin Herrenschmidt 2003-06-22 21:58 ` Terry Greeniaus 2003-06-23 4:47 ` Chris Studholme @ 2003-06-26 17:02 ` Chris Studholme 2003-06-26 17:33 ` Terry Greeniaus 2 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-26 17:02 UTC (permalink / raw) To: linuxppc-dev; +Cc: Terry Greeniaus 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-26 17:02 ` how to setup PLL1 on 750FX Chris Studholme @ 2003-06-26 17:33 ` Terry Greeniaus 2003-06-26 20:47 ` Chris Studholme 0 siblings, 1 reply; 21+ messages in thread From: Terry Greeniaus @ 2003-06-26 17:33 UTC (permalink / raw) To: Chris Studholme; +Cc: linuxppc-dev 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-26 17:33 ` Terry Greeniaus @ 2003-06-26 20:47 ` Chris Studholme 2003-06-27 11:37 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-26 20:47 UTC (permalink / raw) To: Terry Greeniaus; +Cc: linuxppc-dev, Benjamin Herrenschmidt 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-26 20:47 ` Chris Studholme @ 2003-06-27 11:37 ` Benjamin Herrenschmidt 2003-06-28 3:05 ` Chris Studholme 0 siblings, 1 reply; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-06-27 11:37 UTC (permalink / raw) To: Chris Studholme; +Cc: Terry Greeniaus, linuxppc-dev > 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-27 11:37 ` Benjamin Herrenschmidt @ 2003-06-28 3:05 ` Chris Studholme 2003-06-28 8:23 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-28 3:05 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: Terry Greeniaus, linuxppc-dev 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 diff -b -c -r linux-2.4-benh.orig/arch/ppc/config.in linux-2.4-benh/arch/ppc/config.in *** linux-2.4-benh.orig/arch/ppc/config.in Fri May 16 09:27:13 2003 --- linux-2.4-benh/arch/ppc/config.in Thu Jun 26 22:04:18 2003 *************** *** 38,43 **** --- 38,47 ---- bool 'MPC8260 CPM Support' CONFIG_8260 fi + if [ "$CONFIG_6xx" = "y" ]; then + bool 'BlueChip 750FX Support' CONFIG_BLUECHIP_750FX + fi + if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y diff -b -c -r linux-2.4-benh.orig/arch/ppc/configs/pmac_defconfig linux-2.4-benh/arch/ppc/configs/pmac_defconfig *** linux-2.4-benh.orig/arch/ppc/configs/pmac_defconfig Mon Jun 16 04:40:40 2003 --- 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 diff -b -c -r linux-2.4-benh.orig/arch/ppc/defconfig linux-2.4-benh/arch/ppc/defconfig *** linux-2.4-benh.orig/arch/ppc/defconfig Mon Jun 16 04:40:40 2003 --- 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/cputable.c linux-2.4-benh/arch/ppc/kernel/cputable.c *** linux-2.4-benh.orig/arch/ppc/kernel/cputable.c Mon Jun 16 04:40:40 2003 --- linux-2.4-benh/arch/ppc/kernel/cputable.c Thu Jun 26 17:38:35 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); diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/misc.S linux-2.4-benh/arch/ppc/kernel/misc.S *** linux-2.4-benh.orig/arch/ppc/kernel/misc.S Thu Mar 27 05:43:31 2003 --- linux-2.4-benh/arch/ppc/kernel/misc.S Fri Jun 27 11:52:30 2003 *************** *** 110,118 **** * doesn't change r3 */ _GLOBAL(identify_cpu) addis r8,r3,cpu_specs@ha addi r8,r8,cpu_specs@l ! mfpvr r7 1: lwz r5,CPU_SPEC_PVR_MASK(r8) and r5,r5,r7 --- 110,131 ---- * doesn't change r3 */ _GLOBAL(identify_cpu) + mfpvr r7 + + #ifdef CONFIG_BLUECHIP_750FX + /* 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: + #endif /* CONFIG_BLUECHIP_750FX */ + addis r8,r3,cpu_specs@ha addi r8,r8,cpu_specs@l ! 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 diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/prom.c linux-2.4-benh/arch/ppc/kernel/prom.c *** linux-2.4-benh.orig/arch/ppc/kernel/prom.c Thu Feb 27 10:14:49 2003 --- linux-2.4-benh/arch/ppc/kernel/prom.c Fri Jun 27 11:52:00 2003 *************** *** 78,83 **** --- 78,90 ---- extern boot_infos_t *boot_infos; unsigned long dev_tree_size; + #ifdef CONFIG_BLUECHIP_750FX + /* extra properties for 750fx */ + unsigned int reduced_clock_frequency; + struct property reduced_clock_frequency_prop; + struct property dynamic_power_step_prop; + #endif /* CONFIG_BLUECHIP_750FX */ + void __openfirmware phys_call_rtas(int service, int nargs, int nret, ...) { *************** *** 101,106 **** --- 108,214 ---- rtas(&u, rtas_data); } + #ifdef CONFIG_BLUECHIP_750FX + /* Fix device tree (cpu-frequency and L2 cache size) for 750FX. + */ + static void __init + prom_fixup_for_750fx(void) + { + struct device_node *cpunode, *cachenode; + u32 *value; + unsigned int busfreq,hid1,multiplier,cpufreq=0; + unsigned int cachesize, cacheline; + + /* cache size */ + cachesize = 0x00080000; + cacheline = 64; + + /* assume only one CPU */ + cpunode = find_type_devices("cpu"); + if (!cpunode) + return; + + value = (u32*)get_property(cpunode, "cpu-version", NULL); + if (value) + *value = real_pvr; + + /* calculate cpu clock frequency */ + value = (u32*)get_property(cpunode, "bus-frequency", NULL); + if (value) { + busfreq = *value; + if (66000000<busfreq && busfreq<67000000) + busfreq=66666667; + else if (99000000<busfreq && busfreq<101000000) + busfreq=100000000; + else if (132000000<busfreq && busfreq<134000000) + busfreq=133333334; + + /* get cpu frequency multiplier */ + hid1 = mfspr(HID1); + if (hid1&0x00010000) + multiplier = (hid1>>3)&0x1F; + else if (hid1&0x00020000) + multiplier = (hid1>>11)&0x1F; + else + multiplier = (hid1>>27)&0x1F; + if (multiplier==0x1F) + multiplier=0; + else if (multiplier>20) + multiplier=(multiplier-10)*2; + else if (multiplier==3) + multiplier=2; + if (multiplier>=2) + cpufreq = busfreq * multiplier / 2; + + /* PLL1 is configured in identify_cpu_750fx (in misc.S) */ + reduced_clock_frequency = busfreq * DEFAULT_PLL1_CONFIG / 2; + memset(&reduced_clock_frequency_prop,-1, + sizeof(struct property)); + reduced_clock_frequency_prop.name = "reduced-clock-frequency"; + reduced_clock_frequency_prop.length = 4; + reduced_clock_frequency_prop.value = + (unsigned char*)&reduced_clock_frequency; + prom_add_property(cpunode,&reduced_clock_frequency_prop); + + memset(&dynamic_power_step_prop,-1,sizeof(struct property)); + dynamic_power_step_prop.name = "dynamic-power-step"; + dynamic_power_step_prop.length = 0; + dynamic_power_step_prop.value = + (unsigned char*)&dynamic_power_step_prop; + prom_add_property(cpunode,&dynamic_power_step_prop); + } + + value = (u32*)get_property(cpunode, "clock-frequency", NULL); + if (value && cpufreq) + *value = cpufreq; + + /* correct L2 cache size and clock frequency */ + cachenode = find_type_devices("cache"); + if (!cachenode) + return; + + value = (u32*)get_property(cachenode, "clock-frequency", NULL); + if (value && cpufreq) + *value = cpufreq; + + value = (u32*)get_property(cachenode, "d-cache-size", NULL); + if (value) + *value = cachesize; + + value = (u32*)get_property(cachenode, "d-cache-line-size", NULL); + if (value) + *value = cacheline; + + value = (u32*)get_property(cachenode, "i-cache-size", NULL); + if (value) + *value = cachesize; + + value = (u32*)get_property(cachenode, "i-cache-line-size", NULL); + if (value) + *value = cacheline; + } + #endif /* CONFIG_BLUECHIP_750FX */ + /* * finish_device_tree is called once things are running normally * (i.e. with text and data mapped to the address they were linked at). *************** *** 161,166 **** --- 269,279 ---- mem = finish_node(allnodes, mem, NULL, 1, 1); dev_tree_size = mem - (unsigned long) allnodes; klimit = (char *) mem; + + #ifdef CONFIG_BLUECHIP_750FX + if ((PVR_VER(real_pvr)==0x7000) && (PVR_VER(mfspr(PVR))==8)) + prom_fixup_for_750fx(); + #endif /* CONFIG_BLUECHIP_750FX */ } static unsigned long __init diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/setup.c linux-2.4-benh/arch/ppc/kernel/setup.c *** linux-2.4-benh.orig/arch/ppc/kernel/setup.c Mon Jun 16 04:40:41 2003 --- linux-2.4-benh/arch/ppc/kernel/setup.c Thu Jun 26 18:54:25 2003 *************** *** 155,161 **** lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %u\n", i); #else ! pvr = mfspr(PVR); lpj = loops_per_jiffy; #endif --- 155,161 ---- lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %u\n", i); #else ! pvr = real_pvr; lpj = loops_per_jiffy; #endif diff -b -c -r linux-2.4-benh.orig/arch/ppc/platforms/pmac_cpufreq.c linux-2.4-benh/arch/ppc/platforms/pmac_cpufreq.c *** linux-2.4-benh.orig/arch/ppc/platforms/pmac_cpufreq.c Wed Apr 30 10:29:25 2003 --- linux-2.4-benh/arch/ppc/platforms/pmac_cpufreq.c Thu Jun 26 18:58:46 2003 *************** *** 238,243 **** --- 238,244 ---- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) * - iBook2 500 (PMU based, 400Mhz & 500Mhz) * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) + * - BlueChip G3 upgraded Pismo PowerBook (CPU based) */ static int __init pmac_cpufreq_setup(void) *************** *** 302,308 **** cpufreq_uses_pmu = 1; } /* Else check for 750FX */ ! else if (PVR_VER(mfspr(PVR)) == 0x7000) { if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) goto out; hi_freq = cur_freq; --- 303,309 ---- cpufreq_uses_pmu = 1; } /* Else check for 750FX */ ! else if (PVR_VER(real_pvr) == 0x7000) { if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) goto out; hi_freq = cur_freq; diff -b -c -r linux-2.4-benh.orig/include/asm-ppc/processor.h linux-2.4-benh/include/asm-ppc/processor.h *** linux-2.4-benh.orig/include/asm-ppc/processor.h Thu Jun 26 17:19:10 2003 --- linux-2.4-benh/include/asm-ppc/processor.h Fri Jun 27 11:51:29 2003 *************** *** 559,564 **** --- 559,567 ---- #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ + /* default low speed config for cases where we set PLL1 ourselves */ + #define DEFAULT_PLL1_CONFIG 8 /* for 4x bus-speed */ + #define _GLOBAL(n)\ .globl n;\ n: *************** *** 616,621 **** --- 619,629 ---- #define _machine 0 #endif /* CONFIG_ALL_PPC */ + /* Some machines report incorrect version with mfspr(PVR). Use this global + * instead. + */ + extern unsigned int real_pvr; + struct task_struct; void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void release_thread(struct task_struct *); ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-28 3:05 ` Chris Studholme @ 2003-06-28 8:23 ` Benjamin Herrenschmidt 2003-06-30 18:57 ` Chris Studholme 0 siblings, 1 reply; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-06-28 8:23 UTC (permalink / raw) To: Chris Studholme; +Cc: Terry Greeniaus, linuxppc-dev 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-28 8:23 ` Benjamin Herrenschmidt @ 2003-06-30 18:57 ` Chris Studholme 2003-07-01 9:52 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 21+ messages in thread From: Chris Studholme @ 2003-06-30 18:57 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: Terry Greeniaus, linuxppc-dev 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 diff -b -c -r linux-2.4-benh.orig/arch/ppc/config.in linux-2.4-benh/arch/ppc/config.in *** linux-2.4-benh.orig/arch/ppc/config.in Fri May 16 09:27:13 2003 --- linux-2.4-benh/arch/ppc/config.in Thu Jun 26 22:04:18 2003 *************** *** 38,43 **** --- 38,47 ---- bool 'MPC8260 CPM Support' CONFIG_8260 fi + if [ "$CONFIG_6xx" = "y" ]; then + bool 'BlueChip 750FX Support' CONFIG_BLUECHIP_750FX + fi + if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y diff -b -c -r linux-2.4-benh.orig/arch/ppc/configs/pmac_defconfig linux-2.4-benh/arch/ppc/configs/pmac_defconfig *** linux-2.4-benh.orig/arch/ppc/configs/pmac_defconfig Mon Jun 16 04:40:40 2003 --- 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 diff -b -c -r linux-2.4-benh.orig/arch/ppc/defconfig linux-2.4-benh/arch/ppc/defconfig *** linux-2.4-benh.orig/arch/ppc/defconfig Mon Jun 16 04:40:40 2003 --- 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 */ ! lis r3,real_pvr@ha ! lwz r3,real_pvr@l(r3) srwi r3,r3,16 cmpli cr0,r3,0x8000 /* 7450 */ cmpli cr1,r3,0x000c /* 7400 */ *************** *** 318,324 **** mfspr r4,SPRN_HID1 stw r4,CS_HID1(r5) /* If rev 2.x, backup HID2 */ ! mfspr r3,PVR andi. r3,r3,0xff00 cmpi cr0,r3,0x0200 bne 1f --- 337,343 ---- mfspr r4,SPRN_HID1 stw r4,CS_HID1(r5) /* If rev 2.x, backup HID2 */ ! mfspr r3,PVR /* don't need real_pvr here */ andi. r3,r3,0xff00 cmpi cr0,r3,0x0200 bne 1f *************** *** 349,355 **** isync /* Now deal with CPU type dependent registers */ ! mfspr r3,PVR srwi r3,r3,16 cmpli cr0,r3,0x8000 /* 7450 */ cmpli cr1,r3,0x000c /* 7400 */ --- 368,375 ---- isync /* Now deal with CPU type dependent registers */ ! lis r3,(real_pvr-KERNELBASE)@ha ! lwz r3,real_pvr@l(r3) srwi r3,r3,16 cmpli cr0,r3,0x8000 /* 7450 */ cmpli cr1,r3,0x000c /* 7400 */ *************** *** 407,413 **** * to PLL 0 on all */ /* If rev 2.x, restore HID2 with low voltage bit cleared */ ! mfspr r3,PVR andi. r3,r3,0xff00 cmpi cr0,r3,0x0200 bne 4f --- 427,433 ---- * to PLL 0 on all */ /* If rev 2.x, restore HID2 with low voltage bit cleared */ ! mfspr r3,PVR /* don't need real_pvr here */ andi. r3,r3,0xff00 cmpi cr0,r3,0x0200 bne 4f diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/cputable.c linux-2.4-benh/arch/ppc/kernel/cputable.c *** linux-2.4-benh.orig/arch/ppc/kernel/cputable.c Mon Jun 16 04:40:40 2003 --- linux-2.4-benh/arch/ppc/kernel/cputable.c Thu Jun 26 17:38:35 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); diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/misc.S linux-2.4-benh/arch/ppc/kernel/misc.S *** linux-2.4-benh.orig/arch/ppc/kernel/misc.S Thu Mar 27 05:43:31 2003 --- linux-2.4-benh/arch/ppc/kernel/misc.S Mon Jun 30 12:08:47 2003 *************** *** 113,118 **** --- 113,140 ---- addis r8,r3,cpu_specs@ha addi r8,r8,cpu_specs@l mfpvr r7 + + #ifdef CONFIG_BLUECHIP_750FX + /* if pvr reports 750, check for 750fx */ + srwi r6,r7,16 + cmpli 0,r6,8 + bne 1f + + mfspr r5,SPRN_HID1 + andis. r6,r5,0x0001 + xori r6,r5,0x0002 + beq 2f + xori r6,r5,0x0200 + 2: mtspr SPRN_HID1,r6 + mfspr r6,SPRN_HID1 + cmplw 0,r5,r6 + beq 1f + + /* pvr is actually 0x7000nnnn, not 0x0008nnnn */ + xoris r7,r7,0x7008 + mtspr SPRN_HID1,r5 + #endif /* CONFIG_BLUECHIP_750FX */ + 1: lwz r5,CPU_SPEC_PVR_MASK(r8) and r5,r5,r7 *************** *** 127,132 **** --- 149,156 ---- 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 /* diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/prom.c linux-2.4-benh/arch/ppc/kernel/prom.c *** linux-2.4-benh.orig/arch/ppc/kernel/prom.c Thu Feb 27 10:14:49 2003 --- linux-2.4-benh/arch/ppc/kernel/prom.c Mon Jun 30 08:34:09 2003 *************** *** 78,83 **** --- 78,90 ---- extern boot_infos_t *boot_infos; unsigned long dev_tree_size; + #ifdef CONFIG_BLUECHIP_750FX + /* extra properties for 750fx */ + unsigned int reduced_clock_frequency; + struct property reduced_clock_frequency_prop; + struct property dynamic_power_step_prop; + #endif /* CONFIG_BLUECHIP_750FX */ + void __openfirmware phys_call_rtas(int service, int nargs, int nret, ...) { *************** *** 101,106 **** --- 108,221 ---- rtas(&u, rtas_data); } + #ifdef CONFIG_BLUECHIP_750FX + /* Fix device tree (cpu-frequency and L2 cache size) for 750FX. + */ + static void __init + prom_fixup_for_750fx(void) + { + struct device_node *cpunode, *cachenode; + u32 *value; + unsigned int cachesize, cacheline; + unsigned int busfreq,hid1,multiplier; + + /* cache size */ + cachesize = 0x00080000; + cacheline = 64; + + /* assume only one CPU */ + cpunode = find_type_devices("cpu"); + if (!cpunode) + return; + + value = (u32*)get_property(cpunode, "cpu-version", NULL); + if (value) + *value = real_pvr; + + /* L2 cache */ + cachenode = find_type_devices("cache"); + if (!cachenode) + return; + + value = (u32*)get_property(cachenode, "d-cache-size", NULL); + if (value) + *value = cachesize; + + value = (u32*)get_property(cachenode, "d-cache-line-size", NULL); + if (value) + *value = cacheline; + + value = (u32*)get_property(cachenode, "i-cache-size", NULL); + if (value) + *value = cachesize; + + value = (u32*)get_property(cachenode, "i-cache-line-size", NULL); + if (value) + *value = cacheline; + + /* calculate cpu clock frequency */ + value = (u32*)get_property(cpunode, "bus-frequency", NULL); + if (value && *value>0) { + busfreq = *value; + if (66000000<busfreq && busfreq<67000000) + busfreq=66666667; + else if (99000000<busfreq && busfreq<101000000) + busfreq=100000000; + else if (132000000<busfreq && busfreq<134000000) + busfreq=133333334; + + /* get frequency multiplier (current speed) */ + hid1 = mfspr(HID1); + if (hid1&0x00010000) + multiplier = (hid1>>3)&0x1F; + else if (hid1&0x00020000) + multiplier = (hid1>>11)&0x1F; + else + multiplier = (hid1>>27)&0x1F; + if (multiplier==0x1F) + multiplier=0; + else if (multiplier>20) + multiplier=(multiplier-10)*2; + else if (multiplier==3) + multiplier=2; + if (multiplier>=2) { + value = (u32*)get_property(cpunode,"clock-frequency",NULL); + if (value) + *value = busfreq * multiplier / 2; + + value = (u32*)get_property(cachenode,"clock-frequency",NULL); + if (value) + *value = busfreq * multiplier / 2; + } + + /* get frequency multiplier (low speed) */ + multiplier = (hid1>>3)&0x1F; + if (multiplier==0x1F) + multiplier=0; + else if (multiplier>20) + multiplier=(multiplier-10)*2; + else if (multiplier==3) + multiplier=2; + if (multiplier>=2) { + reduced_clock_frequency = busfreq * multiplier / 2; + memset(&reduced_clock_frequency_prop,-1,sizeof(struct property)); + reduced_clock_frequency_prop.name = "reduced-clock-frequency"; + reduced_clock_frequency_prop.length = 4; + reduced_clock_frequency_prop.value = + (unsigned char*)&reduced_clock_frequency; + prom_add_property(cpunode,&reduced_clock_frequency_prop); + + memset(&dynamic_power_step_prop,-1,sizeof(struct property)); + dynamic_power_step_prop.name = "dynamic-power-step"; + dynamic_power_step_prop.length = 0; + dynamic_power_step_prop.value = + (unsigned char*)&dynamic_power_step_prop; + prom_add_property(cpunode,&dynamic_power_step_prop); + } + } + } + #endif /* CONFIG_BLUECHIP_750FX */ + /* * finish_device_tree is called once things are running normally * (i.e. with text and data mapped to the address they were linked at). *************** *** 161,166 **** --- 276,286 ---- mem = finish_node(allnodes, mem, NULL, 1, 1); dev_tree_size = mem - (unsigned long) allnodes; klimit = (char *) mem; + + #ifdef CONFIG_BLUECHIP_750FX + if ((PVR_VER(real_pvr)==0x7000) && (PVR_VER(mfspr(PVR))==8)) + prom_fixup_for_750fx(); + #endif /* CONFIG_BLUECHIP_750FX */ } static unsigned long __init diff -b -c -r linux-2.4-benh.orig/arch/ppc/kernel/setup.c linux-2.4-benh/arch/ppc/kernel/setup.c *** linux-2.4-benh.orig/arch/ppc/kernel/setup.c Mon Jun 16 04:40:41 2003 --- linux-2.4-benh/arch/ppc/kernel/setup.c Thu Jun 26 18:54:25 2003 *************** *** 155,161 **** lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %u\n", i); #else ! pvr = mfspr(PVR); lpj = loops_per_jiffy; #endif --- 155,161 ---- lpj = cpu_data[i].loops_per_jiffy; seq_printf(m, "processor\t: %u\n", i); #else ! pvr = real_pvr; lpj = loops_per_jiffy; #endif diff -b -c -r linux-2.4-benh.orig/arch/ppc/platforms/pmac_cpufreq.c linux-2.4-benh/arch/ppc/platforms/pmac_cpufreq.c *** linux-2.4-benh.orig/arch/ppc/platforms/pmac_cpufreq.c Wed Apr 30 10:29:25 2003 --- linux-2.4-benh/arch/ppc/platforms/pmac_cpufreq.c Thu Jun 26 18:58:46 2003 *************** *** 238,243 **** --- 238,244 ---- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) * - iBook2 500 (PMU based, 400Mhz & 500Mhz) * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) + * - BlueChip G3 upgraded Pismo PowerBook (CPU based) */ static int __init pmac_cpufreq_setup(void) *************** *** 302,308 **** cpufreq_uses_pmu = 1; } /* Else check for 750FX */ ! else if (PVR_VER(mfspr(PVR)) == 0x7000) { if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) goto out; hi_freq = cur_freq; --- 303,309 ---- cpufreq_uses_pmu = 1; } /* Else check for 750FX */ ! else if (PVR_VER(real_pvr) == 0x7000) { if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) goto out; hi_freq = cur_freq; diff -b -c -r linux-2.4-benh.orig/include/asm-ppc/processor.h linux-2.4-benh/include/asm-ppc/processor.h *** linux-2.4-benh.orig/include/asm-ppc/processor.h Thu Jun 26 17:19:10 2003 --- linux-2.4-benh/include/asm-ppc/processor.h Mon Jun 30 13:53:17 2003 *************** *** 559,564 **** --- 559,567 ---- #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ + /* default low speed config for cases where we set PLL1 ourselves */ + #define DEFAULT_PLL1_CONFIG 0x44 /* for 4x bus-speed and <600MHz */ + #define _GLOBAL(n)\ .globl n;\ n: *************** *** 616,621 **** --- 619,629 ---- #define _machine 0 #endif /* CONFIG_ALL_PPC */ + /* Some machines report incorrect version with mfspr(PVR). Use this global + * instead. + */ + extern unsigned int real_pvr; + struct task_struct; void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void release_thread(struct task_struct *); ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: how to setup PLL1 on 750FX 2003-06-30 18:57 ` Chris Studholme @ 2003-07-01 9:52 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 21+ messages in thread From: Benjamin Herrenschmidt @ 2003-07-01 9:52 UTC (permalink / raw) To: Chris Studholme; +Cc: Terry Greeniaus, linuxppc-dev On Mon, 2003-06-30 at 20:57, Chris Studholme wrote: > 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. 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/ ^ permalink raw reply [flat|nested] 21+ messages in thread
[parent not found: <200306130459.XAA18908@lists.linuxppc.org>]
* Re: pismo upgraded to 750fx not detected correctly [not found] <200306130459.XAA18908@lists.linuxppc.org> @ 2003-06-13 5:44 ` Terry Greeniaus 2003-06-19 18:18 ` Chris Studholme 0 siblings, 1 reply; 21+ messages in thread From: Terry Greeniaus @ 2003-06-13 5:44 UTC (permalink / raw) To: linuxppc-dev On Thu, 12 Jun 2003, Chris Studholme wrote: > I have a Powerbook G3 (Pismo) 400MHz that I've been running Linux on for > almost 3 years now. It has been working great, but to ensure that it > continues to serve me well, I purchased the Powerlogix BlueChip G3 900MHz > upgrade <http://www.powerlogix.com/products2/bcg3pismo/index.html>. The > machine still runs Linux ok, but I have a few problems. > > First off, the new processor is an IBM 750FX, but it is recognized as a > 740/750. > > $ cat /proc/cpuinfo > cpu : 740/750 > temperature : 20 C (uncalibrated) > clock : 550MHz > revision : 2.2 (pvr 0008 0202) > bogomips : 1795.68 > machine : PowerBook3,1 > motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh > detected as : 70 (PowerBook Pismo) > pmac flags : 00000007 > L2 cache : 1024K unified > memory : 256MB > pmac-generation : NewWorld > > I believe pvr should be 7000 0202. Also, the clock speed is 900MHz, not > 550MHz. I have verified, using some numerical cpu bound programs I have, > that this machine is running at least twice as fast as it did before the > upgrade. Also, note that the bogomips value seems to imply the machine is > actually running at 900MHz. Finally, the L2 cache is now only 512K, but > included on the processor die running at 900MHz. [mega-snip] 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. As for why it is showing up as 1MB L2 cache, I'm not sure except that the firmware writes to the 750FX L2CR as though it were a 1MB 750 L2 cache, and then Linux may be reading that value back later on. It's harmless since those other bits in the 750FX L2CR don't do anything, but it might be confusing the kernel. As for why your test program didn't ramp up/down in speed as you changed the PLL ratio, I don't know, but I didn't look over it very carefully. These CPUs definitely support it, so you were probably doing something incorrectly, or maybe the code wasn't allowing it because it thinks it is a 750 and not a 750FX CPU. TG ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: pismo upgraded to 750fx not detected correctly 2003-06-13 5:44 ` pismo upgraded to 750fx not detected correctly Terry Greeniaus @ 2003-06-19 18:18 ` Chris Studholme 0 siblings, 0 replies; 21+ messages in thread From: Chris Studholme @ 2003-06-19 18:18 UTC (permalink / raw) To: linuxppc-dev On Fri, 13 Jun 2003, Terry Greeniaus wrote: > 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? Chris. ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* pismo upgraded to 750fx not detected correctly
@ 2003-06-12 20:05 Chris Studholme
0 siblings, 0 replies; 21+ messages in thread
From: Chris Studholme @ 2003-06-12 20:05 UTC (permalink / raw)
To: linuxppc-dev
Hi all,
I have a Powerbook G3 (Pismo) 400MHz that I've been running Linux on for
almost 3 years now. It has been working great, but to ensure that it
continues to serve me well, I purchased the Powerlogix BlueChip G3 900MHz
upgrade <http://www.powerlogix.com/products2/bcg3pismo/index.html>. The
machine still runs Linux ok, but I have a few problems.
First off, the new processor is an IBM 750FX, but it is recognized as a
740/750.
$ cat /proc/cpuinfo
cpu : 740/750
temperature : 20 C (uncalibrated)
clock : 550MHz
revision : 2.2 (pvr 0008 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 00000007
L2 cache : 1024K unified
memory : 256MB
pmac-generation : NewWorld
I believe pvr should be 7000 0202. Also, the clock speed is 900MHz, not
550MHz. I have verified, using some numerical cpu bound programs I have,
that this machine is running at least twice as fast as it did before the
upgrade. Also, note that the bogomips value seems to imply the machine is
actually running at 900MHz. Finally, the L2 cache is now only 512K, but
included on the processor die running at 900MHz.
I don't know the linux source that well, but it looks to me like these
values are being read from the open firmware and not from the cpu
directly. Is there a way I can alter linux to double check the values and
correct them if the firmware is wrong? As a first stab at the problem, I
made the following change to arch/ppc/kernel/cputable.c (in 2.4.20-ben10):
*** cputable.c.orig Tue May 27 16:38:20 2003
--- cputable.c Tue May 27 16:42:14 2003
***************
*** 161,166 ****
--- 161,175 ----
32, 32,
__setup_cpu_750fx
},
+ { /* 750FX (Powerlogix Pismo upgrade) */
+ 0xffffffff, 0x00080202, "750FX",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
+ CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
+ COMMON_PPC,
+ 32, 32,
+ __setup_cpu_750fx
+ },
{ /* 740/750 (L2CR bit need fixup for 740) */
0xffff0000, 0x00080000, "740/750",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
This corrects cpuinfo slightly, but is obviously not a very good solution.
$ cat /proc/cpuinfo
cpu : 750FX
temperature : 20 C (uncalibrated)
clock : 550MHz
revision : 2.2 (pvr 0008 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 1024K unified
memory : 256MB
pmac-generation : NewWorld
Also, note that MacOS also fails to correctly detect the cpu and clock
speed. To get the correct values and fiddle with the 750fx's fancy
features (like clock speed scaling), I had to install a tool developed by
Powerlogix called CPU Director
<http://www.powerlogix.com/support2/cpudirector/index.html>.
My motivation for this work is not just to get cpuinfo to display the
correct data, but to get cpufreq working on this machine. With the
following patch to arch/ppc/platforms/pmac_cpufreq.c I think I've come
close.
*** pmac_cpufreq.c.orig Wed May 21 23:33:27 2003
--- pmac_cpufreq.c Thu Jun 12 14:22:22 2003
***************
*** 19,25 ****
#include <asm/cputable.h>
#include <asm/time.h>
! #undef DEBUG_FREQ
extern void low_choose_750fx_pll(int pll);
extern void low_sleep_handler(void);
--- 19,25 ----
#include <asm/cputable.h>
#include <asm/time.h>
! #define DEBUG_FREQ
extern void low_choose_750fx_pll(int pll);
extern void low_sleep_handler(void);
***************
*** 304,309 ****
--- 304,318 ----
has_freq_ctl = 1;
cpufreq_uses_pmu = 1;
}
+ /* Else check for Pismo/Powerlogix 900 */
+ else if (machine_is_compatible("PowerBook3,1")) {
+ printk("CPUFREQ: pismo detected\n");
+ cur_freq = 900000;
+ low_freq = 400000;
+ hi_freq = 900000;
+ cpufreq_uses_pmu = 0;
+ has_freq_ctl = 1;
+ }
/* Else check for 750FX */
else if (PVR_VER(mfspr(PVR)) == 0x7000) {
if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
After boot with this change, I get:
$ cat /proc/cpuinfo
cpu : 750FX
temperature : 20 C (uncalibrated)
clock : 900MHz
revision : 2.2 (pvr 0008 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 1024K unified
memory : 256MB
pmac-generation : NewWorld
$ cat /proc/cpufreq
minimum CPU frequency - maximum CPU frequency - policy
CPU 0 400000 kHz ( 44 %) - 900000 kHz (100 %) - performance
Now, I can try to change processor speed as follows:
# echo -n "0:0:0:powersave" > /proc/cpufreq
# cat /proc/cpuinfo
cpu : 750FX
temperature : 24 C (uncalibrated)
clock : 400MHz
revision : 2.2 (pvr 0008 0202)
bogomips : 798.08
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 1024K unified
memory : 256MB
pmac-generation : NewWorld
# cat /proc/cpufreq
minimum CPU frequency - maximum CPU frequency - policy
CPU 0 400000 kHz ( 44 %) - 400000 kHz ( 44 %) - powersave
And to return to top speed:
# echo -n "0:900000:900000:performance" > /proc/cpufreq
# cat /proc/cpuinfo
cpu : 750FX
temperature : 39 C (uncalibrated)
clock : 900MHz
revision : 2.2 (pvr 0008 0202)
bogomips : 1795.68
machine : PowerBook3,1
motherboard : PowerBook3,1 MacRISC2 MacRISC Power Macintosh
detected as : 70 (PowerBook Pismo)
pmac flags : 0000000f
L2 cache : 1024K unified
memory : 256MB
pmac-generation : NewWorld
# cat /proc/cpufreq
minimum CPU frequency - maximum CPU frequency - policy
CPU 0 900000 kHz (100 %) - 900000 kHz (100 %) - performance
Relevent lines from `dmesg` are:
Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb
Total memory = 256MB; using 512kB for hash table (at c0280000)
Linux version 2.4.20-ben10 (cvs@achilles) (gcc version 2.95.4 20011002 (Debian prerelease)) #10 Thu May 29 16:51:37 EDT
Found Uninorth memory controller & host bridge, revision: 7
Mapped at 0xfdffc000
Found a Keylargo mac-io controller, rev: 3, mapped at 0xfdf7c000
Processor NAP mode on idle enabled.
PowerMac motherboard: PowerBook Pismo
CPU HID1 : 0x92000000
.. other stuff ..
Initializing RT netlink socket
Thermal assist unit using timers, shrink_timer: 200 jiffies
CPUFREQ: pismo detected
Starting kswapd
.. other stuff ..
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
Yenta IRQ list 0000, PCI irq58
Socket status: 30000086
HID1, before: 92000000
HID1, after: 92010000
Calibrating delay loop... 897.84 BogoMIPS
HID1, before: 92010000
HID1, after: 92000000
Calibrating delay loop... 1795.68 BogoMIPS
Note that at low speed (400MHz), the bogomips value reported in cpuinfo is
as expected, but the debug message above seems to indicate a clock speed
of 450MHz.
Anyway, all this appeared quite nice, but it doesn't work. I wrote the
following little program to try to verify the cpu freq change:
#include <stdio.h>
#include <time.h>
int main() {
clock_t start,end;
int i,j;
do {
start = clock();
j = 0;
for (i=0; i<100*1000*1000; ++i) j+=i;
end = clock();
printf("%d\n",(int)(end-start));
} while (1);
return 0;
}
and compiled it without any optimization. Here's some sample output:
$ ./speed
1150000
1140000
1140000
1140000
1150000
1150000
1140000
1140000
1120000
1090000
1130000
1140000
1150000
These lines are output about one per second. I expect both the number and
the rate at which the lines are output to change by about a factor of 2
when the cpu freq changes; however, this does not happen.
At this point, I'm stuck. I hope you can provide comments and
suggestions. Please let me know if there is any more info I can provide
or if there is something else I should try. Thanks.
Chris.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 21+ messages in threadend of thread, other threads:[~2003-07-01 9:52 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200306200459.XAA31217@lists.linuxppc.org>
2003-06-20 5:53 ` pismo upgraded to 750fx not detected correctly Terry Greeniaus
2003-06-21 15:58 ` Chris Studholme
2003-06-22 9:49 ` Benjamin Herrenschmidt
2003-06-22 21:58 ` Terry Greeniaus
2003-06-23 6:01 ` Benjamin Herrenschmidt
2003-06-23 4:47 ` Chris Studholme
2003-06-23 8:27 ` Gabriel Paubert
2003-06-23 17:16 ` Chris Studholme
2003-06-24 8:18 ` Gabriel Paubert
2003-06-23 17:46 ` Benjamin Herrenschmidt
2003-06-26 17:02 ` how to setup PLL1 on 750FX Chris Studholme
2003-06-26 17:33 ` Terry Greeniaus
2003-06-26 20:47 ` Chris Studholme
2003-06-27 11:37 ` Benjamin Herrenschmidt
2003-06-28 3:05 ` Chris Studholme
2003-06-28 8:23 ` Benjamin Herrenschmidt
2003-06-30 18:57 ` Chris Studholme
2003-07-01 9:52 ` Benjamin Herrenschmidt
[not found] <200306130459.XAA18908@lists.linuxppc.org>
2003-06-13 5:44 ` pismo upgraded to 750fx not detected correctly Terry Greeniaus
2003-06-19 18:18 ` Chris Studholme
2003-06-12 20:05 Chris Studholme
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).