mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/7] ARM: stm32mp1: rename to stm32mp
@ 2019-06-03 19:05 Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 2/7] reset_source: add new Brownout reset (BOR) source Ahmad Fatoum
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

Serial and clk driver both depend on CONFIG_ARCH_STM32MP1,
so either the Kconfig symbol or their depend needs to change.

Patches posted by the vendor to Linux, U-Boot and their BSP
Yocto-Layer speak of a STM32MP-Family of which the STM32MP1
is the first series, thus rename the arch by dropping the 1.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/Kconfig                                              | 4 ++--
 arch/arm/Makefile                                             | 2 +-
 arch/arm/configs/{stm32mp1_defconfig => stm32mp_defconfig}    | 2 +-
 arch/arm/{mach-stm32mp1 => mach-stm32mp}/Kconfig              | 2 +-
 arch/arm/{mach-stm32mp1 => mach-stm32mp}/Makefile             | 0
 .../{mach-stm32mp1 => mach-stm32mp}/include/mach/debug_ll.h   | 0
 arch/arm/{mach-stm32mp1 => mach-stm32mp}/include/mach/stm32.h | 0
 images/Makefile                                               | 2 +-
 images/{Makefile.stm32mp1 => Makefile.stm32mp}                | 0
 9 files changed, 6 insertions(+), 6 deletions(-)
 rename arch/arm/configs/{stm32mp1_defconfig => stm32mp_defconfig} (98%)
 rename arch/arm/{mach-stm32mp1 => mach-stm32mp}/Kconfig (87%)
 rename arch/arm/{mach-stm32mp1 => mach-stm32mp}/Makefile (100%)
 rename arch/arm/{mach-stm32mp1 => mach-stm32mp}/include/mach/debug_ll.h (100%)
 rename arch/arm/{mach-stm32mp1 => mach-stm32mp}/include/mach/stm32.h (100%)
 rename images/{Makefile.stm32mp1 => Makefile.stm32mp} (100%)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 480c6f011797..1d4b6e09ce79 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -207,7 +207,7 @@ config ARCH_S3C64xx
 	select CPU_V6
 	select GENERIC_GPIO
 
-config ARCH_STM32MP1
+config ARCH_STM32MP
 	bool "ST stm32mp1xx"
 	select CPU_V7
 	select HAVE_PBL_MULTI_IMAGES
@@ -304,7 +304,7 @@ source "arch/arm/mach-pxa/Kconfig"
 source "arch/arm/mach-rockchip/Kconfig"
 source "arch/arm/mach-samsung/Kconfig"
 source "arch/arm/mach-socfpga/Kconfig"
-source "arch/arm/mach-stm32mp1/Kconfig"
+source "arch/arm/mach-stm32mp/Kconfig"
 source "arch/arm/mach-versatile/Kconfig"
 source "arch/arm/mach-vexpress/Kconfig"
 source "arch/arm/mach-tegra/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 4d54f339f15c..5cb46f661335 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -98,7 +98,7 @@ machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_ROCKCHIP)		:= rockchip
 machine-$(CONFIG_ARCH_SAMSUNG)		:= samsung
 machine-$(CONFIG_ARCH_SOCFPGA)		:= socfpga
-machine-$(CONFIG_ARCH_STM32MP1)		:= stm32mp1
+machine-$(CONFIG_ARCH_STM32MP)		:= stm32mp
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
 machine-$(CONFIG_ARCH_TEGRA)		:= tegra
diff --git a/arch/arm/configs/stm32mp1_defconfig b/arch/arm/configs/stm32mp_defconfig
similarity index 98%
rename from arch/arm/configs/stm32mp1_defconfig
rename to arch/arm/configs/stm32mp_defconfig
index 2922ce3632e1..657b2edf57f2 100644
--- a/arch/arm/configs/stm32mp1_defconfig
+++ b/arch/arm/configs/stm32mp_defconfig
@@ -1,4 +1,4 @@
-CONFIG_ARCH_STM32MP1=y
+CONFIG_ARCH_STM32MP=y
 CONFIG_MACH_STM32MP157C_DK2=y
 CONFIG_THUMB2_BAREBOX=y
 CONFIG_ARM_BOARD_APPEND_ATAG=y
diff --git a/arch/arm/mach-stm32mp1/Kconfig b/arch/arm/mach-stm32mp/Kconfig
similarity index 87%
rename from arch/arm/mach-stm32mp1/Kconfig
rename to arch/arm/mach-stm32mp/Kconfig
index cc7cf23cfb31..bcf7293c465b 100644
--- a/arch/arm/mach-stm32mp1/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -1,4 +1,4 @@
-if ARCH_STM32MP1
+if ARCH_STM32MP
 
 config ARCH_STM32MP1157
 	bool
diff --git a/arch/arm/mach-stm32mp1/Makefile b/arch/arm/mach-stm32mp/Makefile
similarity index 100%
rename from arch/arm/mach-stm32mp1/Makefile
rename to arch/arm/mach-stm32mp/Makefile
diff --git a/arch/arm/mach-stm32mp1/include/mach/debug_ll.h b/arch/arm/mach-stm32mp/include/mach/debug_ll.h
similarity index 100%
rename from arch/arm/mach-stm32mp1/include/mach/debug_ll.h
rename to arch/arm/mach-stm32mp/include/mach/debug_ll.h
diff --git a/arch/arm/mach-stm32mp1/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
similarity index 100%
rename from arch/arm/mach-stm32mp1/include/mach/stm32.h
rename to arch/arm/mach-stm32mp/include/mach/stm32.h
diff --git a/images/Makefile b/images/Makefile
index 479647a82726..293e644319ea 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -140,7 +140,7 @@ include $(srctree)/images/Makefile.mxs
 include $(srctree)/images/Makefile.omap3
 include $(srctree)/images/Makefile.rockchip
 include $(srctree)/images/Makefile.socfpga
-include $(srctree)/images/Makefile.stm32mp1
+include $(srctree)/images/Makefile.stm32mp
 include $(srctree)/images/Makefile.tegra
 include $(srctree)/images/Makefile.vexpress
 include $(srctree)/images/Makefile.xburst
diff --git a/images/Makefile.stm32mp1 b/images/Makefile.stm32mp
similarity index 100%
rename from images/Makefile.stm32mp1
rename to images/Makefile.stm32mp
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 2/7] reset_source: add new Brownout reset (BOR) source
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  2019-06-04  8:11   ` Sascha Hauer
  2019-06-03 19:05 ` [PATCH 3/7] watchdog: add stm32 watchdog and reset driver Ahmad Fatoum
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

The STM32MP1 can report brown out as reason for a reset,
which doesn't fit into existing reasons. Thus add a new
one to the enumeration.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/reset_source.c  | 1 +
 include/reset_source.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/common/reset_source.c b/common/reset_source.c
index 338d7b9acb30..0489724f3e7f 100644
--- a/common/reset_source.c
+++ b/common/reset_source.c
@@ -28,6 +28,7 @@ static const char * const reset_src_names[] = {
 	[RESET_JTAG] = "JTAG",
 	[RESET_THERM] = "THERM",
 	[RESET_EXT] = "EXT",
+	[RESET_BOR] = "BOR",
 };
 
 static enum reset_src_type reset_source;
diff --git a/include/reset_source.h b/include/reset_source.h
index 86e415abcf84..c124278ec674 100644
--- a/include/reset_source.h
+++ b/include/reset_source.h
@@ -22,6 +22,7 @@ enum reset_src_type {
 	RESET_JTAG,	/* JTAG reset */
 	RESET_THERM,	/* SoC shut down because of overtemperature */
 	RESET_EXT,	/* External reset through device pin */
+	RESET_BOR,	/* Brownout Reset */
 };
 
 #ifdef CONFIG_RESET_SOURCE
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 3/7] watchdog: add stm32 watchdog and reset driver
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 2/7] reset_source: add new Brownout reset (BOR) source Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  2019-06-04  8:24   ` Sascha Hauer
  2019-06-04 17:23   ` Roland Hieber
  2019-06-03 19:05 ` [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig Ahmad Fatoum
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

The driver supports setting watchdog timeout, system reset
and querying reset reason. Disabling watchdog isn't possible
in hardware, thus users should either enable it before boot
or have the poller take care of feeding it.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../mach-stm32mp/include/mach/reset-reason.h  |  28 ++
 drivers/watchdog/Kconfig                      |   8 +
 drivers/watchdog/Makefile                     |   1 +
 drivers/watchdog/stm32_wdt.c                  | 288 ++++++++++++++++++
 4 files changed, 325 insertions(+)
 create mode 100644 arch/arm/mach-stm32mp/include/mach/reset-reason.h
 create mode 100644 drivers/watchdog/stm32_wdt.c

diff --git a/arch/arm/mach-stm32mp/include/mach/reset-reason.h b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
new file mode 100644
index 000000000000..1165b347c31f
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
@@ -0,0 +1,28 @@
+#ifndef __MACH_RESET_REASON_H__
+#define __MACH_RESET_REASON_H__
+
+#include <reset_source.h>
+
+#define RCC_RSTF_POR		BIT(0)
+#define RCC_RSTF_BOR		BIT(1)
+#define RCC_RSTF_PAD		BIT(2)
+#define RCC_RSTF_HCSS		BIT(3)
+#define RCC_RSTF_VCORE		BIT(4)
+
+#define RCC_RSTF_MPSYS		BIT(6)
+#define RCC_RSTF_MCSYS		BIT(7)
+#define RCC_RSTF_IWDG1		BIT(8)
+#define RCC_RSTF_IWDG2		BIT(9)
+
+#define RCC_RSTF_STDBY		BIT(11)
+#define RCC_RSTF_CSTDBY		BIT(12)
+#define RCC_RSTF_MPUP0		BIT(13)
+#define RCC_RSTF_MPUP1		BIT(14)
+
+struct stm32_reset_reason {
+	uint32_t mask;
+	enum reset_src_type type;
+	int instance;
+};
+
+#endif
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 04efb1a3c866..5a28b530099d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -81,4 +81,12 @@ config RAVE_SP_WATCHDOG
 	depends on RAVE_SP_CORE
 	help
 	  Support for the watchdog on RAVE SP device.
+
+config STM32_IWDG_WATCHDOG
+        bool "Enable IWDG watchdog driver for STM32 processors"
+	depends on ARCH_STM32MP
+	select MFD_SYSCON
+        help
+                Enable the STM32 watchdog (IWDG) driver. Enable support to
+                configure STM32's on-SoC watchdog.
 endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 6c8d36c8b805..b2f39fa3719e 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_WATCHDOG_IMX) += imxwd.o
 obj-$(CONFIG_WATCHDOG_ORION) += orion_wdt.o
 obj-$(CONFIG_ARCH_BCM283X) += bcm2835_wdt.o
 obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
+obj-$(CONFIG_STM32_IWDG_WATCHDOG) += stm32_wdt.o
diff --git a/drivers/watchdog/stm32_wdt.c b/drivers/watchdog/stm32_wdt.c
new file mode 100644
index 000000000000..a972aade5900
--- /dev/null
+++ b/drivers/watchdog/stm32_wdt.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <init.h>
+#include <watchdog.h>
+#include <restart.h>
+#include <asm/io.h>
+#include <of_device.h>
+#include <linux/log2.h>
+#include <linux/iopoll.h>
+#include <linux/clk.h>
+#include <mfd/syscon.h>
+#include <mach/reset-reason.h>
+
+/* IWDG registers */
+#define IWDG_KR		0x00	/* Key register */
+#define IWDG_PR		0x04	/* Prescaler Register */
+#define IWDG_RLR	0x08	/* ReLoad Register */
+#define IWDG_SR		0x0C	/* Status Register */
+
+/* IWDG_KR register bit mask */
+#define KR_KEY_RELOAD	0xAAAA	/* Reload counter enable */
+#define KR_KEY_ENABLE	0xCCCC	/* Peripheral enable */
+#define KR_KEY_EWA	0x5555	/* Write access enable */
+
+/* IWDG_PR register bit values */
+#define PR_SHIFT	2
+
+/* IWDG_RLR register values */
+#define RLR_MAX		GENMASK(11, 0)
+
+/* IWDG_SR register bit mask */
+#define SR_PVU	BIT(0) /* Watchdog prescaler value update */
+#define SR_RVU	BIT(1) /* Watchdog counter reload value update */
+
+#define RCC_MP_GRSTCSETR		0x404
+#define RCC_MP_RSTSCLRR			0x408
+#define RCC_MP_GRSTCSETR_MPSYSRST	BIT(0)
+
+/* set timeout to 100 ms */
+#define TIMEOUT_US	100000
+
+struct stm32_iwdg {
+	struct watchdog wdd;
+	struct restart_handler restart;
+	void __iomem *iwdg_base;
+	struct regmap *rcc_regmap;
+	unsigned int timeout;
+	unsigned int rate;
+};
+
+static inline struct stm32_iwdg *to_stm32_iwdg(struct watchdog *wdd)
+{
+	return container_of(wdd, struct stm32_iwdg, wdd);
+}
+
+static void __noreturn stm32_iwdg_restart_handler(struct restart_handler *rst)
+{
+	struct stm32_iwdg *wd = container_of(rst, struct stm32_iwdg, restart);
+
+	regmap_update_bits(wd->rcc_regmap, RCC_MP_GRSTCSETR,
+			   RCC_MP_GRSTCSETR_MPSYSRST, RCC_MP_GRSTCSETR_MPSYSRST);
+
+	mdelay(1000);
+	hang();
+}
+
+static void stm32_iwdg_ping(struct stm32_iwdg *wd)
+{
+	writel(KR_KEY_RELOAD, wd->iwdg_base + IWDG_KR);
+}
+
+static int stm32_iwdg_start(struct stm32_iwdg *wd, unsigned int timeout)
+{
+	u32 presc, iwdg_rlr, iwdg_pr, iwdg_sr;
+	int ret;
+
+	presc = DIV_ROUND_UP(timeout * wd->rate, RLR_MAX + 1);
+
+	/* The prescaler is align on power of 2 and start at 2 ^ PR_SHIFT. */
+	presc = roundup_pow_of_two(presc);
+	iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT;
+	iwdg_rlr = ((timeout * wd->rate) / presc) - 1;
+
+	/* enable write access */
+	writel(KR_KEY_EWA, wd->iwdg_base + IWDG_KR);
+
+	/* set prescaler & reload registers */
+	writel(iwdg_pr, wd->iwdg_base + IWDG_PR);
+	writel(iwdg_rlr, wd->iwdg_base + IWDG_RLR);
+	writel(KR_KEY_ENABLE, wd->iwdg_base + IWDG_KR);
+
+	/* wait for the registers to be updated (max 100ms) */
+	ret = readl_poll_timeout(wd->iwdg_base + IWDG_SR, iwdg_sr,
+				 !(iwdg_sr & (SR_PVU | SR_RVU)),
+				 TIMEOUT_US);
+	if (!ret)
+		wd->timeout = timeout;
+
+	return ret;
+}
+
+
+static int stm32_iwdg_set_timeout(struct watchdog *wdd, unsigned int timeout)
+{
+	struct stm32_iwdg *wd = to_stm32_iwdg(wdd);
+	int ret;
+
+	if (!timeout)
+		return -EINVAL; /* can't disable */
+
+	if (timeout > wdd->timeout_max)
+		return -EINVAL;
+
+	if (wd->timeout != timeout) {
+		ret = stm32_iwdg_start(wd, timeout);
+		if (ret) {
+			dev_err(wdd->hwdev, "Fail to (re)start watchdog\n");
+			return ret;
+		}
+	}
+
+	stm32_iwdg_ping(wd);
+	return 0;
+}
+
+static const struct stm32_reset_reason stm32_reset_reasons[] = {
+	{ RCC_RSTF_POR,		RESET_POR, 0 },
+	{ RCC_RSTF_BOR,		RESET_BOR, 0 },
+	{ RCC_RSTF_STDBY,	RESET_WKE, 0 },
+	{ RCC_RSTF_CSTDBY,	RESET_WKE, 1 },
+	{ RCC_RSTF_MPSYS,	RESET_RST, 2 },
+	{ RCC_RSTF_MPUP0,	RESET_RST, 0 },
+	{ RCC_RSTF_MPUP1,	RESET_RST, 1 },
+	{ RCC_RSTF_IWDG1,	RESET_WDG, 0 },
+	{ RCC_RSTF_IWDG2,	RESET_WDG, 1 },
+	{ RCC_RSTF_PAD,		RESET_EXT, 1 },
+	{ /* sentinel */ }
+};
+
+static int stm32_set_reset_reason(struct regmap *rcc)
+{
+	enum reset_src_type type = RESET_UKWN;
+	u32 reg;
+	int ret;
+	int i, instance = 0;
+
+	/*
+	 * SRSR register captures ALL reset event that occured since
+	 * POR, so we need to clear it to make sure we only caputre
+	 * the latest one.
+	 */
+	ret = regmap_read(rcc, RCC_MP_RSTSCLRR, &reg);
+	if (ret)
+		return ret;
+
+	for (i = 0; stm32_reset_reasons[i].mask; i++) {
+		if (reg & stm32_reset_reasons[i].mask) {
+			type     = stm32_reset_reasons[i].type;
+			instance = stm32_reset_reasons[i].instance;
+			break;
+		}
+	}
+
+	reset_source_set_priority(type, RESET_SOURCE_DEFAULT_PRIORITY);
+	reset_source_set_instance(type, instance);
+
+	pr_info("STM32 RCC reset reason %s (MP_RSTSR: 0x%08x)\n",
+		reset_source_name(), reg);
+
+	return 0;
+}
+
+struct stm32_iwdg_data {
+	bool has_pclk;
+	u32 max_prescaler;
+};
+
+static const struct stm32_iwdg_data stm32_iwdg_data = {
+	.has_pclk = false, .max_prescaler = 256,
+};
+
+static const struct stm32_iwdg_data stm32mp1_iwdg_data = {
+	.has_pclk = true, .max_prescaler = 1024,
+};
+
+static const struct of_device_id stm32_iwdg_of_match[] = {
+	{ .compatible = "st,stm32-iwdg",    .data = &stm32_iwdg_data },
+	{ .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_data },
+	{ /* sentinel */ }
+};
+
+static int stm32_iwdg_probe(struct device_d *dev)
+{
+	struct stm32_iwdg_data *data;
+	struct stm32_iwdg *wd;
+	struct resource *res;
+	struct watchdog *wdd;
+	struct clk *clk;
+	int ret;
+
+	wd = xzalloc(sizeof(*wd));
+
+	ret = dev_get_drvdata(dev, (const void **)&data);
+	if (ret)
+		return -ENODEV;
+
+	res = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(res)) {
+		dev_err(dev, "could not get timer memory region\n");
+		return PTR_ERR(res);
+	}
+	wd->iwdg_base = IOMEM(res->start);
+
+	clk = of_clk_get_by_name(dev->device_node, "lsi");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = clk_enable(clk);
+	if (ret)
+		return ret;
+
+	wd->rate = clk_get_rate(clk);
+
+	if (data->has_pclk) {
+		clk = of_clk_get_by_name(dev->device_node, "pclk");
+		if (IS_ERR(clk))
+			return PTR_ERR(clk);
+
+		ret = clk_enable(clk);
+		if (ret)
+			return ret;
+	}
+
+	wdd              = &wd->wdd;
+	wdd->hwdev       = dev;
+	wdd->set_timeout = stm32_iwdg_set_timeout;
+	wdd->timeout_max = (RLR_MAX + 1) * data->max_prescaler * 1000;
+	wdd->timeout_max /= wd->rate * 1000;
+	wdd->timeout_cur = wdd->timeout_max;
+
+	ret = stm32_iwdg_set_timeout(wdd, wdd->timeout_max);
+	if (ret) {
+		dev_err(dev, "Failed to set initial watchdog timeout\n");
+		return ret;
+	}
+
+	ret = watchdog_register(wdd);
+	if (ret) {
+		dev_err(dev, "Failed to register watchdog device\n");
+		return ret;
+	}
+
+	wd->restart.name = "stm32-iwdg";
+	wd->restart.restart = stm32_iwdg_restart_handler;
+	wd->restart.priority = 200;
+
+	wd->rcc_regmap = syscon_regmap_lookup_by_compatible("st,stm32mp1-rcc");
+	if (IS_ERR(wd->rcc_regmap)) {
+		dev_warn(dev, "Cannot register restart handler\n");
+		goto end;
+	}
+
+	ret = restart_handler_register(&wd->restart);
+	if (ret) {
+		dev_warn(dev, "Cannot register restart handler\n");
+		goto end;
+	}
+
+	ret = stm32_set_reset_reason(wd->rcc_regmap);
+	if (ret) {
+		dev_warn(dev, "Cannot determine reset reason\n");
+		goto end;
+	}
+end:
+	dev_info(dev, "probed\n");
+	return 0;
+}
+
+static struct driver_d stm32_iwdg_driver = {
+	.name  = "stm32-iwdg",
+	.probe = stm32_iwdg_probe,
+	.of_compatible = DRV_OF_COMPAT(stm32_iwdg_of_match),
+};
+device_platform_driver(stm32_iwdg_driver);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 2/7] reset_source: add new Brownout reset (BOR) source Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 3/7] watchdog: add stm32 watchdog and reset driver Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  2019-06-03 19:34   ` Sam Ravnborg
  2019-06-03 19:05 ` [PATCH 5/7] ARM: stm32mp: stm32mp157c-dk2: configure debug_ll UART Ahmad Fatoum
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

With the IWDG driver implemented in barebox, have it be part of the
default configuration.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/configs/stm32mp_defconfig | 5 ++++-
 arch/arm/dts/stm32mp157c-dk2.dts   | 4 ++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/stm32mp_defconfig b/arch/arm/configs/stm32mp_defconfig
index 657b2edf57f2..99523a78650e 100644
--- a/arch/arm/configs/stm32mp_defconfig
+++ b/arch/arm/configs/stm32mp_defconfig
@@ -25,7 +25,6 @@ CONFIG_CONSOLE_ALLOW_COLOR=y
 CONFIG_PBL_CONSOLE=y
 CONFIG_PARTITION=y
 CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
-CONFIG_POLLER=y
 CONFIG_RESET_SOURCE=y
 CONFIG_DEBUG_INITCALLS=y
 CONFIG_CMD_DMESG=y
@@ -71,6 +70,7 @@ CONFIG_CMD_MM=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_DETECT=y
 CONFIG_CMD_FLASH=y
+CONFIG_CMD_WD=y
 CONFIG_CMD_BAREBOX_UPDATE=y
 CONFIG_CMD_OF_NODE=y
 CONFIG_CMD_OF_PROPERTY=y
@@ -86,6 +86,9 @@ CONFIG_DRIVER_NET_DESIGNWARE_GENERIC=y
 CONFIG_AT803X_PHY=y
 CONFIG_MICREL_PHY=y
 # CONFIG_SPI is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_POLLER=y
+CONFIG_STM32_IWDG_WATCHDOG=y
 # CONFIG_PINCTRL is not set
 CONFIG_FS_EXT4=y
 CONFIG_FS_TFTP=y
diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts
index 7565cabc3d92..5c39a1a4f5a8 100644
--- a/arch/arm/dts/stm32mp157c-dk2.dts
+++ b/arch/arm/dts/stm32mp157c-dk2.dts
@@ -12,3 +12,7 @@
 	model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
 	compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
 };
+
+&iwdg2 {
+       status = "okay";
+};
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 5/7] ARM: stm32mp: stm32mp157c-dk2: configure debug_ll UART
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2019-06-03 19:05 ` [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 6/7] ARM: stm32mp: stm32mp157c-dk2: compress the DTB Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 7/7] ARM: stm32mp: add entry point, not point.pblb to pblb-y Ahmad Fatoum
  5 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

This configures UART4 for use as the debug_ll UART,
whenever CONFIG_DEBUG_LL is defined.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/stm32mp157c-dk2/lowlevel.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
index b8e5959bef83..7f66cbfa1224 100644
--- a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
+++ b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
@@ -5,6 +5,24 @@
 #include <mach/stm32.h>
 #include <debug_ll.h>
 
+#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
+#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
+#define GPIOG_BASE 0x50008000
+
+static inline void setup_uart(void)
+{
+	/* UART4 clock enable */
+	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
+
+	/* GPIOG clock enable */
+	writel(BIT(6), RCC_MP_AHB4ENSETR);
+	/* GPIO configuration for EVAL board => UART4 TX = G11 */
+	writel(0xffbfffff, GPIOG_BASE + 0x00);
+	writel(0x00006000, GPIOG_BASE + 0x24);
+
+	putc_ll('>');
+}
+
 extern char __dtb_stm32mp157c_dk2_start[];
 
 ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
@@ -13,6 +31,9 @@ ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
 
 	arm_cpu_lowlevel_init();
 
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
 	fdt = __dtb_stm32mp157c_dk2_start + get_runtime_offset();
 
 	barebox_arm_entry(STM32_DDR_BASE, SZ_512M, fdt);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 6/7] ARM: stm32mp: stm32mp157c-dk2: compress the DTB
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2019-06-03 19:05 ` [PATCH 5/7] ARM: stm32mp: stm32mp157c-dk2: configure debug_ll UART Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  2019-06-03 19:05 ` [PATCH 7/7] ARM: stm32mp: add entry point, not point.pblb to pblb-y Ahmad Fatoum
  5 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

This reduces saves 20K with my configuration (from 247K to 227K).

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/boards/stm32mp157c-dk2/lowlevel.c | 4 ++--
 arch/arm/mach-stm32mp/Kconfig              | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
index 7f66cbfa1224..73e1fa1cee3d 100644
--- a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
+++ b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
@@ -23,7 +23,7 @@ static inline void setup_uart(void)
 	putc_ll('>');
 }
 
-extern char __dtb_stm32mp157c_dk2_start[];
+extern char __dtb_z_stm32mp157c_dk2_start[];
 
 ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
 {
@@ -34,7 +34,7 @@ ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
 
-	fdt = __dtb_stm32mp157c_dk2_start + get_runtime_offset();
+	fdt = __dtb_z_stm32mp157c_dk2_start + get_runtime_offset();
 
 	barebox_arm_entry(STM32_DDR_BASE, SZ_512M, fdt);
 }
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index bcf7293c465b..be16294f5ad7 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -5,6 +5,7 @@ config ARCH_STM32MP1157
 
 config MACH_STM32MP157C_DK2
 	select ARCH_STM32MP1157
+	select ARM_USE_COMPRESSED_DTB
 	bool "STM32MP157C-DK2 board"
 
 endif
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 7/7] ARM: stm32mp: add entry point, not point.pblb to pblb-y
  2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2019-06-03 19:05 ` [PATCH 6/7] ARM: stm32mp: stm32mp157c-dk2: compress the DTB Ahmad Fatoum
@ 2019-06-03 19:05 ` Ahmad Fatoum
  5 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:05 UTC (permalink / raw)
  To: barebox

Other images/Makefile.${arch}s, e.g. images/Makefile.imx, populate
pblp-* with the entry points to build, not the pbl file that's
generated. Adjust the images/Makefile.stm32mp  to do the same.

Cc: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 images/Makefile.stm32mp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/images/Makefile.stm32mp b/images/Makefile.stm32mp
index d26231cd92d1..c49b1d72b788 100644
--- a/images/Makefile.stm32mp
+++ b/images/Makefile.stm32mp
@@ -3,6 +3,6 @@
 # barebox image generation Makefile for STMicroelectronics MP1
 #
 
-pblb-$(CONFIG_MACH_STM32MP157C_DK2) += start_stm32mp157c_dk2.pblb
+pblb-$(CONFIG_MACH_STM32MP157C_DK2) += start_stm32mp157c_dk2
 FILE_barebox-stm32mp157c-dk2.img = start_stm32mp157c_dk2.pblb
 image-$(CONFIG_MACH_STM32MP157C_DK2) += barebox-stm32mp157c-dk2.img
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig
  2019-06-03 19:05 ` [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig Ahmad Fatoum
@ 2019-06-03 19:34   ` Sam Ravnborg
  2019-06-03 19:46     ` Ahmad Fatoum
  0 siblings, 1 reply; 15+ messages in thread
From: Sam Ravnborg @ 2019-06-03 19:34 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

Hi Ahmad.

Subject: [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig
                                 ^

Someone just renamed this arch to stm32mp...

	Sam

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig
  2019-06-03 19:34   ` Sam Ravnborg
@ 2019-06-03 19:46     ` Ahmad Fatoum
  0 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-03 19:46 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: barebox

Hello Sam,

On 3/6/19 21:34, Sam Ravnborg wrote:
> Hi Ahmad.
> 
> Subject: [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig
>                                  ^
> 
> Someone just renamed this arch to stm32mp...

Ye, the script that I use to generate the prefixes didn't account for that.. :D


> 
> 	Sam
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 2/7] reset_source: add new Brownout reset (BOR) source
  2019-06-03 19:05 ` [PATCH 2/7] reset_source: add new Brownout reset (BOR) source Ahmad Fatoum
@ 2019-06-04  8:11   ` Sascha Hauer
  2019-06-04  8:31     ` Ahmad Fatoum
  0 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2019-06-04  8:11 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Jun 03, 2019 at 09:05:54PM +0200, Ahmad Fatoum wrote:
> The STM32MP1 can report brown out as reason for a reset,
> which doesn't fit into existing reasons. Thus add a new
> one to the enumeration.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  common/reset_source.c  | 1 +
>  include/reset_source.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/common/reset_source.c b/common/reset_source.c
> index 338d7b9acb30..0489724f3e7f 100644
> --- a/common/reset_source.c
> +++ b/common/reset_source.c
> @@ -28,6 +28,7 @@ static const char * const reset_src_names[] = {
>  	[RESET_JTAG] = "JTAG",
>  	[RESET_THERM] = "THERM",
>  	[RESET_EXT] = "EXT",
> +	[RESET_BOR] = "BOR",
>  };
>  
>  static enum reset_src_type reset_source;
> diff --git a/include/reset_source.h b/include/reset_source.h
> index 86e415abcf84..c124278ec674 100644
> --- a/include/reset_source.h
> +++ b/include/reset_source.h
> @@ -22,6 +22,7 @@ enum reset_src_type {
>  	RESET_JTAG,	/* JTAG reset */
>  	RESET_THERM,	/* SoC shut down because of overtemperature */
>  	RESET_EXT,	/* External reset through device pin */
> +	RESET_BOR,	/* Brownout Reset */

Reading "BOR" as "Brown Out Reset" is not very obvious. Maybe better use
RESET_BROWNOUT and "BROWNOUT". That shouldn't be too long to read and
write.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 3/7] watchdog: add stm32 watchdog and reset driver
  2019-06-03 19:05 ` [PATCH 3/7] watchdog: add stm32 watchdog and reset driver Ahmad Fatoum
@ 2019-06-04  8:24   ` Sascha Hauer
  2019-06-04  8:51     ` Ahmad Fatoum
  2019-06-04 17:23   ` Roland Hieber
  1 sibling, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2019-06-04  8:24 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Jun 03, 2019 at 09:05:55PM +0200, Ahmad Fatoum wrote:
> The driver supports setting watchdog timeout, system reset
> and querying reset reason. Disabling watchdog isn't possible
> in hardware, thus users should either enable it before boot
> or have the poller take care of feeding it.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  .../mach-stm32mp/include/mach/reset-reason.h  |  28 ++
>  drivers/watchdog/Kconfig                      |   8 +
>  drivers/watchdog/Makefile                     |   1 +
>  drivers/watchdog/stm32_wdt.c                  | 288 ++++++++++++++++++
>  4 files changed, 325 insertions(+)
>  create mode 100644 arch/arm/mach-stm32mp/include/mach/reset-reason.h
>  create mode 100644 drivers/watchdog/stm32_wdt.c
> 
> diff --git a/arch/arm/mach-stm32mp/include/mach/reset-reason.h b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> new file mode 100644
> index 000000000000..1165b347c31f
> --- /dev/null
> +++ b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> @@ -0,0 +1,28 @@
> +#ifndef __MACH_RESET_REASON_H__
> +#define __MACH_RESET_REASON_H__
> +
> +#include <reset_source.h>
> +
> +#define RCC_RSTF_POR		BIT(0)
> +#define RCC_RSTF_BOR		BIT(1)
> +#define RCC_RSTF_PAD		BIT(2)
> +#define RCC_RSTF_HCSS		BIT(3)
> +#define RCC_RSTF_VCORE		BIT(4)
> +
> +#define RCC_RSTF_MPSYS		BIT(6)
> +#define RCC_RSTF_MCSYS		BIT(7)
> +#define RCC_RSTF_IWDG1		BIT(8)
> +#define RCC_RSTF_IWDG2		BIT(9)
> +
> +#define RCC_RSTF_STDBY		BIT(11)
> +#define RCC_RSTF_CSTDBY		BIT(12)
> +#define RCC_RSTF_MPUP0		BIT(13)
> +#define RCC_RSTF_MPUP1		BIT(14)
> +
> +struct stm32_reset_reason {
> +	uint32_t mask;
> +	enum reset_src_type type;
> +	int instance;
> +};

This is used in the driver only. Why is this in a header file?

> +
> +#endif
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 04efb1a3c866..5a28b530099d 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -81,4 +81,12 @@ config RAVE_SP_WATCHDOG
>  	depends on RAVE_SP_CORE
>  	help
>  	  Support for the watchdog on RAVE SP device.
> +
> +config STM32_IWDG_WATCHDOG
> +        bool "Enable IWDG watchdog driver for STM32 processors"

spaces instead of tabs here.

> +	depends on ARCH_STM32MP
> +	select MFD_SYSCON
> +        help
> +                Enable the STM32 watchdog (IWDG) driver. Enable support to
> +                configure STM32's on-SoC watchdog.
>  endif
> +
> +static int stm32_iwdg_probe(struct device_d *dev)
> +{
> +	struct stm32_iwdg_data *data;
> +	struct stm32_iwdg *wd;
> +	struct resource *res;
> +	struct watchdog *wdd;
> +	struct clk *clk;
> +	int ret;
> +
> +	wd = xzalloc(sizeof(*wd));
> +
> +	ret = dev_get_drvdata(dev, (const void **)&data);
> +	if (ret)
> +		return -ENODEV;
> +
> +	res = dev_request_mem_resource(dev, 0);
> +	if (IS_ERR(res)) {
> +		dev_err(dev, "could not get timer memory region\n");
> +		return PTR_ERR(res);
> +	}
> +	wd->iwdg_base = IOMEM(res->start);
> +
> +	clk = of_clk_get_by_name(dev->device_node, "lsi");

This function is only to be used when there's no struct device_d *
available. clk_get() is what you want to use here.

> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	ret = clk_enable(clk);
> +	if (ret)
> +		return ret;
> +
> +	wd->rate = clk_get_rate(clk);
> +
> +	if (data->has_pclk) {
> +		clk = of_clk_get_by_name(dev->device_node, "pclk");
> +		if (IS_ERR(clk))
> +			return PTR_ERR(clk);
> +
> +		ret = clk_enable(clk);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	wdd              = &wd->wdd;
> +	wdd->hwdev       = dev;
> +	wdd->set_timeout = stm32_iwdg_set_timeout;
> +	wdd->timeout_max = (RLR_MAX + 1) * data->max_prescaler * 1000;
> +	wdd->timeout_max /= wd->rate * 1000;
> +	wdd->timeout_cur = wdd->timeout_max;

Please don't do such alignment things. When somebody has to change
something here he only has the choice of breaking the alignment or
changing unrelated lines.

> +
> +	ret = stm32_iwdg_set_timeout(wdd, wdd->timeout_max);
> +	if (ret) {
> +		dev_err(dev, "Failed to set initial watchdog timeout\n");
> +		return ret;
> +	}
> +
> +	ret = watchdog_register(wdd);
> +	if (ret) {
> +		dev_err(dev, "Failed to register watchdog device\n");
> +		return ret;
> +	}
> +
> +	wd->restart.name = "stm32-iwdg";
> +	wd->restart.restart = stm32_iwdg_restart_handler;
> +	wd->restart.priority = 200;
> +
> +	wd->rcc_regmap = syscon_regmap_lookup_by_compatible("st,stm32mp1-rcc");
> +	if (IS_ERR(wd->rcc_regmap)) {
> +		dev_warn(dev, "Cannot register restart handler\n");
> +		goto end;
> +	}
> +
> +	ret = restart_handler_register(&wd->restart);
> +	if (ret) {
> +		dev_warn(dev, "Cannot register restart handler\n");
> +		goto end;
> +	}
> +
> +	ret = stm32_set_reset_reason(wd->rcc_regmap);
> +	if (ret) {
> +		dev_warn(dev, "Cannot determine reset reason\n");
> +		goto end;
> +	}

Are the last three failures really failures? You skip the remaining
steps but still you return with success which looks inconsistent.

> +end:
> +	dev_info(dev, "probed\n");
> +	return 0;
> +}

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 2/7] reset_source: add new Brownout reset (BOR) source
  2019-06-04  8:11   ` Sascha Hauer
@ 2019-06-04  8:31     ` Ahmad Fatoum
  0 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-04  8:31 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

On 4/6/19 10:11, Sascha Hauer wrote:
> On Mon, Jun 03, 2019 at 09:05:54PM +0200, Ahmad Fatoum wrote:
>> The STM32MP1 can report brown out as reason for a reset,
>> which doesn't fit into existing reasons. Thus add a new
>> one to the enumeration.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>>  common/reset_source.c  | 1 +
>>  include/reset_source.h | 1 +
>>  2 files changed, 2 insertions(+)
>>
>> diff --git a/common/reset_source.c b/common/reset_source.c
>> index 338d7b9acb30..0489724f3e7f 100644
>> --- a/common/reset_source.c
>> +++ b/common/reset_source.c
>> @@ -28,6 +28,7 @@ static const char * const reset_src_names[] = {
>>  	[RESET_JTAG] = "JTAG",
>>  	[RESET_THERM] = "THERM",
>>  	[RESET_EXT] = "EXT",
>> +	[RESET_BOR] = "BOR",
>>  };
>>  
>>  static enum reset_src_type reset_source;
>> diff --git a/include/reset_source.h b/include/reset_source.h
>> index 86e415abcf84..c124278ec674 100644
>> --- a/include/reset_source.h
>> +++ b/include/reset_source.h
>> @@ -22,6 +22,7 @@ enum reset_src_type {
>>  	RESET_JTAG,	/* JTAG reset */
>>  	RESET_THERM,	/* SoC shut down because of overtemperature */
>>  	RESET_EXT,	/* External reset through device pin */
>> +	RESET_BOR,	/* Brownout Reset */
> 
> Reading "BOR" as "Brown Out Reset" is not very obvious. Maybe better use
> RESET_BROWNOUT and "BROWNOUT". That shouldn't be too long to read and
> write.

Will rename in v2, along with Sam's comment. 

> 
> Sascha
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 3/7] watchdog: add stm32 watchdog and reset driver
  2019-06-04  8:24   ` Sascha Hauer
@ 2019-06-04  8:51     ` Ahmad Fatoum
  2019-06-04 11:07       ` Sascha Hauer
  0 siblings, 1 reply; 15+ messages in thread
From: Ahmad Fatoum @ 2019-06-04  8:51 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hello,

On 4/6/19 10:24, Sascha Hauer wrote:
> On Mon, Jun 03, 2019 at 09:05:55PM +0200, Ahmad Fatoum wrote:
>> The driver supports setting watchdog timeout, system reset
>> and querying reset reason. Disabling watchdog isn't possible
>> in hardware, thus users should either enable it before boot
>> or have the poller take care of feeding it.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>>  .../mach-stm32mp/include/mach/reset-reason.h  |  28 ++
>>  drivers/watchdog/Kconfig                      |   8 +
>>  drivers/watchdog/Makefile                     |   1 +
>>  drivers/watchdog/stm32_wdt.c                  | 288 ++++++++++++++++++
>>  4 files changed, 325 insertions(+)
>>  create mode 100644 arch/arm/mach-stm32mp/include/mach/reset-reason.h
>>  create mode 100644 drivers/watchdog/stm32_wdt.c
>>
>> diff --git a/arch/arm/mach-stm32mp/include/mach/reset-reason.h b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
>> new file mode 100644
>> index 000000000000..1165b347c31f
>> --- /dev/null
>> +++ b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
>> @@ -0,0 +1,28 @@
>> +#ifndef __MACH_RESET_REASON_H__
>> +#define __MACH_RESET_REASON_H__
>> +
>> +#include <reset_source.h>
>> +
>> +#define RCC_RSTF_POR		BIT(0)
>> +#define RCC_RSTF_BOR		BIT(1)
>> +#define RCC_RSTF_PAD		BIT(2)
>> +#define RCC_RSTF_HCSS		BIT(3)
>> +#define RCC_RSTF_VCORE		BIT(4)
>> +
>> +#define RCC_RSTF_MPSYS		BIT(6)
>> +#define RCC_RSTF_MCSYS		BIT(7)
>> +#define RCC_RSTF_IWDG1		BIT(8)
>> +#define RCC_RSTF_IWDG2		BIT(9)
>> +
>> +#define RCC_RSTF_STDBY		BIT(11)
>> +#define RCC_RSTF_CSTDBY		BIT(12)
>> +#define RCC_RSTF_MPUP0		BIT(13)
>> +#define RCC_RSTF_MPUP1		BIT(14)
>> +
>> +struct stm32_reset_reason {
>> +	uint32_t mask;
>> +	enum reset_src_type type;
>> +	int instance;
>> +};
> 
> This is used in the driver only. Why is this in a header file?

The driver is applicable to both stm32 and stm32mp, but the reasons
differ in bit mask. A future mach-stm32 could reuse the driver,
but define its own reset-reason.h. What do you think?

> 
>> +
>> +#endif
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 04efb1a3c866..5a28b530099d 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -81,4 +81,12 @@ config RAVE_SP_WATCHDOG
>>  	depends on RAVE_SP_CORE
>>  	help
>>  	  Support for the watchdog on RAVE SP device.
>> +
>> +config STM32_IWDG_WATCHDOG
>> +        bool "Enable IWDG watchdog driver for STM32 processors"
> 
> spaces instead of tabs here.
> 
>> +	depends on ARCH_STM32MP
>> +	select MFD_SYSCON
>> +        help
>> +                Enable the STM32 watchdog (IWDG) driver. Enable support to
>> +                configure STM32's on-SoC watchdog.
>>  endif
>> +
>> +static int stm32_iwdg_probe(struct device_d *dev)
>> +{
>> +	struct stm32_iwdg_data *data;
>> +	struct stm32_iwdg *wd;
>> +	struct resource *res;
>> +	struct watchdog *wdd;
>> +	struct clk *clk;
>> +	int ret;
>> +
>> +	wd = xzalloc(sizeof(*wd));
>> +
>> +	ret = dev_get_drvdata(dev, (const void **)&data);
>> +	if (ret)
>> +		return -ENODEV;
>> +
>> +	res = dev_request_mem_resource(dev, 0);
>> +	if (IS_ERR(res)) {
>> +		dev_err(dev, "could not get timer memory region\n");
>> +		return PTR_ERR(res);
>> +	}
>> +	wd->iwdg_base = IOMEM(res->start);
>> +
>> +	clk = of_clk_get_by_name(dev->device_node, "lsi");
> 
> This function is only to be used when there's no struct device_d *
> available. clk_get() is what you want to use here.

ok

> 
>> +	if (IS_ERR(clk))
>> +		return PTR_ERR(clk);
>> +
>> +	ret = clk_enable(clk);
>> +	if (ret)
>> +		return ret;
>> +
>> +	wd->rate = clk_get_rate(clk);
>> +
>> +	if (data->has_pclk) {
>> +		clk = of_clk_get_by_name(dev->device_node, "pclk");
>> +		if (IS_ERR(clk))
>> +			return PTR_ERR(clk);
>> +
>> +		ret = clk_enable(clk);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	wdd              = &wd->wdd;
>> +	wdd->hwdev       = dev;
>> +	wdd->set_timeout = stm32_iwdg_set_timeout;
>> +	wdd->timeout_max = (RLR_MAX + 1) * data->max_prescaler * 1000;
>> +	wdd->timeout_max /= wd->rate * 1000;
>> +	wdd->timeout_cur = wdd->timeout_max;
> 
> Please don't do such alignment things. When somebody has to change
> something here he only has the choice of breaking the alignment or
> changing unrelated lines.

ok

> 
>> +
>> +	ret = stm32_iwdg_set_timeout(wdd, wdd->timeout_max);
>> +	if (ret) {
>> +		dev_err(dev, "Failed to set initial watchdog timeout\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = watchdog_register(wdd);
>> +	if (ret) {
>> +		dev_err(dev, "Failed to register watchdog device\n");
>> +		return ret;
>> +	}
>> +
>> +	wd->restart.name = "stm32-iwdg";
>> +	wd->restart.restart = stm32_iwdg_restart_handler;
>> +	wd->restart.priority = 200;
>> +
>> +	wd->rcc_regmap = syscon_regmap_lookup_by_compatible("st,stm32mp1-rcc");
>> +	if (IS_ERR(wd->rcc_regmap)) {
>> +		dev_warn(dev, "Cannot register restart handler\n");
>> +		goto end;
>> +	}
>> +
>> +	ret = restart_handler_register(&wd->restart);
>> +	if (ret) {
>> +		dev_warn(dev, "Cannot register restart handler\n");
>> +		goto end;
>> +	}
>> +
>> +	ret = stm32_set_reset_reason(wd->rcc_regmap);
>> +	if (ret) {
>> +		dev_warn(dev, "Cannot determine reset reason\n");
>> +		goto end;
>> +	}
> 
> Are the last three failures really failures? You skip the remaining
> steps but still you return with success which looks inconsistent.

Right, restart handler failure shouldn't affect setting the reset
reason. I'll correct this.

I would keep the warnings, because I think it's appropriate to inform the
user that functionality they expected to be available isn't.
e.g. dw_wdt does this, imx-wd doesn't.

> 
>> +end:
>> +	dev_info(dev, "probed\n");
>> +	return 0;
>> +}
> 
> Sascha
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 3/7] watchdog: add stm32 watchdog and reset driver
  2019-06-04  8:51     ` Ahmad Fatoum
@ 2019-06-04 11:07       ` Sascha Hauer
  0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2019-06-04 11:07 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Tue, Jun 04, 2019 at 10:51:49AM +0200, Ahmad Fatoum wrote:
> Hello,
> 
> On 4/6/19 10:24, Sascha Hauer wrote:
> > On Mon, Jun 03, 2019 at 09:05:55PM +0200, Ahmad Fatoum wrote:
> >> The driver supports setting watchdog timeout, system reset
> >> and querying reset reason. Disabling watchdog isn't possible
> >> in hardware, thus users should either enable it before boot
> >> or have the poller take care of feeding it.
> >>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> >> ---
> >>  .../mach-stm32mp/include/mach/reset-reason.h  |  28 ++
> >>  drivers/watchdog/Kconfig                      |   8 +
> >>  drivers/watchdog/Makefile                     |   1 +
> >>  drivers/watchdog/stm32_wdt.c                  | 288 ++++++++++++++++++
> >>  4 files changed, 325 insertions(+)
> >>  create mode 100644 arch/arm/mach-stm32mp/include/mach/reset-reason.h
> >>  create mode 100644 drivers/watchdog/stm32_wdt.c
> >>
> >> diff --git a/arch/arm/mach-stm32mp/include/mach/reset-reason.h b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> >> new file mode 100644
> >> index 000000000000..1165b347c31f
> >> --- /dev/null
> >> +++ b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> >> @@ -0,0 +1,28 @@
> >> +#ifndef __MACH_RESET_REASON_H__
> >> +#define __MACH_RESET_REASON_H__
> >> +
> >> +#include <reset_source.h>
> >> +
> >> +#define RCC_RSTF_POR		BIT(0)
> >> +#define RCC_RSTF_BOR		BIT(1)
> >> +#define RCC_RSTF_PAD		BIT(2)
> >> +#define RCC_RSTF_HCSS		BIT(3)
> >> +#define RCC_RSTF_VCORE		BIT(4)
> >> +
> >> +#define RCC_RSTF_MPSYS		BIT(6)
> >> +#define RCC_RSTF_MCSYS		BIT(7)
> >> +#define RCC_RSTF_IWDG1		BIT(8)
> >> +#define RCC_RSTF_IWDG2		BIT(9)
> >> +
> >> +#define RCC_RSTF_STDBY		BIT(11)
> >> +#define RCC_RSTF_CSTDBY		BIT(12)
> >> +#define RCC_RSTF_MPUP0		BIT(13)
> >> +#define RCC_RSTF_MPUP1		BIT(14)
> >> +
> >> +struct stm32_reset_reason {
> >> +	uint32_t mask;
> >> +	enum reset_src_type type;
> >> +	int instance;
> >> +};
> > 
> > This is used in the driver only. Why is this in a header file?
> 
> The driver is applicable to both stm32 and stm32mp, but the reasons
> differ in bit mask. A future mach-stm32 could reuse the driver,
> but define its own reset-reason.h. What do you think?

I think you shouldn't decide at build time which SoC the driver
supports. Add a proper namespace to the defines so that both SoCs
can be compiled in at once.

> > Are the last three failures really failures? You skip the remaining
> > steps but still you return with success which looks inconsistent.
> 
> Right, restart handler failure shouldn't affect setting the reset
> reason. I'll correct this.
> 
> I would keep the warnings, because I think it's appropriate to inform the
> user that functionality they expected to be available isn't.
> e.g. dw_wdt does this, imx-wd doesn't.

Ok.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 3/7] watchdog: add stm32 watchdog and reset driver
  2019-06-03 19:05 ` [PATCH 3/7] watchdog: add stm32 watchdog and reset driver Ahmad Fatoum
  2019-06-04  8:24   ` Sascha Hauer
@ 2019-06-04 17:23   ` Roland Hieber
  1 sibling, 0 replies; 15+ messages in thread
From: Roland Hieber @ 2019-06-04 17:23 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Jun 03, 2019 at 09:05:55PM +0200, Ahmad Fatoum wrote:
> The driver supports setting watchdog timeout, system reset
> and querying reset reason. Disabling watchdog isn't possible
> in hardware, thus users should either enable it before boot
> or have the poller take care of feeding it.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  .../mach-stm32mp/include/mach/reset-reason.h  |  28 ++
>  drivers/watchdog/Kconfig                      |   8 +
>  drivers/watchdog/Makefile                     |   1 +
>  drivers/watchdog/stm32_wdt.c                  | 288 ++++++++++++++++++
>  4 files changed, 325 insertions(+)
>  create mode 100644 arch/arm/mach-stm32mp/include/mach/reset-reason.h
>  create mode 100644 drivers/watchdog/stm32_wdt.c
> 
> diff --git a/arch/arm/mach-stm32mp/include/mach/reset-reason.h b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> new file mode 100644
> index 000000000000..1165b347c31f
> --- /dev/null
> +++ b/arch/arm/mach-stm32mp/include/mach/reset-reason.h
> @@ -0,0 +1,28 @@
> +#ifndef __MACH_RESET_REASON_H__
> +#define __MACH_RESET_REASON_H__
> +
> +#include <reset_source.h>
> +
> +#define RCC_RSTF_POR		BIT(0)
> +#define RCC_RSTF_BOR		BIT(1)
> +#define RCC_RSTF_PAD		BIT(2)
> +#define RCC_RSTF_HCSS		BIT(3)
> +#define RCC_RSTF_VCORE		BIT(4)
> +
> +#define RCC_RSTF_MPSYS		BIT(6)
> +#define RCC_RSTF_MCSYS		BIT(7)
> +#define RCC_RSTF_IWDG1		BIT(8)
> +#define RCC_RSTF_IWDG2		BIT(9)
> +
> +#define RCC_RSTF_STDBY		BIT(11)
> +#define RCC_RSTF_CSTDBY		BIT(12)
> +#define RCC_RSTF_MPUP0		BIT(13)
> +#define RCC_RSTF_MPUP1		BIT(14)
> +
> +struct stm32_reset_reason {
> +	uint32_t mask;
> +	enum reset_src_type type;
> +	int instance;
> +};
> +
> +#endif
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 04efb1a3c866..5a28b530099d 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -81,4 +81,12 @@ config RAVE_SP_WATCHDOG
>  	depends on RAVE_SP_CORE
>  	help
>  	  Support for the watchdog on RAVE SP device.
> +
> +config STM32_IWDG_WATCHDOG
> +        bool "Enable IWDG watchdog driver for STM32 processors"

"STM32 IWDG" should be enough, the other options in that menu are
also very short.

 - Roland

> +	depends on ARCH_STM32MP
> +	select MFD_SYSCON
> +        help
> +                Enable the STM32 watchdog (IWDG) driver. Enable support to
> +                configure STM32's on-SoC watchdog.
>  endif
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 6c8d36c8b805..b2f39fa3719e 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_WATCHDOG_IMX) += imxwd.o
>  obj-$(CONFIG_WATCHDOG_ORION) += orion_wdt.o
>  obj-$(CONFIG_ARCH_BCM283X) += bcm2835_wdt.o
>  obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
> +obj-$(CONFIG_STM32_IWDG_WATCHDOG) += stm32_wdt.o
> diff --git a/drivers/watchdog/stm32_wdt.c b/drivers/watchdog/stm32_wdt.c
> new file mode 100644
> index 000000000000..a972aade5900
> --- /dev/null
> +++ b/drivers/watchdog/stm32_wdt.c
> @@ -0,0 +1,288 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
> +/*
> + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <watchdog.h>
> +#include <restart.h>
> +#include <asm/io.h>
> +#include <of_device.h>
> +#include <linux/log2.h>
> +#include <linux/iopoll.h>
> +#include <linux/clk.h>
> +#include <mfd/syscon.h>
> +#include <mach/reset-reason.h>
> +
> +/* IWDG registers */
> +#define IWDG_KR		0x00	/* Key register */
> +#define IWDG_PR		0x04	/* Prescaler Register */
> +#define IWDG_RLR	0x08	/* ReLoad Register */
> +#define IWDG_SR		0x0C	/* Status Register */
> +
> +/* IWDG_KR register bit mask */
> +#define KR_KEY_RELOAD	0xAAAA	/* Reload counter enable */
> +#define KR_KEY_ENABLE	0xCCCC	/* Peripheral enable */
> +#define KR_KEY_EWA	0x5555	/* Write access enable */
> +
> +/* IWDG_PR register bit values */
> +#define PR_SHIFT	2
> +
> +/* IWDG_RLR register values */
> +#define RLR_MAX		GENMASK(11, 0)
> +
> +/* IWDG_SR register bit mask */
> +#define SR_PVU	BIT(0) /* Watchdog prescaler value update */
> +#define SR_RVU	BIT(1) /* Watchdog counter reload value update */
> +
> +#define RCC_MP_GRSTCSETR		0x404
> +#define RCC_MP_RSTSCLRR			0x408
> +#define RCC_MP_GRSTCSETR_MPSYSRST	BIT(0)
> +
> +/* set timeout to 100 ms */
> +#define TIMEOUT_US	100000
> +
> +struct stm32_iwdg {
> +	struct watchdog wdd;
> +	struct restart_handler restart;
> +	void __iomem *iwdg_base;
> +	struct regmap *rcc_regmap;
> +	unsigned int timeout;
> +	unsigned int rate;
> +};
> +
> +static inline struct stm32_iwdg *to_stm32_iwdg(struct watchdog *wdd)
> +{
> +	return container_of(wdd, struct stm32_iwdg, wdd);
> +}
> +
> +static void __noreturn stm32_iwdg_restart_handler(struct restart_handler *rst)
> +{
> +	struct stm32_iwdg *wd = container_of(rst, struct stm32_iwdg, restart);
> +
> +	regmap_update_bits(wd->rcc_regmap, RCC_MP_GRSTCSETR,
> +			   RCC_MP_GRSTCSETR_MPSYSRST, RCC_MP_GRSTCSETR_MPSYSRST);
> +
> +	mdelay(1000);
> +	hang();
> +}
> +
> +static void stm32_iwdg_ping(struct stm32_iwdg *wd)
> +{
> +	writel(KR_KEY_RELOAD, wd->iwdg_base + IWDG_KR);
> +}
> +
> +static int stm32_iwdg_start(struct stm32_iwdg *wd, unsigned int timeout)
> +{
> +	u32 presc, iwdg_rlr, iwdg_pr, iwdg_sr;
> +	int ret;
> +
> +	presc = DIV_ROUND_UP(timeout * wd->rate, RLR_MAX + 1);
> +
> +	/* The prescaler is align on power of 2 and start at 2 ^ PR_SHIFT. */
> +	presc = roundup_pow_of_two(presc);
> +	iwdg_pr = presc <= 1 << PR_SHIFT ? 0 : ilog2(presc) - PR_SHIFT;
> +	iwdg_rlr = ((timeout * wd->rate) / presc) - 1;
> +
> +	/* enable write access */
> +	writel(KR_KEY_EWA, wd->iwdg_base + IWDG_KR);
> +
> +	/* set prescaler & reload registers */
> +	writel(iwdg_pr, wd->iwdg_base + IWDG_PR);
> +	writel(iwdg_rlr, wd->iwdg_base + IWDG_RLR);
> +	writel(KR_KEY_ENABLE, wd->iwdg_base + IWDG_KR);
> +
> +	/* wait for the registers to be updated (max 100ms) */
> +	ret = readl_poll_timeout(wd->iwdg_base + IWDG_SR, iwdg_sr,
> +				 !(iwdg_sr & (SR_PVU | SR_RVU)),
> +				 TIMEOUT_US);
> +	if (!ret)
> +		wd->timeout = timeout;
> +
> +	return ret;
> +}
> +
> +
> +static int stm32_iwdg_set_timeout(struct watchdog *wdd, unsigned int timeout)
> +{
> +	struct stm32_iwdg *wd = to_stm32_iwdg(wdd);
> +	int ret;
> +
> +	if (!timeout)
> +		return -EINVAL; /* can't disable */
> +
> +	if (timeout > wdd->timeout_max)
> +		return -EINVAL;
> +
> +	if (wd->timeout != timeout) {
> +		ret = stm32_iwdg_start(wd, timeout);
> +		if (ret) {
> +			dev_err(wdd->hwdev, "Fail to (re)start watchdog\n");
> +			return ret;
> +		}
> +	}
> +
> +	stm32_iwdg_ping(wd);
> +	return 0;
> +}
> +
> +static const struct stm32_reset_reason stm32_reset_reasons[] = {
> +	{ RCC_RSTF_POR,		RESET_POR, 0 },
> +	{ RCC_RSTF_BOR,		RESET_BOR, 0 },
> +	{ RCC_RSTF_STDBY,	RESET_WKE, 0 },
> +	{ RCC_RSTF_CSTDBY,	RESET_WKE, 1 },
> +	{ RCC_RSTF_MPSYS,	RESET_RST, 2 },
> +	{ RCC_RSTF_MPUP0,	RESET_RST, 0 },
> +	{ RCC_RSTF_MPUP1,	RESET_RST, 1 },
> +	{ RCC_RSTF_IWDG1,	RESET_WDG, 0 },
> +	{ RCC_RSTF_IWDG2,	RESET_WDG, 1 },
> +	{ RCC_RSTF_PAD,		RESET_EXT, 1 },
> +	{ /* sentinel */ }
> +};
> +
> +static int stm32_set_reset_reason(struct regmap *rcc)
> +{
> +	enum reset_src_type type = RESET_UKWN;
> +	u32 reg;
> +	int ret;
> +	int i, instance = 0;
> +
> +	/*
> +	 * SRSR register captures ALL reset event that occured since
> +	 * POR, so we need to clear it to make sure we only caputre
> +	 * the latest one.
> +	 */
> +	ret = regmap_read(rcc, RCC_MP_RSTSCLRR, &reg);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; stm32_reset_reasons[i].mask; i++) {
> +		if (reg & stm32_reset_reasons[i].mask) {
> +			type     = stm32_reset_reasons[i].type;
> +			instance = stm32_reset_reasons[i].instance;
> +			break;
> +		}
> +	}
> +
> +	reset_source_set_priority(type, RESET_SOURCE_DEFAULT_PRIORITY);
> +	reset_source_set_instance(type, instance);
> +
> +	pr_info("STM32 RCC reset reason %s (MP_RSTSR: 0x%08x)\n",
> +		reset_source_name(), reg);
> +
> +	return 0;
> +}
> +
> +struct stm32_iwdg_data {
> +	bool has_pclk;
> +	u32 max_prescaler;
> +};
> +
> +static const struct stm32_iwdg_data stm32_iwdg_data = {
> +	.has_pclk = false, .max_prescaler = 256,
> +};
> +
> +static const struct stm32_iwdg_data stm32mp1_iwdg_data = {
> +	.has_pclk = true, .max_prescaler = 1024,
> +};
> +
> +static const struct of_device_id stm32_iwdg_of_match[] = {
> +	{ .compatible = "st,stm32-iwdg",    .data = &stm32_iwdg_data },
> +	{ .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_data },
> +	{ /* sentinel */ }
> +};
> +
> +static int stm32_iwdg_probe(struct device_d *dev)
> +{
> +	struct stm32_iwdg_data *data;
> +	struct stm32_iwdg *wd;
> +	struct resource *res;
> +	struct watchdog *wdd;
> +	struct clk *clk;
> +	int ret;
> +
> +	wd = xzalloc(sizeof(*wd));
> +
> +	ret = dev_get_drvdata(dev, (const void **)&data);
> +	if (ret)
> +		return -ENODEV;
> +
> +	res = dev_request_mem_resource(dev, 0);
> +	if (IS_ERR(res)) {
> +		dev_err(dev, "could not get timer memory region\n");
> +		return PTR_ERR(res);
> +	}
> +	wd->iwdg_base = IOMEM(res->start);
> +
> +	clk = of_clk_get_by_name(dev->device_node, "lsi");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	ret = clk_enable(clk);
> +	if (ret)
> +		return ret;
> +
> +	wd->rate = clk_get_rate(clk);
> +
> +	if (data->has_pclk) {
> +		clk = of_clk_get_by_name(dev->device_node, "pclk");
> +		if (IS_ERR(clk))
> +			return PTR_ERR(clk);
> +
> +		ret = clk_enable(clk);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	wdd              = &wd->wdd;
> +	wdd->hwdev       = dev;
> +	wdd->set_timeout = stm32_iwdg_set_timeout;
> +	wdd->timeout_max = (RLR_MAX + 1) * data->max_prescaler * 1000;
> +	wdd->timeout_max /= wd->rate * 1000;
> +	wdd->timeout_cur = wdd->timeout_max;
> +
> +	ret = stm32_iwdg_set_timeout(wdd, wdd->timeout_max);
> +	if (ret) {
> +		dev_err(dev, "Failed to set initial watchdog timeout\n");
> +		return ret;
> +	}
> +
> +	ret = watchdog_register(wdd);
> +	if (ret) {
> +		dev_err(dev, "Failed to register watchdog device\n");
> +		return ret;
> +	}
> +
> +	wd->restart.name = "stm32-iwdg";
> +	wd->restart.restart = stm32_iwdg_restart_handler;
> +	wd->restart.priority = 200;
> +
> +	wd->rcc_regmap = syscon_regmap_lookup_by_compatible("st,stm32mp1-rcc");
> +	if (IS_ERR(wd->rcc_regmap)) {
> +		dev_warn(dev, "Cannot register restart handler\n");
> +		goto end;
> +	}
> +
> +	ret = restart_handler_register(&wd->restart);
> +	if (ret) {
> +		dev_warn(dev, "Cannot register restart handler\n");
> +		goto end;
> +	}
> +
> +	ret = stm32_set_reset_reason(wd->rcc_regmap);
> +	if (ret) {
> +		dev_warn(dev, "Cannot determine reset reason\n");
> +		goto end;
> +	}
> +end:
> +	dev_info(dev, "probed\n");
> +	return 0;
> +}
> +
> +static struct driver_d stm32_iwdg_driver = {
> +	.name  = "stm32-iwdg",
> +	.probe = stm32_iwdg_probe,
> +	.of_compatible = DRV_OF_COMPAT(stm32_iwdg_of_match),
> +};
> +device_platform_driver(stm32_iwdg_driver);
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Roland Hieber                     | r.hieber@pengutronix.de     |
Pengutronix e.K.                  | https://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim | Phone: +49-5121-206917-5086 |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2019-06-04 17:23 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-03 19:05 [PATCH 1/7] ARM: stm32mp1: rename to stm32mp Ahmad Fatoum
2019-06-03 19:05 ` [PATCH 2/7] reset_source: add new Brownout reset (BOR) source Ahmad Fatoum
2019-06-04  8:11   ` Sascha Hauer
2019-06-04  8:31     ` Ahmad Fatoum
2019-06-03 19:05 ` [PATCH 3/7] watchdog: add stm32 watchdog and reset driver Ahmad Fatoum
2019-06-04  8:24   ` Sascha Hauer
2019-06-04  8:51     ` Ahmad Fatoum
2019-06-04 11:07       ` Sascha Hauer
2019-06-04 17:23   ` Roland Hieber
2019-06-03 19:05 ` [PATCH 4/7] ARM: stm32mp1: enable watchdog in oftree and defconfig Ahmad Fatoum
2019-06-03 19:34   ` Sam Ravnborg
2019-06-03 19:46     ` Ahmad Fatoum
2019-06-03 19:05 ` [PATCH 5/7] ARM: stm32mp: stm32mp157c-dk2: configure debug_ll UART Ahmad Fatoum
2019-06-03 19:05 ` [PATCH 6/7] ARM: stm32mp: stm32mp157c-dk2: compress the DTB Ahmad Fatoum
2019-06-03 19:05 ` [PATCH 7/7] ARM: stm32mp: add entry point, not point.pblb to pblb-y Ahmad Fatoum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox