All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] watchdog: K3: Add RTI watchdog support
@ 2020-06-23  6:20 Jan Kiszka
  2020-06-23  6:20 ` [PATCH 1/3] watchdog: Add support for K3 RTI watchdog Jan Kiszka
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jan Kiszka @ 2020-06-23  6:20 UTC (permalink / raw)
  To: u-boot

This brings watchdog support for the TI K3 SoCs, derived from the Linux
kernel, augmented with firmware loading as needed on the AM65x.

Tested on the AM65x EVM and the IOT2050 (also AM65x-based, upstream
support will be posted soon).

Jan

Jan Kiszka (3):
  watchdog: Add support for K3 RTI watchdog
  watchdog: rti_wdt: Add support for loading firmware
  arm: dts: k3: Add RTI watchdogs

 arch/arm/dts/k3-am65-mcu.dtsi   |   9 ++
 arch/arm/dts/k3-j721e-main.dtsi |  18 ++++
 drivers/watchdog/Kconfig        |  27 ++++++
 drivers/watchdog/Makefile       |   4 +
 drivers/watchdog/rti_wdt.c      | 157 ++++++++++++++++++++++++++++++++
 drivers/watchdog/rti_wdt_fw.S   |  20 ++++
 6 files changed, 235 insertions(+)
 create mode 100644 drivers/watchdog/rti_wdt.c
 create mode 100644 drivers/watchdog/rti_wdt_fw.S

-- 
2.26.2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] watchdog: Add support for K3 RTI watchdog
  2020-06-23  6:20 [PATCH 0/3] watchdog: K3: Add RTI watchdog support Jan Kiszka
@ 2020-06-23  6:20 ` Jan Kiszka
  2020-06-23  6:20 ` [PATCH 2/3] watchdog: rti_wdt: Add support for loading firmware Jan Kiszka
  2020-06-23  6:20 ` [PATCH 3/3] arm: dts: k3: Add RTI watchdogs Jan Kiszka
  2 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2020-06-23  6:20 UTC (permalink / raw)
  To: u-boot

From: Jan Kiszka <jan.kiszka@siemens.com>

This is based on the Linux kernel driver for the RTI watchdog.

To actually reset the system on an AM65x, it requires firmware running
on the R5 that accepts the NMI and issues the actual system reset via
TISCI. Kind of an iTCO, except that this watchdog hardware has support
for no-way-out, and only for that.

On the J721E, reset works without extra firmware help when routing the
RTI interrupt via the ESM.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 drivers/watchdog/Kconfig   |   7 ++
 drivers/watchdog/Makefile  |   1 +
 drivers/watchdog/rti_wdt.c | 133 +++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)
 create mode 100644 drivers/watchdog/rti_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index bf06180cdd..ee99bd2af1 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -155,6 +155,13 @@ config WDT_ORION
 	  Select this to enable Orion watchdog timer, which can be found on some
 	  Marvell Armada chips.
 
+config WDT_K3_RTI
+	bool "Texas Instruments K3 RTI watchdog"
+	depends on WDT && ARCH_K3
+	help
+	  Say Y here if you want to include support for the K3 watchdog
+	  timer (RTI module) available in the K3 generation of processors.
+
 config WDT_SANDBOX
 	bool "Enable Watchdog Timer support for Sandbox"
 	depends on SANDBOX && WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 519bbd3a40..16bdbf4970 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
 obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
 obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
+obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
 obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
 obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c
new file mode 100644
index 0000000000..3089a22da6
--- /dev/null
+++ b/drivers/watchdog/rti_wdt.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Siemens AG, 2020
+ *
+ * Authors:
+ *   Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * Derived from linux/drivers/watchdog/rti_wdt.c
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <power-domain.h>
+#include <wdt.h>
+#include <asm/io.h>
+
+/* Timer register set definition */
+#define RTIDWDCTRL		0x90
+#define RTIDWDPRLD		0x94
+#define RTIWDSTATUS		0x98
+#define RTIWDKEY		0x9c
+#define RTIDWDCNTR		0xa0
+#define RTIWWDRXCTRL		0xa4
+#define RTIWWDSIZECTRL		0xa8
+
+#define RTIWWDRX_NMI		0xa
+
+#define RTIWWDSIZE_50P		0x50
+
+#define WDENABLE_KEY		0xa98559da
+
+#define WDKEY_SEQ0		0xe51a
+#define WDKEY_SEQ1		0xa35c
+
+#define WDT_PRELOAD_SHIFT	13
+
+#define WDT_PRELOAD_MAX		0xfff
+
+struct rti_wdt_priv {
+	phys_addr_t regs;
+	unsigned int clk_khz;
+	struct power_domain pwrdmn;
+};
+
+static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+	struct rti_wdt_priv *priv = dev_get_priv(dev);
+	u32 timer_margin;
+	int ret;
+
+	ret = power_domain_on(&priv->pwrdmn);
+	if (ret) {
+		dev_err(dev, "Power domain on failed\n");
+		return ret;
+	}
+
+	if (readl(priv->regs + RTIDWDCTRL) == WDENABLE_KEY)
+		return -EBUSY;
+
+	timer_margin = timeout_ms * priv->clk_khz / 1000;
+	timer_margin >>= WDT_PRELOAD_SHIFT;
+	if (timer_margin > WDT_PRELOAD_MAX)
+		timer_margin = WDT_PRELOAD_MAX;
+
+	writel(timer_margin, priv->regs + RTIDWDPRLD);
+	writel(RTIWWDRX_NMI, priv->regs + RTIWWDRXCTRL);
+	writel(RTIWWDSIZE_50P, priv->regs + RTIWWDSIZECTRL);
+
+	readl(priv->regs + RTIWWDSIZECTRL);
+
+	writel(WDENABLE_KEY, priv->regs + RTIDWDCTRL);
+
+	return 0;
+}
+
+static int rti_wdt_reset(struct udevice *dev)
+{
+	struct rti_wdt_priv *priv = dev_get_priv(dev);
+	u32 prld;
+
+	/* Make sure we do not reset too early */
+	prld = readl(priv->regs + RTIDWDPRLD) << WDT_PRELOAD_SHIFT;
+	if (readl(priv->regs + RTIDWDCNTR) >= prld / 2)
+		return -EPERM;
+
+	writel(WDKEY_SEQ0, priv->regs + RTIWDKEY);
+	writel(WDKEY_SEQ1, priv->regs + RTIWDKEY);
+
+	return 0;
+}
+
+static int rti_wdt_probe(struct udevice *dev)
+{
+	struct rti_wdt_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	priv->regs = devfdt_get_addr(dev);
+	if (!priv->regs)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	priv->clk_khz = clk_get_rate(&clk);
+
+	ret = power_domain_get_by_index(dev, &priv->pwrdmn, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct wdt_ops rti_wdt_ops = {
+	.start = rti_wdt_start,
+	.reset = rti_wdt_reset,
+};
+
+static const struct udevice_id rti_wdt_ids[] = {
+	{ .compatible = "ti,j7-rti-wdt" },
+	{ }
+};
+
+U_BOOT_DRIVER(rti_wdt) = {
+	.name = "rti_wdt",
+	.id = UCLASS_WDT,
+	.of_match = rti_wdt_ids,
+	.ops = &rti_wdt_ops,
+	.probe = rti_wdt_probe,
+	.priv_auto_alloc_size = sizeof(struct rti_wdt_priv),
+};
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] watchdog: rti_wdt: Add support for loading firmware
  2020-06-23  6:20 [PATCH 0/3] watchdog: K3: Add RTI watchdog support Jan Kiszka
  2020-06-23  6:20 ` [PATCH 1/3] watchdog: Add support for K3 RTI watchdog Jan Kiszka
@ 2020-06-23  6:20 ` Jan Kiszka
  2020-06-23  6:20 ` [PATCH 3/3] arm: dts: k3: Add RTI watchdogs Jan Kiszka
  2 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2020-06-23  6:20 UTC (permalink / raw)
  To: u-boot

From: Jan Kiszka <jan.kiszka@siemens.com>

To avoid the need of extra boot scripting on AM65x for loading a
watchdog firmware, add the required rproc init and loading logic for the
first R5F core to the watchdog start handler. The firmware itself is
embedded into U-Boot binary.

One possible firmware source is https://github.com/siemens/k3-rti-wdt.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 drivers/watchdog/Kconfig      | 20 ++++++++++++++++++++
 drivers/watchdog/Makefile     |  3 +++
 drivers/watchdog/rti_wdt.c    | 24 ++++++++++++++++++++++++
 drivers/watchdog/rti_wdt_fw.S | 20 ++++++++++++++++++++
 4 files changed, 67 insertions(+)
 create mode 100644 drivers/watchdog/rti_wdt_fw.S

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ee99bd2af1..fd6ab9a85b 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -162,6 +162,26 @@ config WDT_K3_RTI
 	  Say Y here if you want to include support for the K3 watchdog
 	  timer (RTI module) available in the K3 generation of processors.
 
+if WDT_K3_RTI
+
+config WDT_K3_RTI_LOAD_FW
+	bool "Load watchdog firmware"
+	depends on REMOTEPROC
+	help
+	  Automatically load the specified firmware image into the MCU R5F
+	  core 0. On the AM65x, this firmware is supposed to handle the expiry
+	  of the watchdog timer, typically by resetting the system.
+
+config WDT_K3_RTI_FW_FILE
+	string "Watchdog firmware image file"
+	default "k3-rti-wdt.fw"
+	depends on WDT_K3_RTI_LOAD_FW
+	help
+	  Firmware image to be embedded into U-Boot and loaded on watchdog
+	  start.
+
+endif
+
 config WDT_SANDBOX
 	bool "Enable Watchdog Timer support for Sandbox"
 	depends on SANDBOX && WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 16bdbf4970..bf58684875 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -28,7 +28,10 @@ obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
 obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
 obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
 obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
+obj-$(CONFIG_WDT_K3_RTI_LOAD_FW) += rti_wdt_fw.o
 obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
 obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
 obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o
+
+$(obj)/rti_wdt_fw.o: $(shell readlink -f $(CONFIG_WDT_K3_RTI_FW_FILE)) FORCE
diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c
index 3089a22da6..786ab61f90 100644
--- a/drivers/watchdog/rti_wdt.c
+++ b/drivers/watchdog/rti_wdt.c
@@ -14,6 +14,7 @@
 #include <power-domain.h>
 #include <wdt.h>
 #include <asm/io.h>
+#include <remoteproc.h>
 
 /* Timer register set definition */
 #define RTIDWDCTRL		0x90
@@ -37,12 +38,17 @@
 
 #define WDT_PRELOAD_MAX		0xfff
 
+#define RTI_PROC_ID		0
+
 struct rti_wdt_priv {
 	phys_addr_t regs;
 	unsigned int clk_khz;
 	struct power_domain pwrdmn;
 };
 
+extern const u32 rti_wdt_fw[];
+extern const int rti_wdt_fw_size;
+
 static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
 	struct rti_wdt_priv *priv = dev_get_priv(dev);
@@ -58,6 +64,24 @@ static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 	if (readl(priv->regs + RTIDWDCTRL) == WDENABLE_KEY)
 		return -EBUSY;
 
+#ifdef CONFIG_WDT_K3_RTI_LOAD_FW
+	ret = rproc_dev_init(RTI_PROC_ID);
+	if (ret) {
+	    fw_error:
+		dev_err(dev, "Failed to load watchdog firmware into remote processor %d\n",
+			RTI_PROC_ID);
+		return ret;
+	}
+
+	ret = rproc_load(RTI_PROC_ID, (ulong)rti_wdt_fw, rti_wdt_fw_size);
+	if (ret)
+		goto fw_error;
+
+	ret = rproc_start(RTI_PROC_ID);
+	if (ret)
+		goto fw_error;
+#endif
+
 	timer_margin = timeout_ms * priv->clk_khz / 1000;
 	timer_margin >>= WDT_PRELOAD_SHIFT;
 	if (timer_margin > WDT_PRELOAD_MAX)
diff --git a/drivers/watchdog/rti_wdt_fw.S b/drivers/watchdog/rti_wdt_fw.S
new file mode 100644
index 0000000000..78d99ff9f2
--- /dev/null
+++ b/drivers/watchdog/rti_wdt_fw.S
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Siemens AG, 2020
+ *
+ * Authors:
+ *   Jan Kiszka <jan.kiszka@siemens.com>
+ */
+
+.section .rodata
+
+.global rti_wdt_fw
+.global rti_wdt_fw_size
+
+rti_wdt_fw:
+.align 4
+.incbin CONFIG_WDT_K3_RTI_FW_FILE
+rti_wdt_fw_end:
+
+rti_wdt_fw_size:
+.int rti_wdt_fw_end - rti_wdt_fw
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] arm: dts: k3: Add RTI watchdogs
  2020-06-23  6:20 [PATCH 0/3] watchdog: K3: Add RTI watchdog support Jan Kiszka
  2020-06-23  6:20 ` [PATCH 1/3] watchdog: Add support for K3 RTI watchdog Jan Kiszka
  2020-06-23  6:20 ` [PATCH 2/3] watchdog: rti_wdt: Add support for loading firmware Jan Kiszka
@ 2020-06-23  6:20 ` Jan Kiszka
  2 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2020-06-23  6:20 UTC (permalink / raw)
  To: u-boot

From: Jan Kiszka <jan.kiszka@siemens.com>

Add DT entries for main domain watchdog0 and 1 instances on the J721e
well as RTI1-based watchdog on the AM65x. RTI0 does not work for this
purpose on the AM65x, so leave it out.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 arch/arm/dts/k3-am65-mcu.dtsi   |  9 +++++++++
 arch/arm/dts/k3-j721e-main.dtsi | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi
index bc9a87210d..dfed234d44 100644
--- a/arch/arm/dts/k3-am65-mcu.dtsi
+++ b/arch/arm/dts/k3-am65-mcu.dtsi
@@ -102,4 +102,13 @@
 			#size-cells = <0>;
 		};
 	};
+
+	mcu_rti1: rti at 40610000 {
+		compatible = "ti,j7-rti-wdt";
+		reg = <0x0 0x40610000 0x0 0x100>;
+		clocks = <&k3_clks 135 0>;
+		power-domains = <&k3_pds 135 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 135 0>;
+		assigned-clock-parents = <&k3_clks 135 4>;
+	};
 };
diff --git a/arch/arm/dts/k3-j721e-main.dtsi b/arch/arm/dts/k3-j721e-main.dtsi
index 1433932e7f..a285b1afa8 100644
--- a/arch/arm/dts/k3-j721e-main.dtsi
+++ b/arch/arm/dts/k3-j721e-main.dtsi
@@ -543,4 +543,22 @@
 		clocks = <&k3_clks 193 0>;
 		power-domains = <&k3_pds 193 TI_SCI_PD_EXCLUSIVE>;
 	};
+
+	watchdog0: watchdog at 2200000 {
+		compatible = "ti,j7-rti-wdt";
+		reg = <0x0 0x2200000 0x0 0x100>;
+		clocks = <&k3_clks 252 1>;
+		power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 252 1>;
+		assigned-clock-parents = <&k3_clks 252 5>;
+	};
+
+	watchdog1: watchdog at 2210000 {
+		compatible = "ti,j7-rti-wdt";
+		reg = <0x0 0x2210000 0x0 0x100>;
+		clocks = <&k3_clks 253 1>;
+		power-domains = <&k3_pds 253 TI_SCI_PD_EXCLUSIVE>;
+		assigned-clocks = <&k3_clks 253 1>;
+		assigned-clock-parents = <&k3_clks 253 5>;
+	};
 };
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-06-23  6:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23  6:20 [PATCH 0/3] watchdog: K3: Add RTI watchdog support Jan Kiszka
2020-06-23  6:20 ` [PATCH 1/3] watchdog: Add support for K3 RTI watchdog Jan Kiszka
2020-06-23  6:20 ` [PATCH 2/3] watchdog: rti_wdt: Add support for loading firmware Jan Kiszka
2020-06-23  6:20 ` [PATCH 3/3] arm: dts: k3: Add RTI watchdogs Jan Kiszka

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.