All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] watchdog: Add booke watchdog driver
@ 2021-03-05  3:32 Chris Packham
  0 siblings, 0 replies; only message in thread
From: Chris Packham @ 2021-03-05  3:32 UTC (permalink / raw)
  To: u-boot

Add a driver for the PowerPC Book E watchdog driver that is present on a
number of Freescale/NXP SoCs.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
Reviewed-by: Stefan Roese <sr@denx.de>

---

Changes in v2:
- Remove #include of common.h
- Add review from Stefan

 drivers/watchdog/Kconfig     |   7 +++
 drivers/watchdog/Makefile    |   1 +
 drivers/watchdog/booke_wdt.c | 106 +++++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+)
 create mode 100644 drivers/watchdog/booke_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 602ccbe41c00..82a24871451b 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -111,6 +111,13 @@ config WDT_BCM6345
 	  The watchdog timer is stopped when initialized.
 	  It performs full SoC reset.
 
+config WDT_BOOKE
+	bool "PowerPC Book-E watchdog driver"
+	depends on WDT && MPC85xx
+	help
+	  Watchdog driver for PowerPC Book-E chips, such as the Freescale
+	  MPC85xx SOCs and the IBM PowerPC 440.
+
 config WDT_CDNS
 	bool "Cadence watchdog timer support"
 	depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 6e70c7ae19ce..5c7ef593fe53 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -21,6 +21,7 @@ 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_BOOKE) += booke_wdt.o
 obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
 obj-$(CONFIG_WDT_ORION) += orion_wdt.o
 obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
new file mode 100644
index 000000000000..50c091956e73
--- /dev/null
+++ b/drivers/watchdog/booke_wdt.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Watchdog timer for PowerPC Book-E systems
+ */
+
+#include <div64.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/processor.h>
+
+#define WDTP_MASK TCR_WP(0x3f)
+
+/* For the specified period, determine the number of seconds
+ * corresponding to the reset time.  There will be a watchdog
+ * exception at approximately 3/5 of this time.
+ *
+ * The formula to calculate this is given by:
+ * 2.5 * (2^(63-period+1)) / timebase_freq
+ *
+ * In order to simplify things, we assume that period is
+ * at least 1.  This will still result in a very long timeout.
+ */
+static unsigned long long period_to_sec(unsigned int period)
+{
+	unsigned long long tmp = 1ULL << (64 - period);
+	unsigned long tmp2 = get_tbclk();
+
+	/* tmp may be a very large number and we don't want to overflow,
+	 * so divide the timebase freq instead of multiplying tmp
+	 */
+	tmp2 = tmp2 / 5 * 2;
+
+	do_div(tmp, tmp2);
+	return tmp;
+}
+
+/*
+ * This procedure will find the highest period which will give a timeout
+ * greater than the one required. e.g. for a bus speed of 66666666 and
+ * and a parameter of 2 secs, then this procedure will return a value of 38.
+ */
+static unsigned int sec_to_period(unsigned int secs)
+{
+	unsigned int period;
+
+	for (period = 63; period > 0; period--) {
+		if (period_to_sec(period) >= secs)
+			return period;
+	}
+	return 0;
+}
+
+static int booke_wdt_reset(struct udevice *dev)
+{
+	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS);
+
+	return 0;
+}
+
+static int booke_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+	u32 val;
+	unsigned int timeout = DIV_ROUND_UP(timeout_ms, 1000);
+
+	/* clear status before enabling watchdog */
+	booke_wdt_reset(dev);
+	val = mfspr(SPRN_TCR);
+	val &= ~WDTP_MASK;
+	val |= (TCR_WIE | TCR_WRC(WRC_CHIP) | TCR_WP(sec_to_period(timeout)));
+
+	mtspr(SPRN_TCR, val);
+
+	return 0;
+}
+
+static int booke_wdt_stop(struct udevice *dev)
+{
+	u32 val;
+
+	val = mfspr(SPRN_TCR);
+	val &= ~(TCR_WIE | WDTP_MASK);
+	mtspr(SPRN_TCR, val);
+
+	/* clear status to make sure nothing is pending */
+	booke_wdt_reset(dev);
+
+	return 0;
+}
+
+static const struct wdt_ops booke_wdt_ops = {
+	.start = booke_wdt_start,
+	.stop = booke_wdt_stop,
+	.reset = booke_wdt_reset,
+};
+
+static const struct udevice_id booke_wdt_ids[] = {
+	{ .compatible = "fsl,booke-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(booke_wdt) = {
+	.name = "booke_wdt",
+	.id = UCLASS_WDT,
+	.of_match = booke_wdt_ids,
+	.ops = &booke_wdt_ops,
+};
-- 
2.30.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-03-05  3:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-05  3:32 [PATCH v2] watchdog: Add booke watchdog driver Chris Packham

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.