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