arm: sunxi: h6: fix reset using r_wdog
authorClément Péron <peron.clem@gmail.com>
Wed, 17 Apr 2019 17:41:05 +0000 (19:41 +0200)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 20 May 2019 16:54:47 +0000 (22:24 +0530)
Some H6 boards have a watchdog which didn't make the SoC
reboot properly.

Reason is still unknown but several people have test it.
Chen-Yu Tsai :
Pine H64 = H6 V200-AWIN H6448BA 7782 => OK
OrangePi Lite 2 = H6 V200-AWIN H8068BA 61C2 => KO

Martin Ayotte :
Pine H64 = H8069BA 6892 => OK
OrangePi 3 = HA047BA 69W2 => KO
OrangePi One Plus = H7310BA 6842 => KO
OrangePi Lite2 = H6448BA 6662 => KO

Clément Péron:
Beelink GS1 = H6 V200-AWIN H7309BA 6842 => KO

After the series of result, Icenowy try to reach Allwinner about this
issue but they seems not interested to investigate it.

As we don't have the ARIS coproc to do power management and watchdogis
the only solution to reset the board.

So, Change from watchdog to R_watchdog to allow a reboot on all H6
boards.

Signed-off-by: Clément Péron <peron.clem@gmail.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
arch/arm/mach-sunxi/board.c

index 41a9b0fc47c079ed72e2697fd2d13dfa4c3a4302..6392cb07b472247057d264eff854148cd360a52c 100644 (file)
@@ -60,6 +60,7 @@
 #define SUNXI_RTC_BASE                 0x07000000
 #define SUNXI_R_CPUCFG_BASE            0x07000400
 #define SUNXI_PRCM_BASE                        0x07010000
+#define SUNXI_R_WDOG_BASE              0x07020400
 #define SUNXI_R_PIO_BASE               0x07022000
 #define SUNXI_R_UART_BASE              0x07080000
 #define SUNXI_R_TWI_BASE               0x07081400
index c6dd7b8e54b05c74c04394064cdb7d6139ec7a03..921e4c5175bcca1f0417c5e3968a9f19987d7dc7 100644 (file)
@@ -289,9 +289,14 @@ void reset_cpu(ulong addr)
                writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
        }
 #elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_MACH_SUN50I_H6)
+#if defined(CONFIG_MACH_SUN50I_H6)
+       /* WDOG is broken for some H6 rev. use the R_WDOG instead */
        static const struct sunxi_wdog *wdog =
-                ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
-
+               (struct sunxi_wdog *)SUNXI_R_WDOG_BASE;
+#else
+       static const struct sunxi_wdog *wdog =
+               ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+#endif
        /* Set the watchdog for its shortest interval (.5s) and wait */
        writel(WDT_CFG_RESET, &wdog->cfg);
        writel(WDT_MODE_EN, &wdog->mode);