ARM: sunxi: Fix reset support on sun6i/sun8i
Subsystems (2)
cover ARM: sunxi: Fix reset support on sun6i/sun8i
Hi,
This series fixes support for the reset command on sun6i/sun8i. The watchdog hardware has changed in sun6i, both the register addresses and definitions. This makes the reset command unusable on sun6i.
Patch 1 moves the watchdog register definitions into a separate file. The rationale behind this is that on sun6i, the watchdog is effectively a separate piece of hardware and not part of the timer.
Patch 2 fixes the register definitions for sun6i, most importantly the watchdog offsets.
Patch 3 adds the sun6i version of reset via watchdog timeout.
I intended to submit this series after the basic sun8i series. It just so happens that I forgot to leave my A23 tablet on at the office, hence I won't be able to test that series until next week.
Since this series has no dependencies nor conflicts, I decided to send this one first.
Cheers
ChenYu
Chen-Yu Tsai (3):
ARM: sunxi: Move watchdog register definitions to separate file
ARM: sunxi: Add sun6i/sun8i timer block register definition
ARM: sunxi: Fix reset command on sun6i/sun8i
arch/arm/cpu/armv7/sunxi/board.c | 15 ++++++++++ arch/arm/include/asm/arch-sunxi/timer.h | 23 ++++++---------- arch/arm/include/asm/arch-sunxi/watchdog.h | 44 ++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/watchdog.h
Signature · 1 line
2.1.1
PATCH 1/3 ARM: sunxi: Move watchdog register definitions to separate file
On later Allwinner SoCs, the watchdog hardware is by all means a separate hardware block, with its own address range and interrupt line.
Move the register definitions to a separate file to facilitate supporting newer SoCs.
--- arch/arm/include/asm/arch-sunxi/timer.h | 17 +++-------------- arch/arm/include/asm/arch-sunxi/watchdog.h | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/watchdog.h
arch/arm/include/asm/arch-sunxi/timer.h +3 -14
@@ -11,14 +11,10 @@#ifndef _SUNXI_TIMER_H_#define _SUNXI_TIMER_H_ -#define WDT_CTRL_RESTART (0x1 << 0) -#define WDT_CTRL_KEY (0x0a57 << 1) -#define WDT_MODE_EN (0x1 << 0) -#define WDT_MODE_RESET_EN (0x1 << 1) -#ifndef __ASSEMBLY__#include <linux/types.h> +#include <asm/arch/watchdog.h> /* General purpose timer */ struct sunxi_timer {
@@ -43,12 +39,6 @@ struct sunxi_64cnt {u32 hi;/* 0xa8 */ }; -/* Watchdog */ -struct sunxi_wdog { -u32 ctl;/* 0x90 */ -u32 mode;/* 0x94 */ -}; -/* Rtc */ struct sunxi_rtc {u32 ctl;/* 0x100 */
@@ -77,9 +67,8 @@ struct sunxi_timer_reg {struct sunxi_timer timer[6 ];/* We have 6 timers */ u8 res2[16 ];struct sunxi_avs avs; -struct sunxi_wdog wdog; -u8 res3[8 ]; -struct sunxi_64cnt cnt64; +struct sunxi_wdog wdog;/* 0x90 */ +struct sunxi_64cnt cnt64;/* 0xa0 */ u8 res4[0x58 ];struct sunxi_rtc rtc;struct sunxi_alarm alarm;
arch/arm/include/asm/arch-sunxi/watchdog.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +* (C) Copyright 2014 +* Chen-Yu Tsai <[email protected]> +* +* Watchdog register definitions +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _SUNXI_WATCHDOG_H_ +#define _SUNXI_WATCHDOG_H_ + +#define WDT_CTRL_RESTART (0x1 << 0) +#define WDT_CTRL_KEY (0x0a57 << 1) +#define WDT_MODE_EN (0x1 << 0) +#define WDT_MODE_RESET_EN (0x1 << 1) + +struct sunxi_wdog { +u32 ctl;/* 0x00 */ +u32 mode;/* 0x04 */ +u32 res[2 ]; +}; + +#endif /* _SUNXI_WATCHDOG_H_ */
Signature · 1 line
2.1.1
PATCH 1/3 ARM: sunxi: Move watchdog register definitions to separate file
Quoted 8 lines · Chen-Yu Tsai
On later Allwinner SoCs, the watchdog hardware is by all means a separate hardware block, with its own address range and interrupt line.
Move the register definitions to a separate file to facilitate supporting newer SoCs.
Signed-off-by Chen-Yu Tsai <[email protected]>
(nb: this isn't pure code motion, please mention that in the commit log in the future).
PATCH 2/3 ARM: sunxi: Add sun6i/sun8i timer block register definition
In reply to Chen-Yu TsaiThe RTC hardware has been moved out of the timer block on sun6i/sun8i. In addition, there are more watchdogs available.
Also note that the timer block definition is not completely accurate for sun5i/sun7i. Various blocks are missing or have been moved out.
--- arch/arm/include/asm/arch-sunxi/timer.h | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/include/asm/arch-sunxi/timer.h +6 -0
@@ -67,7 +67,9 @@ struct sunxi_timer_reg {struct sunxi_timer timer[6 ];/* We have 6 timers */ u8 res2[16 ];struct sunxi_avs avs; +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I )struct sunxi_wdog wdog;/* 0x90 */ +/* XXX the following is not accurate for sun5i/sun7i */ struct sunxi_64cnt cnt64;/* 0xa0 */ u8 res4[0x58 ];struct sunxi_rtc rtc;
@@ -75,6 +77,10 @@ struct sunxi_timer_reg {struct sunxi_tgp tgp[4 ];u8 res5[8 ];u32 cpu_cfg; +#else /* CONFIG_SUN6I || CONFIG_SUN8I || ... */ +u8 res3[16 ]; +struct sunxi_wdog wdog[5 ];/* We have 5 watchdogs */ +#endif };#endif /* __ASSEMBLY__ */
Signature · 1 line
2.1.1
PATCH 2/3 ARM: sunxi: Add sun6i/sun8i timer block register definition
Quoted 7 lines · Chen-Yu Tsai
The RTC hardware has been moved out of the timer block on sun6i/sun8i. In addition, there are more watchdogs available.
Also note that the timer block definition is not completely accurate for sun5i/sun7i. Various blocks are missing or have been moved out.
Signed-off-by Chen-Yu Tsai <[email protected]>
Quoted 29 lines
--- arch/arm/include/asm/arch-sunxi/timer.h | 6 ++++++ 1 file changed, 6 insertions(+)arch/arm/include/asm/arch-sunxi/timer.h +6
-0@@ -67,7 +67,9 @@ struct sunxi_timer_reg {struct sunxi_timer timer[6 ];/* We have 6 timers */ u8 res2[16 ];struct sunxi_avs avs; +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I )struct sunxi_wdog wdog;/* 0x90 */ +/* XXX the following is not accurate for sun5i/sun7i */ struct sunxi_64cnt cnt64;/* 0xa0 */ u8 res4[0x58 ];struct sunxi_rtc rtc;@@ -75,6 +77,10 @@ struct sunxi_timer_reg {struct sunxi_tgp tgp[4 ];u8 res5[8 ];u32 cpu_cfg; +#else /* CONFIG_SUN6I || CONFIG_SUN8I || ... */ +u8 res3[16 ]; +struct sunxi_wdog wdog[5 ];/* We have 5 watchdogs */ +#endif };#endif /* __ASSEMBLY__ */
PATCH 3/3 ARM: sunxi: Fix reset command on sun6i/sun8i
In reply to Chen-Yu TsaiThe watchdog on sun6i/sun8i has a different layout.
Add the new layout and fix up the setup functions so that reset works.
--- arch/arm/cpu/armv7/sunxi/board.c | 15 +++++++++++++++ arch/arm/include/asm/arch-sunxi/watchdog.h | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+)
arch/arm/cpu/armv7/sunxi/board.c +15 -0
@@ -75,6 +75,7 @@ int gpio_init(void)void reset_cpu (ulong addr) { +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I )static const struct sunxi_wdog *wdog = &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE )->wdog;
@@ -86,6 +87,20 @@ void reset_cpu(ulong addr)/* sun5i sometimes gets stuck without this */ writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); } +#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */ +static const struct sunxi_wdog *wdog = + ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE )->wdog; + +/* Set the watchdog for its shortest interval (.5s) and wait */ +writel (WDT_CFG_RESET , &wdog->cfg); +writel (WDT_MODE_EN , &wdog->mode); +writel (WDT_CTRL_KEY |WDT_CTRL_RESTART , &wdog->ctl); + +while (1 ) { +/* sun5i sometimes gets stuck without this */ +writel (WDT_MODE_EN , &wdog->mode); + } +#endif }/* do some early init */
arch/arm/include/asm/arch-sunxi/watchdog.h +20 -0
@@ -12,6 +12,9 @@#define WDT_CTRL_RESTART (0x1 << 0)#define WDT_CTRL_KEY (0x0a57 << 1) + +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I ) +#define WDT_MODE_EN (0x1 << 0)#define WDT_MODE_RESET_EN (0x1 << 1)
@@ -21,4 +24,21 @@ struct sunxi_wdog {u32 res[2 ]; }; +#else + +#define WDT_CFG_RESET (0x1) +#define WDT_MODE_EN (0x1) + +struct sunxi_wdog { +u32 irq_en;/* 0x00 */ +u32 irq_sta;/* 0x04 */ +u32 res1[2 ]; +u32 ctl;/* 0x10 */ +u32 cfg;/* 0x14 */ +u32 mode;/* 0x18 */ +u32 res2; +}; + +#endif +#endif /* _SUNXI_WATCHDOG_H_ */
Signature · 1 line
2.1.1
PATCH 3/3 ARM: sunxi: Fix reset command on sun6i/sun8i
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 97
Quoted 8 lines · Chen-Yu Tsai
arch/arm/cpu/armv7/sunxi/board.c +8
-0+#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */ +static const struct sunxi_wdog *wdog = + ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE )->wdog; + +/* Set the watchdog for its shortest interval (.5s) and wait */ +writel (WDT_CFG_RESET , &wdog->cfg); +writel (WDT_MODE_EN , &wdog->mode); +writel (WDT_CTRL_KEY |WDT_CTRL_RESTART , &wdog->ctl);
That's annoyingly close to the 4/5/7i version, but not quite close enough to allow any meaningful sharing :-/
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 100
Quoted 2 lines
arch/arm/cpu/armv7/sunxi/board.c +2
-0+while (1 ) { +/* sun5i sometimes gets stuck without this */
Is this not therefore unnecessary on 6i/8i?
Quoted 42 lines
arch/arm/cpu/armv7/sunxi/board.c +3
-0+ writel(WDT_MODE_EN, &wdog->mode); + } +#endif }/* do some early init */ arch/arm/include/asm/arch-sunxi/watchdog.h +20
-0@@ -12,6 +12,9 @@#define WDT_CTRL_RESTART (0x1 << 0)#define WDT_CTRL_KEY (0x0a57 << 1) + +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I ) +#define WDT_MODE_EN (0x1 << 0)#define WDT_MODE_RESET_EN (0x1 << 1)@@ -21,4 +24,21 @@ struct sunxi_wdog {u32 res[2 ]; }; +#else + +#define WDT_CFG_RESET (0x1) +#define WDT_MODE_EN (0x1) + +struct sunxi_wdog { +u32 irq_en;/* 0x00 */ +u32 irq_sta;/* 0x04 */ +u32 res1[2 ]; +u32 ctl;/* 0x10 */ +u32 cfg;/* 0x14 */ +u32 mode;/* 0x18 */ +u32 res2; +}; + +#endif +#endif /* _SUNXI_WATCHDOG_H_ */
PATCH 3/3 ARM: sunxi: Fix reset command on sun6i/sun8i
Quoted 12 lines · Ian Campbell
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 97
Quoted 8 lines · Chen-Yu Tsai
arch/arm/cpu/armv7/sunxi/board.c +8
-0+#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */ +static const struct sunxi_wdog *wdog = + ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE )->wdog; + +/* Set the watchdog for its shortest interval (.5s) and wait */ +writel (WDT_CFG_RESET , &wdog->cfg); +writel (WDT_MODE_EN , &wdog->mode); +writel (WDT_CTRL_KEY |WDT_CTRL_RESTART , &wdog->ctl);That's annoyingly close to the 4/5/7i version, but not quite close enough to allow any meaningful sharing :-/
I suppose it is possible to share using clrsetbits...
Quoted 4 lines
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 100
Quoted 2 lines
arch/arm/cpu/armv7/sunxi/board.c +2
-0+while (1 ) { +/* sun5i sometimes gets stuck without this */ Is this not therefore unnecessary on 6i/8i?
The kernel restart driver uses this.
But Allwinner's original code does not.
ChenYu
Quoted 44 lines
Quoted 42 lines
arch/arm/cpu/armv7/sunxi/board.c +3
-0+ writel(WDT_MODE_EN, &wdog->mode); + } +#endif }/* do some early init */ arch/arm/include/asm/arch-sunxi/watchdog.h +20
-0@@ -12,6 +12,9 @@#define WDT_CTRL_RESTART (0x1 << 0)#define WDT_CTRL_KEY (0x0a57 << 1) + +#if defined(CONFIG_SUN4I ) || defined(CONFIG_SUN5I ) || defined(CONFIG_SUN7I ) +#define WDT_MODE_EN (0x1 << 0)#define WDT_MODE_RESET_EN (0x1 << 1)@@ -21,4 +24,21 @@ struct sunxi_wdog {u32 res[2 ]; }; +#else + +#define WDT_CFG_RESET (0x1) +#define WDT_MODE_EN (0x1) + +struct sunxi_wdog { +u32 irq_en;/* 0x00 */ +u32 irq_sta;/* 0x04 */ +u32 res1[2 ]; +u32 ctl;/* 0x10 */ +u32 cfg;/* 0x14 */ +u32 mode;/* 0x18 */ +u32 res2; +}; + +#endif +#endif /* _SUNXI_WATCHDOG_H_ */
PATCH 3/3 ARM: sunxi: Fix reset command on sun6i/sun8i
Quoted 14 lines · Chen-Yu Tsai
Quoted 12 lines · Ian Campbell
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 97
Quoted 8 lines · Chen-Yu Tsai
arch/arm/cpu/armv7/sunxi/board.c +8
-0+#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */ +static const struct sunxi_wdog *wdog = + ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE )->wdog; + +/* Set the watchdog for its shortest interval (.5s) and wait */ +writel (WDT_CFG_RESET , &wdog->cfg); +writel (WDT_MODE_EN , &wdog->mode); +writel (WDT_CTRL_KEY |WDT_CTRL_RESTART , &wdog->ctl);That's annoyingly close to the 4/5/7i version, but not quite close enough to allow any meaningful sharing :-/
Quoted 1 line
I suppose it is possible to share using clrsetbits...
I think it probably isn't worth it.
Quoted 8 lines
Quoted 5 lines
arch/arm/cpu/armv7/sunxi/board.c void reset_cpu(ulong addr) · line 100
Quoted 3 lines
arch/arm/cpu/armv7/sunxi/board.c +2
-0+while (1 ) { +/* sun5i sometimes gets stuck without this */ Is this not therefore unnecessary on 6i/8i?
The kernel restart driver uses this.
But Allwinner's original code does not.
Unless it is needed in practice lets just leave it out.
Ian.
cover ARM: sunxi: Fix reset support on sun6i/sun8i
In reply to Chen-Yu TsaiHi,
Quoted 6 lines · Chen-Yu Tsai
Hi,
This series fixes support for the reset command on sun6i/sun8i. The watchdog hardware has changed in sun6i, both the register addresses and definitions. This makes the reset command unusable on sun6i.
Doesn't this break building multi-sub-arch kernels that support both sun4i/sun5i/sun7i and sun6i/sun8i?
Would it be possible to just add a new driver for the modified watchdog or put all the bits that changed into the device tree?
Thanks,
Signature · 4 lines
Julian Calaby Email: julian.calaby at gmail.com Profile: http://www.google.com/profiles/julian.calaby/
cover ARM: sunxi: Fix reset support on sun6i/sun8i
Hi,
Quoted 5 lines · Julian Calaby
Hi,
Quoted 2 lines · Chen-Yu Tsai
Hi,
Quoted 7 lines
Quoted 4 lines
This series fixes support for the reset command on sun6i/sun8i. The watchdog hardware has changed in sun6i, both the register addresses and definitions. This makes the reset command unusable on sun6i.
Doesn't this break building multi-sub-arch kernels that support both sun4i/sun5i/sun7i and sun6i/sun8i?
Last time I checked, U-boot doesn't do multi-arch kernels.
Quoted 2 lines
Would it be possible to just add a new driver for the modified watchdog or put all the bits that changed into the device tree?
That is pretty much what the "kernel" version of this does.
See: http://www.spinics.net/lists/arm-kernel/msg362853.html
Cheers
ChenYu
cover ARM: sunxi: Fix reset support on sun6i/sun8i
Hi,
Quoted 13 lines · Chen-Yu Tsai
Hi,
Quoted 10 lines · Julian Calaby
Hi,
Quoted 6 lines · Chen-Yu Tsai
Hi,
This series fixes support for the reset command on sun6i/sun8i. The watchdog hardware has changed in sun6i, both the register addresses and definitions. This makes the reset command unusable on sun6i.
Quoted 4 lines
Quoted 2 lines
Doesn't this break building multi-sub-arch kernels that support both sun4i/sun5i/sun7i and sun6i/sun8i?
Last time I checked, U-boot doesn't do multi-arch kernels.
Looking at the paths, I could have sworn this was kernel code.
In that case, sorry for the noise.
Thanks,
Signature · 4 lines
Julian Calaby Email: julian.calaby at gmail.com Profile: http://www.google.com/profiles/julian.calaby/