All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Levinsky <ben.levinsky@amd.com>
To: <andersson@kernel.org>, <mathieu.poirier@linaro.org>
Cc: <robh@kernel.org>, <krzk+dt@kernel.org>, <conor+dt@kernel.org>,
	<linux-remoteproc@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <ben.levinsky@amd.com>,
	<tanmay.shah@amd.com>, <michal.simek@amd.com>
Subject: [PATCH 2/2] remoteproc: add AMD MicroBlaze driver
Date: Tue, 14 Apr 2026 09:15:58 -0700	[thread overview]
Message-ID: <20260414161558.2579920-3-ben.levinsky@amd.com> (raw)
In-Reply-To: <20260414161558.2579920-1-ben.levinsky@amd.com>

 Add an AMD MicroBlaze remoteproc driver.

 The driver parses the executable firmware memory window from
 the remoteproc device node's reg property, interprets that
 address and size in the MicroBlaze-local address space, and
 then uses standard devicetree address translation through the
 parent bus ranges property to obtain the corresponding
 Linux-visible system physical address.

 The resulting translated region is registered as the executable
 remoteproc carveout and coredump segment.

 The MicroBlaze is controlled through an active-low reset GPIO and kept in
 reset until firmware loading completes.

 The firmware-name property is optional, allowing firmware to be
 assigned later through the remoteproc framework.

Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
---
 MAINTAINERS                               |   7 +
 drivers/remoteproc/Kconfig                |  15 ++
 drivers/remoteproc/Makefile               |   1 +
 drivers/remoteproc/amd_microblaze_rproc.c | 202 ++++++++++++++++++++++
 4 files changed, 225 insertions(+)
 create mode 100644 drivers/remoteproc/amd_microblaze_rproc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a7e30df8ba5d..a70397b9ca71 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1172,6 +1172,13 @@ F:	drivers/gpu/drm/amd/include/vi_structs.h
 F:	include/uapi/linux/kfd_ioctl.h
 F:	include/uapi/linux/kfd_sysfs.h
 
+AMD MICROBLAZE REMOTEPROC DRIVER
+M:	Ben Levinsky <ben.levinsky@amd.com>
+L:	linux-remoteproc@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/remoteproc/amd,microblaze.yaml
+F:	drivers/remoteproc/amd_microblaze_rproc.c
+
 AMD MP2 I2C DRIVER
 M:	Elie Morisse <syniurge@gmail.com>
 M:	Shyam Sundar S K <shyam-sundar.s-k@amd.com>
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index ee54436fea5a..76de743241a7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -23,6 +23,21 @@ config REMOTEPROC_CDEV
 
 	  It's safe to say N if you don't want to use this interface.
 
+config AMD_MICROBLAZE_REMOTEPROC
+	tristate "AMD MicroBlaze remoteproc support"
+	depends on OF
+	depends on GPIOLIB || COMPILE_TEST
+	help
+	  Say y or m here to support a MicroBlaze remote processor controlled
+	  by Linux through the remoteproc framework.
+
+	  This driver matches designs where executable firmware memory is
+	  described in the MicroBlaze-local address space and translated to
+	  the system physical address space with standard devicetree address
+	  translation.
+
+	  If unsure, say N.
+
 config IMX_REMOTEPROC
 	tristate "i.MX remoteproc support"
 	depends on ARCH_MXC
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 1c7598b8475d..8717a0aec2e6 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,6 +11,7 @@ remoteproc-y				+= remoteproc_sysfs.o
 remoteproc-y				+= remoteproc_virtio.o
 remoteproc-y				+= remoteproc_elf_loader.o
 obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
+obj-$(CONFIG_AMD_MICROBLAZE_REMOTEPROC)	+= amd_microblaze_rproc.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
 obj-$(CONFIG_IMX_DSP_REMOTEPROC)	+= imx_dsp_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
diff --git a/drivers/remoteproc/amd_microblaze_rproc.c b/drivers/remoteproc/amd_microblaze_rproc.c
new file mode 100644
index 000000000000..c664a70d246b
--- /dev/null
+++ b/drivers/remoteproc/amd_microblaze_rproc.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD MicroBlaze Remote Processor driver
+ *
+ * Copyright (C) 2026 Advanced Micro Devices, Inc.
+ *
+ * This driver supports a MicroBlaze remote processor managed by Linux
+ * through the remoteproc framework.
+ *
+ * The executable firmware memory is described in the MicroBlaze-local
+ * address space and translated to the Linux-visible system physical
+ * address with standard devicetree address translation.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+
+#include "remoteproc_internal.h"
+
+struct mb_rproc {
+	struct device *dev;
+	struct gpio_desc *reset;
+};
+
+static int mb_rproc_mem_region_map(struct rproc *rproc,
+				   struct rproc_mem_entry *mem)
+{
+	void __iomem *va;
+
+	va = ioremap_wc(mem->dma, mem->len);
+	if (!va)
+		return -ENOMEM;
+
+	mem->va = (__force void *)va;
+	mem->is_iomem = true;
+
+	return 0;
+}
+
+static int mb_rproc_mem_region_unmap(struct rproc *rproc,
+				     struct rproc_mem_entry *mem)
+{
+	iounmap((void __iomem *)mem->va);
+
+	return 0;
+}
+
+static int mb_rproc_prepare(struct rproc *rproc)
+{
+	struct mb_rproc *mb = rproc->priv;
+	struct rproc_mem_entry *mem;
+	struct resource res;
+	u64 da, size;
+	int ret;
+
+	ret = of_property_read_reg(mb->dev->of_node, 0, &da, &size);
+	if (ret) {
+		dev_err(mb->dev, "failed to parse executable memory reg\n");
+		return ret;
+	}
+
+	if (!size || size > U32_MAX) {
+		dev_err(mb->dev, "invalid executable memory size\n");
+		return -EINVAL;
+	}
+
+	ret = of_address_to_resource(mb->dev->of_node, 0, &res);
+	if (ret) {
+		dev_err(mb->dev, "failed to translate executable memory reg\n");
+		return ret;
+	}
+
+	mem = rproc_mem_entry_init(mb->dev, NULL, (dma_addr_t)res.start,
+				   (size_t)size, da,
+				   mb_rproc_mem_region_map,
+				   mb_rproc_mem_region_unmap,
+				   dev_name(mb->dev));
+	if (!mem)
+		return -ENOMEM;
+
+	rproc_add_carveout(rproc, mem);
+	rproc_coredump_add_segment(rproc, da, (size_t)size);
+
+	return 0;
+}
+
+static int mb_rproc_start(struct rproc *rproc)
+{
+	struct mb_rproc *mb = rproc->priv;
+
+	/* reset-gpios is declared active-low, so logical 0 releases reset */
+	gpiod_set_value_cansleep(mb->reset, 0);
+
+	return 0;
+}
+
+static int mb_rproc_stop(struct rproc *rproc)
+{
+	struct mb_rproc *mb = rproc->priv;
+
+	/* reset-gpios is declared active-low, so logical 1 asserts reset */
+	gpiod_set_value_cansleep(mb->reset, 1);
+
+	return 0;
+}
+
+static int mb_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	int ret;
+
+	ret = rproc_elf_load_rsc_table(rproc, fw);
+	if (ret == -EINVAL) {
+		dev_dbg(&rproc->dev, "no resource table found\n");
+		return 0;
+	}
+
+	return ret;
+}
+
+static const struct rproc_ops mb_rproc_ops = {
+	.prepare	= mb_rproc_prepare,
+	.start		= mb_rproc_start,
+	.stop		= mb_rproc_stop,
+	.load		= rproc_elf_load_segments,
+	.sanity_check	= rproc_elf_sanity_check,
+	.get_boot_addr	= rproc_elf_get_boot_addr,
+	.parse_fw	= mb_rproc_parse_fw,
+};
+
+static int mb_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mb_rproc *mb;
+	struct rproc *rproc;
+	const char *fw_name = NULL;
+	int ret;
+
+	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
+	if (ret < 0 && ret != -EINVAL)
+		return dev_err_probe(dev, ret,
+				     "failed to parse firmware-name property\n");
+
+	rproc = devm_rproc_alloc(dev, dev_name(dev), &mb_rproc_ops, fw_name,
+				 sizeof(*mb));
+	if (!rproc)
+		return -ENOMEM;
+
+	mb = rproc->priv;
+	mb->dev = dev;
+
+	/*
+	 * Keep the MicroBlaze in reset until remoteproc has finished loading
+	 * firmware into the executable memory window described by reg and
+	 * translated through the parent bus ranges property.
+	 */
+	mb->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(mb->reset))
+		return dev_err_probe(dev, PTR_ERR(mb->reset),
+				     "failed to get reset gpio\n");
+
+	rproc->auto_boot = false;
+
+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to set DMA mask\n");
+
+	platform_set_drvdata(pdev, rproc);
+
+	ret = devm_rproc_add(dev, rproc);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register rproc\n");
+
+	dev_dbg(dev, "MicroBlaze remoteproc registered\n");
+
+	return 0;
+}
+
+static const struct of_device_id mb_rproc_of_match[] = {
+	{ .compatible = "amd,microblaze" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mb_rproc_of_match);
+
+static struct platform_driver mb_rproc_driver = {
+	.probe = mb_rproc_probe,
+	.driver = {
+		.name = "amd-microblaze-rproc",
+		.of_match_table = mb_rproc_of_match,
+	},
+};
+module_platform_driver(mb_rproc_driver);
+
+MODULE_DESCRIPTION("AMD MicroBlaze Remote Processor driver");
+MODULE_AUTHOR("Ben Levinsky");
+MODULE_LICENSE("GPL");
-- 
2.34.1


  parent reply	other threads:[~2026-04-14 16:16 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-14 16:15 [PATCH 0/2] Add a MicroBlaze remoteproc driver and binding Ben Levinsky
2026-04-14 16:15 ` [PATCH 1/2] dt-bindings: remoteproc: add AMD MicroBlaze binding Ben Levinsky
2026-04-14 17:29   ` Rob Herring (Arm)
2026-04-14 17:53   ` Krzysztof Kozlowski
2026-04-15  6:16     ` Michal Simek
2026-04-15  6:50       ` Krzysztof Kozlowski
2026-04-15  6:55         ` Michal Simek
2026-04-15  7:07           ` Krzysztof Kozlowski
2026-04-15  8:06             ` Michal Simek
2026-04-15  8:24               ` Krzysztof Kozlowski
2026-04-15  8:35                 ` Michal Simek
2026-04-15 12:19       ` Rob Herring
2026-04-15 12:41         ` Michal Simek
2026-04-14 16:15 ` Ben Levinsky [this message]
2026-04-14 17:56   ` [PATCH 2/2] remoteproc: add AMD MicroBlaze driver Krzysztof Kozlowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260414161558.2579920-3-ben.levinsky@amd.com \
    --to=ben.levinsky@amd.com \
    --cc=andersson@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=michal.simek@amd.com \
    --cc=robh@kernel.org \
    --cc=tanmay.shah@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.