From 5bc0a260d13cf1bf88008c3fe7652c76378b8190 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:43 -0600 Subject: [PATCH 01/12] arm: mach-k3: Move SYS_K3_SPL_ATF definition into R5 Kconfig Loading ATF is only supported from the R5, move the Kconfig symbol definition to match. Signed-off-by: Andrew Davis Reviewed-by: Igor Opaniuk --- arch/arm/mach-k3/Kconfig | 7 ------- arch/arm/mach-k3/r5/Kconfig | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig index fdde67c2d39..cb83bd20258 100644 --- a/arch/arm/mach-k3/Kconfig +++ b/arch/arm/mach-k3/Kconfig @@ -116,13 +116,6 @@ config K3_EARLY_CONS_IDX Use this option to set the index of the serial device to be used for the early console during SPL execution. -config SYS_K3_SPL_ATF - bool "Start Cortex-A from SPL" - depends on CPU_V7R - help - Enabling this will try to start Cortex-A (typically with ATF) - after SPL from R5. - config K3_ATF_LOAD_ADDR hex "Load address of ATF image" default 0x70000000 diff --git a/arch/arm/mach-k3/r5/Kconfig b/arch/arm/mach-k3/r5/Kconfig index ae79f8ff6cd..317a6c4b67e 100644 --- a/arch/arm/mach-k3/r5/Kconfig +++ b/arch/arm/mach-k3/r5/Kconfig @@ -43,3 +43,9 @@ config K3_SYSFW_IMAGE_SPI_OFFS 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" + help + Enabling this will try to start Cortex-A (typically with ATF) + after SPL from R5. From 3e572c9bed167b619d5732fb2095196ec7c29035 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:44 -0600 Subject: [PATCH 02/12] arm: mach-k3: Move disable_linefill_optimization() into R5 directory The disable_linefill_optimization() function is only ever loaded by the R5 core, move the code into the R5 directory. Signed-off-by: Andrew Davis Reviewed-by: Igor Opaniuk --- arch/arm/mach-k3/common.c | 25 ------------------------- arch/arm/mach-k3/r5/Makefile | 1 + arch/arm/mach-k3/r5/common.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 arch/arm/mach-k3/r5/common.c diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index f411366778f..5d53efed85b 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -453,31 +453,6 @@ void board_prep_linux(struct bootm_headers *images) } #endif -#ifdef CONFIG_CPU_V7R -void disable_linefill_optimization(void) -{ - u32 actlr; - - /* - * On K3 devices there are 2 conditions where R5F can deadlock: - * 1.When software is performing series of store operations to - * cacheable write back/write allocate memory region and later - * on software execute barrier operation (DSB or DMB). R5F may - * hang at the barrier instruction. - * 2.When software is performing a mix of load and store operations - * within a tight loop and store operations are all writing to - * cacheable write back/write allocates memory regions, R5F may - * hang at one of the load instruction. - * - * To avoid the above two conditions disable linefill optimization - * inside Cortex R5F. - */ - asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr)); - actlr |= (1 << 13); /* Set DLFO bit */ - asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); -} -#endif - static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions, enum k3_firewall_region_type fwl_type) { diff --git a/arch/arm/mach-k3/r5/Makefile b/arch/arm/mach-k3/r5/Makefile index b666ed34d10..ef0bf39d450 100644 --- a/arch/arm/mach-k3/r5/Makefile +++ b/arch/arm/mach-k3/r5/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SOC_K3_AM625) += am62x/ obj-$(CONFIG_SOC_K3_AM62A7) += am62ax/ obj-$(CONFIG_SOC_K3_J784S4) += j784s4/ +obj-y += common.o obj-y += lowlevel_init.o obj-y += r5_mpu.o diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c new file mode 100644 index 00000000000..ef81f50c6c7 --- /dev/null +++ b/arch/arm/mach-k3/r5/common.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * K3: R5 Common Architecture initialization + * + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include +#include +#include + +#include "../common.h" + +void disable_linefill_optimization(void) +{ + u32 actlr; + + /* + * On K3 devices there are 2 conditions where R5F can deadlock: + * 1.When software is performing series of store operations to + * cacheable write back/write allocate memory region and later + * on software execute barrier operation (DSB or DMB). R5F may + * hang at the barrier instruction. + * 2.When software is performing a mix of load and store operations + * within a tight loop and store operations are all writing to + * cacheable write back/write allocates memory regions, R5F may + * hang at one of the load instruction. + * + * To avoid the above two conditions disable linefill optimization + * inside Cortex R5F. + */ + asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr)); + actlr |= (1 << 13); /* Set DLFO bit */ + asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); +} From b4516be351895cf2217fba7688667c1a6a827b42 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:45 -0600 Subject: [PATCH 03/12] arm: mach-k3: Move tispl.bin loading into R5 directory ATF, OPTEE, DM (tispl.bin) loading is only ever done by the R5 core, move the code into the R5 directory. Signed-off-by: Andrew Davis --- arch/arm/mach-k3/common.c | 248 +--------------------------------- arch/arm/mach-k3/r5/common.c | 249 +++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 245 deletions(-) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 5d53efed85b..8db7ca0725e 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -28,27 +28,6 @@ #include #include -#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) -enum { - IMAGE_ID_ATF, - IMAGE_ID_OPTEE, - IMAGE_ID_SPL, - IMAGE_ID_DM_FW, - IMAGE_AMT, -}; - -#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) -static const char *image_os_match[IMAGE_AMT] = { - "arm-trusted-firmware", - "tee", - "U-Boot", - "DM", -}; -#endif - -static struct image_info fit_image_info[IMAGE_AMT]; -#endif - struct ti_sci_handle *get_ti_sci_handle(void) { struct udevice *dev; @@ -128,233 +107,12 @@ int early_console_init(void) } #endif -#if IS_ENABLED(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 -} - -int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr) -{ - struct udevice *fsdev; - char *name = NULL; - int size = 0; - - if (!IS_ENABLED(CONFIG_FS_LOADER)) - return 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 (!get_fs_loader(&fsdev)) { - size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr, - 0, 0); - } - - return size; -} - -void release_resources_for_core_shutdown(void) -{ - struct ti_sci_handle *ti_sci = get_ti_sci_handle(); - struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops; - struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops; - int ret; - u32 i; - - /* Iterate through list of devices to put (shutdown) */ - for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { - u32 id = put_device_ids[i]; - - ret = dev_ops->put_device(ti_sci, id); - if (ret) - panic("Failed to put device %u (%d)\n", id, ret); - } - - /* Iterate through list of cores to put (shutdown) */ - for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { - u32 id = put_core_ids[i]; - - /* - * Queue up the core shutdown request. Note that this call - * needs to be followed up by an actual invocation of an WFE - * or WFI CPU instruction. - */ - ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); - if (ret) - panic("Failed sending core %u shutdown message (%d)\n", - id, ret); - } -} - -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(); - u32 loadaddr = 0; - int ret, size = 0, shut_cpu = 0; - - /* 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(); - - if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { - size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load", - &loadaddr); - } - - /* - * It is assumed that remoteproc device 1 is the corresponding - * Cortex-A core which runs ATF. Make sure DT reflects the same. - */ - if (!fit_image_info[IMAGE_ID_ATF].image_start) - fit_image_info[IMAGE_ID_ATF].image_start = - spl_image->entry_point; - - ret = rproc_load(1, fit_image_info[IMAGE_ID_ATF].image_start, 0x200); - if (ret) - panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret); - -#if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) && IS_ENABLED(CONFIG_SYS_K3_SPL_ATF)) - /* Authenticate ATF */ - void *image_addr = (void *)fit_image_info[IMAGE_ID_ATF].image_start; - - debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, - fit_image_info[IMAGE_ID_ATF].image_start, - fit_image_info[IMAGE_ID_ATF].image_len, - image_os_match[IMAGE_ID_ATF]); - - ti_secure_image_post_process(&image_addr, - (size_t *)&fit_image_info[IMAGE_ID_ATF].image_len); - - /* Authenticate OPTEE */ - image_addr = (void *)fit_image_info[IMAGE_ID_OPTEE].image_start; - - debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, - fit_image_info[IMAGE_ID_OPTEE].image_start, - fit_image_info[IMAGE_ID_OPTEE].image_len, - image_os_match[IMAGE_ID_OPTEE]); - - ti_secure_image_post_process(&image_addr, - (size_t *)&fit_image_info[IMAGE_ID_OPTEE].image_len); - -#endif - - if (!fit_image_info[IMAGE_ID_DM_FW].image_len && - !(size > 0 && valid_elf_image(loadaddr))) { - shut_cpu = 1; - goto start_arm64; - } - - if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { - loadaddr = load_elf_image_phdr(loadaddr); - } else { - loadaddr = fit_image_info[IMAGE_ID_DM_FW].image_start; - if (valid_elf_image(loadaddr)) - loadaddr = load_elf_image_phdr(loadaddr); - } - - debug("%s: jumping to address %x\n", __func__, loadaddr); - -start_arm64: - /* Add an extra newline to differentiate the ATF logs from SPL */ - printf("Starting ATF on ARM64 core...\n\n"); - - ret = rproc_start(1); - if (ret) - panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); - - if (shut_cpu) { - debug("Shutting down...\n"); - release_resources_for_core_shutdown(); - - while (1) - asm volatile("wfe"); - } - image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr; - - image_entry(); -} -#endif - -#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) +#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) && !IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) void board_fit_image_post_process(const void *fit, int node, void **p_image, size_t *p_size) { -#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) - int len; - int i; - const char *os; - u32 addr; - - os = fdt_getprop(fit, node, "os", &len); - addr = fdt_getprop_u32_default_node(fit, node, 0, "entry", -1); - - debug("%s: processing image: addr=%x, size=%d, os=%s\n", __func__, - addr, *p_size, os); - - for (i = 0; i < IMAGE_AMT; i++) { - if (!strcmp(os, image_os_match[i])) { - fit_image_info[i].image_start = addr; - fit_image_info[i].image_len = *p_size; - debug("%s: matched image for ID %d\n", __func__, i); - break; - } - } - /* - * Only DM and the DTBs are being authenticated here, - * rest will be authenticated when A72 cluster is up - */ - if ((i != IMAGE_ID_ATF) && (i != IMAGE_ID_OPTEE)) -#endif - { - ti_secure_image_check_binary(p_image, p_size); - ti_secure_image_post_process(p_image, p_size); - } -#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) - else - ti_secure_image_check_binary(p_image, p_size); -#endif + ti_secure_image_check_binary(p_image, p_size); + ti_secure_image_post_process(p_image, p_size); } #endif diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c index ef81f50c6c7..87d4712efd4 100644 --- a/arch/arm/mach-k3/r5/common.c +++ b/arch/arm/mach-k3/r5/common.c @@ -5,12 +5,225 @@ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ */ +#include #include #include #include +#include +#include +#include +#include +#include +#include #include "../common.h" +#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF) +enum { + IMAGE_ID_ATF, + IMAGE_ID_OPTEE, + IMAGE_ID_SPL, + IMAGE_ID_DM_FW, + IMAGE_AMT, +}; + +#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) +static const char *image_os_match[IMAGE_AMT] = { + "arm-trusted-firmware", + "tee", + "U-Boot", + "DM", +}; +#endif + +static struct image_info fit_image_info[IMAGE_AMT]; + +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 +} + +int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr) +{ + struct udevice *fsdev; + char *name = NULL; + int size = 0; + + if (!IS_ENABLED(CONFIG_FS_LOADER)) + return 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 (!get_fs_loader(&fsdev)) { + size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr, + 0, 0); + } + + return size; +} + +void release_resources_for_core_shutdown(void) +{ + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); + struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops; + struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops; + int ret; + u32 i; + + /* Iterate through list of devices to put (shutdown) */ + for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { + u32 id = put_device_ids[i]; + + ret = dev_ops->put_device(ti_sci, id); + if (ret) + panic("Failed to put device %u (%d)\n", id, ret); + } + + /* Iterate through list of cores to put (shutdown) */ + for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { + u32 id = put_core_ids[i]; + + /* + * Queue up the core shutdown request. Note that this call + * needs to be followed up by an actual invocation of an WFE + * or WFI CPU instruction. + */ + ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); + if (ret) + panic("Failed sending core %u shutdown message (%d)\n", + id, ret); + } +} + +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(); + u32 loadaddr = 0; + int ret, size = 0, shut_cpu = 0; + + /* 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(); + + if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { + size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load", + &loadaddr); + } + + /* + * It is assumed that remoteproc device 1 is the corresponding + * Cortex-A core which runs ATF. Make sure DT reflects the same. + */ + if (!fit_image_info[IMAGE_ID_ATF].image_start) + fit_image_info[IMAGE_ID_ATF].image_start = + spl_image->entry_point; + + ret = rproc_load(1, fit_image_info[IMAGE_ID_ATF].image_start, 0x200); + if (ret) + panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret); + +#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) + /* Authenticate ATF */ + void *image_addr = (void *)fit_image_info[IMAGE_ID_ATF].image_start; + + debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, + fit_image_info[IMAGE_ID_ATF].image_start, + fit_image_info[IMAGE_ID_ATF].image_len, + image_os_match[IMAGE_ID_ATF]); + + ti_secure_image_post_process(&image_addr, + (size_t *)&fit_image_info[IMAGE_ID_ATF].image_len); + + /* Authenticate OPTEE */ + image_addr = (void *)fit_image_info[IMAGE_ID_OPTEE].image_start; + + debug("%s: Authenticating image: addr=%lx, size=%ld, os=%s\n", __func__, + fit_image_info[IMAGE_ID_OPTEE].image_start, + fit_image_info[IMAGE_ID_OPTEE].image_len, + image_os_match[IMAGE_ID_OPTEE]); + + ti_secure_image_post_process(&image_addr, + (size_t *)&fit_image_info[IMAGE_ID_OPTEE].image_len); +#endif + + if (!fit_image_info[IMAGE_ID_DM_FW].image_len && + !(size > 0 && valid_elf_image(loadaddr))) { + shut_cpu = 1; + goto start_arm64; + } + + if (!fit_image_info[IMAGE_ID_DM_FW].image_start) { + loadaddr = load_elf_image_phdr(loadaddr); + } else { + loadaddr = fit_image_info[IMAGE_ID_DM_FW].image_start; + if (valid_elf_image(loadaddr)) + loadaddr = load_elf_image_phdr(loadaddr); + } + + debug("%s: jumping to address %x\n", __func__, loadaddr); + +start_arm64: + /* Add an extra newline to differentiate the ATF logs from SPL */ + printf("Starting ATF on ARM64 core...\n\n"); + + ret = rproc_start(1); + if (ret) + panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret); + + if (shut_cpu) { + debug("Shutting down...\n"); + release_resources_for_core_shutdown(); + + while (1) + asm volatile("wfe"); + } + image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr; + + image_entry(); +} +#endif + void disable_linefill_optimization(void) { u32 actlr; @@ -33,3 +246,39 @@ void disable_linefill_optimization(void) actlr |= (1 << 13); /* Set DLFO bit */ asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); } + +#if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) +void board_fit_image_post_process(const void *fit, int node, void **p_image, + size_t *p_size) +{ + int len; + int i; + const char *os; + u32 addr; + + os = fdt_getprop(fit, node, "os", &len); + addr = fdt_getprop_u32_default_node(fit, node, 0, "entry", -1); + + debug("%s: processing image: addr=%x, size=%d, os=%s\n", __func__, + addr, *p_size, os); + + for (i = 0; i < IMAGE_AMT; i++) { + if (!strcmp(os, image_os_match[i])) { + fit_image_info[i].image_start = addr; + fit_image_info[i].image_len = *p_size; + debug("%s: matched image for ID %d\n", __func__, i); + break; + } + } + /* + * Only DM and the DTBs are being authenticated here, + * rest will be authenticated when A72 cluster is up + */ + if ((i != IMAGE_ID_ATF) && (i != IMAGE_ID_OPTEE)) { + ti_secure_image_check_binary(p_image, p_size); + ti_secure_image_post_process(p_image, p_size); + } else { + ti_secure_image_check_binary(p_image, p_size); + } +} +#endif From 60c75ab0cb6e0a95ba723c70c4b0278d21806280 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:46 -0600 Subject: [PATCH 04/12] arm: mach-k3: am62a7: Disable firewalls only after loading SYSFW Currently we do this multiple times, instead just do it once after loading SYSFW in R5 SPL. Signed-off-by: Andrew Davis --- arch/arm/mach-k3/am62a7_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-k3/am62a7_init.c b/arch/arm/mach-k3/am62a7_init.c index d72e19936b9..ccbde5bdd85 100644 --- a/arch/arm/mach-k3/am62a7_init.c +++ b/arch/arm/mach-k3/am62a7_init.c @@ -142,6 +142,9 @@ void board_init_f(ulong dummy) panic("ROM has not loaded TIFS firmware\n"); k3_sysfw_loader(true, NULL, NULL); + + /* Disable ROM configured firewalls right after loading sysfw */ + remove_fwl_configs(cbass_main_fwls, ARRAY_SIZE(cbass_main_fwls)); #endif #if defined(CONFIG_CPU_V7R) @@ -170,9 +173,6 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver(); - /* Disable ROM configured firewalls right after loading sysfw */ - remove_fwl_configs(cbass_main_fwls, ARRAY_SIZE(cbass_main_fwls)); - #if defined(CONFIG_K3_AM62A_DDRSS) ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) From 3e38688ec6fd365c98a5a21fedc91631f90fc837 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:47 -0600 Subject: [PATCH 05/12] arm: mach-k3: Move firewall removal into R5 directory Firewalls are only ever removed by the R5 core, move this code into the R5 directory. Signed-off-by: Andrew Davis --- arch/arm/mach-k3/common.c | 44 ------------------------------------ arch/arm/mach-k3/r5/common.c | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 8db7ca0725e..ed8aec360c9 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -211,50 +211,6 @@ void board_prep_linux(struct bootm_headers *images) } #endif -static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions, - enum k3_firewall_region_type fwl_type) -{ - struct ti_sci_fwl_ops *fwl_ops; - struct ti_sci_handle *ti_sci; - struct ti_sci_msg_fwl_region region; - size_t j; - - ti_sci = get_ti_sci_handle(); - fwl_ops = &ti_sci->ops.fwl_ops; - - for (j = 0; j < fwl_data.regions; j++) { - region.fwl_id = fwl_data.fwl_id; - region.region = j; - region.n_permission_regs = 3; - - fwl_ops->get_fwl_region(ti_sci, ®ion); - - /* Don't disable the background regions */ - if (region.control != 0 && - ((region.control >> K3_FIREWALL_BACKGROUND_BIT) & 1) == fwl_type) { - pr_debug("Attempting to disable firewall %5d (%25s)\n", - region.fwl_id, fwl_data.name); - region.control = 0; - - if (fwl_ops->set_fwl_region(ti_sci, ®ion)) - pr_err("Could not disable firewall %5d (%25s)\n", - region.fwl_id, fwl_data.name); - } - } -} - -void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size) -{ - size_t i; - - for (i = 0; i < fwl_data_size; i++) { - remove_fwl_regions(fwl_data[i], fwl_data[i].regions, - K3_FIREWALL_REGION_FOREGROUND); - remove_fwl_regions(fwl_data[i], fwl_data[i].regions, - K3_FIREWALL_REGION_BACKGROUND); - } -} - void spl_enable_cache(void) { #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c index 87d4712efd4..7309573a3fa 100644 --- a/arch/arm/mach-k3/r5/common.c +++ b/arch/arm/mach-k3/r5/common.c @@ -247,6 +247,50 @@ void disable_linefill_optimization(void) asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); } +static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions, + enum k3_firewall_region_type fwl_type) +{ + struct ti_sci_fwl_ops *fwl_ops; + struct ti_sci_handle *ti_sci; + struct ti_sci_msg_fwl_region region; + size_t j; + + ti_sci = get_ti_sci_handle(); + fwl_ops = &ti_sci->ops.fwl_ops; + + for (j = 0; j < fwl_data.regions; j++) { + region.fwl_id = fwl_data.fwl_id; + region.region = j; + region.n_permission_regs = 3; + + fwl_ops->get_fwl_region(ti_sci, ®ion); + + /* Don't disable the background regions */ + if (region.control != 0 && + ((region.control >> K3_FIREWALL_BACKGROUND_BIT) & 1) == fwl_type) { + pr_debug("Attempting to disable firewall %5d (%25s)\n", + region.fwl_id, fwl_data.name); + region.control = 0; + + if (fwl_ops->set_fwl_region(ti_sci, ®ion)) + pr_err("Could not disable firewall %5d (%25s)\n", + region.fwl_id, fwl_data.name); + } + } +} + +void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size) +{ + size_t i; + + for (i = 0; i < fwl_data_size; i++) { + remove_fwl_regions(fwl_data[i], fwl_data[i].regions, + K3_FIREWALL_REGION_FOREGROUND); + remove_fwl_regions(fwl_data[i], fwl_data[i].regions, + K3_FIREWALL_REGION_BACKGROUND); + } +} + #if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) void board_fit_image_post_process(const void *fit, int node, void **p_image, size_t *p_size) From f7a1e8e4e794a9b6a4d10957270876de2f8e2300 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 1 Feb 2024 18:24:48 -0600 Subject: [PATCH 06/12] arm: mach-k3: Move ARM64 specific code into new arm64 directory Like we did with R5, move ARM64 code into a specific directory to make it clear what code is only meant to run on each core type. Signed-off-by: Andrew Davis --- arch/arm/mach-k3/Makefile | 3 +-- arch/arm/mach-k3/arm64/Makefile | 6 ++++++ arch/arm/mach-k3/{ => arm64}/arm64-mmu.c | 0 arch/arm/mach-k3/{ => arm64}/cache.S | 0 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-k3/arm64/Makefile rename arch/arm/mach-k3/{ => arm64}/arm64-mmu.c (100%) rename arch/arm/mach-k3/{ => arm64}/cache.S (100%) diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile index 945698e6e86..19b2d79e57d 100644 --- a/arch/arm/mach-k3/Makefile +++ b/arch/arm/mach-k3/Makefile @@ -3,9 +3,8 @@ # Copyright (C) 2017-2018 Texas Instruments Incorporated - https://www.ti.com/ # Lokesh Vutla +obj-$(CONFIG_ARM64) += arm64/ obj-$(CONFIG_CPU_V7R) += r5/ -obj-$(CONFIG_ARM64) += arm64-mmu.o -obj-$(CONFIG_ARM64) += cache.o obj-$(CONFIG_OF_LIBFDT) += common_fdt.o ifeq ($(CONFIG_OF_LIBFDT)$(CONFIG_OF_SYSTEM_SETUP),yy) obj-$(CONFIG_SOC_K3_AM654) += am654_fdt.o diff --git a/arch/arm/mach-k3/arm64/Makefile b/arch/arm/mach-k3/arm64/Makefile new file mode 100644 index 00000000000..f3d322e17f8 --- /dev/null +++ b/arch/arm/mach-k3/arm64/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ + +obj-y += arm64-mmu.o +obj-y += cache.o diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64/arm64-mmu.c similarity index 100% rename from arch/arm/mach-k3/arm64-mmu.c rename to arch/arm/mach-k3/arm64/arm64-mmu.c diff --git a/arch/arm/mach-k3/cache.S b/arch/arm/mach-k3/arm64/cache.S similarity index 100% rename from arch/arm/mach-k3/cache.S rename to arch/arm/mach-k3/arm64/cache.S From 86e770b3e01f31ca8bf08ef60de4eaa842a35a50 Mon Sep 17 00:00:00 2001 From: Joao Paulo Goncalves Date: Thu, 8 Feb 2024 10:29:50 +0100 Subject: [PATCH 07/12] arm: mach-k3: am62: Get soc max temperature by grade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AM62x SoC is available in multiple temperature grade: - Commercial: 0° to 95° C - Industrial: -40° to 105° C - Automotive: -40° to 125° C Add a new function that returns the am62 max temperature value accordingly to its temperature grade in Celsius. Signed-off-by: Joao Paulo Goncalves Signed-off-by: Francesco Dolcini --- arch/arm/mach-k3/include/mach/am62_hardware.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h index 4cf7778a89e..264f8a488b4 100644 --- a/arch/arm/mach-k3/include/mach/am62_hardware.h +++ b/arch/arm/mach-k3/include/mach/am62_hardware.h @@ -42,6 +42,10 @@ #define JTAG_DEV_FEATURE_NO_PRU 0x4 +#define JTAG_DEV_TEMP_COMMERCIAL 0x3 +#define JTAG_DEV_TEMP_INDUSTRIAL 0x4 +#define JTAG_DEV_TEMP_AUTOMOTIVE 0x5 + #define CTRLMMR_MAIN_DEVSTAT (WKUP_CTRL_MMR0_BASE + 0x30) #define MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK GENMASK(6, 3) #define MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT 3 @@ -105,6 +109,19 @@ static inline int k3_get_temp_grade(void) return (full_devid & JTAG_DEV_TEMP_MASK) >> JTAG_DEV_TEMP_SHIFT; } +static inline int k3_get_max_temp(void) +{ + switch (k3_get_temp_grade()) { + case JTAG_DEV_TEMP_INDUSTRIAL: + return 105; + case JTAG_DEV_TEMP_AUTOMOTIVE: + return 125; + case JTAG_DEV_TEMP_COMMERCIAL: + default: + return 95; + } +} + static inline int k3_has_pru(void) { u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID); From cc801630b27c2f5187a58e1d7f42a15550bbf542 Mon Sep 17 00:00:00 2001 From: Joao Paulo Goncalves Date: Thu, 8 Feb 2024 10:29:51 +0100 Subject: [PATCH 08/12] arm: mach-k3: am62: Fixup thermal zone critical points Read the max temperature for the SoC temperature grade from the hardware and change the critical trip nodes on each thermal zone of FDT at runtime so they are correct with the hardware value for its grade. Signed-off-by: Joao Paulo Goncalves Signed-off-by: Francesco Dolcini --- arch/arm/mach-k3/am625_fdt.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm/mach-k3/am625_fdt.c b/arch/arm/mach-k3/am625_fdt.c index 970dd3447de..3c46d1028fd 100644 --- a/arch/arm/mach-k3/am625_fdt.c +++ b/arch/arm/mach-k3/am625_fdt.c @@ -38,11 +38,48 @@ static void fdt_fixup_pru_node_am625(void *blob, int has_pru) fdt_del_node_path(blob, "/bus@f0000/pruss@30040000"); } +static int fdt_fixup_trips_node(void *blob, int zoneoffset, int maxc) +{ + int node, trip; + + node = fdt_subnode_offset(blob, zoneoffset, "trips"); + if (node < 0) + return -1; + + fdt_for_each_subnode(trip, blob, node) { + const char *type = fdt_getprop(blob, trip, "type", NULL); + + if (!type || (strncmp(type, "critical", 8) != 0)) + continue; + + if (fdt_setprop_u32(blob, trip, "temperature", 1000 * maxc) < 0) + return -1; + } + + return 0; +} + +static void fdt_fixup_thermal_zone_nodes_am625(void *blob, int maxc) +{ + int node, zone; + + node = fdt_path_offset(blob, "/thermal-zones"); + if (node < 0) + return; + + fdt_for_each_subnode(zone, blob, node) { + if (fdt_fixup_trips_node(blob, zone, maxc) < 0) + printf("Failed to set temperature in %s critical trips\n", + fdt_get_name(blob, zone, NULL)); + } +} + int ft_system_setup(void *blob, struct bd_info *bd) { fdt_fixup_cores_nodes_am625(blob, k3_get_core_nr()); fdt_fixup_gpu_nodes_am625(blob, k3_has_gpu()); fdt_fixup_pru_node_am625(blob, k3_has_pru()); + fdt_fixup_thermal_zone_nodes_am625(blob, k3_get_max_temp()); return 0; } From f05add3822a09273392bc9c74b6dc4d6a42917ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Fri, 9 Feb 2024 09:06:53 +0100 Subject: [PATCH 09/12] configs: am64x_evm_r5_defconfig: enlarge simple malloc pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the default size the stack grows into the malloc, pool leading to stack corruption and boot failure. Signed-off-by: Thomas Weißschuh --- configs/am64x_evm_r5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/am64x_evm_r5_defconfig b/configs/am64x_evm_r5_defconfig index 56df6a4a19c..707fe506f38 100644 --- a/configs/am64x_evm_r5_defconfig +++ b/configs/am64x_evm_r5_defconfig @@ -42,6 +42,7 @@ CONFIG_SPL_SYS_REPORT_STACK_F_USAGE=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x400000 CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SYS_MALLOC=y CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y From 333031011c8fcd3020caef41128f9687725c462c Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Tue, 20 Feb 2024 15:34:51 +0530 Subject: [PATCH 10/12] dma: ti: k3-udma: Fix error handling for setup_resources() in udma_probe() In udma_probe() the return value of setup_resources() is stored in the u32 "ch_count" member of "struct udma_dev", due to which any negative return value which indicates an error is masked. Fix this by storing the return value of setup_resources() in the already declared integer variable "ret", followed by assigning it to the "ch_count" member of "struct udma_dev" in case of no error. While at it, change the "return ret" at the end of udma_probe() to a "return 0", to explicitly indicate that probe was successful. Fixes: a8837cf43839 ("dma: ti: k3-udma: Query DMA channels allocated from Resource Manager") Signed-off-by: Siddharth Vadapalli Reviewed-by: Dan Carpenter --- drivers/dma/ti/k3-udma.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index eea9ec96598..ed0a9bf487a 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1770,9 +1770,11 @@ static int udma_probe(struct udevice *dev) return PTR_ERR(ud->ringacc); ud->dev = dev; - ud->ch_count = setup_resources(ud); - if (ud->ch_count <= 0) - return ud->ch_count; + ret = setup_resources(ud); + if (ret < 0) + return ret; + + ud->ch_count = ret; for (i = 0; i < ud->bchan_cnt; i++) { struct udma_bchan *bchan = &ud->bchans[i]; @@ -1831,7 +1833,7 @@ static int udma_probe(struct udevice *dev) uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM | DMA_SUPPORTS_MEM_TO_DEV; - return ret; + return 0; } static int udma_push_to_ring(struct k3_nav_ring *ring, void *elem) From 87720385ab69396d045b9d9cf045896593f1774c Mon Sep 17 00:00:00 2001 From: Vishal Mahaveer Date: Tue, 20 Feb 2024 14:39:44 -0600 Subject: [PATCH 11/12] board: ti: rm-cfg: Update rm-cfg to reflect new resource reservation With the latest TIFS firmware, an additional virtual interrupt and event is reserved for TIFS usage on am62x and am62ax devices. Update the rm-cfg to reflect this new reservation. Signed-off-by: Vishal Mahaveer --- board/ti/am62ax/rm-cfg.yaml | 8 ++++---- board/ti/am62x/rm-cfg.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/board/ti/am62ax/rm-cfg.yaml b/board/ti/am62ax/rm-cfg.yaml index 73e8e15f66a..cbd087de797 100644 --- a/board/ti/am62ax/rm-cfg.yaml +++ b/board/ti/am62ax/rm-cfg.yaml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ -# Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/ +# Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/ # # Resource management configuration for AM62A # @@ -519,13 +519,13 @@ rm-cfg: reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 35 reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 36 reserved: 0 @@ -567,7 +567,7 @@ rm-cfg: reserved: 0 - start_resource: 1038 - num_resource: 498 + num_resource: 497 type: 1805 host_id: 128 reserved: 0 diff --git a/board/ti/am62x/rm-cfg.yaml b/board/ti/am62x/rm-cfg.yaml index 725f7c83f0d..26d99b03b80 100644 --- a/board/ti/am62x/rm-cfg.yaml +++ b/board/ti/am62x/rm-cfg.yaml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ -# Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/ +# Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/ # # Resource management configuration for AM62X # @@ -513,13 +513,13 @@ rm-cfg: reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 35 reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 36 reserved: 0 @@ -555,7 +555,7 @@ rm-cfg: reserved: 0 - start_resource: 909 - num_resource: 627 + num_resource: 626 type: 1805 host_id: 128 reserved: 0 From 7022640c10f027e6e2cff00012b3740a78f8b9bc Mon Sep 17 00:00:00 2001 From: Udit Kumar Date: Wed, 21 Feb 2024 19:53:44 +0530 Subject: [PATCH 12/12] dma: ti: k3-udma: Fix ring_idx to pair k3 nav rings ring_idx was not correctly assigned in case of tflow_id is zero. Which leads to wrong pairing of DMA for drivers like OSPI. Fixes: 4312a1dfca26 ("dma: ti: k3-udma: Use ring_idx to pair k3 nav rings") Reviewed-by: Jai Luthra Signed-off-by: Udit Kumar --- drivers/dma/ti/k3-udma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index ed0a9bf487a..ef3074aa13f 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -884,10 +884,10 @@ static int udma_alloc_tx_resources(struct udma_chan *uc) return ret; tchan = uc->tchan; - if (tchan->tflow_id >= 0) + if (tchan->tflow_id > 0) ring_idx = tchan->tflow_id; else - ring_idx = ud->bchan_cnt + tchan->id; + ring_idx = tchan->id; ret = k3_nav_ringacc_request_rings_pair(ud->ringacc, ring_idx, -1, &uc->tchan->t_ring,