Am 20.01.20 um 10:53 schrieb Alex Nemirovsky:
> From: Jason Li <[email protected]>
> 
> Add support for hardware watchdog timer on all Cortina Access
> CAxxxx family of SoCs.
> 
> Signed-off-by: Jason Li <[email protected]>
> Signed-off-by: Alex Nemirovsky <[email protected]>
> ---
> 
>  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 <[email protected]>
> @@ -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 <[email protected]>
> 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 <[email protected]>
> + *
> + */

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,
> +};
> 

-- 
- Daniel

Reply via email to