mirror of
https://github.com/u-boot/u-boot.git
synced 2025-01-19 17:23:24 +08:00
watchdog: mpc8xxx: Make it generic
mpc8xx, mpc83xx and mpc86xx have similar watchdog with almost same memory registers. Refactor the driver to get the register addresses from the device tree and use the compatible to know the prescale factor. Calculate the watchdog setup value from the provided timeout. Don't declare it anymore as an HW_WATCHDOG, u-boot will start servicing the watchdog early enough. On mpc8xx the watchdog configuration register is also used for configuring the bus monitor. So add it as an option to the watchdog when it is mpc8xx. When watchdog is not selected, leave the configuration of the initial SYPCR from Kconfig. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
This commit is contained in:
parent
21eaade449
commit
26e8ebcd7c
@ -48,7 +48,8 @@ config SYS_SIUMCR
|
||||
SIU Module Configuration (11-6)
|
||||
|
||||
config SYS_SYPCR
|
||||
hex "SYPCR register"
|
||||
hex "SYPCR register" if !WDT_MPC8xxx
|
||||
default 0
|
||||
help
|
||||
System Protection Control (11-9)
|
||||
|
||||
|
@ -26,10 +26,9 @@ void cpu_init_f(immap_t __iomem *immr)
|
||||
|
||||
/* SYPCR - contains watchdog control (11-9) */
|
||||
|
||||
#ifndef CONFIG_HW_WATCHDOG
|
||||
/* deactivate watchdog if not enabled in config */
|
||||
out_be32(&immr->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
|
||||
#endif
|
||||
if (!IS_ENABLED(CONFIG_WDT_MPC8xxx))
|
||||
out_be32(&immr->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
|
||||
|
||||
schedule();
|
||||
|
||||
|
@ -18,11 +18,6 @@
|
||||
stdout-path = &SERIAL;
|
||||
};
|
||||
|
||||
WDT: watchdog@0 {
|
||||
device_type = "watchdog";
|
||||
compatible = "fsl,pq1-wdt";
|
||||
};
|
||||
|
||||
SERIAL: serial {
|
||||
compatible = "fsl,pq1-smc";
|
||||
};
|
||||
@ -43,6 +38,13 @@
|
||||
ranges = <0 0xff000000 0x4000>;
|
||||
reg = <0xff000000 0x00000200>;
|
||||
|
||||
WDT: watchdog@0 {
|
||||
compatible = "fsl,pq1-wdt";
|
||||
reg = <0x0 0x10>;
|
||||
timeout-sec = <2>;
|
||||
hw_margin_ms = <1000>;
|
||||
};
|
||||
|
||||
CPM1_PIO_B: gpio-controller@ab8 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,cpm1-pario-bank-b";
|
||||
|
@ -9,9 +9,25 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
WDT: watchdog@0 {
|
||||
compatible = "fsl,pq1-wdt";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
soc: immr@ff000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
device-type = "soc";
|
||||
compatible = "simple-bus";
|
||||
ranges = <0 0xff000000 0x4000>;
|
||||
reg = <0xff000000 0x00000200>;
|
||||
|
||||
WDT: watchdog@0 {
|
||||
compatible = "fsl,pq1-wdt";
|
||||
reg = <0x0 0x10>;
|
||||
timeout-sec = <2>;
|
||||
hw_margin_ms = <1000>;
|
||||
};
|
||||
};
|
||||
|
||||
SERIAL: smc@0 {
|
||||
compatible = "fsl,pq1-smc";
|
||||
};
|
||||
|
@ -138,17 +138,3 @@ int board_early_init_f(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
struct udevice *watchdog_dev = NULL;
|
||||
|
||||
if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
|
||||
puts("Cannot find watchdog!\n");
|
||||
} else {
|
||||
puts("Enabling watchdog.\n");
|
||||
wdt_start(watchdog_dev, 0xffff, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ CONFIG_TARGET_CMPC885=y
|
||||
CONFIG_MPC885=y
|
||||
CONFIG_CMD_IMMAP=y
|
||||
CONFIG_SYS_SIUMCR=0x00620000
|
||||
CONFIG_SYS_SYPCR=0xFFFFFF8F
|
||||
CONFIG_SYS_TBSCR=0x00C3
|
||||
CONFIG_SYS_PISCR=0x0000
|
||||
CONFIG_SYS_PLPRCR_BOOL=y
|
||||
@ -106,5 +105,6 @@ CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_MPC8XX_SPI=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_MPC8xxx_BME=y
|
||||
# CONFIG_REGEX is not set
|
||||
CONFIG_LZMA=y
|
||||
|
@ -11,7 +11,6 @@ CONFIG_MPC8xx=y
|
||||
CONFIG_TARGET_MCR3000=y
|
||||
CONFIG_CMD_IMMAP=y
|
||||
CONFIG_SYS_SIUMCR=0x00600400
|
||||
CONFIG_SYS_SYPCR=0xFFFFFF8F
|
||||
CONFIG_SYS_TBSCR=0x00C3
|
||||
CONFIG_SYS_PISCR=0x0000
|
||||
CONFIG_SYS_PLPRCR_BOOL=y
|
||||
@ -29,7 +28,6 @@ CONFIG_AUTOBOOT_PROMPT="\nEnter password - autoboot in %d sec...\n"
|
||||
CONFIG_AUTOBOOT_DELAY_STR="root"
|
||||
CONFIG_USE_BOOTCOMMAND=y
|
||||
CONFIG_BOOTCOMMAND="run flashboot"
|
||||
CONFIG_BOARD_EARLY_INIT_R=y
|
||||
# CONFIG_HWCONFIG is not set
|
||||
CONFIG_MISC_INIT_R=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
@ -102,4 +100,5 @@ CONFIG_MPC8XX_FEC=y
|
||||
# CONFIG_PCI is not set
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_MPC8xxx_BME=y
|
||||
CONFIG_LZMA=y
|
||||
|
@ -187,10 +187,26 @@ config WDT_MESON_GXBB
|
||||
config WDT_MPC8xxx
|
||||
bool "MPC8xxx watchdog timer support"
|
||||
depends on WDT && MPC8xx
|
||||
select HW_WATCHDOG
|
||||
help
|
||||
Select this to enable mpc8xxx watchdog timer
|
||||
|
||||
config WDT_MPC8xxx_BME
|
||||
bool "Enable MPC8xx Bus Monitoring"
|
||||
depends on WDT_MPC8xxx && MPC8xx
|
||||
help
|
||||
Select this to enable mpc8xx Bus Monitor.
|
||||
|
||||
config WDT_MPC8xxx_BMT
|
||||
int "MPC8xx Bus Monitor Timing" if WDT_MPC8xxx_BME
|
||||
range 0 255
|
||||
default 255
|
||||
depends on WDT_MPC8xxx
|
||||
help
|
||||
Bus monitor timing. Defines the timeout period, in 8 system clock
|
||||
resolution, for the bus monitor.
|
||||
|
||||
Maximum timeout is 2,040 clocks (255 x 8).
|
||||
|
||||
config WDT_MT7620
|
||||
bool "MediaTek MT7620 watchdog timer support"
|
||||
depends on WDT && SOC_MT7620
|
||||
|
@ -7,32 +7,61 @@
|
||||
#include <env.h>
|
||||
#include <dm.h>
|
||||
#include <wdt.h>
|
||||
#include <mpc8xx.h>
|
||||
#include <asm/cpm_8xx.h>
|
||||
#include <clock_legacy.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
void hw_watchdog_reset(void)
|
||||
{
|
||||
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
|
||||
struct mpc8xxx_wdt {
|
||||
__be32 res0;
|
||||
__be32 swcrr; /* System watchdog control register */
|
||||
#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
|
||||
#define SWCRR_BME 0x00000080 /* Bus monitor enable (mpc8xx) */
|
||||
#define SWCRR_SWF 0x00000008 /* Software Watchdog Freeze (mpc8xx). */
|
||||
#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
|
||||
#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
|
||||
#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
|
||||
__be32 swcnr; /* System watchdog count register */
|
||||
u8 res1[2];
|
||||
__be16 swsrr; /* System watchdog service register */
|
||||
u8 res2[0xf0];
|
||||
};
|
||||
|
||||
out_be16(&immap->im_siu_conf.sc_swsr, 0x556c); /* write magic1 */
|
||||
out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */
|
||||
struct mpc8xxx_wdt_priv {
|
||||
struct mpc8xxx_wdt __iomem *base;
|
||||
};
|
||||
|
||||
static int mpc8xxx_wdt_reset(struct udevice *dev)
|
||||
{
|
||||
struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
out_be16(&priv->base->swsrr, 0x556c); /* write magic1 */
|
||||
out_be16(&priv->base->swsrr, 0xaa39); /* write magic2 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc8xxx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
|
||||
{
|
||||
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
|
||||
u32 val = CONFIG_SYS_SYPCR;
|
||||
struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
|
||||
const char *mode = env_get("watchdog_mode");
|
||||
ulong prescaler = dev_get_driver_data(dev);
|
||||
u16 swtc = min_t(u16, timeout * get_board_sys_clk() / 1000 / prescaler, U16_MAX);
|
||||
u32 val;
|
||||
|
||||
mpc8xxx_wdt_reset(dev);
|
||||
|
||||
if (strcmp(mode, "off") == 0)
|
||||
val = val & ~(SYPCR_SWE | SYPCR_SWRI);
|
||||
val = (swtc << 16) | SWCRR_SWPR;
|
||||
else if (strcmp(mode, "nmi") == 0)
|
||||
val = (val & ~SYPCR_SWRI) | SYPCR_SWE;
|
||||
val = (swtc << 16) | SWCRR_SWPR | SWCRR_SWEN;
|
||||
else
|
||||
val = (swtc << 16) | SWCRR_SWPR | SWCRR_SWEN | SWCRR_SWRI;
|
||||
|
||||
out_be32(&immap->im_siu_conf.sc_sypcr, val);
|
||||
if (IS_ENABLED(CONFIG_WDT_MPC8xxx_BME))
|
||||
val |= (CONFIG_WDT_MPC8xxx_BMT << 8) | SWCRR_BME;
|
||||
|
||||
if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
|
||||
out_be32(&priv->base->swcrr, val);
|
||||
|
||||
if (!(in_be32(&priv->base->swcrr) & SWCRR_SWEN))
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
|
||||
@ -40,18 +69,23 @@ static int mpc8xxx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
|
||||
|
||||
static int mpc8xxx_wdt_stop(struct udevice *dev)
|
||||
{
|
||||
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
|
||||
struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
|
||||
clrbits_be32(&priv->base->swcrr, SWCRR_SWEN);
|
||||
|
||||
if (in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE)
|
||||
if (in_be32(&priv->base->swcrr) & SWCRR_SWEN)
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc8xxx_wdt_reset(struct udevice *dev)
|
||||
static int mpc8xxx_wdt_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
hw_watchdog_reset();
|
||||
struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = (void __iomem *)devfdt_remap_addr(dev);
|
||||
|
||||
if (!priv->base)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -63,7 +97,7 @@ static const struct wdt_ops mpc8xxx_wdt_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id mpc8xxx_wdt_ids[] = {
|
||||
{ .compatible = "fsl,pq1-wdt" },
|
||||
{ .compatible = "fsl,pq1-wdt", .data = 0x800 },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -72,4 +106,6 @@ U_BOOT_DRIVER(wdt_mpc8xxx) = {
|
||||
.id = UCLASS_WDT,
|
||||
.of_match = mpc8xxx_wdt_ids,
|
||||
.ops = &mpc8xxx_wdt_ops,
|
||||
.of_to_plat = mpc8xxx_wdt_of_to_plat,
|
||||
.priv_auto = sizeof(struct mpc8xxx_wdt_priv),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user