From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This patch cleans up the code used to initialize the 970 CPU, more
specifically, it adds support for the 970FX, makes sure we don't touch
registers we aren't supposed to when running in LPAR mode, and stop blindly
zeroing out HID4 and HID5, we just clear the bits we really want clear in
there and leave the rest to the firmware.


---

 25-akpm/arch/ppc/kernel/cpu_setup_power4.S   |   27 ++++++++++++++----
 25-akpm/arch/ppc/kernel/head.S               |    2 -
 25-akpm/arch/ppc64/kernel/cpu_setup_power4.S |   40 ++++++++++++++++++++-------
 25-akpm/arch/ppc64/kernel/head.S             |    2 -
 4 files changed, 54 insertions(+), 17 deletions(-)

diff -puN arch/ppc64/kernel/cpu_setup_power4.S~ppc-ppc64-cleanup-ppc970-cpu-initialization arch/ppc64/kernel/cpu_setup_power4.S
--- 25/arch/ppc64/kernel/cpu_setup_power4.S~ppc-ppc64-cleanup-ppc970-cpu-initialization	2004-05-04 23:13:31.948013576 -0700
+++ 25-akpm/arch/ppc64/kernel/cpu_setup_power4.S	2004-05-04 23:13:31.958012056 -0700
@@ -18,31 +18,53 @@
 #include <asm/offsets.h>
 #include <asm/cache.h>
 
-_GLOBAL(__power4_cpu_preinit)
+_GLOBAL(__970_cpu_preinit)
 	/*
-	 * On the PPC970, we have to turn off real-mode cache inhibit
-	 * early, before we first turn the MMU off.
+	 * Do nothing if not running in HV mode
+	 */
+	mfmsr	r0
+	rldicl.	r0,r0,4,63
+	beqlr
+
+	/*
+	 * Deal only with PPC970 and PPC970FX.
 	 */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
-	cmpwi	r0,0x39
+	cmpwi	cr0,r0,0x39
+	cmpwi	cr1,r0,0x3c
+	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
 	bnelr
 
+	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
+	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
+	 * HID5:DCBZ32_ill
+	 */
 	li	r0,0
+	mfspr	r3,SPRN_HID4
+	rldimi	r3,r0,40,23	/* clear bit 23 (rm_ci) */
+	rldimi	r3,r0,2,61	/* clear bit 61 (lg_pg_en) */
 	sync
-	mtspr	SPRN_HID4,r0
+	mtspr	SPRN_HID4,r3
 	isync
 	sync
-	mtspr	SPRN_HID5,r0
+	mfspr	r3,SPRN_HID5
+	rldimi	r3,r0,6,56	/* clear bits 56 & 57 (DCBZ*) */
+	sync
+	mtspr	SPRN_HID5,r3
 	isync
+	sync
 
+	/* Setup some basic HID1 features */
 	mfspr	r0,SPRN_HID1
-	li	r11,0x1200		/* enable i-fetch cacheability */
-	sldi	r11,r11,44		/* and prefetch */
-	or	r0,r0,r11
+	li	r3,0x1200		/* enable i-fetch cacheability */
+	sldi	r3,r3,44		/* and prefetch */
+	or	r0,r0,r3
 	mtspr	SPRN_HID1,r0
 	mtspr	SPRN_HID1,r0
 	isync
+
+	/* Clear HIOR */
 	li	r0,0
 	sync
 	mtspr	SPRN_HIOR,0		/* Clear interrupt prefix */
diff -puN arch/ppc64/kernel/head.S~ppc-ppc64-cleanup-ppc970-cpu-initialization arch/ppc64/kernel/head.S
--- 25/arch/ppc64/kernel/head.S~ppc-ppc64-cleanup-ppc970-cpu-initialization	2004-05-04 23:13:31.949013424 -0700
+++ 25-akpm/arch/ppc64/kernel/head.S	2004-05-04 23:13:31.959011904 -0700
@@ -1469,7 +1469,7 @@ _GLOBAL(__start_initialization_pSeries)
 	mr	r23,r3			/* Save phys address we are running at */
 
 	/* Setup some critical 970 SPRs before switching MMU off */
-	bl	.__power4_cpu_preinit
+	bl	.__970_cpu_preinit
 
 	li	r24,0			/* cpu # */
 
diff -puN arch/ppc/kernel/cpu_setup_power4.S~ppc-ppc64-cleanup-ppc970-cpu-initialization arch/ppc/kernel/cpu_setup_power4.S
--- 25/arch/ppc/kernel/cpu_setup_power4.S~ppc-ppc64-cleanup-ppc970-cpu-initialization	2004-05-04 23:13:31.951013120 -0700
+++ 25-akpm/arch/ppc/kernel/cpu_setup_power4.S	2004-05-04 23:13:31.956012360 -0700
@@ -18,24 +18,37 @@
 #include <asm/offsets.h>
 #include <asm/cache.h>
 
-_GLOBAL(__power4_cpu_preinit)
+_GLOBAL(__970_cpu_preinit)
 	/*
-	 * On the PPC970, we have to turn off real-mode cache inhibit
-	 * early, before we first turn the MMU off.
+	 * Deal only with PPC970 and PPC970FX.
 	 */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
-	cmpwi	r0,0x39
+	cmpwi	cr0,r0,0x39
+	cmpwi	cr1,r0,0x3c
+	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
 	bnelr
 
+	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
+	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
+	 * HID5:DCBZ32_ill
+	 */
 	li	r0,0
+	mfspr	r11,SPRN_HID4
+	rldimi	r11,r0,40,23	/* clear bit 23 (rm_ci) */
+	rldimi	r11,r0,2,61	/* clear bit 61 (lg_pg_en) */
 	sync
-	mtspr	SPRN_HID4,r0
+	mtspr	SPRN_HID4,r11
 	isync
 	sync
-	mtspr	SPRN_HID5,r0
+	mfspr	r11,SPRN_HID5
+	rldimi	r11,r0,6,56	/* clear bits 56 & 57 (DCBZ*) */
+	sync
+	mtspr	SPRN_HID5,r11
 	isync
+	sync
 
+	/* Setup some basic HID1 features */
 	mfspr	r0,SPRN_HID1
 	li	r11,0x1200		/* enable i-fetch cacheability */
 	sldi	r11,r11,44		/* and prefetch */
@@ -43,6 +56,8 @@ _GLOBAL(__power4_cpu_preinit)
 	mtspr	SPRN_HID1,r0
 	mtspr	SPRN_HID1,r0
 	isync
+
+	/* Clear HIOR */
 	li	r0,0
 	sync
 	mtspr	SPRN_HIOR,0		/* Clear interrupt prefix */
diff -puN arch/ppc/kernel/head.S~ppc-ppc64-cleanup-ppc970-cpu-initialization arch/ppc/kernel/head.S
--- 25/arch/ppc/kernel/head.S~ppc-ppc64-cleanup-ppc970-cpu-initialization	2004-05-04 23:13:31.953012816 -0700
+++ 25-akpm/arch/ppc/kernel/head.S	2004-05-04 23:13:31.957012208 -0700
@@ -153,7 +153,7 @@ __start:
  * like real mode cache inhibit or exception base
  */
 #ifdef CONFIG_POWER4
-	bl	__power4_cpu_preinit
+	bl	__970_cpu_preinit
 #endif /* CONFIG_POWER4 */
 
 #ifdef CONFIG_APUS

_