
Am 20.01.20 um 10:53 schrieb Alex Nemirovsky:
From: Jason Li jason.li@cortina-access.com
Add support for hardware watchdog timer on all Cortina Access CAxxxx family of SoCs.
Signed-off-by: Jason Li jason.li@cortina-access.com Signed-off-by: Alex Nemirovsky alex.nemirovsky@cortina-access.com
MAINTAINERS | 2 + drivers/watchdog/Kconfig | 8 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/cortina_wdt.c | 144 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 drivers/watchdog/cortina_wdt.c
diff --git a/MAINTAINERS b/MAINTAINERS index b7b3359..f9334f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -180,6 +180,7 @@ F: board/cortina/common/* F: board/cortina/common/Kconfig F: board/cortina/common/armv8/lowlevel_init.S F: drivers/gpio/cortina_gpio.c +F: drivers/watchdog/cortina_wdt.c
ARM/CZ.NIC TURRIS MOX SUPPORT M: Marek Behun marek.behun@nic.cz @@ -662,6 +663,7 @@ F: board/cortina/common/* F: board/cortina/common/Kconfig F: board/cortina/common/mips/* F: drivers/gpio/cortina_gpio.c +F: drivers/watchdog/cortina_wdt.c
MIPS MSCC M: Gregory CLEMENT gregory.clement@bootlin.com diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 8c16d69..2f7dedb 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -99,6 +99,14 @@ config WDT_CDNS Select this to enable Cadence watchdog timer, which can be found on some Xilinx Microzed Platform.
+config WDT_CORTINA
- bool "Cortina Access CAxxxx watchdog timer support"
- depends on WDT
- help
Cortina Access CAxxxx watchdog timer support.
This driver support all CPU ISAs supported by Cortina
Access CAxxxx SoCs.
config WDT_MPC8xx bool "MPC8xx watchdog timer support" depends on WDT && MPC8xx diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 955caef..87f92a4 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o +obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o diff --git a/drivers/watchdog/cortina_wdt.c b/drivers/watchdog/cortina_wdt.c new file mode 100644 index 0000000..61df802 --- /dev/null +++ b/drivers/watchdog/cortina_wdt.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0+
+/*
- Copyright (C) 2020 Cortina-Access
- Author: Jason Li jason.li@cortina-access.com
- */
same comment as in patch 2/4
+#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <wdt.h>
+#define CA_WDT_CTRL 0x00 +#define CA_WDT_PS 0x04 +#define CA_WDT_DIV 0x08 +#define CA_WDT_LD 0x0C +#define CA_WDT_LOADE 0x10 +#define CA_WDT_CNT 0x14 +#define CA_WDT_IE 0x18 +#define CA_WDT_INT 0x1C +#define CA_WDT_STAT 0x20
+/* CA_WDT_CTRL */ +#define CTL_WDT_EN BIT(0) +#define CTL_WDT_RSTEN BIT(1) +#define CTL_WDT_CLK_SEL BIT(2) +/* CA_WDT_LOADE */ +#define WDT_UPD BIT(0) +#define WDT_UPD_PS BIT(1)
+/* Global config */ +#define WDT_RESET_SUB BIT(4) +#define WDT_RESET_ALL_BLOCK BIT(6) +#define WDT_RESET_REMAP BIT(7) +#define WDT_EXT_RESET BIT(8) +#define WDT_RESET_DEFAULT (WDT_EXT_RESET | WDT_RESET_REMAP |
WDT_RESET_ALL_BLOCK | WDT_RESET_SUB)
+struct ca_wdt_priv {
- void __iomem *base;
- void __iomem *global_config;
+};
+static void cortina_wdt_set_timeout(struct udevice *dev, u64 timeout_ms) +{
- struct ca_wdt_priv *priv = dev_get_priv(dev);
- /* Prescale using millisecond unit */
- writel(CORTINA_PER_IO_FREQ / 1000, priv->base + CA_WDT_PS);
- /* Millisecond */
- writel(1, priv->base + CA_WDT_DIV);
- writel(timeout_ms, priv->base + CA_WDT_LD);
- writel(WDT_UPD | WDT_UPD_PS, priv->base + CA_WDT_LOADE);
+}
+static int cortina_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{
- struct ca_wdt_priv *priv = dev_get_priv(dev);
- unsigned int reg_v;
- cortina_wdt_set_timeout(dev, timeout);
- /* WDT Reset option */
- reg_v = readl(priv->global_config);
- reg_v |= WDT_RESET_DEFAULT;
- writel(reg_v, priv->global_config);
- /* Enable WDT */
- reg_v = readl(priv->base);
- reg_v |= (CTL_WDT_EN | CTL_WDT_RSTEN | CTL_WDT_CLK_SEL);
- writel(reg_v, priv->base);
setbits_32() ?
- return 0;
+}
+static int cortina_wdt_stop(struct udevice *dev) +{
- struct ca_wdt_priv *priv = dev_get_priv(dev);
- /* Disable WDT */
- writel(0, priv->base);
- return 0;
+}
+static int cortina_wdt_reset(struct udevice *dev) +{
- struct ca_wdt_priv *priv = dev_get_priv(dev);
- /* Reload WDT counter */
- writel(WDT_UPD, priv->base + CA_WDT_LOADE);
- return 0;
+}
+static int cortina_wdt_expire_now(struct udevice *dev, ulong flags) +{
- /* Set 1ms timeout to reset system */
- cortina_wdt_set_timeout(dev, 1);
- hang();
- return 0;
+}
+static int cortina_wdt_probe(struct udevice *dev) +{
- struct ca_wdt_priv *priv = dev_get_priv(dev);
- priv->base = dev_remap_addr_index(dev, 0);
- if (!priv->base)
return -ENOENT;
- priv->global_config = dev_remap_addr_index(dev, 1);
- if (!priv->global_config)
return -ENOENT;
- /* Stop WDT */
- cortina_wdt_stop(dev);
- return 0;
+}
+static const struct wdt_ops cortina_wdt_ops = {
- .start = cortina_wdt_start,
- .reset = cortina_wdt_reset,
- .stop = cortina_wdt_stop,
- .expire_now = cortina_wdt_expire_now,
+};
+static const struct udevice_id cortina_wdt_ids[] = {
- {.compatible = "cortina,cortina-wdt"},
- {}
+};
+U_BOOT_DRIVER(cortina_wdt) = {
- .name = "cortina_wdt",
- .id = UCLASS_WDT,
- .probe = cortina_wdt_probe,
- .of_match = cortina_wdt_ids,
- .ops = &cortina_wdt_ops,
+};