Skip to contentSkip to conversation

PowerPC: Add cpu_setup functionality to 44x platform

PATCH In review Valentine Barshak 2 participants 5 messages Sep 21, 2007 – Sep 26, 2007 PowerPC

lore
Share & tools
lore
#0 lore raw

cover PowerPC: Add cpu_setup functionality to 44x platform

This patchset adds cpu_setup functionality to PowerPC 44x, moves FPU init to cpu_setup callback and adds 440EPx/440GRx incorrect write to DDR SDRAM errata workaround.

#1 lore raw

PATCH 1/3 PowerPC: Introduce cpu_setup functionality to 44x platform

This adds cpu_setup functionality for ppc44x platform. Low level cpu-spefic initialization routines should be placed in cpu_setup_44x.S and a callback should be added to cputable. The cpu_setup is invoked by identify_cpu() function at early init.

---
 arch/powerpc/kernel/Makefile        |    1 +
 arch/powerpc/kernel/cpu_setup_44x.S |   19 +++++++++++++++++++
 arch/powerpc/kernel/cputable.c      |   13 +++++++------
 3 files changed, 27 insertions(+), 6 deletions(-)
arch/powerpc/kernel/cpu_setup_44x.S +19 -0
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cpu_setup_44x.S linux-2.6/arch/powerpc/kernel/cpu_setup_44x.S
@@ -0,0 +1,19 @@
+/*
+ * This file contains low level CPU setup functions.
+ * Valentine Barshak <[email protected]>
+ * MontaVista Software, Inc (c) 2007
+ *
+ * Based on cpu_setup_6xx code by 
+ * Benjamin Herrenschmidt <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+
arch/powerpc/kernel/cputable.c +7 -6
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cputable.c linux-2.6/arch/powerpc/kernel/cputable.c
@@ -1319,17 +1319,18 @@
 	for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
 		if ((pvr & s->pvr_mask) == s->pvr_value) {
 			*cur = cpu_specs + i;
-#ifdef CONFIG_PPC64
-			/* ppc64 expects identify_cpu to also call setup_cpu
-			 * for that processor. I will consolidate that at a
-			 * later time, for now, just use our friend #ifdef.
+#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
+			/* ppc64 and booke expect identify_cpu to also call 
+			 * setup_cpu for that processor. I will consolidate
+			 * that at a later time, for now, just use #ifdef.
 			 * we also don't need to PTRRELOC the function pointer
-			 * on ppc64 as we are running at 0 in real mode.
+			 * on ppc64 and booke as we are running at 0 in real
+			 * mode on ppc64 and reloc_offset is always 0 on booke.
 			 */
 			if (s->cpu_setup) {
 				s->cpu_setup(offset, s);
 			}
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
 			return s;
 		}
 	BUG();
arch/powerpc/kernel/Makefile +1 -0
diff -ruN linux-2.6.orig/arch/powerpc/kernel/Makefile linux-2.6/arch/powerpc/kernel/Makefile
@@ -56,6 +56,7 @@
 				   udbg.o misc.o io.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o
 obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
+obj-$(CONFIG_44x)		+= cpu_setup_44x.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
#2 lore raw

PATCH 2/3 PowerPC: Move 440EP(x) FPU setup from head_44x to cpu_setup_4xx

In reply to Valentine Barshak

The PowerPC 440EP(x) FPU init is currently done in head_44x under ifdefs. Since we should support more then one board in the same kernel, we move FPU initialization code from head_44x to cpu_setup_44x and add cpu_setup callbacks for 440EP(x).

---
 arch/powerpc/kernel/cpu_setup_44x.S |   14 ++++++++++++++
 arch/powerpc/kernel/cputable.c      |    6 ++++++
 arch/powerpc/kernel/head_44x.S      |   10 ----------
 3 files changed, 20 insertions(+), 10 deletions(-)
arch/powerpc/kernel/cpu_setup_44x.S +14 -0
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cpu_setup_44x.S linux-2.6/arch/powerpc/kernel/cpu_setup_44x.S
@@ -17,3 +17,17 @@
 #include <asm/cputable.h>
 #include <asm/ppc_asm.h>
 
+_GLOBAL(__setup_cpu_440ep)
+	b	__init_fpu_44x
+_GLOBAL(__setup_cpu_440epx)
+	b	__init_fpu_44x
+
+/* enable APU between CPU and FPU */
+_GLOBAL(__init_fpu_44x)
+	mfspr	r3,SPRN_CCR0
+	/* Clear DAPUIB flag in CCR0 */
+	rlwinm	r3,r3,0,12,10
+	mtspr	SPRN_CCR0,r3
+	isync
+	blr
+
arch/powerpc/kernel/cputable.c +6 -0
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cputable.c linux-2.6/arch/powerpc/kernel/cputable.c
@@ -31,6 +31,8 @@
  * and ppc64
  */
 #ifdef CONFIG_PPC32
+extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -1111,6 +1113,7 @@
 		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440ep,
 		.platform		= "ppc440",
 	},
 	{
@@ -1121,6 +1124,7 @@
 		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440ep,
 		.platform		= "ppc440",
 	},
 	{ /* 440EPX */
@@ -1131,6 +1135,8 @@
 		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440epx,
+		.platform		= "ppc440",
 	},
 	{ /* 440GRX */
 		.pvr_mask		= 0xf0000ffb,
arch/powerpc/kernel/head_44x.S +0 -10
diff -ruN linux-2.6.orig/arch/powerpc/kernel/head_44x.S linux-2.6/arch/powerpc/kernel/head_44x.S
@@ -217,16 +217,6 @@
 	lis	r4,interrupt_base@h	/* IVPR only uses the high 16-bits */
 	mtspr	SPRN_IVPR,r4
 
-#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
-	/* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
-	mfspr	r2,SPRN_CCR0
-	lis	r3,0xffef
-	ori	r3,r3,0xffff
-	and	r2,r2,r3
-	mtspr	SPRN_CCR0,r2
-	isync
-#endif
-
 	/*
 	 * This is where the main kernel code starts.
 	 */
#3 lore raw

PATCH 3/3 PowerPC: 440EPx/GRx incorrect write to DDR SDRAM errata workaround

In reply to Valentine Barshak

Add a workaround for PowerPC 440EPx/GRx incorrect write to DDR SDRAM errata. Data can be written to wrong address in SDRAM when write pipelining enabled on plb0. We disable it in the cpu_setup for these processors at early init.

---
 arch/powerpc/kernel/cpu_setup_44x.S |   25 ++++++++++++++++++++++++-
 arch/powerpc/kernel/cputable.c      |    3 +++
 2 files changed, 27 insertions(+), 1 deletion(-)
arch/powerpc/kernel/cpu_setup_44x.S +24 -1
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cpu_setup_44x.S linux-2.6/arch/powerpc/kernel/cpu_setup_44x.S
@@ -20,7 +20,14 @@
 _GLOBAL(__setup_cpu_440ep)
 	b	__init_fpu_44x
 _GLOBAL(__setup_cpu_440epx)
-	b	__init_fpu_44x
+	mflr	r4
+	bl	__init_fpu_44x
+	bl	__plb_disable_wrp
+	mtlr	r4
+	blr
+_GLOBAL(__setup_cpu_440grx)
+	b	__plb_disable_wrp
+
 
 /* enable APU between CPU and FPU */
 _GLOBAL(__init_fpu_44x)
@@ -31,3 +38,19 @@
 	isync
 	blr
 
+/*
+ * Workaround for the incorrect write to DDR SDRAM errata.
+ * The write address can be corrupted during writes to
+ * DDR SDRAM when write pipelining is enabled on PLB0.
+ * Disable write pipelining here.
+ */
+#define DCRN_PLB4A0_ACR	0x81
+
+_GLOBAL(__plb_disable_wrp)
+	mfdcr	r3,DCRN_PLB4A0_ACR
+	/* clear WRP bit in PLB4A0_ACR */
+	rlwinm	r3,r3,0,8,6
+	mtdcr	DCRN_PLB4A0_ACR,r3
+	isync
+	blr
+
arch/powerpc/kernel/cputable.c +3 -0
diff -ruN linux-2.6.orig/arch/powerpc/kernel/cputable.c linux-2.6/arch/powerpc/kernel/cputable.c
@@ -33,6 +33,7 @@
 #ifdef CONFIG_PPC32
 extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -1146,6 +1147,8 @@
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440grx,
+		.platform		= "ppc440",
 	},
 	{	/* 440GP Rev. B */
 		.pvr_mask		= 0xf0000fff,
#4 lore raw
In reply to Valentine Barshak
Quoted 3 lines · On Fri, 21 Sep 2007 18:41:49 +0400 Valentine Barshak <[email protected]>…

This patchset adds cpu_setup functionality to PowerPC 44x, moves FPU init to cpu_setup callback and adds 440EPx/440GRx incorrect write to DDR SDRAM errata workaround.

This set looks pretty good to me. Aside from the slight oddity of adding an essentially empty file in the first patch. But it makes things nicely bisectable and I asked for it to be done that way.

Unless someone has objections, I'll probably pull this in soon after I test a bit.

josh