summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTang Yuantian <yuantian.tang@freescale.com>2014-07-04 17:39:26 +0800
committerYork Sun <yorksun@freescale.com>2014-07-22 16:25:55 -0700
commit7cb7272365983e3a1eedf18a9f688c825e1cf95e (patch)
tree5ce567157d236767a0f05940045bf6f8c3c27ca3
parenta1399a918720337ad14053cf6185786aa33b58b2 (diff)
mpc85xx/t104x: Enable L2 and CPC cache when resume
When resume from deep sleep, uboot needs to enable L2 and CPC cache, or they would be keeping unusable in kernel because kernel didn't enble or initialized them. This patch didn't change the existing L2 cache enabling code, just put them in a function. Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com> Reviewed-by: York Sun <yorksun@freescale.com>
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c163
-rw-r--r--arch/powerpc/include/asm/cache.h6
-rw-r--r--arch/powerpc/lib/board.c5
3 files changed, 98 insertions, 76 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index c2a89c2fa6..b237505d3e 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -200,7 +200,7 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm)
#ifdef CONFIG_SYS_FSL_CPC
#if defined(CONFIG_RAMBOOT_PBL) || defined(CONFIG_SYS_CPC_REINIT_F)
-static void disable_cpc_sram(void)
+void disable_cpc_sram(void)
{
int i;
@@ -251,7 +251,7 @@ static void enable_tdm_law(void)
}
#endif
-static void enable_cpc(void)
+void enable_cpc(void)
{
int i;
u32 size = 0;
@@ -306,6 +306,7 @@ static void invalidate_cpc(void)
#else
#define enable_cpc()
#define invalidate_cpc()
+#define disable_cpc_sram()
#endif /* CONFIG_SYS_FSL_CPC */
/*
@@ -546,88 +547,15 @@ int enable_cluster_l2(void)
/*
* Initialize L2 as cache.
- *
- * The newer 8548, etc, parts have twice as much cache, but
- * use the same bit-encoding as the older 8555, etc, parts.
- *
*/
-int cpu_init_r(void)
+int l2cache_init(void)
{
__maybe_unused u32 svr = get_svr();
-#ifdef CONFIG_SYS_LBC_LCRR
- fsl_lbc_t *lbc = (void __iomem *)LBC_BASE_ADDR;
-#endif
#ifdef CONFIG_L2_CACHE
ccsr_l2cache_t *l2cache = (void __iomem *)CONFIG_SYS_MPC85xx_L2_ADDR;
#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
struct ccsr_cluster_l2 * l2cache = (void __iomem *)CONFIG_SYS_FSL_CLUSTER_1_L2;
#endif
-#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
- extern int spin_table_compat;
- const char *spin;
-#endif
-#ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
- ccsr_sec_t __iomem *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
-#endif
-#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
- defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
- /*
- * CPU22 and NMG_CPU_A011 share the same workaround.
- * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0
- * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
- * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both
- * fixed in 2.0. NMG_CPU_A011 is activated by default and can
- * be disabled by hwconfig with syntax:
- *
- * fsl_cpu_a011:disable
- */
- extern int enable_cpu_a011_workaround;
-#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22
- enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3);
-#else
- char buffer[HWCONFIG_BUFFER_SIZE];
- char *buf = NULL;
- int n, res;
-
- n = getenv_f("hwconfig", buffer, sizeof(buffer));
- if (n > 0)
- buf = buffer;
-
- res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf);
- if (res > 0)
- enable_cpu_a011_workaround = 0;
- else {
- if (n >= HWCONFIG_BUFFER_SIZE) {
- printf("fsl_cpu_a011 was not found. hwconfig variable "
- "may be too long\n");
- }
- enable_cpu_a011_workaround =
- (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) ||
- (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2);
- }
-#endif
- if (enable_cpu_a011_workaround) {
- flush_dcache();
- mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS));
- sync();
- }
-#endif
-#ifdef CONFIG_SYS_FSL_ERRATUM_A005812
- /*
- * A-005812 workaround sets bit 32 of SPR 976 for SoCs running
- * in write shadow mode. Checking DCWS before setting SPR 976.
- */
- if (mfspr(L1CSR2) & L1CSR2_DCWS)
- mtspr(SPRN_HDBCR0, (mfspr(SPRN_HDBCR0) | 0x80000000));
-#endif
-
-#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
- spin = getenv("spin_table_compat");
- if (spin && (*spin == 'n'))
- spin_table_compat = 0;
- else
- spin_table_compat = 1;
-#endif
puts ("L2: ");
@@ -752,6 +680,89 @@ skip_l2:
puts("disabled\n");
#endif
+ return 0;
+}
+
+/*
+ *
+ * The newer 8548, etc, parts have twice as much cache, but
+ * use the same bit-encoding as the older 8555, etc, parts.
+ *
+ */
+int cpu_init_r(void)
+{
+ __maybe_unused u32 svr = get_svr();
+#ifdef CONFIG_SYS_LBC_LCRR
+ fsl_lbc_t *lbc = (void __iomem *)LBC_BASE_ADDR;
+#endif
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ extern int spin_table_compat;
+ const char *spin;
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
+ ccsr_sec_t __iomem *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+#endif
+#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
+ /*
+ * CPU22 and NMG_CPU_A011 share the same workaround.
+ * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0
+ * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
+ * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both
+ * fixed in 2.0. NMG_CPU_A011 is activated by default and can
+ * be disabled by hwconfig with syntax:
+ *
+ * fsl_cpu_a011:disable
+ */
+ extern int enable_cpu_a011_workaround;
+#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22
+ enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3);
+#else
+ char buffer[HWCONFIG_BUFFER_SIZE];
+ char *buf = NULL;
+ int n, res;
+
+ n = getenv_f("hwconfig", buffer, sizeof(buffer));
+ if (n > 0)
+ buf = buffer;
+
+ res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf);
+ if (res > 0) {
+ enable_cpu_a011_workaround = 0;
+ } else {
+ if (n >= HWCONFIG_BUFFER_SIZE) {
+ printf("fsl_cpu_a011 was not found. hwconfig variable "
+ "may be too long\n");
+ }
+ enable_cpu_a011_workaround =
+ (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) ||
+ (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2);
+ }
+#endif
+ if (enable_cpu_a011_workaround) {
+ flush_dcache();
+ mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS));
+ sync();
+ }
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005812
+ /*
+ * A-005812 workaround sets bit 32 of SPR 976 for SoCs running
+ * in write shadow mode. Checking DCWS before setting SPR 976.
+ */
+ if (mfspr(L1CSR2) & L1CSR2_DCWS)
+ mtspr(SPRN_HDBCR0, (mfspr(SPRN_HDBCR0) | 0x80000000));
+#endif
+
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ spin = getenv("spin_table_compat");
+ if (spin && (*spin == 'n'))
+ spin_table_compat = 0;
+ else
+ spin_table_compat = 1;
+#endif
+
+ l2cache_init();
#if defined(CONFIG_RAMBOOT_PBL)
disable_cpc_sram();
#endif
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index cdc1f10872..d3a83910b6 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -57,6 +57,12 @@ extern void unlock_ram_in_cache(void);
#endif /* CONFIG_SYS_INIT_RAM_LOCK */
#endif /* __ASSEMBLY__ */
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+int l2cache_init(void);
+void enable_cpc(void);
+void disable_cpc_sram(void);
+#endif
+
/* prep registers for L2 */
#define CACHECRBA 0x80000823 /* Cache configuration register address */
#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 300ab12a3b..50eb820336 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -370,6 +370,11 @@ void board_init_f(ulong bootflag)
#ifdef CONFIG_DEEP_SLEEP
/* Jump to kernel in deep sleep case */
if (in_be32(&gur->scrtsr[0]) & (1 << 3)) {
+ l2cache_init();
+#if defined(CONFIG_RAMBOOT_PBL)
+ disable_cpc_sram();
+#endif
+ enable_cpc();
start_addr = in_be32(&scfg->sparecr[1]);
kernel_resume = (func_t)start_addr;
kernel_resume();