]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
watchdog: mpc8xxx: Make it generic
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Mon, 3 Apr 2023 08:27:39 +0000 (10:27 +0200)
committerChristophe Leroy <christophe.leroy@csgroup.eu>
Thu, 6 Apr 2023 12:47:47 +0000 (14:47 +0200)
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>
arch/powerpc/cpu/mpc8xx/Kconfig
arch/powerpc/cpu/mpc8xx/cpu_init.c
arch/powerpc/dts/cmpc885.dts
arch/powerpc/dts/mcr3000.dts
board/cssi/mcr3000/mcr3000.c
configs/CMPC885_defconfig
configs/MCR3000_defconfig
drivers/watchdog/Kconfig
drivers/watchdog/mpc8xxx_wdt.c

index a705014512926760ac9fcfe83715fc541dfe3c83..bfd903bc1073f6c847fc8166768a29e2a2ebb94c 100644 (file)
@@ -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)
 
index 86b08a61749bdf884f1c7c19198acec4620591b9..feef792ee77fec7a0c07290d2a43aa536ffb4d6e 100644 (file)
@@ -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();
 
index adda0f3e9dd57b0d21ef42bb67d25b2ff034dd64..7b9566a0fa47fec79df9d5c41034733336a12531 100644 (file)
                stdout-path = &SERIAL;
        };
 
-       WDT: watchdog@0 {
-               device_type = "watchdog";
-               compatible = "fsl,pq1-wdt";
-       };
-
        SERIAL: serial {
                compatible = "fsl,pq1-smc";
        };
                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";
index 5f32d8a2e559acade3fa70ee81023183916c84a3..c4d7737bc672c3b473142c85964684eabac11673 100644 (file)
@@ -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";
        };
index 7b3ab12bd5c2f4dd8d1d87353fa71092a4d7beb5..3514f6749014ab0bb004403df31080110bcb2759 100644 (file)
@@ -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;
-}
index 484a81b8d3f76520d2a0a184453e98f5b6c4ceef..1fe67d02f2f7afa1698ea6d4b91b1d28cf33ed68 100644 (file)
@@ -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
index 4b5ce407eae6bdd94999919a2390acb1fa3999f9..fc2bf5b2f94b04da5335d60b9f46d4a1068d2e8a 100644 (file)
@@ -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
index f6554d5c93eacd9a5f674e5d798d7607e5b82509..f7fbb28d80af63e1dee5269cc2bb7b86e5498e2a 100644 (file)
@@ -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
index ffca3ec877cc366f661f8e9403069dffb1531c1b..9a29938faceef13862b82295d6f579c3fbcf87a0 100644 (file)
@@ -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)
+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];
+};
+
+struct mpc8xxx_wdt_priv {
+       struct mpc8xxx_wdt __iomem *base;
+};
+
+static int mpc8xxx_wdt_reset(struct udevice *dev)
 {
-       immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+       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 */
 
-       out_be16(&immap->im_siu_conf.sc_swsr, 0x556c);  /* write magic1 */
-       out_be16(&immap->im_siu_conf.sc_swsr, 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;
+
+       if (IS_ENABLED(CONFIG_WDT_MPC8xxx_BME))
+               val |= (CONFIG_WDT_MPC8xxx_BMT << 8) | SWCRR_BME;
 
-       out_be32(&immap->im_siu_conf.sc_sypcr, val);
+       out_be32(&priv->base->swcrr, val);
 
-       if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
+       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),
 };