powerpc/8xx: Fix early debug when SMC1 is relocated
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Fri, 4 Dec 2020 10:11:34 +0000 (10:11 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 9 Dec 2020 06:00:54 +0000 (17:00 +1100)
When SMC1 is relocated and early debug is selected, the
board hangs is ppc_md.setup_arch(). This is because ones
the microcode has been loaded and SMC1 relocated, early
debug writes in the weed.

To allow smooth continuation, the SMC1 parameter RAM set up
by the bootloader have to be copied into the new location.

Fixes: 43db76f41824 ("powerpc/8xx: Add microcode patch to move SMC parameter RAM.")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/b2f71f39eca543f1e4ec06596f09a8b12235c701.1607076683.git.christophe.leroy@csgroup.eu
arch/powerpc/include/asm/cpm1.h
arch/powerpc/platforms/8xx/micropatch.c

index a116fe9317892e93426c7904a3b70d3b098e3708..3bdd74739cb88ee621c70a10ec513c2cbccbd3ca 100644 (file)
@@ -68,6 +68,7 @@ extern void cpm_reset(void);
 #define PROFF_SPI      ((uint)0x0180)
 #define PROFF_SCC3     ((uint)0x0200)
 #define PROFF_SMC1     ((uint)0x0280)
+#define PROFF_DSP1     ((uint)0x02c0)
 #define PROFF_SCC4     ((uint)0x0300)
 #define PROFF_SMC2     ((uint)0x0380)
 
index aed4bc75f35205ca145ed58d79f3f45e5793d2c7..aef179fcbd4f86d7fc0db15afc2f81d4330950d1 100644 (file)
@@ -360,6 +360,17 @@ void __init cpm_load_patch(cpm8xx_t *cp)
        if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) {
                smc_uart_t *smp;
 
+               if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) {
+                       int i;
+
+                       for (i = 0; i < sizeof(*smp); i += 4) {
+                               u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i];
+                               u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i];
+
+                               out_be32(dst, in_be32(src));
+                       }
+               }
+
                smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
                out_be16(&smp->smc_rpbase, 0x1ec0);
                smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];