
This patch does 3 things: 1. Enables ECC by setting 21st bit of L2CTLR. 2. Restore data and tag RAM latencies to 3 cycles because iROM sets 0x3000400 L2CTLR value during switching. 3. Disable clean/evict push to external by setting 3rd bit of L2ACTLR. We need to restore this here due to switching.
Signed-off-by: Abhilash Kesavan a.kesavan@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Reviewed-by: Simon Glass sjg@chromium.org Tested-by: Simon Glass sjg@chromium.org --- Changes since v2: - Replaced #ifndef with if(proid_is_soc()) check.
Changes since v1: - Added Reviewed-by & Tested-by.
arch/arm/cpu/armv7/exynos/lowlevel_init.c | 53 +++++++++++++++++++++++-------- arch/arm/cpu/armv7/exynos/soc.c | 27 +++++++++------- 2 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/arch/arm/cpu/armv7/exynos/lowlevel_init.c index 0893b0b..aba6462 100644 --- a/arch/arm/cpu/armv7/exynos/lowlevel_init.c +++ b/arch/arm/cpu/armv7/exynos/lowlevel_init.c @@ -68,24 +68,40 @@ static void enable_smp(void) }
/* + * Enable ECC by setting L2CTLR[21]. + * Set L2CTLR[7] to make tag ram latency 3 cycles and + * set L2CTLR[1] to make data ram latency 3 cycles. + * We need to make RAM latency of 3 cycles here because cores + * power ON and OFF while switching. And everytime a core powers + * ON, iROM provides it a default L2CTLR value 0x400 which stands + * for TAG RAM setup of 1 cycle. Hence, we face a need of + * restoring data and tag latency values. + */ +static void configure_l2_ctlr(void) +{ + uint32_t val; + + mrc_l2_ctlr(val); + val |= (1 << 21); + val |= (1 << 7); + val |= (1 << 1); + mcr_l2_ctlr(val); +} + +/* * Set L2ACTLR[7] to reissue any memory transaction in the L2 that has been * stalled for 1024 cycles to verify that its hazard condition still exists. + * Disable clean/evict push to external by setting L2ACTLR[3]. */ -static void configure_l2actlr(void) +static void configure_l2_actlr(void) { uint32_t val;
- /* Read MIDR for Primary Part Number */ - mrc_midr(val); - val = (val >> 4); - val &= 0xf; - - /* L2ACTLR[7]: Enable hazard detect timeout for A15 */ - if (val == 0xf) { - mrc_l2_aux_ctlr(val); - val |= (1 << 7); - mcr_l2_aux_ctlr(val); - } + mrc_l2_aux_ctlr(val); + val |= (1 << 27); + val |= (1 << 7); + val |= (1 << 3); + mcr_l2_aux_ctlr(val); }
/* @@ -122,7 +138,16 @@ static void low_power_start(void)
/* Set the CPU to SVC32 mode */ svc32_mode_en(); - configure_l2actlr(); + + /* Read MIDR for Primary Part Number */ + mrc_midr(val); + val = (val >> 4); + val &= 0xf; + + if (val == 0xf) { + configure_l2_ctlr(); + configure_l2_actlr(); + }
/* Invalidate L1 & TLB */ val = 0x0; @@ -181,7 +206,7 @@ static void power_down_core(void) static void secondary_cores_configure(void) { /* Setup L2 cache */ - configure_l2actlr(); + configure_l2_ctlr();
/* Clear secondary boot iRAM base */ writel(0x0, (CONFIG_EXYNOS_RELOCATE_CODE_BASE + 0x1C)); diff --git a/arch/arm/cpu/armv7/exynos/soc.c b/arch/arm/cpu/armv7/exynos/soc.c index 427f54c..77d3875 100644 --- a/arch/arm/cpu/armv7/exynos/soc.c +++ b/arch/arm/cpu/armv7/exynos/soc.c @@ -37,30 +37,33 @@ void enable_caches(void) */ static void exynos5_set_l2cache_params(void) { - unsigned int val = 0; + unsigned int l2ctlr = 0, l2actlr = 0;
/* Read L2CTLR value */ - asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r"(val)); + asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r"(l2ctlr));
- /* Set cache setup and latency cycles */ - val |= CACHE_TAG_RAM_SETUP | - CACHE_DATA_RAM_SETUP | - CACHE_TAG_RAM_LATENCY | + /* Set cache latency cycles */ + l2ctlr |= CACHE_TAG_RAM_LATENCY | CACHE_DATA_RAM_LATENCY;
- /* Write new vlaue to L2CTLR */ - asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val)); - if (proid_is_exynos5420() || proid_is_exynos5800()) { + /* Read L2ACTLR value */ - asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val)); + asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (l2actlr));
/* Disable clean/evict push to external */ - val |= CACHE_DISABLE_CLEAN_EVICT; + l2actlr |= CACHE_DISABLE_CLEAN_EVICT;
/* Write new vlaue to L2ACTLR */ - asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val)); + asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (l2actlr)); + } else { + /* Set cache setup cycles */ + l2ctlr |= CACHE_TAG_RAM_SETUP | + CACHE_DATA_RAM_SETUP; } + + /* Write new vlaue to L2CTLR */ + asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(l2ctlr)); }
/*