]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
powerpc/8xx: Handle CPU6 ERRATA directly in mtspr() macro
authorChristophe Leroy <christophe.leroy@c-s.fr>
Tue, 9 Feb 2016 16:08:14 +0000 (17:08 +0100)
committerScott Wood <oss@buserror.net>
Fri, 11 Mar 2016 23:18:02 +0000 (17:18 -0600)
MPC8xx has an ERRATA on the use of mtspr() for some registers
This patch includes the ERRATA handling directly into mtspr() macro
so that mtspr() users don't need to bother about that errata

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Scott Wood <oss@buserror.net>
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/reg_8xx.h

index 52ed654d01ba84a5178102f7c0c7b6835ee1325a..f5f4c66bbbc91331cb82fc731f353eb01bb0a02f 100644 (file)
@@ -1219,9 +1219,11 @@ static inline void mtmsr_isync(unsigned long val)
 #define mfspr(rn)      ({unsigned long rval; \
                        asm volatile("mfspr %0," __stringify(rn) \
                                : "=r" (rval)); rval;})
+#ifndef mtspr
 #define mtspr(rn, v)   asm volatile("mtspr " __stringify(rn) ",%0" : \
                                     : "r" ((unsigned long)(v)) \
                                     : "memory")
+#endif
 
 extern void msr_check_and_set(unsigned long bits);
 extern bool strict_msr_control;
index 0f71c811a8415f4fa674ad7d3732c355e93d9b39..d41412c7748bc15d46e1b236624e512a6b1b18b8 100644 (file)
 #define DC_DFWT                0x40000000      /* Data cache is forced write through */
 #define DC_LES         0x20000000      /* Caches are little endian mode */
 
+#ifdef CONFIG_8xx_CPU6
+#define do_mtspr_cpu6(rn, rn_addr, v)  \
+       do {                                                            \
+               int _reg_cpu6 = rn_addr, _tmp_cpu6[1];          \
+               asm volatile("stw %0, %1;"                              \
+                            "lwz %0, %1;"                              \
+                            "mtspr " __stringify(rn) ",%2" :           \
+                            : "r" (_reg_cpu6), "m"(_tmp_cpu6),         \
+                              "r" ((unsigned long)(v))                 \
+                            : "memory");                               \
+       } while (0)
+
+#define do_mtspr(rn, v)        asm volatile("mtspr " __stringify(rn) ",%0" :   \
+                                    : "r" ((unsigned long)(v))         \
+                                    : "memory")
+#define mtspr(rn, v) \
+       do {                                                            \
+               if (rn == SPRN_IMMR)                                    \
+                       do_mtspr_cpu6(rn, 0x3d30, v);                   \
+               else if (rn == SPRN_IC_CST)                             \
+                       do_mtspr_cpu6(rn, 0x2110, v);                   \
+               else if (rn == SPRN_IC_ADR)                             \
+                       do_mtspr_cpu6(rn, 0x2310, v);                   \
+               else if (rn == SPRN_IC_DAT)                             \
+                       do_mtspr_cpu6(rn, 0x2510, v);                   \
+               else if (rn == SPRN_DC_CST)                             \
+                       do_mtspr_cpu6(rn, 0x3110, v);                   \
+               else if (rn == SPRN_DC_ADR)                             \
+                       do_mtspr_cpu6(rn, 0x3310, v);                   \
+               else if (rn == SPRN_DC_DAT)                             \
+                       do_mtspr_cpu6(rn, 0x3510, v);                   \
+               else if (rn == SPRN_MI_CTR)                             \
+                       do_mtspr_cpu6(rn, 0x2180, v);                   \
+               else if (rn == SPRN_MI_AP)                              \
+                       do_mtspr_cpu6(rn, 0x2580, v);                   \
+               else if (rn == SPRN_MI_EPN)                             \
+                       do_mtspr_cpu6(rn, 0x2780, v);                   \
+               else if (rn == SPRN_MI_TWC)                             \
+                       do_mtspr_cpu6(rn, 0x2b80, v);                   \
+               else if (rn == SPRN_MI_RPN)                             \
+                       do_mtspr_cpu6(rn, 0x2d80, v);                   \
+               else if (rn == SPRN_MI_CAM)                             \
+                       do_mtspr_cpu6(rn, 0x2190, v);                   \
+               else if (rn == SPRN_MI_RAM0)                            \
+                       do_mtspr_cpu6(rn, 0x2390, v);                   \
+               else if (rn == SPRN_MI_RAM1)                            \
+                       do_mtspr_cpu6(rn, 0x2590, v);                   \
+               else if (rn == SPRN_MD_CTR)                             \
+                       do_mtspr_cpu6(rn, 0x3180, v);                   \
+               else if (rn == SPRN_M_CASID)                            \
+                       do_mtspr_cpu6(rn, 0x3380, v);                   \
+               else if (rn == SPRN_MD_AP)                              \
+                       do_mtspr_cpu6(rn, 0x3580, v);                   \
+               else if (rn == SPRN_MD_EPN)                             \
+                       do_mtspr_cpu6(rn, 0x3780, v);                   \
+               else if (rn == SPRN_M_TWB)                              \
+                       do_mtspr_cpu6(rn, 0x3980, v);                   \
+               else if (rn == SPRN_MD_TWC)                             \
+                       do_mtspr_cpu6(rn, 0x3b80, v);                   \
+               else if (rn == SPRN_MD_RPN)                             \
+                       do_mtspr_cpu6(rn, 0x3d80, v);                   \
+               else if (rn == SPRN_M_TW)                               \
+                       do_mtspr_cpu6(rn, 0x3f80, v);                   \
+               else if (rn == SPRN_MD_CAM)                             \
+                       do_mtspr_cpu6(rn, 0x3190, v);                   \
+               else if (rn == SPRN_MD_RAM0)                            \
+                       do_mtspr_cpu6(rn, 0x3390, v);                   \
+               else if (rn == SPRN_MD_RAM1)                            \
+                       do_mtspr_cpu6(rn, 0x3590, v);                   \
+               else if (rn == SPRN_DEC)                                \
+                       do_mtspr_cpu6(rn, 0x2c00, v);                   \
+               else if (rn == SPRN_TBWL)                               \
+                       do_mtspr_cpu6(rn, 0x3880, v);                   \
+               else if (rn == SPRN_TBWU)                               \
+                       do_mtspr_cpu6(rn, 0x3a80, v);                   \
+               else if (rn == SPRN_DPDR)                               \
+                       do_mtspr_cpu6(rn, 0x2d30, v);                   \
+               else                                                    \
+                       do_mtspr(rn, v);                                \
+       } while (0)
+#endif
+
 #endif /* _ASM_POWERPC_REG_8xx_H */