summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMD Danish Anwar <danishanwar@ti.com>2024-02-15 15:19:48 +0530
committerFrancesco Dolcini <francesco.dolcini@toradex.com>2024-03-21 14:26:33 +0000
commit03ca92d09ceb2f49047c9c2bce836ba8a3cd52c4 (patch)
tree89e6867c822d907078d31f895add320cc7bf237e /drivers
parent3621c6c1409dad5edc00ee196d1e4ba690b815b0 (diff)
remoteproc: uclass: Add methods to load firmware to rproc and boot rproc
Add APIs to set a firmware_name to a rproc and boot the rproc with the same firmware. Clients can call rproc_set_firmware() API to set firmware_name for a rproc whereas rproc_boot() will load the firmware set by rproc_set_firmware() to a buffer by calling request_firmware_into_buf(). rproc_boot() will then load the firmware file to the remote processor and start the remote processor. Also include "fs-loader.h" and make remoteproc driver select FS_LOADER in Kconfig so that we can call request_firmware_into_buf() from remoteproc driver. Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/remoteproc/Kconfig8
-rw-r--r--drivers/remoteproc/rproc-uclass.c102
2 files changed, 110 insertions, 0 deletions
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index a7740954c0..3e921b981b 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -10,6 +10,7 @@ menu "Remote Processor drivers"
# All users should depend on DM
config REMOTEPROC
bool
+ select FS_LOADER
depends on DM
# Please keep the configuration alphabetically sorted.
@@ -113,4 +114,11 @@ config REMOTEPROC_TI_IPU
help
Say 'y' here to add support for TI' K3 remoteproc driver.
+config REMOTEPROC_MAX_FW_SIZE
+ hex "Maximum size of firmware that needs to be loaded to rproc"
+ default 0x10000
+ help
+ Maximum size of the firmware file (elf, binary) that needs to be
+ loaded to th rproc core.
+
endmenu
diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c
index 50bcc9030e..da8f6d5dd9 100644
--- a/drivers/remoteproc/rproc-uclass.c
+++ b/drivers/remoteproc/rproc-uclass.c
@@ -11,8 +11,11 @@
#include <elf.h>
#include <errno.h>
#include <log.h>
+#include <fs.h>
+#include <env.h>
#include <malloc.h>
#include <virtio_ring.h>
+#include <fs_loader.h>
#include <remoteproc.h>
#include <asm/io.h>
#include <dm/device-internal.h>
@@ -960,3 +963,102 @@ unsigned long rproc_parse_resource_table(struct udevice *dev, struct rproc *cfg)
return 1;
}
+
+int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ int len;
+ char *p;
+
+ if (!rproc_dev || !fw_name)
+ return -EINVAL;
+
+ uc_pdata = dev_get_uclass_plat(rproc_dev);
+ if (!uc_pdata)
+ return -EINVAL;
+
+ len = strcspn(fw_name, "\n");
+ if (!len) {
+ debug("invalid firmware name\n");
+ return -EINVAL;
+ }
+
+ p = strndup(fw_name, len);
+ if (!p)
+ return -ENOMEM;
+
+ uc_pdata->fw_name = p;
+
+ return 0;
+}
+
+int rproc_boot(struct udevice *rproc_dev)
+{
+ struct dm_rproc_uclass_pdata *uc_pdata;
+ struct udevice *fs_loader;
+ int core_id, ret = 0;
+ char *firmware;
+ void *addr;
+
+ if (!rproc_dev)
+ return -EINVAL;
+
+ uc_pdata = dev_get_uclass_plat(rproc_dev);
+ if (!uc_pdata)
+ return -EINVAL;
+
+ core_id = dev_seq(rproc_dev);
+ firmware = uc_pdata->fw_name;
+
+ if (!firmware) {
+ debug("No firmware set for rproc core %d\n", core_id);
+ return -EINVAL;
+ }
+
+ /* Initialize all rproc cores */
+ if (!rproc_is_initialized()) {
+ ret = rproc_init();
+ if (ret) {
+ debug("rproc_init() failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* Loading firmware to a given address */
+ ret = get_fs_loader(&fs_loader);
+ if (ret) {
+ debug("could not get fs loader: %d\n", ret);
+ return ret;
+ }
+
+ if (CONFIG_REMOTEPROC_MAX_FW_SIZE) {
+ addr = malloc(CONFIG_REMOTEPROC_MAX_FW_SIZE);
+ if (!addr)
+ return -ENOMEM;
+ } else {
+ debug("CONFIG_REMOTEPROC_MAX_FW_SIZE not defined\n");
+ return -EINVAL;
+ }
+
+ ret = request_firmware_into_buf(fs_loader, firmware, addr, CONFIG_REMOTEPROC_MAX_FW_SIZE,
+ 0);
+ if (ret < 0) {
+ debug("could not request %s: %d\n", firmware, ret);
+ goto free_buffer;
+ }
+
+ ret = rproc_load(core_id, (ulong)addr, ret);
+ if (ret) {
+ debug("failed to load %s to rproc core %d from addr 0x%08lX err %d\n",
+ uc_pdata->fw_name, core_id, (ulong)addr, ret);
+ goto free_buffer;
+ }
+
+ ret = rproc_start(core_id);
+ if (ret)
+ debug("failed to start rproc core %d\n", core_id);
+
+free_buffer:
+ free(addr);
+ return ret;
+}