mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
aspeed: Refactor AST2500 RAM Driver and Sysreset Driver
This change switches all existing users of ast2500 Watchdog to Driver Model based Watchdog driver. To perform system reset Sysreset Driver uses first Watchdog device found via uclass_first_device call. Since the system is going to be reset anyway it does not make much difference which watchdog is used. Instead of using Watchdog to reset itself, SDRAM driver now uses Reset driver to do that. These were the only users of the old Watchdog API, so that API is removed. This all is done in one change to avoid having to maintain dual API for watchdog in between. Signed-off-by: Maxim Sloyko <maxims@google.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
c93adc08f3
commit
99f8ad7321
6 changed files with 24 additions and 112 deletions
|
@ -100,45 +100,6 @@ u32 ast_reset_mask_from_flags(ulong flags);
|
|||
* @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
|
||||
*
|
||||
* Note, that this is only supported by ast2500 SoC
|
||||
*
|
||||
* @wdt: watchdog to use for this reset
|
||||
* @mask: reset mask.
|
||||
*/
|
||||
int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask);
|
||||
|
||||
/**
|
||||
* ast_get_wdt() - get a pointer to watchdog registers
|
||||
*
|
||||
* @wdt_number: 0-based WDT peripheral number
|
||||
* @return pointer to registers or -ve error on error
|
||||
*/
|
||||
struct ast_wdt *ast_get_wdt(u8 wdt_number);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_ARCH_WDT_H */
|
||||
|
|
|
@ -11,19 +11,13 @@ config SYS_TEXT_BASE
|
|||
|
||||
config ASPEED_AST2500
|
||||
bool "Support Aspeed AST2500 SoC"
|
||||
depends on DM_RESET
|
||||
select CPU_ARM1176
|
||||
help
|
||||
The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU.
|
||||
It is used as Board Management Controller on many server boards,
|
||||
which is enabled by support of LPC and eSPI peripherals.
|
||||
|
||||
config WDT_NUM
|
||||
int "Number of Watchdog Timers"
|
||||
default 3 if ASPEED_AST2500
|
||||
help
|
||||
The number of Watchdot Timers on a SoC.
|
||||
AST2500 has three WDTsk earlier versions have two or fewer.
|
||||
|
||||
source "arch/arm/mach-aspeed/ast2500/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <errno.h>
|
||||
#include <ram.h>
|
||||
#include <regmap.h>
|
||||
#include <reset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/scu_ast2500.h>
|
||||
#include <asm/arch/sdram_ast2500.h>
|
||||
|
@ -328,6 +329,7 @@ static void ast2500_sdrammc_lock(struct dram_info *info)
|
|||
|
||||
static int ast2500_sdrammc_probe(struct udevice *dev)
|
||||
{
|
||||
struct reset_ctl reset_ctl;
|
||||
struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
|
||||
struct ast2500_sdrammc_regs *regs = priv->regs;
|
||||
int i;
|
||||
|
@ -345,9 +347,15 @@ static int ast2500_sdrammc_probe(struct udevice *dev)
|
|||
}
|
||||
|
||||
clk_set_rate(&priv->ddr_clk, priv->clock_rate);
|
||||
ret = ast_wdt_reset_masked(ast_get_wdt(0), WDT_RESET_SDRAM);
|
||||
ret = reset_get_by_index(dev, 0, &reset_ctl);
|
||||
if (ret) {
|
||||
debug("%s(): SDRAM reset failed\n", __func__);
|
||||
debug("%s(): Failed to get reset signal\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_assert(&reset_ctl);
|
||||
if (ret) {
|
||||
debug("%s(): SDRAM reset failed: %u\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,54 +28,3 @@ ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_WDT
|
||||
void wdt_stop(struct ast_wdt *wdt)
|
||||
{
|
||||
clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
|
||||
}
|
||||
|
||||
void wdt_start(struct ast_wdt *wdt, u32 timeout)
|
||||
{
|
||||
writel(timeout, &wdt->counter_reload_val);
|
||||
writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
|
||||
/*
|
||||
* Setting CLK1MHZ bit is just for compatibility with ast2400 part.
|
||||
* On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
|
||||
* read-only
|
||||
*/
|
||||
setbits_le32(&wdt->ctrl,
|
||||
WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
|
||||
}
|
||||
#endif /* CONFIG_WDT */
|
||||
|
||||
int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask)
|
||||
{
|
||||
#ifdef CONFIG_ASPEED_AST2500
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
writel(mask, &wdt->reset_mask);
|
||||
clrbits_le32(&wdt->ctrl,
|
||||
WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
|
||||
wdt_start(wdt, 1);
|
||||
|
||||
/* Wait for WDT to reset */
|
||||
while (readl(&wdt->ctrl) & WDT_CTRL_EN)
|
||||
;
|
||||
wdt_stop(wdt);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -15,3 +15,5 @@ CONFIG_DM_SERIAL=y
|
|||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_DM_RESET=y
|
||||
|
|
|
@ -8,21 +8,19 @@
|
|||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <wdt.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/wdt.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
/* Number of Watchdog Timer ticks before reset */
|
||||
#define AST_WDT_RESET_TIMEOUT 10
|
||||
#define AST_WDT_FOR_RESET 0
|
||||
|
||||
static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
|
||||
u32 reset_mode = 0;
|
||||
struct udevice *wdt;
|
||||
u32 reset_mode;
|
||||
int ret = uclass_first_device(UCLASS_WDT, &wdt);
|
||||
|
||||
if (IS_ERR(wdt))
|
||||
return PTR_ERR(wdt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
|
@ -35,11 +33,11 @@ static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
|||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
/* Clear reset mode bits */
|
||||
clrsetbits_le32(&wdt->ctrl,
|
||||
(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
|
||||
(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
|
||||
wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
|
||||
ret = wdt_expire_now(wdt, reset_mode);
|
||||
if (ret) {
|
||||
debug("Sysreset failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue