[U-Boot] [PATCH 0/2] Fix minor issues with Serval SoC.

This patch series fix different issues with Serval. - first patch fix resets when DDR training fails. - second patch fix the detection of the board.
This patch series is based on u-boot-mips/next.
Horatiu Vultur (2): mips: mscc: serval: Fix reset board: mscc: serval: Fix board detect
arch/mips/mach-mscc/include/mach/ddr.h | 14 ++++++++++++++ arch/mips/mach-mscc/reset.c | 5 +---- board/mscc/serval/serval.c | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-)

In case the ddr training was failing, it couldn't reset, it was just hanging. Therefore reimplement it, so when ddr training is failing it would call _machine_restart, which power downs the DDR and does a force reset.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- arch/mips/mach-mscc/include/mach/ddr.h | 14 ++++++++++++++ arch/mips/mach-mscc/reset.c | 5 +---- 2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 84ecfbd..97dac3e 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -464,6 +464,19 @@ static inline void hal_vcoreiii_ddr_reset_assert(void) ICPU_RESET_MEM_RST_FORCE, BASE_CFG + ICPU_RESET); }
+#if defined(CONFIG_SOC_SERVAL) +static inline void hal_vcoreiii_ddr_failed(void) +{ + register u32 reset; + + pr_err("DDR training failed\n"); + + /* Jump to reset - does not return */ + reset = KSEG0ADDR(_machine_restart); + icache_lock((void *)reset, 128); // Reset while running from cache + asm volatile ("jr %0" : : "r" (reset)); +} +#else // JR2 || ServalT static inline void hal_vcoreiii_ddr_failed(void) { writel(0, BASE_CFG + ICPU_RESET); @@ -471,6 +484,7 @@ static inline void hal_vcoreiii_ddr_failed(void)
panic("DDR init failed\n"); } +#endif /* Serval */ #endif /* JR2 || ServalT || Serval */
/* diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c index a555fc9..95fe0d8 100644 --- a/arch/mips/mach-mscc/reset.c +++ b/arch/mips/mach-mscc/reset.c @@ -28,16 +28,13 @@ void _machine_restart(void) ICPU_RESET_CORE_RST_FORCE, BASE_CFG + ICPU_RESET); #elif defined(CONFIG_SOC_SERVAL) - register unsigned long i; - /* Prevent VCore-III from being reset with a global reset */ writel(ICPU_RESET_CORE_RST_PROTECT, BASE_CFG + ICPU_RESET);
/* Do global reset */ writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_DEVCPU_GCB + PERF_SOFT_RST);
- for (i = 0; i < 1000; i++) - ; + mdelay(100);
/* Power down DDR for clean DDR re-training */ writel(readl(BASE_CFG + ICPU_MEMCTRL_CTRL) |

Am 11.04.19 um 13:51 schrieb Horatiu Vultur:
In case the ddr training was failing, it couldn't reset, it was just hanging. Therefore reimplement it, so when ddr training is failing it would call _machine_restart, which power downs the DDR and does a force reset.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
arch/mips/mach-mscc/include/mach/ddr.h | 14 ++++++++++++++ arch/mips/mach-mscc/reset.c | 5 +---- 2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 84ecfbd..97dac3e 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -464,6 +464,19 @@ static inline void hal_vcoreiii_ddr_reset_assert(void) ICPU_RESET_MEM_RST_FORCE, BASE_CFG + ICPU_RESET); }
+#if defined(CONFIG_SOC_SERVAL) +static inline void hal_vcoreiii_ddr_failed(void) +{
- register u32 reset;
- pr_err("DDR training failed\n");
- /* Jump to reset - does not return */
- reset = KSEG0ADDR(_machine_restart);
- icache_lock((void *)reset, 128); // Reset while running from cache
- asm volatile ("jr %0" : : "r" (reset));
+}
there is no real difference to the current hal_vcoreiii_ddr_failed() except the GPIO toggling. If that toggling is bad on Serval, couldn't you simply wrap it with #if !defined(CONFIG_SOC_SERVAL)?
+#else // JR2 || ServalT static inline void hal_vcoreiii_ddr_failed(void) { writel(0, BASE_CFG + ICPU_RESET); @@ -471,6 +484,7 @@ static inline void hal_vcoreiii_ddr_failed(void)
panic("DDR init failed\n"); } +#endif /* Serval */ #endif /* JR2 || ServalT || Serval */
/* diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c index a555fc9..95fe0d8 100644 --- a/arch/mips/mach-mscc/reset.c +++ b/arch/mips/mach-mscc/reset.c @@ -28,16 +28,13 @@ void _machine_restart(void) ICPU_RESET_CORE_RST_FORCE, BASE_CFG + ICPU_RESET); #elif defined(CONFIG_SOC_SERVAL)
register unsigned long i;
/* Prevent VCore-III from being reset with a global reset */ writel(ICPU_RESET_CORE_RST_PROTECT, BASE_CFG + ICPU_RESET);
/* Do global reset */ writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_DEVCPU_GCB + PERF_SOFT_RST);
for (i = 0; i < 1000; i++)
;
- mdelay(100);
I guess Gregory open-coded that because mdelay() can't run in the very restricted environment without stack and BSS. If the delay is too short, maybe you should rather increase the iteration count?
/* Power down DDR for clean DDR re-training */ writel(readl(BASE_CFG + ICPU_MEMCTRL_CTRL) |

When detecting the board, it was reading a register in the GPIO page of the phy and based on that value it was making a decision. The bug was that after the GPIO page for the first phy was set it was not reseted back.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- board/mscc/serval/serval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/mscc/serval/serval.c b/board/mscc/serval/serval.c index 52faac9..50444e4 100644 --- a/board/mscc/serval/serval.c +++ b/board/mscc/serval/serval.c @@ -49,10 +49,10 @@ static void do_board_detect(void) gd->board_type = BOARD_TYPE_PCB106; else gd->board_type = BOARD_TYPE_PCB105; - mscc_phy_wr(1, 16, 15, 0); } else { gd->board_type = BOARD_TYPE_PCB105; } + mscc_phy_wr(1, 16, 31, 0x0); }
#if defined(CONFIG_MULTI_DTB_FIT)
participants (2)
-
Daniel Schwierzeck
-
Horatiu Vultur