All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] watchdog: Add booke watchdog driver
@ 2021-03-03  1:39 Chris Packham
  2021-03-03  1:39 ` [PATCH 2/2] (DO NOT APPLY) powerpc: t2080rdb: Enable watchdog Chris Packham
  2021-03-04 13:15 ` [PATCH 1/2] watchdog: Add booke watchdog driver Stefan Roese
  0 siblings, 2 replies; 3+ messages in thread
From: Chris Packham @ 2021-03-03  1:39 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>
---

 drivers/watchdog/Kconfig     |   7 +++
 drivers/watchdog/Makefile    |   1 +
 drivers/watchdog/booke_wdt.c | 107 +++++++++++++++++++++++++++++++++++
 3 files changed, 115 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..4a2d0f3baabd
--- /dev/null
+++ b/drivers/watchdog/booke_wdt.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Watchdog timer for PowerPC Book-E systems
+ */
+
+#include <common.h>
+#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] 3+ messages in thread

* [PATCH 2/2] (DO NOT APPLY) powerpc: t2080rdb: Enable watchdog
  2021-03-03  1:39 [PATCH 1/2] watchdog: Add booke watchdog driver Chris Packham
@ 2021-03-03  1:39 ` Chris Packham
  2021-03-04 13:15 ` [PATCH 1/2] watchdog: Add booke watchdog driver Stefan Roese
  1 sibling, 0 replies; 3+ messages in thread
From: Chris Packham @ 2021-03-03  1:39 UTC (permalink / raw)
  To: u-boot

Enable the watchdog on the T2080RDB.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
I've included this patch to show how I've been testing the driver. I'm
not entirely happy with how the watchdog is represented in the DTS.
Technically it's part of the CPU core so it should probably be under
each of the CPU nodes. The driver itself doesn't deal with any of the
per-cpu stuff that it's Linux counterpart does but I think that's OK for
u-boot.

Maybe it should be one node under the first CPU node (will it actually
get probed there?).

 arch/powerpc/dts/t2080.dtsi | 4 ++++
 configs/T2080RDB_defconfig  | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/arch/powerpc/dts/t2080.dtsi b/arch/powerpc/dts/t2080.dtsi
index 7e446b18df61..cd73adb735f3 100644
--- a/arch/powerpc/dts/t2080.dtsi
+++ b/arch/powerpc/dts/t2080.dtsi
@@ -41,6 +41,10 @@
 		};
 	};
 
+	watchdog at 0 {
+		compatible = "fsl,booke-wdt";
+	};
+
 	soc: soc at ffe000000 {
 		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
 		reg = <0xf 0xfe000000 0 0x00001000>;
diff --git a/configs/T2080RDB_defconfig b/configs/T2080RDB_defconfig
index 9dd01bbe50a5..84494bed188f 100644
--- a/configs/T2080RDB_defconfig
+++ b/configs/T2080RDB_defconfig
@@ -70,5 +70,8 @@ CONFIG_FSL_ESPI=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_STORAGE=y
+# CONFIG_WATCHDOG is not set
+CONFIG_WDT=y
+CONFIG_WDT_BOOKE=y
 CONFIG_ADDR_MAP=y
 CONFIG_SYS_NUM_ADDR_MAP=64
-- 
2.30.1

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

* [PATCH 1/2] watchdog: Add booke watchdog driver
  2021-03-03  1:39 [PATCH 1/2] watchdog: Add booke watchdog driver Chris Packham
  2021-03-03  1:39 ` [PATCH 2/2] (DO NOT APPLY) powerpc: t2080rdb: Enable watchdog Chris Packham
@ 2021-03-04 13:15 ` Stefan Roese
  1 sibling, 0 replies; 3+ messages in thread
From: Stefan Roese @ 2021-03-04 13:15 UTC (permalink / raw)
  To: u-boot

On 03.03.21 02:39, Chris Packham wrote:
> 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>
> ---
> 
>   drivers/watchdog/Kconfig     |   7 +++
>   drivers/watchdog/Makefile    |   1 +
>   drivers/watchdog/booke_wdt.c | 107 +++++++++++++++++++++++++++++++++++
>   3 files changed, 115 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..4a2d0f3baabd
> --- /dev/null
> +++ b/drivers/watchdog/booke_wdt.c
> @@ -0,0 +1,107 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Watchdog timer for PowerPC Book-E systems
> + */
> +
> +#include <common.h>

Please don't include "common.h" any more. There is ongoing work to
depricate this common header.

Other than this:

Reviewed-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan


> +#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,
> +};
> 


Viele Gr??e,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de

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

end of thread, other threads:[~2021-03-04 13:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-03  1:39 [PATCH 1/2] watchdog: Add booke watchdog driver Chris Packham
2021-03-03  1:39 ` [PATCH 2/2] (DO NOT APPLY) powerpc: t2080rdb: Enable watchdog Chris Packham
2021-03-04 13:15 ` [PATCH 1/2] watchdog: Add booke watchdog driver Stefan Roese

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.