From 3ab34bc028e532f5b748104bd65392a575608411 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 12 Feb 2020 13:55:04 +0530 Subject: [PATCH] arm: k3: Add support for loading non linux remote cores Add MAIN domain R5FSS0 remoteproc support from spl. This enables loading the elf firmware in SPL and starting the remotecore. In order to start the core, there should be a file with path "/lib/firmware/j7-main-r5f0_0-fw" under filesystem of respective boot mode. Signed-off-by: Keerthy Signed-off-by: Lokesh Vutla [Guard start_non_linux_remote_cores under CONFIG_FS_LOADER] Signed-off-by: Andreas Dannenberg --- arch/arm/mach-k3/common.c | 84 ++++++++++++++++++++++++++++++++--- arch/arm/mach-k3/common.h | 2 + arch/arm/mach-k3/j721e_init.c | 34 ++++++++++++++ 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 7af60a7f2f..a4c99f17e7 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -17,6 +17,10 @@ #include #include #include +#include +#include +#include +#include struct ti_sci_handle *get_ti_sci_handle(void) { @@ -58,6 +62,74 @@ int early_console_init(void) #endif #ifdef CONFIG_SYS_K3_SPL_ATF + +void init_env(void) +{ +#ifdef CONFIG_SPL_ENV_SUPPORT + char *part; + + env_init(); + env_relocate(); + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC2: + part = env_get("bootpart"); + env_set("storage_interface", "mmc"); + env_set("fw_dev_part", part); + break; + case BOOT_DEVICE_SPI: + env_set("storage_interface", "ubi"); + env_set("fw_ubi_mtdpart", "UBI"); + env_set("fw_ubi_volume", "UBI0"); + break; + default: + printf("%s from device %u not supported!\n", + __func__, spl_boot_device()); + return; + } +#endif +} + +#ifdef CONFIG_FS_LOADER +int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr) +{ + struct udevice *fsdev; + char *name = NULL; + int size = 0; + + *loadaddr = 0; +#ifdef CONFIG_SPL_ENV_SUPPORT + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC2: + name = env_get(name_fw); + *loadaddr = env_get_hex(name_loadaddr, *loadaddr); + break; + default: + printf("Loading rproc fw image from device %u not supported!\n", + spl_boot_device()); + return 0; + } +#endif + if (!*loadaddr) + return 0; + + if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) { + size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr, + 0, 0); + } + + return size; +} +#else +int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr) +{ + return 0; +} +#endif + +__weak void start_non_linux_remote_cores(void) +{ +} + void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { struct ti_sci_handle *ti_sci = get_ti_sci_handle(); @@ -66,15 +138,17 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) /* Release all the exclusive devices held by SPL before starting ATF */ ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci); + ret = rproc_init(); + if (ret) + panic("rproc failed to be initialized (%d)\n", ret); + + init_env(); + start_non_linux_remote_cores(); + /* * It is assumed that remoteproc device 1 is the corresponding * Cortex-A core which runs ATF. Make sure DT reflects the same. */ - ret = rproc_dev_init(1); - if (ret) - panic("%s: ATF failed to initialize on rproc (%d)\n", __func__, - ret); - ret = rproc_load(1, spl_image->entry_point, 0x200); if (ret) panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret); diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index d8b34fe060..42fb8ee6e7 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -24,3 +24,5 @@ void setup_k3_mpu_regions(void); int early_console_init(void); void disable_linefill_optimization(void); void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size); +void start_non_linux_remote_cores(void); +int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr); diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c index f7f7398081..13f3791823 100644 --- a/arch/arm/mach-k3/j721e_init.c +++ b/arch/arm/mach-k3/j721e_init.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_SPL_BUILD #ifdef CONFIG_K3_LOAD_SYSFW @@ -295,3 +296,36 @@ void release_resources_for_core_shutdown(void) } } #endif + +#ifdef CONFIG_SYS_K3_SPL_ATF +void start_non_linux_remote_cores(void) +{ + int size = 0, ret; + u32 loadaddr = 0; + + size = load_firmware("name_mainr5f0_0fw", "addr_mainr5f0_0load", + &loadaddr); + if (size <= 0) + goto err_load; + + /* assuming remoteproc 2 is aliased for the needed remotecore */ + ret = rproc_load(2, loadaddr, size); + if (ret) { + printf("Firmware failed to start on rproc (%d)\n", ret); + goto err_load; + } + + ret = rproc_start(2); + if (ret) { + printf("Firmware init failed on rproc (%d)\n", ret); + goto err_load; + } + + printf("Remoteproc 2 started successfully\n"); + + return; + +err_load: + rproc_reset(2); +} +#endif -- 2.39.5