how to setup PLL1 on 750FX

Chris Studholme cvs at cs.utoronto.ca
Tue Jul 1 04:57:02 EST 2003


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 at ha
! 	lwz	r3,real_pvr at 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 at 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 at ha
  	addi	r8,r8,cpu_specs at 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 at ha
+ 	stw	r7,real_pvr at 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/





More information about the Linuxppc-dev mailing list