[linux-yocto] [PATCH 07/35] arch/powerpc: Reset Updates for Axxia

Daniel Dragomir daniel.dragomir at windriver.com
Thu Nov 13 09:19:34 PST 2014


From: John Jacques <john.jacques at lsi.com>

There is a hardware issue on the 3500 that requires resets to be
issued using the system control register instead of dbcr0.  This
patch implements that work around when the PVR is 0x7ff520c1.

Signed-off-by: John Jacques <john.jacques at lsi.com>
---
 arch/powerpc/sysdev/ppc4xx_soc.c | 71 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
index 0debcc3..a596888 100644
--- a/arch/powerpc/sysdev/ppc4xx_soc.c
+++ b/arch/powerpc/sysdev/ppc4xx_soc.c
@@ -24,6 +24,9 @@
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
 #include <asm/reg.h>
+#ifdef CONFIG_ACP
+#include <asm/mpic.h>
+#endif
 
 static u32 dcrbase_l2c;
 
@@ -190,6 +193,45 @@ static int __init ppc4xx_l2c_probe(void)
 }
 arch_initcall(ppc4xx_l2c_probe);
 
+#ifdef CONFIG_ACP
+
+/*
+ * Issue a "core" reset.
+ */
+
+void
+acp_jump_to_boot_loader(void *input)
+{
+	mpic_teardown_this_cpu(0);
+	/* This is only valid in the "core" reset case, so 0x10000000. */
+	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | 0x10000000);
+
+	while (1)
+		;		/* Just in case the jump fails. */
+}
+
+/*
+ * Get all other cores to run "acp_jump_to_boot_loader()" then go
+ * there as well.
+ */
+
+void
+acp_reset_cores(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		if (cpu != smp_processor_id())
+			smp_call_function_single(cpu, acp_jump_to_boot_loader,
+						 NULL, 0);
+	}
+
+	acp_jump_to_boot_loader(NULL);
+}
+
+
+#endif
+
 /*
  * Apply a system reset. Alternatively a board specific value may be
  * provided via the "reset-type" property in the cpu node.
@@ -214,7 +256,36 @@ void ppc4xx_reset_system(char *cmd)
 			reset_type = prop[0] << 28;
 	}
 
+#ifdef CONFIG_ACP
+	if (DBCR0_RST_CORE == reset_type) {
+		acp_reset_cores();
+	} else {
+		/*
+		  In this case, reset_type is either chip or system.
+
+		  On the AXM3500 (PVR=0x7ff520c1), writing to DBCR0
+		  will occasionally stall the system.  As a
+		  work-around, write to the system control register.
+		*/
+
+		u32 pvr_value;
+
+		asm volatile ("mfpvr    %0" : "=r"(pvr_value));
+
+		if (0x7ff520c1 == pvr_value) {
+			u32 value;
+
+			value = mfdcrx(0xd0a);
+			value |= 0xab;
+			mtdcrx(0xd0a, value);
+			mtdcrx(0xe00, 1);
+		} else {
+			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | reset_type);
+		}
+	}
+#else
 	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | reset_type);
+#endif
 
 	while (1)
 		;	/* Just in case the reset doesn't work */
-- 
1.8.1.4



More information about the linux-yocto mailing list