From: Chia-Wei, Wang <chiawei_wang@aspeedtech.com>
To: u-boot@lists.denx.de
Subject: [PATCH 3/7] wdt: aspeed: Add AST2600 watchdog support
Date: Mon, 14 Dec 2020 13:54:25 +0800 [thread overview]
Message-ID: <20201214055429.32690-4-chiawei_wang@aspeedtech.com> (raw)
In-Reply-To: <20201214055429.32690-1-chiawei_wang@aspeedtech.com>
AST2600 has 8 watchdog timers including 8 sets of
32-bit decrement counters, based on 1MHz clock.
A 64-bit reset mask is also supported to specify
which controllers should be reset by the WDT reset.
Signed-off-by: Chia-Wei, Wang <chiawei_wang@aspeedtech.com>
---
.../arm/include/asm/arch-aspeed/wdt_ast2600.h | 129 ++++++++++++++++++
drivers/watchdog/Kconfig | 9 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/ast2600_wdt.c | 110 +++++++++++++++
4 files changed, 249 insertions(+)
create mode 100644 arch/arm/include/asm/arch-aspeed/wdt_ast2600.h
create mode 100644 drivers/watchdog/ast2600_wdt.c
diff --git a/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h b/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h
new file mode 100644
index 0000000000..96e8ca07e3
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2020 Aspeed Technology Inc.
+ */
+
+#ifndef _ASM_ARCH_WDT_AST2600_H
+#define _ASM_ARCH_WDT_AST2600_H
+
+#define WDT_BASE 0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL 0x4755
+
+/* reset mode */
+#define WDT_RESET_MODE_SOC 0
+#define WDT_RESET_MODE_CHIP 1
+#define WDT_RESET_MODE_CPU 2
+
+/* bit-fields of WDT control register */
+#define WDT_CTRL_2ND_BOOT BIT(7)
+#define WDT_CTRL_RESET_MODE_MASK GENMASK(6, 5)
+#define WDT_CTRL_RESET_MODE_SHIFT 5
+#define WDT_CTRL_CLK1MHZ BIT(4)
+#define WDT_CTRL_RESET BIT(1)
+#define WDT_CTRL_EN BIT(0)
+
+/* bit-fields of WDT reset mask1 register */
+#define WDT_RESET_MASK1_RVAS BIT(25)
+#define WDT_RESET_MASK1_GPIO1 BIT(24)
+#define WDT_RESET_MASK1_XDMA2 BIT(23)
+#define WDT_RESET_MASK1_XDMA1 BIT(22)
+#define WDT_RESET_MASK1_MCTP2 BIT(21)
+#define WDT_RESET_MASK1_MCTP1 BIT(20)
+#define WDT_RESET_MASK1_JTAG1 BIT(19)
+#define WDT_RESET_MASK1_SD_SDIO1 BIT(18)
+#define WDT_RESET_MASK1_MAC2 BIT(17)
+#define WDT_RESET_MASK1_MAC1 BIT(16)
+#define WDT_RESET_MASK1_GPMCU BIT(15)
+#define WDT_RESET_MASK1_DPMCU BIT(14)
+#define WDT_RESET_MASK1_DP BIT(13)
+#define WDT_RESET_MASK1_HAC BIT(12)
+#define WDT_RESET_MASK1_VIDEO BIT(11)
+#define WDT_RESET_MASK1_CRT BIT(10)
+#define WDT_RESET_MASK1_GCRT BIT(9)
+#define WDT_RESET_MASK1_USB11_UHCI BIT(8)
+#define WDT_RESET_MASK1_USB_PORTA BIT(7)
+#define WDT_RESET_MASK1_USB_PORTB BIT(6)
+#define WDT_RESET_MASK1_COPROC BIT(5)
+#define WDT_RESET_MASK1_SOC BIT(4)
+#define WDT_RESET_MASK1_SLI BIT(3)
+#define WDT_RESET_MASK1_AHB BIT(2)
+#define WDT_RESET_MASK1_SDRAM BIT(1)
+#define WDT_RESET_MASK1_ARM BIT(0)
+
+/* bit-fields of WDT reset mask2 register */
+#define WDT_RESET_MASK2_ESPI BIT(26)
+#define WDT_RESET_MASK2_I3C_BUS8 BIT(25)
+#define WDT_RESET_MASK2_I3C_BUS7 BIT(24)
+#define WDT_RESET_MASK2_I3C_BUS6 BIT(23)
+#define WDT_RESET_MASK2_I3C_BUS5 BIT(22)
+#define WDT_RESET_MASK2_I3C_BUS4 BIT(21)
+#define WDT_RESET_MASK2_I3C_BUS3 BIT(20)
+#define WDT_RESET_MASK2_I3C_BUS2 BIT(19)
+#define WDT_RESET_MASK2_I3C_BUS1 BIT(18)
+#define WDT_RESET_MASK2_I3C_GLOBAL BIT(17)
+#define WDT_RESET_MASK2_I2C BIT(16)
+#define WDT_RESET_MASK2_FSI BIT(15)
+#define WDT_RESET_MASK2_ADC BIT(14)
+#define WDT_RESET_MASK2_PWM BIT(13)
+#define WDT_RESET_MASK2_PECI BIT(12)
+#define WDT_RESET_MASK2_LPC BIT(11)
+#define WDT_RESET_MASK2_MDC_MDIO BIT(10)
+#define WDT_RESET_MASK2_GPIO2 BIT(9)
+#define WDT_RESET_MASK2_JTAG2 BIT(8)
+#define WDT_RESET_MASK2_SD_SDIO2 BIT(7)
+#define WDT_RESET_MASK2_MAC4 BIT(6)
+#define WDT_RESET_MASK2_MAC3 BIT(5)
+#define WDT_RESET_MASK2_SOC BIT(4)
+#define WDT_RESET_MASK2_SLI2 BIT(3)
+#define WDT_RESET_MASK2_AHB2 BIT(2)
+#define WDT_RESET_MASK2_SPI1_SPI2 BIT(1)
+#define WDT_RESET_MASK2_ARM BIT(0)
+
+#define WDT_RESET_MASK1_DEFAULT \
+ (WDT_RESET_MASK1_RVAS | WDT_RESET_MASK1_GPIO1 | \
+ WDT_RESET_MASK1_JTAG1 | WDT_RESET_MASK1_SD_SDIO1 | \
+ WDT_RESET_MASK1_MAC2 | WDT_RESET_MASK1_MAC1 | \
+ WDT_RESET_MASK1_HAC | WDT_RESET_MASK1_VIDEO | \
+ WDT_RESET_MASK1_CRT | WDT_RESET_MASK1_GCRT | \
+ WDT_RESET_MASK1_USB11_UHCI | WDT_RESET_MASK1_USB_PORTA | \
+ WDT_RESET_MASK1_USB_PORTB | WDT_RESET_MASK1_COPROC | \
+ WDT_RESET_MASK1_SOC | WDT_RESET_MASK1_ARM)
+
+#define WDT_RESET_MASK2_DEFAULT \
+ (WDT_RESET_MASK2_I3C_BUS8 | WDT_RESET_MASK2_I3C_BUS7 | \
+ WDT_RESET_MASK2_I3C_BUS6 | WDT_RESET_MASK2_I3C_BUS5 | \
+ WDT_RESET_MASK2_I3C_BUS4 | WDT_RESET_MASK2_I3C_BUS3 | \
+ WDT_RESET_MASK2_I3C_BUS2 | WDT_RESET_MASK2_I3C_BUS1 | \
+ WDT_RESET_MASK2_I3C_GLOBAL | WDT_RESET_MASK2_I2C | \
+ WDT_RESET_MASK2_FSI | WDT_RESET_MASK2_ADC | \
+ WDT_RESET_MASK2_PWM | WDT_RESET_MASK2_PECI | \
+ WDT_RESET_MASK2_LPC | WDT_RESET_MASK2_MDC_MDIO | \
+ WDT_RESET_MASK2_GPIO2 | WDT_RESET_MASK2_JTAG2 | \
+ WDT_RESET_MASK2_SD_SDIO2 | WDT_RESET_MASK2_MAC4 | \
+ WDT_RESET_MASK2_MAC3 | WDT_RESET_MASK2_SOC | \
+ WDT_RESET_MASK2_ARM)
+
+#ifndef __ASSEMBLY__
+struct ast2600_wdt {
+ u32 counter_status;
+ u32 counter_reload_val;
+ u32 counter_restart;
+ u32 ctrl;
+ u32 timeout_status;
+ u32 clr_timeout_status;
+ u32 reset_width;
+ u32 reset_mask1;
+ u32 reset_mask2;
+ u32 sw_reset_ctrl;
+ u32 sw_reset_mask1;
+ u32 sw_reset_mask2;
+ u32 sw_reset_disable;
+};
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_AST2600_H */
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4532a40e45..d5edabf3ef 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -86,6 +86,15 @@ config WDT_ASPEED
It currently does not support Boot Flash Addressing Mode Detection or
Second Boot.
+config WDT_AST2600
+ bool "Aspeed AST2600 watchdog timer support"
+ depends on WDT
+ default y if ASPEED_AST2600
+ help
+ Select this to enable watchdog timer for Aspeed ast2500/ast2400 devices.
+ The watchdog timer is stopped when initialized. It performs reset, either
+ full SoC reset or CPU or just some peripherals, based on the flags.
+
config WDT_AT91
bool "AT91 watchdog timer support"
depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 01b8231f2b..cbb6d8407c 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_$(SPL_TPL_)WDT) += wdt-uclass.o
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_AST2600) += ast2600_wdt.o
obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
obj-$(CONFIG_WDT_ORION) += orion_wdt.o
diff --git a/drivers/watchdog/ast2600_wdt.c b/drivers/watchdog/ast2600_wdt.c
new file mode 100644
index 0000000000..6f1eb828f1
--- /dev/null
+++ b/drivers/watchdog/ast2600_wdt.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Aspeed Technology, Inc
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <asm/arch/wdt_ast2600.h>
+#include <linux/err.h>
+
+struct ast2600_wdt_priv {
+ struct ast2600_wdt *regs;
+};
+
+static int ast2600_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+ struct ast2600_wdt_priv *priv = dev_get_priv(dev);
+ struct ast2600_wdt *wdt = priv->regs;
+
+ /* WDT counts in the 1MHz frequency, namely 1us */
+ writel((u32)(timeout_ms * 1000), &wdt->counter_reload_val);
+ writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+ writel(WDT_CTRL_EN | WDT_CTRL_RESET, &wdt->ctrl);
+
+ return 0;
+}
+
+static int ast2600_wdt_stop(struct udevice *dev)
+{
+ struct ast2600_wdt_priv *priv = dev_get_priv(dev);
+ struct ast2600_wdt *wdt = priv->regs;
+
+ clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+
+ writel(WDT_RESET_MASK1_DEFAULT, &wdt->reset_mask1);
+ writel(WDT_RESET_MASK2_DEFAULT, &wdt->reset_mask2);
+
+ return 0;
+}
+
+static int ast2600_wdt_reset(struct udevice *dev)
+{
+ struct ast2600_wdt_priv *priv = dev_get_priv(dev);
+ struct ast2600_wdt *wdt = priv->regs;
+
+ writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+
+ return 0;
+}
+
+static int ast2600_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ int ret;
+ struct ast2600_wdt_priv *priv = dev_get_priv(dev);
+ struct ast2600_wdt *wdt = priv->regs;
+
+ ret = ast2600_wdt_start(dev, 1, flags);
+ if (ret)
+ return ret;
+
+ while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+ ;
+
+ return ast2600_wdt_stop(dev);
+}
+
+static int ast2600_wdt_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ast2600_wdt_priv *priv = dev_get_priv(dev);
+
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct wdt_ops ast2600_wdt_ops = {
+ .start = ast2600_wdt_start,
+ .reset = ast2600_wdt_reset,
+ .stop = ast2600_wdt_stop,
+ .expire_now = ast2600_wdt_expire_now,
+};
+
+static const struct udevice_id ast2600_wdt_ids[] = {
+ { .compatible = "aspeed,ast2600-wdt" },
+ { }
+};
+
+static int ast2600_wdt_probe(struct udevice *dev)
+{
+ debug("%s() wdt%u\n", __func__, dev->seq);
+ ast2600_wdt_stop(dev);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(ast2600_wdt) = {
+ .name = "ast2600_wdt",
+ .id = UCLASS_WDT,
+ .of_match = ast2600_wdt_ids,
+ .probe = ast2600_wdt_probe,
+ .priv_auto_alloc_size = sizeof(struct ast2600_wdt_priv),
+ .ofdata_to_platdata = ast2600_wdt_ofdata_to_platdata,
+ .ops = &ast2600_wdt_ops,
+};
--
2.17.1
next prev parent reply other threads:[~2020-12-14 5:54 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-14 5:54 [PATCH 0/7] Add Aspeed AST2600 support Chia-Wei, Wang
2020-12-14 5:54 ` [PATCH 1/7] clk: aspeed: Add AST2600 clock support Chia-Wei, Wang
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` [PATCH 2/7] ram: aspeed: Add AST2600 DRAM control support Chia-Wei, Wang
2021-01-12 3:00 ` Ryan Chen
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` Chia-Wei, Wang [this message]
2021-01-12 3:00 ` [PATCH 3/7] wdt: aspeed: Add AST2600 watchdog support Ryan Chen
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` [PATCH 4/7] reset: aspeed: Add AST2600 reset support Chia-Wei, Wang
2021-01-12 3:01 ` Ryan Chen
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` [PATCH 5/7] ARM: dts: aspeed: Add AST2600 SoC support Chia-Wei, Wang
2021-01-12 3:01 ` Ryan Chen
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` [PATCH 6/7] aspeed: Add AST2600 platform support Chia-Wei, Wang
2021-01-12 3:01 ` Ryan Chen
2021-01-19 13:04 ` Tom Rini
2020-12-14 5:54 ` [PATCH 7/7] configs: aspeed: Add defconfig for AST2600 EVB Chia-Wei, Wang
2021-01-12 3:02 ` Ryan Chen
2021-01-19 13:04 ` Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201214055429.32690-4-chiawei_wang@aspeedtech.com \
--to=chiawei_wang@aspeedtech.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.