From patchwork Fri Jan 10 10:23:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "J, KEERTHY" X-Patchwork-Id: 239383 List-Id: U-Boot discussion From: j-keerthy at ti.com (Keerthy) Date: Fri, 10 Jan 2020 15:53:26 +0530 Subject: [PATCH 03/10] arm: k3: Add support for loading non linux remote cores In-Reply-To: <20200110102333.22767-1-j-keerthy@ti.com> References: <20200110102333.22767-1-j-keerthy@ti.com> Message-ID: <20200110102333.22767-4-j-keerthy@ti.com> 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 50f5b81dfe..377fcbe80b 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -16,6 +16,10 @@ #include #include #include +#include +#include +#include +#include struct ti_sci_handle *get_ti_sci_handle(void) { @@ -57,6 +61,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_load(); + 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(); @@ -65,15 +137,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 35d1609cdc..f6a1e3aa01 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -17,3 +17,5 @@ void setup_k3_mpu_regions(void); int early_console_init(void); void disable_linefill_optimization(void); +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 4758739266..e9ca5baf8f 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 static void mmr_unlock(u32 base, u32 partition) @@ -240,3 +241,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("mainr5f0_0fwname", "mainr5f0_0loadaddr", + &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