mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/2] remoteproc: register a device for new remoteproc instances
@ 2019-11-20  8:35 Ahmad Fatoum
  2019-11-20  8:35 ` [PATCH 2/2] remoteproc: add support for starting st,stm32mp1-m4 Ahmad Fatoum
  2019-11-25  8:08 ` [PATCH 1/2] remoteproc: register a device for new remoteproc instances Sascha Hauer
  0 siblings, 2 replies; 3+ messages in thread
From: Ahmad Fatoum @ 2019-11-20  8:35 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

struct rproc has a device_d dev field, but so far it was unregistered.
The implementation had a few downsides:

- dev_printf prints NULL, because the unique_name of the device is NULL
- The name used by firmwareload is the device tree node's name, which
  might be unnecessarily verbose, e.g. mlahb:m4@10000000.of
- All remoteproc devices are given the same (unused) name and index

Fix these by registering a device for the remoteproc and using it where
appropriate. While at it, allow the remoteproc name to come from a
device tree alias as well.

This breaks user behavior in that firmwareload now uses the alias or
remoteprocN to reference the remoteproc instance. This is probably
acceptable as the driver is a very recent addition.

Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/remoteproc/remoteproc_core.c | 29 ++++++++++++++++++++++------
 include/linux/remoteproc.h           |  1 -
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 7cac47e06ce9..8a28c1bafc1b 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -107,14 +107,36 @@ static int rproc_firmware_finish(struct firmware_handler *fh)
 	return ret;
 }
 
+static int rproc_register_dev(struct rproc *rproc, const char *alias)
+{
+	if (alias) {
+		rproc->dev.id = DEVICE_ID_SINGLE;
+		dev_set_name(&rproc->dev, alias);
+	} else {
+		rproc->dev.id = DEVICE_ID_DYNAMIC;
+		dev_set_name(&rproc->dev, "remoteproc");
+	}
+
+	return register_device(&rproc->dev);
+}
+
 int rproc_add(struct rproc *rproc)
 {
 	struct device_d *dev = &rproc->dev;
 	struct firmware_handler *fh;
+	const char *alias = NULL;
 	int ret;
 
+	if (dev->device_node)
+		alias = of_alias_get(dev->device_node);
+
+	ret = rproc_register_dev(rproc, alias);
+	if (ret)
+		return ret;
+
 	fh = &rproc->fh;
-	fh->id = xstrdup(rproc->name);
+	fh->id = xstrdup(dev_name(dev));
+	fh->model = xstrdup(rproc->name);
 	fh->open = rproc_firmware_start;
 	fh->write = rproc_firmware_write_buf;
 	fh->close = rproc_firmware_finish;
@@ -153,11 +175,6 @@ struct rproc *rproc_alloc(struct device_d *dev, const char *name,
 	rproc->dev.parent = dev;
 	rproc->dev.priv = rproc;
 
-	/* Assign a unique device index and name */
-	rproc->index = 1;
-
-	dev_set_name(&rproc->dev, "remoteproc%d", rproc->index);
-
 	/* Default to ELF loader if no load function is specified */
 	if (!rproc->ops->load)
 		rproc->ops->load = rproc_elf_load_segments;
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index feee9ee4eea7..c6264d1c0a49 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -38,7 +38,6 @@ struct rproc {
 	void *priv;
 	struct rproc_ops *ops;
 	struct device_d dev;
-	int index;
 
 	void *fw_buf;
 	size_t fw_buf_ofs;
-- 
2.20.1


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

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

* [PATCH 2/2] remoteproc: add support for starting st,stm32mp1-m4
  2019-11-20  8:35 [PATCH 1/2] remoteproc: register a device for new remoteproc instances Ahmad Fatoum
@ 2019-11-20  8:35 ` Ahmad Fatoum
  2019-11-25  8:08 ` [PATCH 1/2] remoteproc: register a device for new remoteproc instances Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Ahmad Fatoum @ 2019-11-20  8:35 UTC (permalink / raw)
  To: barebox

The STM32MP157C-DK2 has a Cortex-M4 MCU in addition to the two Cortex-A7
MPUs. This remoteproc driver allows barebox running on a Cortex-A7 core
to bootstrap the MCU with an ELF binary.

Code ported from Linux v5.3 with rpmsg bits removed.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/remoteproc/Kconfig       |  10 ++
 drivers/remoteproc/Makefile      |   1 +
 drivers/remoteproc/stm32_rproc.c | 199 +++++++++++++++++++++++++++++++
 3 files changed, 210 insertions(+)
 create mode 100644 drivers/remoteproc/stm32_rproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 8139b6442cc8..a193fadb69a9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -21,6 +21,16 @@ config IMX_REMOTEPROC
 
 	  It's safe to say N here.
 
+config STM32_REMOTEPROC
+	tristate "STM32 remoteproc support"
+	depends on ARCH_STM32MP
+	select MFD_SYSCON
+	help
+	  Say y here to support STM32 MCU processors via the
+	  remote processor framework.
+
+	  It's safe to say N here.
+
 endif # REMOTEPROC
 
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 107296922998..43658df5c6ac 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -5,3 +5,4 @@
 
 obj-$(CONFIG_REMOTEPROC)		+= remoteproc_core.o remoteproc_elf_loader.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
+obj-$(CONFIG_STM32_REMOTEPROC)		+= stm32_rproc.o
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
new file mode 100644
index 000000000000..bfd4d5976850
--- /dev/null
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Authors: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ *          Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
+ * Copyright (C) 2019 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <io.h>
+#include <mach/smc.h>
+#include <mfd/syscon.h>
+#include <of_address.h>
+#include <regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+#include "remoteproc_internal.h"
+
+#define HOLD_BOOT		0
+#define RELEASE_BOOT		1
+
+struct stm32_syscon {
+	struct regmap *map;
+	u32 reg;
+	u32 mask;
+};
+
+struct stm32_rproc {
+	struct reset_control *rst;
+	struct stm32_syscon hold_boot;
+	bool secured_soc;
+};
+
+static void *stm32_rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	__be32 in_addr = cpu_to_be32(da);
+	struct device_d *dev = &rproc->dev;
+	u64 paddr;
+
+	paddr = of_translate_dma_address(dev->parent->device_node, &in_addr);
+	if (paddr == OF_BAD_ADDR)
+		return NULL;
+
+	return phys_to_virt(paddr);
+}
+
+static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	struct stm32_syscon *hold_boot = &ddata->hold_boot;
+	struct arm_smccc_res smc_res;
+	int val, err;
+
+	val = hold ? HOLD_BOOT : RELEASE_BOOT;
+
+	if (IS_ENABLED(CONFIG_ARM_SMCC) && ddata->secured_soc) {
+		arm_smccc_smc(STM32_SMC_RCC, STM32_SMC_REG_WRITE,
+			      hold_boot->reg, val, 0, 0, 0, 0, &smc_res);
+		err = smc_res.a0;
+	} else {
+		err = regmap_update_bits(hold_boot->map, hold_boot->reg,
+					 hold_boot->mask, val);
+	}
+
+	if (err)
+		dev_err(&rproc->dev, "failed to set hold boot\n");
+
+	return err;
+}
+
+static int stm32_rproc_start(struct rproc *rproc)
+{
+	int err;
+
+	err = stm32_rproc_set_hold_boot(rproc, false);
+	if (err)
+		return err;
+
+	return stm32_rproc_set_hold_boot(rproc, true);
+}
+
+static int stm32_rproc_stop(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	int err;
+
+	err = stm32_rproc_set_hold_boot(rproc, true);
+	if (err)
+		return err;
+
+	err = reset_control_assert(ddata->rst);
+	if (err) {
+		dev_err(&rproc->dev, "failed to assert the reset\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= stm32_rproc_start,
+	.stop		= stm32_rproc_stop,
+	.da_to_va	= stm32_rproc_da_to_va,
+};
+
+static int stm32_rproc_get_syscon(struct device_node *np, const char *prop,
+				  struct stm32_syscon *syscon)
+{
+	int err = 0;
+
+	syscon->map = syscon_regmap_lookup_by_phandle(np, prop);
+	if (IS_ERR(syscon->map)) {
+		err = PTR_ERR(syscon->map);
+		syscon->map = NULL;
+		goto out;
+	}
+
+	err = of_property_read_u32_index(np, prop, 1, &syscon->reg);
+	if (err)
+		goto out;
+
+	err = of_property_read_u32_index(np, prop, 2, &syscon->mask);
+
+out:
+	return err;
+}
+
+static int stm32_rproc_parse_dt(struct device_d *dev, struct stm32_rproc *ddata)
+{
+	struct device_node *np = dev->device_node;
+	struct stm32_syscon tz;
+	unsigned int tzen;
+	int err;
+
+	ddata->rst = reset_control_get(dev, NULL);
+	if (IS_ERR(ddata->rst)) {
+		dev_err(dev, "failed to get mcu reset\n");
+		return PTR_ERR(ddata->rst);
+	}
+
+	/*
+	 * if platform is secured the hold boot bit must be written by
+	 * smc call and read normally.
+	 * if not secure the hold boot bit could be read/write normally
+	 */
+	err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz);
+	if (err) {
+		dev_err(dev, "failed to get tz syscfg\n");
+		return err;
+	}
+
+	err = regmap_read(tz.map, tz.reg, &tzen);
+	if (err) {
+		dev_err(dev, "failed to read tzen\n");
+		return err;
+	}
+	ddata->secured_soc = tzen & tz.mask;
+
+	err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot",
+				     &ddata->hold_boot);
+	if (err) {
+		dev_err(dev, "failed to get hold boot\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int stm32_rproc_probe(struct device_d *dev)
+{
+	struct rproc *rproc;
+	int ret;
+
+	rproc = rproc_alloc(dev, dev_name(dev), &st_rproc_ops,
+			    sizeof(struct stm32_rproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	ret = stm32_rproc_parse_dt(dev, rproc->priv);
+	if (ret)
+		return ret;
+
+	return rproc_add(rproc);
+}
+
+static const struct of_device_id stm32_rproc_of_match[] = {
+	{ .compatible = "st,stm32mp1-m4" },
+	{ /* sentinel */ },
+};
+
+static struct driver_d stm32_rproc_driver = {
+	.name = "stm32-rproc",
+	.probe = stm32_rproc_probe,
+	.of_compatible = DRV_OF_COMPAT(stm32_rproc_of_match),
+};
+device_platform_driver(stm32_rproc_driver);
-- 
2.20.1


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

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

* Re: [PATCH 1/2] remoteproc: register a device for new remoteproc instances
  2019-11-20  8:35 [PATCH 1/2] remoteproc: register a device for new remoteproc instances Ahmad Fatoum
  2019-11-20  8:35 ` [PATCH 2/2] remoteproc: add support for starting st,stm32mp1-m4 Ahmad Fatoum
@ 2019-11-25  8:08 ` Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2019-11-25  8:08 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox, Oleksij Rempel

On Wed, Nov 20, 2019 at 09:35:36AM +0100, Ahmad Fatoum wrote:
> struct rproc has a device_d dev field, but so far it was unregistered.
> The implementation had a few downsides:
> 
> - dev_printf prints NULL, because the unique_name of the device is NULL
> - The name used by firmwareload is the device tree node's name, which
>   might be unnecessarily verbose, e.g. mlahb:m4@10000000.of
> - All remoteproc devices are given the same (unused) name and index
> 
> Fix these by registering a device for the remoteproc and using it where
> appropriate. While at it, allow the remoteproc name to come from a
> device tree alias as well.
> 
> This breaks user behavior in that firmwareload now uses the alias or
> remoteprocN to reference the remoteproc instance. This is probably
> acceptable as the driver is a very recent addition.
> 
> Cc: Oleksij Rempel <o.rempel@pengutronix.de>
> Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
> ---
>  drivers/remoteproc/remoteproc_core.c | 29 ++++++++++++++++++++++------
>  include/linux/remoteproc.h           |  1 -
>  2 files changed, 23 insertions(+), 7 deletions(-)

Applied, thanks

Sascha

-- 
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 |

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

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

end of thread, other threads:[~2019-11-25  8:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-20  8:35 [PATCH 1/2] remoteproc: register a device for new remoteproc instances Ahmad Fatoum
2019-11-20  8:35 ` [PATCH 2/2] remoteproc: add support for starting st,stm32mp1-m4 Ahmad Fatoum
2019-11-25  8:08 ` [PATCH 1/2] remoteproc: register a device for new remoteproc instances Sascha Hauer

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