diff options
author | maxims@google.com <maxims@google.com> | 2017-04-17 12:00:22 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-05-08 11:57:31 -0400 |
commit | 1eb0a464b7434175800c98a175909588d38c1dae (patch) | |
tree | 32b328b44d53ac1af19901f94385c3a648bc8893 /arch | |
parent | 0753bc2d30d7ca4a0ea4ef7f97083961c3a9d0e0 (diff) | |
download | u-boot-1eb0a464b7434175800c98a175909588d38c1dae.tar.gz u-boot-1eb0a464b7434175800c98a175909588d38c1dae.tar.xz u-boot-1eb0a464b7434175800c98a175909588d38c1dae.zip |
aspeed: Watchdog Timer Driver
This driver supports ast2500 and ast2400 SoCs.
Only ast2500 supports reset_mask and thus the option of resettting
individual peripherals using WDT.
Signed-off-by: Maxim Sloyko <maxims@google.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/arch-aspeed/wdt.h | 53 | ||||
-rw-r--r-- | arch/arm/mach-aspeed/ast_wdt.c | 40 |
2 files changed, 80 insertions, 13 deletions
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h index b292a0e67b..981fa05a56 100644 --- a/arch/arm/include/asm/arch-aspeed/wdt.h +++ b/arch/arm/include/asm/arch-aspeed/wdt.h @@ -67,15 +67,60 @@ struct ast_wdt { u32 timeout_status; u32 clr_timeout_status; u32 reset_width; -#ifdef CONFIG_ASPEED_AST2500 + /* On pre-ast2500 SoCs this register is reserved. */ u32 reset_mask; -#else - u32 reserved0; -#endif }; +/** + * Given flags parameter passed to wdt_reset or wdt_start uclass functions, + * gets Reset Mode value from it. + * + * @flags: flags parameter passed into wdt_reset or wdt_start + * @return Reset Mode value + */ +u32 ast_reset_mode_from_flags(ulong flags); + +/** + * Given flags parameter passed to wdt_reset or wdt_start uclass functions, + * gets Reset Mask value from it. Reset Mask is only supported on ast2500 + * + * @flags: flags parameter passed into wdt_reset or wdt_start + * @return Reset Mask value + */ +u32 ast_reset_mask_from_flags(ulong flags); + +/** + * Given Reset Mask and Reset Mode values, converts them to flags, + * suitable for passing into wdt_start or wdt_reset uclass functions. + * + * On ast2500 Reset Mask is 25 bits wide and Reset Mode is 2 bits wide, so they + * can both be packed into single 32 bits wide value. + * + * @reset_mode: Reset Mode + * @reset_mask: Reset Mask + */ +ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask); + +#ifndef CONFIG_WDT +/** + * Stop WDT + * + * @wdt: watchdog to stop + * + * When using driver model this function has different signature + */ void wdt_stop(struct ast_wdt *wdt); + +/** + * Stop WDT + * + * @wdt: watchdog to start + * @timeout watchdog timeout in number of clock ticks + * + * When using driver model this function has different signature + */ void wdt_start(struct ast_wdt *wdt, u32 timeout); +#endif /* CONFIG_WDT */ /** * Reset peripherals specified by mask diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c index 22481ab7ea..895fba3366 100644 --- a/arch/arm/mach-aspeed/ast_wdt.c +++ b/arch/arm/mach-aspeed/ast_wdt.c @@ -9,6 +9,27 @@ #include <asm/arch/wdt.h> #include <linux/err.h> +u32 ast_reset_mode_from_flags(ulong flags) +{ + return flags & WDT_CTRL_RESET_MASK; +} + +u32 ast_reset_mask_from_flags(ulong flags) +{ + return flags >> 2; +} + +ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask) +{ + ulong ret = reset_mode & WDT_CTRL_RESET_MASK; + + if (ret == WDT_CTRL_RESET_SOC) + ret |= (reset_mask << 2); + + return ret; +} + +#ifndef CONFIG_WDT void wdt_stop(struct ast_wdt *wdt) { clrbits_le32(&wdt->ctrl, WDT_CTRL_EN); @@ -26,15 +47,7 @@ void wdt_start(struct ast_wdt *wdt, u32 timeout) setbits_le32(&wdt->ctrl, WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ); } - -struct ast_wdt *ast_get_wdt(u8 wdt_number) -{ - if (wdt_number > CONFIG_WDT_NUM - 1) - return ERR_PTR(-EINVAL); - - return (struct ast_wdt *)(WDT_BASE + - sizeof(struct ast_wdt) * wdt_number); -} +#endif /* CONFIG_WDT */ int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask) { @@ -57,3 +70,12 @@ int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask) return -EINVAL; #endif } + +struct ast_wdt *ast_get_wdt(u8 wdt_number) +{ + if (wdt_number > CONFIG_WDT_NUM - 1) + return ERR_PTR(-EINVAL); + + return (struct ast_wdt *)(WDT_BASE + + sizeof(struct ast_wdt) * wdt_number); +} |