From ebdc27895492e740d96c67d624821cfeb56c7544 Mon Sep 17 00:00:00 2001 From: Alex Nemirovsky Date: Mon, 23 Dec 2019 20:19:20 +0000 Subject: MIPS: allow override of flush_dcache_range() Useful in custom HW designs which have a need to flush dcache range in a completely non standard way. Signed-off-by: Alex Nemirovsky --- arch/mips/lib/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index 502956d050..1a8c87d094 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -141,7 +141,7 @@ ops_done: instruction_hazard_barrier(); } -void flush_dcache_range(ulong start_addr, ulong stop) +void __weak flush_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); unsigned long slsize = scache_line_size(); -- cgit From 47a1933aa738851ffde5770316ab0f8b47db753a Mon Sep 17 00:00:00 2001 From: Alex Nemirovsky Date: Mon, 23 Dec 2019 20:53:56 +0000 Subject: MIPS: allow override of get_tbclk() Allow SoC or board layers with reconfigurable cpu clocks capabilties to do implementation specific lookups and service get_tbclk() requests. Signed-off-by: Alex Nemirovsky --- arch/mips/cpu/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/cpu/time.c b/arch/mips/cpu/time.c index a1508e3b88..e0c1868b8c 100644 --- a/arch/mips/cpu/time.c +++ b/arch/mips/cpu/time.c @@ -13,7 +13,7 @@ unsigned long notrace timer_read_counter(void) return read_c0_count(); } -ulong notrace get_tbclk(void) +ulong notrace __weak get_tbclk(void) { return CONFIG_SYS_MIPS_TIMER_FREQ; } -- cgit From 7048bb13b2d6309ef8386fca665247d3afa36ab0 Mon Sep 17 00:00:00 2001 From: Lars Povlsen Date: Thu, 6 Feb 2020 10:45:40 +0100 Subject: 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 Reviewed-by: Alexandre Belloni Reviewed-by: Horatiu Vultur Signed-off-by: Lars Povlsen --- arch/mips/mach-mscc/cpu.c | 9 +++++---- arch/mips/mach-mscc/dram.c | 14 +++++--------- arch/mips/mach-mscc/include/mach/ddr.h | 4 ---- arch/mips/mach-mscc/lowlevel_init.S | 17 ++++++++++++++++- 4 files changed, 26 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c index ac75d51da5..3ee589891b 100644 --- a/arch/mips/mach-mscc/cpu.c +++ b/arch/mips/mach-mscc/cpu.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -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 c43f7a585b..72c70c9e84 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 d1f4287f65..bf75e52ec3 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 dfbe06766c..91f29ae252 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) -- cgit From fb9acad30562177287d8cffec19e5dfa6f072de7 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 13 Feb 2020 07:04:00 +0100 Subject: mips: cmd: go: Flush cache before jumping to app/image It has been noticed on MT7628/88 platforms, that booting the RAM image does not work reliably. Sometimes it works and sometimes not. Debugging showed that this "might" be a cache related issue as very strange errors occurred (e.g. output corrupted etc). This patch adds a cache flush for the complete SDRAM area to the go cmd before jumping to the entry point for the MIPS architecture. The complete area is flushed as we don't know at this point, how big the area of the "application" really is. Signed-off-by: Stefan Roese Reviewed-by: Daniel Schwierzeck Tested-by: Mauro Condarelli Cc: Daniel Schwierzeck Cc: Mauro Condarelli Cc: Weijie Gao --- arch/mips/lib/Makefile | 1 + arch/mips/lib/boot.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 arch/mips/lib/boot.c (limited to 'arch') diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 589bc651f9..24a72d9c97 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -11,5 +11,6 @@ obj-y += stack.o obj-y += traps.o obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-$(CONFIG_CMD_GO) += boot.o lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o diff --git a/arch/mips/lib/boot.c b/arch/mips/lib/boot.c new file mode 100644 index 0000000000..db862f6379 --- /dev/null +++ b/arch/mips/lib/boot.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Stefan Roese + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long do_go_exec(ulong (*entry)(int, char * const []), + int argc, char * const argv[]) +{ + /* + * Flush cache before jumping to application. Let's flush the + * whole SDRAM area, since we don't know the size of the image + * that was loaded. + */ + flush_cache(gd->bd->bi_memstart, gd->ram_top - gd->bd->bi_memstart); + + return entry(argc, argv); +} -- cgit