From: John Jacques <john.jacq...@lsi.com> Signed-off-by: John Jacques <john.jacq...@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 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto