From 8915a40da4298ebe69052e3538cd33f917a85351 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Tue, 4 Feb 2020 11:09:49 +0530 Subject: ARM: mach-k3: arm64-mmu: map 64bit FSS MMIO space in A53 MMU Populate address mapping entries in A53 MMU for 4 GB of MMIO space reserved for providing MMIO access to multiple flash devices through OSPI/HBMC IPs within FSS. Signed-off-by: Vignesh Raghavendra --- arch/arm/mach-k3/arm64-mmu.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64-mmu.c index 7f908eee80..b1d1d6e494 100644 --- a/arch/arm/mach-k3/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64-mmu.c @@ -49,6 +49,13 @@ struct mm_region am654_mem_map[NR_MMU_REGIONS] = { .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE + }, { + .virt = 0x500000000UL, + .phys = 0x500000000UL, + .size = 0x400000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { /* List terminator */ 0, -- cgit From 7d0866b9be660e0f885bd18c04414bb0cbffb3b7 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 4 Feb 2020 11:09:50 +0530 Subject: ARM: mach-k3: sysfw-loader: Use SPI memmapped addr when loading SYSFW Since ROM configures OSPI controller to be in memory mapped mode in OSPI boot, R5 SPL can directly pass the memory mapped pointer to ROM. With this ROM can directly pull the SYSFW image from OSPI. Signed-off-by: Lokesh Vutla Signed-off-by: Vignesh Raghavendra --- arch/arm/mach-k3/Kconfig | 8 ++++++++ arch/arm/mach-k3/sysfw-loader.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig index 8f4272286c..a13cbef9b5 100644 --- a/arch/arm/mach-k3/Kconfig +++ b/arch/arm/mach-k3/Kconfig @@ -126,6 +126,14 @@ config K3_SYSFW_IMAGE_SIZE_MAX tree blob. Keep it as tight as possible, as this directly affects the overall SPL memory footprint. +config K3_SYSFW_IMAGE_SPI_OFFS + hex "SPI offset of SYSFW firmware and configuration blob" + depends on K3_LOAD_SYSFW + default 0x6C0000 + help + Offset of the combined System Firmware and configuration image tree + blob to be loaded when booting from a SPI flash memory. + config SYS_K3_SPL_ATF bool "Start Cortex-A from SPL" depends on SPL && CPU_V7R diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index 94dbeb9437..3677a37f55 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include "common.h" @@ -197,12 +199,32 @@ exit: } #endif +#if CONFIG_IS_ENABLED(SPI_LOAD) +static void *k3_sysfw_get_spi_addr(void) +{ + struct udevice *dev; + fdt_addr_t addr; + int ret; + + ret = uclass_find_device_by_seq(UCLASS_SPI, CONFIG_SF_DEFAULT_BUS, + true, &dev); + if (ret) + return NULL; + + addr = dev_read_addr_index(dev, 1); + if (addr == FDT_ADDR_T_NONE) + return NULL; + + return (void *)(addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS); +} +#endif + void k3_sysfw_loader(void (*config_pm_done_callback)(void)) { struct spl_image_info spl_image = { 0 }; struct spl_boot_device bootdev = { 0 }; struct ti_sci_handle *ti_sci; - int ret; + int ret = 0; /* Reserve a block of aligned memory for loading the SYSFW image */ sysfw_load_address = memalign(ARCH_DMA_MINALIGN, @@ -243,6 +265,13 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void)) #endif break; #endif +#if CONFIG_IS_ENABLED(SPI_LOAD) + case BOOT_DEVICE_SPI: + sysfw_load_address = k3_sysfw_get_spi_addr(); + if (!sysfw_load_address) + ret = -ENODEV; + break; +#endif #if CONFIG_IS_ENABLED(YMODEM_SUPPORT) case BOOT_DEVICE_UART: #ifdef CONFIG_K3_EARLY_CONS -- cgit From 3ab34bc028e532f5b748104bd65392a575608411 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 12 Feb 2020 13:55:04 +0530 Subject: 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(-) (limited to 'arch/arm/mach-k3') 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 -- cgit From 6dce1cfa56ab269c2df67ba71d4905d9f54f95e6 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 12 Feb 2020 13:55:05 +0530 Subject: armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM Enable execute permission for mcu_r5fss0_core0 BTCM so that we can jump to a firmware directly from SPL. Signed-off-by: Keerthy --- arch/arm/mach-k3/r5_mpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/r5_mpu.c b/arch/arm/mach-k3/r5_mpu.c index ee076ed877..3d2ff6775a 100644 --- a/arch/arm/mach-k3/r5_mpu.c +++ b/arch/arm/mach-k3/r5_mpu.c @@ -26,7 +26,9 @@ struct mpu_region_config k3_mpu_regions[16] = { /* U-Boot's code area marking it as WB and Write allocate */ {CONFIG_SYS_SDRAM_BASE, REGION_2, XN_DIS, PRIV_RW_USR_RW, O_I_WB_RD_WR_ALLOC, REGION_2GB}, - {0x0, 3, 0x0, 0x0, 0x0, 0x0}, + /* mcu_r5fss0_core0 BTCM area marking it as WB and Write allocate. */ + {0x41010000, 3, XN_DIS, PRIV_RW_USR_RW, O_I_WB_RD_WR_ALLOC, + REGION_8MB}, {0x0, 4, 0x0, 0x0, 0x0, 0x0}, {0x0, 5, 0x0, 0x0, 0x0, 0x0}, {0x0, 6, 0x0, 0x0, 0x0, 0x0}, -- cgit From d154252fc9bbc48c0cfb4b8e655ac6ea40ad166a Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 12 Feb 2020 13:55:06 +0530 Subject: armv7R: K3: Add support for jumping to firmware MCU Domain rf50 is currently shutting down after loading the ATF. Load elf firmware and jump to firmware post loading ATF. ROM doesn't enable ATCM memory, so make sure that firmware that is being loaded doesn't use ATCM memory or override SPL. Signed-off-by: Keerthy Signed-off-by: Lokesh Vutla --- arch/arm/mach-k3/common.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index a4c99f17e7..b2d25edc7e 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -132,8 +132,10 @@ __weak void start_non_linux_remote_cores(void) void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { + typedef void __noreturn (*image_entry_noargs_t)(void); struct ti_sci_handle *ti_sci = get_ti_sci_handle(); - int ret; + u32 loadaddr = 0; + int ret, size; /* Release all the exclusive devices held by SPL before starting ATF */ ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci); @@ -144,6 +146,9 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) init_env(); start_non_linux_remote_cores(); + size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load", + &loadaddr); + /* * It is assumed that remoteproc device 1 is the corresponding @@ -159,13 +164,18 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) ret = rproc_start(1); if (ret) panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); + if (!(size > 0 && valid_elf_image(loadaddr))) { + debug("Shutting down...\n"); + release_resources_for_core_shutdown(); + + while (1) + asm volatile("wfe"); + } - debug("Releasing resources...\n"); - release_resources_for_core_shutdown(); + image_entry_noargs_t image_entry = + (image_entry_noargs_t)load_elf_image_phdr(loadaddr); - debug("Finalizing core shutdown...\n"); - while (1) - asm volatile("wfe"); + image_entry(); } #endif -- cgit From 6e44aebdbb96e9465ec874b926fa108fd10d9b59 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 10 Mar 2020 16:50:58 +0530 Subject: arm: mach-k3: Add a separate function for printing sysfw version Add a separate function for printing sysfw version so that it can be called independently of k3_sysfw_loader. Signed-off-by: Lokesh Vutla Signed-off-by: Vignesh Raghavendra --- arch/arm/mach-k3/am6_init.c | 9 +++++---- arch/arm/mach-k3/common.c | 22 ++++++++++++++++++++++ arch/arm/mach-k3/common.h | 1 + arch/arm/mach-k3/j721e_init.c | 3 +++ arch/arm/mach-k3/sysfw-loader.c | 18 ------------------ 5 files changed, 31 insertions(+), 22 deletions(-) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index 63cd7e0458..0f739818f6 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -133,10 +133,8 @@ void board_init_f(ulong dummy) pinctrl_select_state(dev, "default"); /* - * Load, start up, and configure system controller firmware. Provide - * the U-Boot console init function to the SYSFW post-PM configuration - * callback hook, effectively switching on (or over) the console - * output. + * Load, start up, and configure system controller firmware while + * also populating the SYSFW post-PM configuration callback hook. */ k3_sysfw_loader(preloader_console_init); @@ -150,6 +148,9 @@ void board_init_f(ulong dummy) preloader_console_init(); #endif + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + /* Perform EEPROM-based board detection */ do_board_detect(); diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index b2d25edc7e..efd84ec7eb 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -35,6 +35,28 @@ struct ti_sci_handle *get_ti_sci_handle(void) return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev); } +void k3_sysfw_print_ver(void) +{ + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); + char fw_desc[sizeof(ti_sci->version.firmware_description) + 1]; + + /* + * Output System Firmware version info. Note that since the + * 'firmware_description' field is not guaranteed to be zero- + * terminated we manually add a \0 terminator if needed. Further + * note that we intentionally no longer rely on the extended + * printf() formatter '%.*s' to not having to require a more + * full-featured printf() implementation. + */ + strncpy(fw_desc, ti_sci->version.firmware_description, + sizeof(ti_sci->version.firmware_description)); + fw_desc[sizeof(fw_desc) - 1] = '\0'; + + printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n", + ti_sci->version.abi_major, ti_sci->version.abi_minor, + ti_sci->version.firmware_revision, fw_desc); +} + DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_K3_EARLY_CONS diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 42fb8ee6e7..b1cbe116ef 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -26,3 +26,4 @@ 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); +void k3_sysfw_print_ver(void); diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c index 13f3791823..511cfd2fab 100644 --- a/arch/arm/mach-k3/j721e_init.c +++ b/arch/arm/mach-k3/j721e_init.c @@ -172,6 +172,9 @@ void board_init_f(ulong dummy) preloader_console_init(); #endif + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + /* Perform EEPROM-based board detection */ do_board_detect(); diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index 3677a37f55..0229491493 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -330,22 +330,4 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void)) */ if (config_pm_done_callback) config_pm_done_callback(); - - /* - * Output System Firmware version info. Note that since the - * 'firmware_description' field is not guaranteed to be zero- - * terminated we manually add a \0 terminator if needed. Further - * note that we intentionally no longer rely on the extended - * printf() formatter '%.*s' to not having to require a more - * full-featured printf() implementation. - */ - char fw_desc[sizeof(ti_sci->version.firmware_description) + 1]; - - strncpy(fw_desc, ti_sci->version.firmware_description, - sizeof(ti_sci->version.firmware_description)); - fw_desc[sizeof(fw_desc) - 1] = '\0'; - - printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n", - ti_sci->version.abi_major, ti_sci->version.abi_minor, - ti_sci->version.firmware_revision, fw_desc); } -- cgit From 8f4109e09dd78ea31e8177b9904fcfde60e7e23e Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 10 Mar 2020 16:05:55 -0500 Subject: armv8: K3: j721e: Add DSP internal memory regions in MMU table The A72 U-Boot code supports early load and boot of a number of remote processors including the C66_0 and C66_1 DSPs. The current code supports only loading into the DDR regions which were already given the appropriate memory attributes. The C66 DSPs also have L1 and L2 internal memory regions that can behave as normal-memories. Add a new entry to the J721E MMU table covering these regions with the appropriate memory attributes to allow the A72 U-Boot code to support loading directly into these memory regions. Signed-off-by: Suman Anna --- arch/arm/mach-k3/arm64-mmu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-k3') diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64-mmu.c index b1d1d6e494..95f830b7ff 100644 --- a/arch/arm/mach-k3/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64-mmu.c @@ -67,7 +67,7 @@ struct mm_region *mem_map = am654_mem_map; #ifdef CONFIG_SOC_K3_J721E /* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */ -#define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 5) +#define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 6) /* ToDo: Add 64bit IO */ struct mm_region j721e_mem_map[NR_MMU_REGIONS] = { @@ -109,6 +109,12 @@ struct mm_region j721e_mem_map[NR_MMU_REGIONS] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x4d80000000UL, + .phys = 0x4d80000000UL, + .size = 0x0002000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE }, { /* List terminator */ 0, -- cgit