summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Povlsen <[email protected]>2020-02-06 10:45:40 +0100
committerDaniel Schwierzeck <[email protected]>2020-04-09 18:55:59 +0200
commit7048bb13b2d6309ef8386fca665247d3afa36ab0 (patch)
tree236eb7433c2c06d3469b0bce455f1e569ef3095f
parentea148789318c8152acb0a3974d4a8342dbd6b901 (diff)
mips: vcoreiii: Fix cache coherency issues
This patch fixes an stability issue seen on some vcoreiii targets, which was root caused to a cache inconsistency situation. The inconsistency was caused by having kuseg pointing to NOR area but used as a stack/gd/heap area during initialization, while only relatively late remapping the RAM area into kuseg position. The fix is to initialize the DDR right after the TLB setup, and then remapping it into position before gd/stack/heap usage. Reported-by: Ramin Seyed-Moussavi <[email protected]> Reviewed-by: Alexandre Belloni <[email protected]> Reviewed-by: Horatiu Vultur <[email protected]> Signed-off-by: Lars Povlsen <[email protected]>
-rw-r--r--arch/mips/mach-mscc/cpu.c9
-rw-r--r--arch/mips/mach-mscc/dram.c14
-rw-r--r--arch/mips/mach-mscc/include/mach/ddr.h4
-rw-r--r--arch/mips/mach-mscc/lowlevel_init.S17
4 files changed, 26 insertions, 18 deletions
diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c
index ac75d51da5f..3ee589891b1 100644
--- a/arch/mips/mach-mscc/cpu.c
+++ b/arch/mips/mach-mscc/cpu.c
@@ -7,6 +7,7 @@
#include <asm/io.h>
#include <asm/types.h>
+#include <asm/mipsregs.h>
#include <mach/tlb.h>
#include <mach/ddr.h>
@@ -53,7 +54,6 @@ void vcoreiii_tlb_init(void)
MMU_REGIO_RW);
#endif
-#if CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO
/*
* If U-Boot is located in NOR then we want to be able to use
* the data cache in order to boot in a decent duration
@@ -71,9 +71,10 @@ void vcoreiii_tlb_init(void)
create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW,
MSCC_ATTRIB2);
- /* Enable caches by clearing the bit ERL, which is set on reset */
- write_c0_status(read_c0_status() & ~BIT(2));
-#endif /* CONFIG_SYS_TEXT_BASE */
+ /* Enable mapping (using TLB) kuseg by clearing the bit ERL,
+ * which is set on reset.
+ */
+ write_c0_status(read_c0_status() & ~ST0_ERL);
}
int mach_cpu_init(void)
diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c
index c43f7a585bf..72c70c9e843 100644
--- a/arch/mips/mach-mscc/dram.c
+++ b/arch/mips/mach-mscc/dram.c
@@ -31,7 +31,7 @@ static inline int vcoreiii_train_bytelane(void)
int vcoreiii_ddr_init(void)
{
- int res;
+ register int res;
if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT)
& ICPU_MEMCTRL_STAT_INIT_DONE)) {
@@ -40,20 +40,19 @@ int vcoreiii_ddr_init(void)
if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane())
hal_vcoreiii_ddr_failed();
}
-#if (CONFIG_SYS_TEXT_BASE != 0x20000000)
+
res = dram_check();
if (res == 0)
hal_vcoreiii_ddr_verified();
else
hal_vcoreiii_ddr_failed();
- /* Clear boot-mode and read-back to activate/verify */
+ /* Remap DDR to kuseg: Clear boot-mode */
clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
ICPU_GENERAL_CTRL_BOOT_MODE_ENA);
+ /* - and read-back to activate/verify */
readl(BASE_CFG + ICPU_GENERAL_CTRL);
-#else
- res = 0;
-#endif
+
return res;
}
@@ -66,9 +65,6 @@ int print_cpuinfo(void)
int dram_init(void)
{
- while (vcoreiii_ddr_init())
- ;
-
gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
return 0;
}
diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h
index d1f4287f654..bf75e52ec3c 100644
--- a/arch/mips/mach-mscc/include/mach/ddr.h
+++ b/arch/mips/mach-mscc/include/mach/ddr.h
@@ -435,16 +435,12 @@ static inline void hal_vcoreiii_ddr_failed(void)
reset = KSEG0ADDR(_machine_restart);
icache_lock((void *)reset, 128);
asm volatile ("jr %0"::"r" (reset));
-
- panic("DDR init failed\n");
}
#else /* JR2 || ServalT */
static inline void hal_vcoreiii_ddr_failed(void)
{
writel(0, BASE_CFG + ICPU_RESET);
writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_CFG + PERF_SOFT_RST);
-
- panic("DDR init failed\n");
}
#endif
diff --git a/arch/mips/mach-mscc/lowlevel_init.S b/arch/mips/mach-mscc/lowlevel_init.S
index dfbe06766cd..91f29ae252c 100644
--- a/arch/mips/mach-mscc/lowlevel_init.S
+++ b/arch/mips/mach-mscc/lowlevel_init.S
@@ -8,6 +8,7 @@
.set noreorder
.extern vcoreiii_tlb_init
+ .extern vcoreiii_ddr_init
#ifdef CONFIG_SOC_LUTON
.extern pll_init
#endif
@@ -17,14 +18,28 @@ LEAF(lowlevel_init)
* As we have no stack yet, we can assume the restricted
* luxury of the sX-registers without saving them
*/
- move s0,ra
+
+ /* Modify ra/s0 such we return to physical NOR location */
+ li t0, 0x0fffffff
+ li t1, CONFIG_SYS_TEXT_BASE
+ and s0, ra, t0
+ add s0, s0, t1
jal vcoreiii_tlb_init
nop
+
#ifdef CONFIG_SOC_LUTON
jal pll_init
nop
#endif
+
+ /* Initialize DDR controller to enable stack/gd/heap */
+0:
+ jal vcoreiii_ddr_init
+ nop
+ bnez v0, 0b /* Retry on error */
+ nop
+
jr s0
nop
END(lowlevel_init)