diff mbox

[U-Boot,2/3] orion_wdt: Support for the Orion Watchdog

Message ID 20170512141008.15947-3-marek.behun@nic.cz
State Superseded
Delegated to: Stefan Roese
Headers show

Commit Message

Marek BehĂșn May 12, 2017, 2:10 p.m. UTC
This watchdog can be found on some Armada chips.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/watchdog/Kconfig     |   7 +++
 drivers/watchdog/Makefile    |   1 +
 drivers/watchdog/orion_wdt.c | 128 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 136 insertions(+)
 create mode 100644 drivers/watchdog/orion_wdt.c

Comments

Tom Rini May 14, 2017, 6:51 p.m. UTC | #1
On Fri, May 12, 2017 at 04:10:07PM +0200, Marek BehĂșn wrote:

> This watchdog can be found on some Armada chips.
> 
> Signed-off-by: Marek Behun <marek.behun@nic.cz>
> ---
>  drivers/watchdog/Kconfig     |   7 +++
>  drivers/watchdog/Makefile    |   1 +
>  drivers/watchdog/orion_wdt.c | 128 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 136 insertions(+)
>  create mode 100644 drivers/watchdog/orion_wdt.c

In a few places you're adding 2 newlines instead of one, please fix.
Also:
[snip]
> +config ORION_WATCHDOG
> +	bool "Enable "
> +	select HW_WATCHDOG

You need to finish the "Enable" line, and most likely add a depends on
... as well, unless you can also enable and build it for sandbox (which
would be great, that's where we get our static analysis done).

> + * This file is licensed under  the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.

SPDX tag please.

For the rest of it, please make it use the watchdog uclass and so forth,
thanks!
diff mbox

Patch

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index bdaf5d4..c2df88f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -12,6 +12,13 @@  config BCM2835_WDT
 	  This provides basic infrastructure to support BCM2835/2836 watchdog
 	  hardware, with a max timeout of ~15secs.
 
+config ORION_WATCHDOG
+	bool "Enable "
+	select HW_WATCHDOG
+	help
+	  Say Y here to enable the Orion watchdog, which can be found on some
+	  Marvell Armada chips.
+
 config ULP_WATCHDOG
 	bool "i.MX7ULP watchdog"
 	help
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 8378601..7df33f0 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -19,3 +19,4 @@  obj-$(CONFIG_WDT) += wdt-uclass.o
 obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
 obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
 obj-$(CONFIG_BCM2835_WDT)       += bcm2835_wdt.o
+obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
new file mode 100644
index 0000000..35d129b
--- /dev/null
+++ b/drivers/watchdog/orion_wdt.c
@@ -0,0 +1,128 @@ 
+/*
+ * drivers/watchdog/orion_wdt.c
+ *
+ * Watchdog driver for Orion/Kirkwood processors
+ *
+ * Authors:	Tomas Hlavacek <tmshlvck@gmail.com>
+ * 		Sylver Bruneau <sylver.bruneau@googlemail.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+
+/*
+ * Watchdog timer block registers.
+ */
+
+#define ORION_WDT_REG MVEBU_REGISTER(0x20300)
+#define ORION_WDT_RSTOUTREG MVEBU_REGISTER(0x20704)
+#define ORION_WDT_RSTOUTMASKREG MVEBU_REGISTER(0x18260)
+
+#define RSTOUT_ENABLE_BIT BIT(8)
+#define RSTOUT_MASK_BIT BIT(10)
+#define WDT_ENABLE_BIT BIT(8)
+
+#define ORION_WDT_COUNTER_OFFSET 0x34
+
+
+#define TIMER_CTRL		0x0000
+#define TIMER_A370_STATUS	0x04
+
+#define WDT_MAX_CYCLE_COUNT	0xffffffff
+
+#define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
+#define WDT_A370_EXPIRED	BIT(31)
+
+#define FIXED_CLKRATE 25000000 /* Hz */
+#ifndef ORION_WDT_TIMEOUT
+#define ORION_WDT_TIMEOUT 120 /* sec */
+#endif
+
+
+static int orion_wdt_ping(void)
+{
+	/* Reload watchdog duration */
+	writel((u32)FIXED_CLKRATE * ORION_WDT_TIMEOUT,
+	       ORION_WDT_REG + ORION_WDT_COUNTER_OFFSET);
+	return 0;
+}
+
+static int orion_wdt_start(void)
+{
+	u32 reg;
+
+	/* Enable the fixed watchdog clock input */
+        reg = readl(ORION_WDT_REG + TIMER_CTRL);
+        reg |= WDT_AXP_FIXED_ENABLE_BIT;
+        writel(reg, ORION_WDT_REG + TIMER_CTRL);
+
+	/* Set watchdog duration */
+	writel((u32)FIXED_CLKRATE * ORION_WDT_TIMEOUT,
+		ORION_WDT_REG + ORION_WDT_COUNTER_OFFSET);
+
+	/* Clear the watchdog expiration bit */
+	reg = readl(ORION_WDT_REG + TIMER_A370_STATUS);
+	reg &= ~WDT_A370_EXPIRED;
+	writel(reg, ORION_WDT_REG + TIMER_A370_STATUS);
+
+	/* Enable watchdog timer */
+	reg = readl(ORION_WDT_REG + TIMER_CTRL);
+	reg |= WDT_ENABLE_BIT;
+	writel(reg, ORION_WDT_REG + TIMER_CTRL);
+
+	/* Enable reset on watchdog */
+	reg = readl(ORION_WDT_RSTOUTREG);
+	reg |= RSTOUT_ENABLE_BIT;
+	writel(reg, ORION_WDT_RSTOUTREG);
+
+	reg = readl(ORION_WDT_RSTOUTMASKREG);
+	reg &= ~RSTOUT_MASK_BIT;
+	writel(reg, ORION_WDT_RSTOUTMASKREG);
+	
+	return 0;
+}
+
+static int orion_wdt_stop(void)
+{
+	u32 reg;
+
+	/* Disable reset on watchdog */
+	reg = readl(ORION_WDT_RSTOUTMASKREG);
+	reg |= RSTOUT_MASK_BIT;
+	writel(reg, ORION_WDT_RSTOUTMASKREG);
+
+	reg = readl(ORION_WDT_RSTOUTREG);
+	reg &= ~RSTOUT_ENABLE_BIT;
+	writel(reg, ORION_WDT_RSTOUTREG);
+
+	/* Disable watchdog timer */
+	reg = readl(ORION_WDT_REG + TIMER_CTRL);
+	reg &= ~WDT_ENABLE_BIT;
+	writel(reg, ORION_WDT_REG + TIMER_CTRL);
+
+	return 0;
+}
+
+void hw_watchdog_disable(void)
+{
+	orion_wdt_stop();
+}
+
+void hw_watchdog_reset(void)
+{
+	orion_wdt_ping();
+}
+
+void hw_watchdog_init(void)
+{
+	orion_wdt_start();
+}
+