mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/8] ARM: i.MX7: add serial download reboot mode
@ 2022-10-17  7:09 Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 1/8] restart: make restart.h header self-contained Ahmad Fatoum
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox

BootROM can be forced into USB recovery on i.MX7 just like on the
i.MX8M, with the difference that reset is a bit more involved,
because warm resets via watchdogs are broken on this SoC.

We do a bit of cleanup and then tackle that via a syscon-reboot
device describing the Cortex-A7 CPU0 reset.

Ahmad Fatoum (8):
  restart: make restart.h header self-contained
  restart: do restart-priority OF parsing in restart_handler_register
  restart: add reset -w for warm bootrom reset
  watchdog: imxwd: don't register broken imxwd-warm for i.MX7
  watchdog: imxwd: set imxwd-warm as reboot mode default handler
  Documentations: devicetree: bindings: document watchdog-priority
  ARM: i.MX7: describe USB serial download boot mode
  ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom

 Documentation/boards/imx.rst                  |  2 +-
 Documentation/boards/stm32mp.rst              |  6 ++-
 .../devicetree/bindings/power/restart.rst     | 15 ++++++++
 .../devicetree/bindings/watchdog/watchdog.rst | 10 +++++
 Documentation/user/reboot-mode.rst            |  7 +++-
 arch/arm/configs/imx_v7_defconfig             |  2 +
 arch/arm/dts/imx7.dtsi                        | 37 +++++++++++++++++++
 arch/arm/dts/stm32mp131.dtsi                  |  4 ++
 arch/arm/dts/stm32mp151.dtsi                  |  4 ++
 commands/reset.c                              | 16 +++++---
 common/restart.c                              | 37 +++++++++----------
 drivers/clk/clk-stm32mp1.c                    |  2 +-
 drivers/mfd/da9053.c                          |  2 +-
 drivers/mfd/da9063.c                          |  2 +-
 drivers/mfd/rn5t568.c                         |  2 +-
 drivers/power/reset/stm32-reboot.c            |  6 ++-
 drivers/power/reset/syscon-reboot.c           |  1 +
 drivers/watchdog/imxwd.c                      | 31 ++++++++++++----
 include/restart.h                             | 15 ++++++--
 include/soc/stm32/reboot.h                    |  6 ++-
 20 files changed, 161 insertions(+), 46 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/restart.rst
 create mode 100644 Documentation/devicetree/bindings/watchdog/watchdog.rst
 create mode 100644 arch/arm/dts/imx7.dtsi

-- 
2.30.2




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

* [PATCH 1/8] restart: make restart.h header self-contained
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 2/8] restart: do restart-priority OF parsing in restart_handler_register Ahmad Fatoum
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Code may fail compile depending on include order. Fix this.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/restart.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/restart.h b/include/restart.h
index 2d15c7598acc..27fab1b80dfb 100644
--- a/include/restart.h
+++ b/include/restart.h
@@ -2,6 +2,11 @@
 #ifndef __INCLUDE_RESTART_H
 #define __INCLUDE_RESTART_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct device_node;
+
 void restart_handlers_print(void);
 void __noreturn restart_machine(void);
 struct restart_handler *restart_handler_get_by_name(const char *name);
-- 
2.30.2




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

* [PATCH 2/8] restart: do restart-priority OF parsing in restart_handler_register
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 1/8] restart: make restart.h header self-contained Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 3/8] restart: add reset -w for warm bootrom reset Ahmad Fatoum
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The restart-priority OF property is parsed for a number of MFDs, but
there is no reason really not to parse it for every restart handler that
has a device tree node like we already do for watchdogs.
Add a new struct restart_handler::of_node field and look into it if
populated. With this of_get_restart_priority, is no longer used, so drop it.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../devicetree/bindings/power/restart.rst     | 10 ++++++++++
 common/restart.c                              | 20 +++++--------------
 drivers/mfd/da9053.c                          |  2 +-
 drivers/mfd/da9063.c                          |  2 +-
 drivers/mfd/rn5t568.c                         |  2 +-
 include/restart.h                             |  5 +++--
 6 files changed, 21 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/restart.rst

diff --git a/Documentation/devicetree/bindings/power/restart.rst b/Documentation/devicetree/bindings/power/restart.rst
new file mode 100644
index 000000000000..8c866f6e0ded
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/restart.rst
@@ -0,0 +1,10 @@
+System Restart Controllers
+==========================
+
+In addition to upstream bindings, following properties are understood:
+
+Optional properties:
+
+- ``restart-priority`` : Overrides the priority set by the driver. Normally,
+  the device with the biggest reach should reset the system.
+  See :ref:`_system_reset` for more information.
diff --git a/common/restart.c b/common/restart.c
index b6f2bbf25b10..9e988838bc60 100644
--- a/common/restart.c
+++ b/common/restart.c
@@ -27,6 +27,11 @@ int restart_handler_register(struct restart_handler *rst)
 	if (!rst->priority)
 		rst->priority = RESTART_DEFAULT_PRIORITY;
 
+	if (rst->of_node) {
+		of_property_read_u32(rst->of_node, "restart-priority",
+				     &rst->priority);
+	}
+
 	list_add_tail(&rst->list, &restart_handler_list);
 
 	pr_debug("registering restart handler \"%s\" with priority %d\n",
@@ -102,21 +107,6 @@ void __noreturn restart_machine(void)
 	hang();
 }
 
-/**
- * of_get_restart_priority() - get the desired restart priority from device tree
- * @node:	The device_node to read the property from
- *
- * return: The priority
- */
-unsigned int of_get_restart_priority(struct device_node *node)
-{
-	unsigned int priority = RESTART_DEFAULT_PRIORITY;
-
-	of_property_read_u32(node, "restart-priority", &priority);
-
-	return priority;
-}
-
 /*
  * restart_handlers_print - print informations about all restart handlers
  */
diff --git a/drivers/mfd/da9053.c b/drivers/mfd/da9053.c
index 99827c968922..693c0ca606f7 100644
--- a/drivers/mfd/da9053.c
+++ b/drivers/mfd/da9053.c
@@ -272,7 +272,7 @@ static int da9053_probe(struct device_d *dev)
 
 	da9053_detect_reset_source(da9053);
 
-	da9053->restart.priority = of_get_restart_priority(dev->device_node);
+	da9053->restart.of_node = dev->device_node;
 	da9053->restart.name = "da9063";
 	da9053->restart.restart = &da9053_force_system_reset;
 
diff --git a/drivers/mfd/da9063.c b/drivers/mfd/da9063.c
index a4e5226f3c98..4627dd1aa5a2 100644
--- a/drivers/mfd/da9063.c
+++ b/drivers/mfd/da9063.c
@@ -383,7 +383,7 @@ static int da9063_probe(struct device_d *dev)
 
 	da9063_detect_reset_source(priv);
 
-	priv->restart.priority = of_get_restart_priority(dev->device_node);
+	priv->restart.of_node = dev->device_node;
 	priv->restart.name = "da9063";
 	priv->restart.restart = &da9063_restart;
 
diff --git a/drivers/mfd/rn5t568.c b/drivers/mfd/rn5t568.c
index c1c792cbecf0..4bbab54fe48b 100644
--- a/drivers/mfd/rn5t568.c
+++ b/drivers/mfd/rn5t568.c
@@ -138,7 +138,7 @@ static int __init rn5t568_i2c_probe(struct device_d *dev)
 	regmap_write(pmic_instance->regmap, RN5T568_REPCNT, RN5T568_REPCNT_OFF_RESETO_16MS |
 		     RN5T568_REPCNT_OFF_REPWRTIM_1000MS | RN5T568_REPCNT_OFF_REPWRON);
 
-	pmic_instance->restart.priority = of_get_restart_priority(dev->device_node);
+	pmic_instance->restart.of_node = dev->device_node;
 	pmic_instance->restart.name = "RN5T568";
 	pmic_instance->restart.restart = &rn5t568_restart;
 	restart_handler_register(&pmic_instance->restart);
diff --git a/include/restart.h b/include/restart.h
index 27fab1b80dfb..330b50a53ab2 100644
--- a/include/restart.h
+++ b/include/restart.h
@@ -11,9 +11,12 @@ void restart_handlers_print(void);
 void __noreturn restart_machine(void);
 struct restart_handler *restart_handler_get_by_name(const char *name);
 
+struct device_node;
+
 struct restart_handler {
 	void (*restart)(struct restart_handler *);
 	int priority;
+	struct device_node *of_node;
 	const char *name;
 	struct list_head list;
 };
@@ -24,6 +27,4 @@ int restart_handler_register_fn(const char *name,
 
 #define RESTART_DEFAULT_PRIORITY 100
 
-unsigned int of_get_restart_priority(struct device_node *node);
-
 #endif /* __INCLUDE_RESTART_H */
-- 
2.30.2




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

* [PATCH 3/8] restart: add reset -w for warm bootrom reset
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 1/8] restart: make restart.h header self-contained Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 2/8] restart: do restart-priority OF parsing in restart_handler_register Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 4/8] watchdog: imxwd: don't register broken imxwd-warm for i.MX7 Ahmad Fatoum
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We currently support reboot mode communication with BootROMs of the
i.MX6Q/DL, i.MX8MM and STM32MP15x. For each of these, the user must
take care to use the correct reset as the highest priority reset often
clears the non-volatile register mapped by the syscon holding the reboot
mode. As we only have one BootROM, we can improve usability by adding a
global flag that describes whether a restart handler is suitable for
use after a bootrom reboot mode write. Add a flag bit describing this
and allow populating it from the device tree as well as from drivers.

Existing i.MX/STM32 drivers will be moved onto this in follow-up
commits.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 Documentation/boards/imx.rst                    |  2 +-
 .../devicetree/bindings/power/restart.rst       |  5 +++++
 Documentation/user/reboot-mode.rst              |  7 ++++++-
 commands/reset.c                                | 16 ++++++++++------
 common/restart.c                                | 17 +++++++++++++----
 include/restart.h                               |  5 ++++-
 6 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst
index 4ce9d9808cc1..6c16923340a8 100644
--- a/Documentation/boards/imx.rst
+++ b/Documentation/boards/imx.rst
@@ -105,7 +105,7 @@ that BootROM should select after a warm reset::
           mode-serial = <0x10 0x40000000>;
   };
 
-  barebox@FSL i.MX8MM EVK board:/ gpr.reboot_mode.next=serial reset -r imxwd-warm
+  barebox@FSL i.MX8MM EVK board:/ gpr.reboot_mode.next=serial reset -w
 
 This will cause barebox to fall into serial download mode on an i.MX8MM.
 
diff --git a/Documentation/devicetree/bindings/power/restart.rst b/Documentation/devicetree/bindings/power/restart.rst
index 8c866f6e0ded..42b87f7e9c65 100644
--- a/Documentation/devicetree/bindings/power/restart.rst
+++ b/Documentation/devicetree/bindings/power/restart.rst
@@ -8,3 +8,8 @@ Optional properties:
 - ``restart-priority`` : Overrides the priority set by the driver. Normally,
   the device with the biggest reach should reset the system.
   See :ref:`_system_reset` for more information.
+
+- ``barebox,restart-warm-bootrom`` : Restart will not cause loss to non-volatile
+  registers sampled by the bootrom at startup. This is a necessary precondition
+  for working :ref:`reboot_mode` communication between barebox and the SoC's
+  BootROM.
diff --git a/Documentation/user/reboot-mode.rst b/Documentation/user/reboot-mode.rst
index 83d4136b8592..1929a67e0bc9 100644
--- a/Documentation/user/reboot-mode.rst
+++ b/Documentation/user/reboot-mode.rst
@@ -47,7 +47,9 @@ Reboot mode providers have priorities. The provider with the highest
 priority has its parameters aliased as ``$global.system.reboot_mode.prev``
 and ``$global.system.reboot_mode.next``. After executing the init scripts,
 barebox startup will ``source /env/bmode/${global.system.reboot_mode.prev}``
-if available.
+if available. Example usage::
+
+	gpr.reboot_mode=serial reset -w
 
 Reset
 =====
@@ -60,6 +62,9 @@ If such reboot mode storage is used, users must take care to use the correct
 reset provider. In barebox, multiple reset providers may co-exist. The
 ``reset`` command allows listing and choosing a specific reboot mode.
 
+For communication with the SoC's BootROM, a warm reset can be triggered
+with ``reset -w`` if a suitable reset handler has been registered.
+
 Disambiguation
 ==============
 
diff --git a/commands/reset.c b/commands/reset.c
index fe54e2f9b472..88e677afab34 100644
--- a/commands/reset.c
+++ b/commands/reset.c
@@ -12,12 +12,12 @@
 static int cmd_reset(int argc, char *argv[])
 {
 	struct restart_handler *rst;
-	int opt, shutdown_flag;
+	int opt, shutdown_flag, flags = 0;
 	const char *name = NULL;
 
 	shutdown_flag = 1;
 
-	while ((opt = getopt(argc, argv, "flr:")) > 0) {
+	while ((opt = getopt(argc, argv, "flwr:")) > 0) {
 		switch (opt) {
 		case 'f':
 			shutdown_flag = 0;
@@ -25,6 +25,9 @@ static int cmd_reset(int argc, char *argv[])
 		case 'l':
 			restart_handlers_print();
 			return 0;
+		case 'w':
+			flags |= RESTART_FLAG_WARM_BOOTROM;
+			break;
 		case 'r':
 			name = optarg;
 			break;
@@ -33,9 +36,9 @@ static int cmd_reset(int argc, char *argv[])
 		}
 	}
 
-	rst = restart_handler_get_by_name(name);
-	if (!rst && name) {
-		printf("reset '%s' does not exist\n", name);
+	rst = restart_handler_get_by_name(name, flags);
+	if (!rst && (name || flags)) {
+		printf("No matching restart handler found\n");
 		return COMMAND_ERROR;
 	}
 
@@ -57,13 +60,14 @@ BAREBOX_CMD_HELP_START(reset)
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT("-f",  "force RESET, don't call shutdown")
 BAREBOX_CMD_HELP_OPT("-l",  "list reset handlers")
+BAREBOX_CMD_HELP_OPT("-w",  "only consider warm BootROM reboot-mode-preserving resets")
 BAREBOX_CMD_HELP_OPT("-r RESET",  "use reset handler named RESET")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(reset)
 	.cmd		= cmd_reset,
 	BAREBOX_CMD_DESC("perform RESET of the CPU")
-	BAREBOX_CMD_OPTS("[-flr]")
+	BAREBOX_CMD_OPTS("[-flrw]")
 	BAREBOX_CMD_GROUP(CMD_GRP_BOOT)
 	BAREBOX_CMD_HELP(cmd_reset_help)
 	BAREBOX_CMD_COMPLETE(empty_complete)
diff --git a/common/restart.c b/common/restart.c
index 9e988838bc60..0294b36eccca 100644
--- a/common/restart.c
+++ b/common/restart.c
@@ -30,6 +30,9 @@ int restart_handler_register(struct restart_handler *rst)
 	if (rst->of_node) {
 		of_property_read_u32(rst->of_node, "restart-priority",
 				     &rst->priority);
+		if (of_property_read_bool(rst->of_node,
+					  "barebox,restart-warm-bootrom"))
+			rst->flags |= RESTART_FLAG_WARM_BOOTROM;
 	}
 
 	list_add_tail(&rst->list, &restart_handler_list);
@@ -73,7 +76,7 @@ int restart_handler_register_fn(const char *name,
 /**
  * restart_handler_get_by_name() - reset the whole system
  */
-struct restart_handler *restart_handler_get_by_name(const char *name)
+struct restart_handler *restart_handler_get_by_name(const char *name, int flags)
 {
 	struct restart_handler *rst = NULL, *tmp;
 	unsigned int priority = 0;
@@ -81,6 +84,8 @@ struct restart_handler *restart_handler_get_by_name(const char *name)
 	list_for_each_entry(tmp, &restart_handler_list, list) {
 		if (name && tmp->name && strcmp(name, tmp->name))
 			continue;
+		if (flags && (tmp->flags & flags) != flags)
+			continue;
 		if (tmp->priority > priority) {
 			priority = tmp->priority;
 			rst = tmp;
@@ -97,7 +102,7 @@ void __noreturn restart_machine(void)
 {
 	struct restart_handler *rst;
 
-	rst = restart_handler_get_by_name(NULL);
+	rst = restart_handler_get_by_name(NULL, 0);
 	if (rst) {
 		pr_debug("%s: using restart handler %s\n", __func__, rst->name);
 		console_flush();
@@ -114,6 +119,10 @@ void restart_handlers_print(void)
 {
 	struct restart_handler *tmp;
 
-	list_for_each_entry(tmp, &restart_handler_list, list)
-		printf("%-20s %6d\n", tmp->name, tmp->priority);
+	list_for_each_entry(tmp, &restart_handler_list, list) {
+		printf("%-20s %6d ", tmp->name, tmp->priority);
+		if (tmp->flags & RESTART_FLAG_WARM_BOOTROM)
+			putchar('W');
+		putchar('\n');
+	}
 }
diff --git a/include/restart.h b/include/restart.h
index 330b50a53ab2..15f30bb7ad4d 100644
--- a/include/restart.h
+++ b/include/restart.h
@@ -4,18 +4,21 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/bitops.h>
 
 struct device_node;
 
 void restart_handlers_print(void);
 void __noreturn restart_machine(void);
-struct restart_handler *restart_handler_get_by_name(const char *name);
+struct restart_handler *restart_handler_get_by_name(const char *name, int flags);
 
 struct device_node;
 
 struct restart_handler {
 	void (*restart)(struct restart_handler *);
 	int priority;
+#define RESTART_FLAG_WARM_BOOTROM	BIT(0)
+	int flags;
 	struct device_node *of_node;
 	const char *name;
 	struct list_head list;
-- 
2.30.2




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

* [PATCH 4/8] watchdog: imxwd: don't register broken imxwd-warm for i.MX7
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2022-10-17  7:09 ` [PATCH 3/8] restart: add reset -w for warm bootrom reset Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 5/8] watchdog: imxwd: set imxwd-warm as reboot mode default handler Ahmad Fatoum
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Due to erratum e10574 "Watchdog: A watchdog timeout or software trigger
will not reset the SOC", any use of the watchdog reset must trigger an
external PMIC or reset circuit. Registering imxwd-warm thus serves no
purpose, so don't register it for i.MX7. We'll need an alternative for
reboot mode, which will follow in a later commit.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/watchdog/imxwd.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index dba92cb46afb..b669f6702d62 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -213,7 +213,7 @@ static void imx_watchdog_detect_reset_source(struct imx_wd *priv)
 	/* else keep the default 'unknown' state */
 }
 
-static int imx21_wd_init(struct imx_wd *priv)
+static int imx21_wd_init_no_warm_reset(struct imx_wd *priv)
 {
 	imx_watchdog_detect_reset_source(priv);
 
@@ -225,6 +225,17 @@ static int imx21_wd_init(struct imx_wd *priv)
 	return 0;
 }
 
+static int imx21_wd_init(struct imx_wd *priv)
+{
+	priv->restart_warm.name = "imxwd-warm";
+	priv->restart_warm.restart = imxwd_force_soc_reset_internal;
+	priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10;
+
+	restart_handler_register(&priv->restart_warm);
+
+	return imx21_wd_init_no_warm_reset(priv);
+}
+
 static int imx_wd_probe(struct device_d *dev)
 {
 	struct resource *iores;
@@ -294,12 +305,6 @@ static int imx_wd_probe(struct device_d *dev)
 
 	restart_handler_register(&priv->restart);
 
-	priv->restart_warm.name = "imxwd-warm";
-	priv->restart_warm.restart = imxwd_force_soc_reset_internal;
-	priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10;
-
-	restart_handler_register(&priv->restart_warm);
-
 	return 0;
 
 error_unregister:
@@ -310,6 +315,14 @@ on_error:
 	return ret;
 }
 
+static const struct imx_wd_ops imx7d_wd_ops = {
+	.set_timeout = imx21_watchdog_set_timeout,
+	.soc_reset = imx21_soc_reset,
+	.init = imx21_wd_init_no_warm_reset,
+	.is_running = imx21_watchdog_is_running,
+	.timeout_max = 128,
+};
+
 static const struct imx_wd_ops imx21_wd_ops = {
 	.set_timeout = imx21_watchdog_set_timeout,
 	.soc_reset = imx21_soc_reset,
@@ -331,6 +344,9 @@ static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {
 	}, {
 		.compatible = "fsl,imx21-wdt",
 		.data = &imx21_wd_ops,
+	}, {
+		.compatible = "fsl,imx7d-wdt",
+		.data = &imx7d_wd_ops,
 	}, {
 		/* sentinel */
 	}
-- 
2.30.2




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

* [PATCH 5/8] watchdog: imxwd: set imxwd-warm as reboot mode default handler
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2022-10-17  7:09 ` [PATCH 4/8] watchdog: imxwd: don't register broken imxwd-warm for i.MX7 Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 6/8] Documentations: devicetree: bindings: document watchdog-priority Ahmad Fatoum
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Set RESTART_FLAG_WARM_BOOTROM for imxwd-warm, so reset -w directly
selects this handler. i.MX6QDL/8MM Users now can just do

  gpr.reboot_mode.next=serial reset -w

and it should behave as expected.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/watchdog/imxwd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index b669f6702d62..5e9962866f54 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -230,6 +230,7 @@ static int imx21_wd_init(struct imx_wd *priv)
 	priv->restart_warm.name = "imxwd-warm";
 	priv->restart_warm.restart = imxwd_force_soc_reset_internal;
 	priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10;
+	priv->restart_warm.flags = RESTART_FLAG_WARM_BOOTROM;
 
 	restart_handler_register(&priv->restart_warm);
 
-- 
2.30.2




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

* [PATCH 6/8] Documentations: devicetree: bindings: document watchdog-priority
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2022-10-17  7:09 ` [PATCH 5/8] watchdog: imxwd: set imxwd-warm as reboot mode default handler Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:09 ` [PATCH 7/8] ARM: i.MX7: describe USB serial download boot mode Ahmad Fatoum
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We parse watchdog-priority for every OF-enabled watchdog device, but
failed to document it. Remedy this.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 .../devicetree/bindings/watchdog/watchdog.rst          | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/watchdog.rst

diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.rst b/Documentation/devicetree/bindings/watchdog/watchdog.rst
new file mode 100644
index 000000000000..415a4520f45e
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/watchdog.rst
@@ -0,0 +1,10 @@
+Watchdogs
+=========
+
+In addition to the upstream bindings, following properties are understood:
+
+Optional properties:
+
+- ``watchdog-priority`` : Overrides the priority set by the driver. Normally,
+  the watchdog device with the biggest reach should reset the system.
+  See :ref:`_system_reset` for more information.
-- 
2.30.2




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

* [PATCH 7/8] ARM: i.MX7: describe USB serial download boot mode
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (5 preceding siblings ...)
  2022-10-17  7:09 ` [PATCH 6/8] Documentations: devicetree: bindings: document watchdog-priority Ahmad Fatoum
@ 2022-10-17  7:09 ` Ahmad Fatoum
  2022-10-17  7:10 ` [PATCH 8/8] ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom Ahmad Fatoum
  2022-10-18  9:13 ` [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:09 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Due to i.MX7 erratum e10574: "Watchdog: A watchdog timeout or software
trigger will not reset the SOC", we can't do warm reset via imxwd-warm
for BootROM reboot mode as we do on other i.MX SoCs.

What we can do instead though, is use the SoC's reset controller to
toggle the Cortex-A7's reset. This will have us reenter BootROM with
GPR registers intact. Forcing serial download on the i.MX7 now possible
with:

  gpr.reboot_mode.next=serial reset -w

Note that the new restart handler is not fit for general purpose.
Depending on boot medium, it may hang, because the BootROM may not
reinitialize the peripheral properly.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/arm/configs/imx_v7_defconfig   |  2 ++
 arch/arm/dts/imx7.dtsi              | 37 +++++++++++++++++++++++++++++
 drivers/power/reset/syscon-reboot.c |  1 +
 3 files changed, 40 insertions(+)
 create mode 100644 arch/arm/dts/imx7.dtsi

diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig
index d07abe28aeac..3cbec267fc87 100644
--- a/arch/arm/configs/imx_v7_defconfig
+++ b/arch/arm/configs/imx_v7_defconfig
@@ -208,6 +208,8 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED=y
 CONFIG_GENERIC_PHY=y
 CONFIG_USB_NOP_XCEIV=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_TFTP=y
 CONFIG_FS_TFTP_MAX_WINDOW_SIZE=8
diff --git a/arch/arm/dts/imx7.dtsi b/arch/arm/dts/imx7.dtsi
new file mode 100644
index 000000000000..1c67bdc54620
--- /dev/null
+++ b/arch/arm/dts/imx7.dtsi
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+
+#include "imx7d-ddrc.dtsi"
+
+/ {
+	aliases {
+		gpr.reboot_mode = &reboot_mode_gpr;
+	};
+};
+
+&src {
+	compatible = "fsl,imx7d-src", "syscon", "simple-mfd";
+
+	reboot_mode_gpr: reboot-mode {
+		compatible = "barebox,syscon-reboot-mode";
+		offset = <0x94>, <0x98>; /* SRC_GPR{9,10} */
+		mask = <0xffffffff>, <0x40000000>;
+		mode-normal = <0>, <0>;
+		mode-serial = <0x00000010>, <0x40000000>;
+	};
+
+	ca7_reset: cortex-a7-reboot {
+		compatible = "syscon-reboot";
+		regmap = <&src>;
+		offset = <0x4>;
+		mask = <1>;
+		value = <1>;
+		/* This is not fit for use as general purpose reset */
+		restart-priority = <5>;
+		/*
+		 * Can't use imxwd-warm due to errata e10574:
+		 * Watchdog: A watchdog timeout or software trigger will
+		 * not reset the SOC
+		 */
+		barebox,restart-warm-bootrom;
+	};
+};
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c
index 2dbb6c1ddcb8..b6b8db75caba 100644
--- a/drivers/power/reset/syscon-reboot.c
+++ b/drivers/power/reset/syscon-reboot.c
@@ -71,6 +71,7 @@ static int syscon_reboot_probe(struct device_d *dev)
 	ctx->restart_handler.name = "syscon-reboot";
 	ctx->restart_handler.restart = syscon_restart_handle;
 	ctx->restart_handler.priority = 192;
+	ctx->restart_handler.of_node = dev->device_node;
 
 	err = restart_handler_register(&ctx->restart_handler);
 	if (err)
-- 
2.30.2




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

* [PATCH 8/8] ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (6 preceding siblings ...)
  2022-10-17  7:09 ` [PATCH 7/8] ARM: i.MX7: describe USB serial download boot mode Ahmad Fatoum
@ 2022-10-17  7:10 ` Ahmad Fatoum
  2022-10-18  9:13 ` [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Ahmad Fatoum @ 2022-10-17  7:10 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

All STM32MP1 DTs already include their respective barebox SoC header, so
set barebox,restart-warm-bootrom there, so users can portably run:

  tamp.reboot_mode.next=serial reset -w

To get into DFU mode.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 Documentation/boards/stm32mp.rst   | 6 +++++-
 arch/arm/dts/stm32mp131.dtsi       | 4 ++++
 arch/arm/dts/stm32mp151.dtsi       | 4 ++++
 drivers/clk/clk-stm32mp1.c         | 2 +-
 drivers/power/reset/stm32-reboot.c | 6 ++++--
 include/soc/stm32/reboot.h         | 6 ++++--
 6 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/Documentation/boards/stm32mp.rst b/Documentation/boards/stm32mp.rst
index 4cdd281a9e14..813117a04f22 100644
--- a/Documentation/boards/stm32mp.rst
+++ b/Documentation/boards/stm32mp.rst
@@ -164,9 +164,13 @@ normal barebox functionality like creating a DFU-gadget in barebox,
 Fastboot/USB mass storage ... etc.
 
 The FIP image containing barebox can be generated as described in
-137::ref:`stm32mp_fip`. Upstream TF-A doesn't support DFU for
+:ref:`stm32mp_fip`. Upstream TF-A doesn't support DFU for
 SSBLs using the legacy stm32image format.
 
+DFU mode can be forced via :ref:`reboot_mode` from a booted system with::
+
+  tamp.reboot_mode.next=serial reset -w
+
 Boot source selection
 ---------------------
 
diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi
index 2ecad85f086e..89a7ffcb814f 100644
--- a/arch/arm/dts/stm32mp131.dtsi
+++ b/arch/arm/dts/stm32mp131.dtsi
@@ -12,3 +12,7 @@
 		reg = <0x5a003000 0x1000>;
 	};
 };
+
+&iwdg2 {
+	barebox,restart-warm-bootrom;
+};
diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi
index ac6536a556a9..d3e924dc0072 100644
--- a/arch/arm/dts/stm32mp151.dtsi
+++ b/arch/arm/dts/stm32mp151.dtsi
@@ -37,6 +37,10 @@
 	barebox,provide-mac-address = <&ethernet0 0x39>;
 };
 
+&iwdg2 {
+	barebox,restart-warm-bootrom;
+};
+
 &tamp {
 	reboot_mode_tamp: reboot-mode {
 		compatible = "syscon-reboot-mode";
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index c4b03e9f6d74..6753a3689085 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -2280,7 +2280,7 @@ static int stm32mp1_rcc_init(struct device_d *dev)
 	if (ret)
 		return ret;
 
-	stm32mp_system_restart_init(base);
+	stm32mp_system_restart_init(dev);
 	return 0;
 }
 
diff --git a/drivers/power/reset/stm32-reboot.c b/drivers/power/reset/stm32-reboot.c
index 809531e71396..147b4d9d8164 100644
--- a/drivers/power/reset/stm32-reboot.c
+++ b/drivers/power/reset/stm32-reboot.c
@@ -108,17 +108,19 @@ static void stm32_set_reset_reason(struct stm32_reset *priv,
 		reset_source_to_string(type), reg);
 }
 
-void stm32mp_system_restart_init(void __iomem *base)
+void stm32mp_system_restart_init(struct device_d *dev)
 {
 	struct stm32_reset *priv;
+	struct device_node *np = dev_of_node(dev);
 
 	priv = xzalloc(sizeof(*priv));
 
-	priv->base = base;
+	priv->base = of_iomap(np, 0);
 
 	priv->restart.name = "stm32-rcc";
 	priv->restart.restart = stm32mp_rcc_restart_handler;
 	priv->restart.priority = 200;
+	priv->restart.of_node = np;
 
 	restart_handler_register(&priv->restart);
 
diff --git a/include/soc/stm32/reboot.h b/include/soc/stm32/reboot.h
index d6c731f59f74..cf0d0286e753 100644
--- a/include/soc/stm32/reboot.h
+++ b/include/soc/stm32/reboot.h
@@ -5,10 +5,12 @@
 
 #include <linux/compiler.h>
 
+struct device_d;
+
 #ifdef CONFIG_RESET_STM32
-void stm32mp_system_restart_init(void __iomem *rcc);
+void stm32mp_system_restart_init(struct device_d *rcc);
 #else
-static inline void stm32mp_system_restart_init(void __iomem *rcc)
+static inline void stm32mp_system_restart_init(struct device_d *rcc)
 {
 }
 #endif
-- 
2.30.2




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

* Re: [PATCH 0/8] ARM: i.MX7: add serial download reboot mode
  2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
                   ` (7 preceding siblings ...)
  2022-10-17  7:10 ` [PATCH 8/8] ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom Ahmad Fatoum
@ 2022-10-18  9:13 ` Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2022-10-18  9:13 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Oct 17, 2022 at 09:09:52AM +0200, Ahmad Fatoum wrote:
> BootROM can be forced into USB recovery on i.MX7 just like on the
> i.MX8M, with the difference that reset is a bit more involved,
> because warm resets via watchdogs are broken on this SoC.
> 
> We do a bit of cleanup and then tackle that via a syscon-reboot
> device describing the Cortex-A7 CPU0 reset.
> 
> Ahmad Fatoum (8):
>   restart: make restart.h header self-contained
>   restart: do restart-priority OF parsing in restart_handler_register
>   restart: add reset -w for warm bootrom reset
>   watchdog: imxwd: don't register broken imxwd-warm for i.MX7
>   watchdog: imxwd: set imxwd-warm as reboot mode default handler
>   Documentations: devicetree: bindings: document watchdog-priority
>   ARM: i.MX7: describe USB serial download boot mode
>   ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom

Applied, thanks

Sascha

> 
>  Documentation/boards/imx.rst                  |  2 +-
>  Documentation/boards/stm32mp.rst              |  6 ++-
>  .../devicetree/bindings/power/restart.rst     | 15 ++++++++
>  .../devicetree/bindings/watchdog/watchdog.rst | 10 +++++
>  Documentation/user/reboot-mode.rst            |  7 +++-
>  arch/arm/configs/imx_v7_defconfig             |  2 +
>  arch/arm/dts/imx7.dtsi                        | 37 +++++++++++++++++++
>  arch/arm/dts/stm32mp131.dtsi                  |  4 ++
>  arch/arm/dts/stm32mp151.dtsi                  |  4 ++
>  commands/reset.c                              | 16 +++++---
>  common/restart.c                              | 37 +++++++++----------
>  drivers/clk/clk-stm32mp1.c                    |  2 +-
>  drivers/mfd/da9053.c                          |  2 +-
>  drivers/mfd/da9063.c                          |  2 +-
>  drivers/mfd/rn5t568.c                         |  2 +-
>  drivers/power/reset/stm32-reboot.c            |  6 ++-
>  drivers/power/reset/syscon-reboot.c           |  1 +
>  drivers/watchdog/imxwd.c                      | 31 ++++++++++++----
>  include/restart.h                             | 15 ++++++--
>  include/soc/stm32/reboot.h                    |  6 ++-
>  20 files changed, 161 insertions(+), 46 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power/restart.rst
>  create mode 100644 Documentation/devicetree/bindings/watchdog/watchdog.rst
>  create mode 100644 arch/arm/dts/imx7.dtsi
> 
> -- 
> 2.30.2
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



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

end of thread, other threads:[~2022-10-18  9:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-17  7:09 [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 1/8] restart: make restart.h header self-contained Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 2/8] restart: do restart-priority OF parsing in restart_handler_register Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 3/8] restart: add reset -w for warm bootrom reset Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 4/8] watchdog: imxwd: don't register broken imxwd-warm for i.MX7 Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 5/8] watchdog: imxwd: set imxwd-warm as reboot mode default handler Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 6/8] Documentations: devicetree: bindings: document watchdog-priority Ahmad Fatoum
2022-10-17  7:09 ` [PATCH 7/8] ARM: i.MX7: describe USB serial download boot mode Ahmad Fatoum
2022-10-17  7:10 ` [PATCH 8/8] ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom Ahmad Fatoum
2022-10-18  9:13 ` [PATCH 0/8] ARM: i.MX7: add serial download reboot mode Sascha Hauer

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