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

Charlie Paul cpaul.windriver at gmail.com
Tue Jul 8 07:22:05 PDT 2014


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

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

diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
index 0debcc3..5505f46 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;
 
@@ -60,7 +63,7 @@ static irqreturn_t l2c_error_handler(int irq, void *dev)
 	}
 
 	/* Clear parity errors */
-	if (sr & (L2C_SR_CPE | L2C_SR_TPE)){
+	if (sr & (L2C_SR_CPE | L2C_SR_TPE)) {
 		mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, 0);
 		mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);
 	} else {
@@ -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.7.9.5



More information about the linux-yocto mailing list