All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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.