All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marek Behún" <marek.behun@nic.cz>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v4 2/7] orion_wdt: Support for the Orion Watchdog
Date: Fri,  9 Jun 2017 19:28:41 +0200	[thread overview]
Message-ID: <20170609172845.10238-3-marek.behun@nic.cz> (raw)
In-Reply-To: <20170609172845.10238-1-marek.behun@nic.cz>

The Orion watchdog can be found on some Marvell Armada chips.

This driver is based on the code by Tomas Hlavacek in the CZ.NIC
turris-omnia-uboot repository, which can be found at
https://gitlab.labs.nic.cz/turris/turris-omnia-uboot, and that
one is based on code by Sylver Bruneau. His code is already in
mainline Linux kernel.

The code uses the new driver model API.

Signed-off-by: Tomas Hlavacek <tomas.hlavacek@nic.cz>
Signed-off-by: Marek Behun <marek.behun@nic.cz>

 create mode 100644 drivers/watchdog/orion_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b911233db3..d360a17d4d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -62,4 +62,11 @@ config WDT_BCM6345
 	  The watchdog timer is stopped when initialized.
 	  It performs full SoC reset.
 
+config WDT_ORION
+	bool "Orion watchdog timer support"
+	depends on WDT
+	help
+	   Select this to enable Orion watchdog timer, which can be found on some
+	   Marvell Armada chips.
+
 endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4b19e4ccf6..3230cbb2ad 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
 obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
 obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
 obj-$(CONFIG_BCM2835_WDT)       += bcm2835_wdt.o
+obj-$(CONFIG_WDT_ORION) += orion_wdt.o
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
new file mode 100644
index 0000000000..a0df02d103
--- /dev/null
+++ b/drivers/watchdog/orion_wdt.c
@@ -0,0 +1,177 @@
+/*
+ * drivers/watchdog/orion_wdt.c
+ *
+ * Watchdog driver for Orion/Kirkwood processors
+ *
+ * Authors:	Tomas Hlavacek <tmshlvck@gmail.com>
+ * 		Sylver Bruneau <sylver.bruneau@googlemail.com>
+ * 		Marek Behun <marek.behun@nic.cz>
+ *
+ * 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 <dm.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct orion_wdt_priv {
+	void __iomem *reg;
+	int wdt_counter_offset;
+	void __iomem *rstout;
+	void __iomem *rstout_mask;
+	u32 timeout;
+};
+
+#define RSTOUT_ENABLE_BIT		BIT(8)
+#define RSTOUT_MASK_BIT			BIT(10)
+#define WDT_ENABLE_BIT			BIT(8)
+
+#define TIMER_CTRL			0x0000
+#define TIMER_A370_STATUS		0x04
+
+#define WDT_AXP_FIXED_ENABLE_BIT	BIT(10)
+#define WDT_A370_EXPIRED		BIT(31)
+
+static int orion_wdt_reset(struct udevice *dev)
+{
+	struct orion_wdt_priv *priv = dev_get_priv(dev);
+
+	/* Reload watchdog duration */
+	writel(priv->timeout, priv->reg + priv->wdt_counter_offset);
+
+	return 0;
+}
+
+static int orion_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct orion_wdt_priv *priv = dev_get_priv(dev);
+	u32 reg;
+
+	priv->timeout = (u32) timeout;
+
+	/* Enable the fixed watchdog clock input */
+	reg = readl(priv->reg + TIMER_CTRL);
+	reg |= WDT_AXP_FIXED_ENABLE_BIT;
+	writel(reg, priv->reg + TIMER_CTRL);
+
+	/* Set watchdog duration */
+	writel(priv->timeout, priv->reg + priv->wdt_counter_offset);
+
+	/* Clear the watchdog expiration bit */
+	reg = readl(priv->reg + TIMER_A370_STATUS);
+	reg &= ~WDT_A370_EXPIRED;
+	writel(reg, priv->reg + TIMER_A370_STATUS);
+
+	/* Enable watchdog timer */
+	reg = readl(priv->reg + TIMER_CTRL);
+	reg |= WDT_ENABLE_BIT;
+	writel(reg, priv->reg + TIMER_CTRL);
+
+	/* Enable reset on watchdog */
+	reg = readl(priv->rstout);
+	reg |= RSTOUT_ENABLE_BIT;
+	writel(reg, priv->rstout);
+
+	reg = readl(priv->rstout_mask);
+	reg &= ~RSTOUT_MASK_BIT;
+	writel(reg, priv->rstout_mask);
+
+	return 0;
+}
+
+static int orion_wdt_stop(struct udevice *dev)
+{
+	struct orion_wdt_priv *priv = dev_get_priv(dev);
+	u32 reg;
+
+	/* Disable reset on watchdog */
+	reg = readl(priv->rstout_mask);
+	reg |= RSTOUT_MASK_BIT;
+	writel(reg, priv->rstout_mask);
+
+	reg = readl(priv->rstout);
+	reg &= ~RSTOUT_ENABLE_BIT;
+	writel(reg, priv->rstout);
+
+	/* Disable watchdog timer */
+	reg = readl(priv->reg + TIMER_CTRL);
+	reg &= ~WDT_ENABLE_BIT;
+	writel(reg, priv->reg + TIMER_CTRL);
+
+	return 0;
+}
+
+static inline bool save_reg_from_ofdata(struct udevice *dev, int index,
+					void __iomem **reg, int *offset)
+{
+	fdt_addr_t addr;
+	fdt_size_t off;
+
+	addr = fdtdec_get_addr_size_auto_noparent(
+		gd->fdt_blob, dev_of_offset(dev), "reg", index, &off, true);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return false;
+
+	*reg = (void __iomem *) addr;
+	if (offset)
+		*offset = off;
+
+	return true;
+}
+
+static int orion_wdt_ofdata_to_platdata(struct udevice *dev)
+{
+	struct orion_wdt_priv *priv = dev_get_priv(dev);
+
+	if (!save_reg_from_ofdata(dev, 0, &priv->reg,
+				  &priv->wdt_counter_offset))
+		goto err;
+
+	if (!save_reg_from_ofdata(dev, 1, &priv->rstout, NULL))
+		goto err;
+
+	if (!save_reg_from_ofdata(dev, 2, &priv->rstout_mask, NULL))
+		goto err;
+
+	return 0;
+err:
+	debug("%s: Could not determine Orion wdt IO addresses\n", __func__);
+	return -ENXIO;
+}
+
+static int orion_wdt_probe(struct udevice *dev)
+{
+	debug("%s: Probing wdt%u\n", __func__, dev->seq);
+	orion_wdt_stop(dev);
+
+	return 0;
+}
+
+static const struct wdt_ops orion_wdt_ops = {
+	.start = orion_wdt_start,
+	.reset = orion_wdt_reset,
+	.stop = orion_wdt_stop,
+};
+
+static const struct udevice_id orion_wdt_ids[] = {
+	{ .compatible = "marvell,armada-380-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(orion_wdt) = {
+	.name = "orion_wdt",
+	.id = UCLASS_WDT,
+	.of_match = orion_wdt_ids,
+	.probe = orion_wdt_probe,
+	.priv_auto_alloc_size = sizeof(struct orion_wdt_priv),
+	.ofdata_to_platdata = orion_wdt_ofdata_to_platdata,
+	.ops = &orion_wdt_ops,
+};
-- 
2.13.0

  parent reply	other threads:[~2017-06-09 17:28 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-09 17:28 [U-Boot] [PATCH v4 0/6] Support for the Turris Omnia router Marek Behún
2017-06-09 17:28 ` [U-Boot] [PATCH v4 1/7] driver/ddr: Add support for setting timing in hws_topology_map Marek Behún
2018-01-10  2:49   ` Chris Packham
2017-06-09 17:28 ` Marek Behún [this message]
2017-06-09 17:28 ` [U-Boot] [PATCH v4 3/7] arch/arm/dts: Add Turris Omnia device tree Marek Behún
2017-07-07 11:58   ` Stefan Roese
2017-07-07 12:22     ` Marek Behún
2017-07-07 13:36       ` Stefan Roese
2017-06-09 17:28 ` [U-Boot] [PATCH v4 4/7] drivers/i2c/muxes/pca954x: Add pca9547 I2C mux support Marek Behún
2017-09-28 21:27   ` Chris Packham
2017-06-09 17:28 ` [U-Boot] [PATCH v4 5/7] drivers/misc: Add basic support for ATSHA204A Crypto module Marek Behún
2017-06-09 17:28 ` [U-Boot] [PATCH v4 6/7] marvell: armada385: Add the Turris Omnia board Marek Behún
2017-07-12  5:53 ` [U-Boot] [PATCH v4 0/6] Support for the Turris Omnia router Stefan Roese
2018-01-17 15:52 ` Andreas Färber
2018-01-18 17:20   ` Stefan Roese
2018-01-18 17:56     ` Andreas Färber
2018-01-20  1:40     ` Andreas Färber
2018-01-20  2:30       ` Andreas Färber
2018-01-20  9:07         ` Stefan Roese
2018-01-20 14:32           ` Sean Nyekjær
2018-01-21 12:39             ` Andreas Färber
2018-01-21 12:53               ` Sean Nyekjær
2018-01-22  7:57               ` Sean Nyekjær
2018-01-20  3:34       ` Andreas Färber
2018-01-20  9:48         ` [U-Boot] [EXT] " Kostya Porotchkin
2018-01-20 12:34           ` [U-Boot] mrvl_uart.sh and Turris Omnia (was: [EXT] Re: [PATCH v4 0/6] Support for the Turris Omnia router) Andreas Färber
2018-01-21  9:02             ` Kostya Porotchkin

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=20170609172845.10238-3-marek.behun@nic.cz \
    --to=marek.behun@nic.cz \
    --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.