From: Andrew Davis Date: Fri, 10 May 2024 20:21:24 +0000 (-0500) Subject: arm: mach-k3: Move code specific to a SoC into that SoC's directory X-Git-Tag: v2024.10~114^2~20^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=42826664e4452304bdadc909d7c5f791d4abc552;p=platform%2Fkernel%2Fu-boot.git arm: mach-k3: Move code specific to a SoC into that SoC's directory Each SoC now has a directory in mach-k3, let's move the SoC specific files into their respective directories. Signed-off-by: Andrew Davis --- diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile index 3101f57d32..2b3ebd5c53 100644 --- a/arch/arm/mach-k3/Makefile +++ b/arch/arm/mach-k3/Makefile @@ -6,24 +6,12 @@ obj-$(CONFIG_ARM64) += arm64/ obj-$(CONFIG_CPU_V7R) += r5/ obj-$(CONFIG_OF_LIBFDT) += common_fdt.o -ifeq ($(CONFIG_OF_LIBFDT)$(CONFIG_OF_SYSTEM_SETUP),yy) -obj-$(CONFIG_SOC_K3_AM654) += am654_fdt.o -obj-$(CONFIG_SOC_K3_J721E) += j721e_fdt.o -obj-$(CONFIG_SOC_K3_J721S2) += j721s2_fdt.o -obj-$(CONFIG_SOC_K3_AM625) += am625_fdt.o -obj-$(CONFIG_SOC_K3_AM62A7) += am62a7_fdt.o -obj-$(CONFIG_SOC_K3_J784S4) += j784s4_fdt.o -endif -ifeq ($(CONFIG_SPL_BUILD),y) -obj-$(CONFIG_SOC_K3_AM654) += am654_init.o -obj-$(CONFIG_SOC_K3_J721E) += j721e_init.o -obj-$(CONFIG_SOC_K3_J721S2) += j721s2_init.o -obj-$(CONFIG_SOC_K3_AM642) += am642_init.o -obj-$(CONFIG_SOC_K3_AM625) += am625_init.o -obj-$(CONFIG_SOC_K3_AM62A7) += am62a7_init.o -obj-$(CONFIG_SOC_K3_J784S4) += j784s4_init.o -obj-$(CONFIG_SOC_K3_AM62P5) += am62p5_init.o -endif obj-y += common.o security.o +obj-$(CONFIG_SOC_K3_AM62A7) += am62ax/ +obj-$(CONFIG_SOC_K3_AM62P5) += am62px/ obj-$(CONFIG_SOC_K3_AM625) += am62x/ obj-$(CONFIG_SOC_K3_AM642) += am64x/ +obj-$(CONFIG_SOC_K3_AM654) += am65x/ +obj-$(CONFIG_SOC_K3_J721E) += j721e/ +obj-$(CONFIG_SOC_K3_J721S2) += j721s2/ +obj-$(CONFIG_SOC_K3_J784S4) += j784s4/ diff --git a/arch/arm/mach-k3/am625_fdt.c b/arch/arm/mach-k3/am625_fdt.c deleted file mode 100644 index c56adef13b..0000000000 --- a/arch/arm/mach-k3/am625_fdt.c +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2023 Toradex - https://www.toradex.com/ - */ - -#include -#include "common_fdt.h" -#include - -static void fdt_fixup_cores_nodes_am625(void *blob, int core_nr) -{ - char node_path[32]; - - if (core_nr < 1) - return; - - for (; core_nr < 4; core_nr++) { - snprintf(node_path, sizeof(node_path), "/cpus/cpu@%d", core_nr); - fdt_del_node_path(blob, node_path); - snprintf(node_path, sizeof(node_path), "/cpus/cpu-map/cluster0/core%d", core_nr); - fdt_del_node_path(blob, node_path); - snprintf(node_path, sizeof(node_path), "/bus@f0000/watchdog@e0%d0000", core_nr); - fdt_del_node_path(blob, node_path); - } -} - -static void fdt_fixup_gpu_nodes_am625(void *blob, int has_gpu) -{ - if (!has_gpu) { - fdt_del_node_path(blob, "/bus@f0000/gpu@fd00000"); - fdt_del_node_path(blob, "/bus@f0000/watchdog@e0f0000"); - } -} - -static void fdt_fixup_pru_node_am625(void *blob, int has_pru) -{ - if (!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()); - fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); - fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); - - return 0; -} diff --git a/arch/arm/mach-k3/am625_init.c b/arch/arm/mach-k3/am625_init.c deleted file mode 100644 index 668f9a51ef..0000000000 --- a/arch/arm/mach-k3/am625_init.c +++ /dev/null @@ -1,311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * AM625: SoC specific initialization - * - * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/ - * Suman Anna - */ - -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include - -#define RTC_BASE_ADDRESS 0x2b1f0000 -#define REG_K3RTC_S_CNT_LSW (RTC_BASE_ADDRESS + 0x18) -#define REG_K3RTC_KICK0 (RTC_BASE_ADDRESS + 0x70) -#define REG_K3RTC_KICK1 (RTC_BASE_ADDRESS + 0x74) - -/* Magic values for lock/unlock */ -#define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13 -#define K3RTC_KICK1_UNLOCK_VALUE 0x95a4f1e0 - -/* TISCI DEV ID for A53 Clock */ -#define AM62X_DEV_A53SS0_CORE_0_DEV_ID 135 - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 4); - mmr_unlock(CTRL_MMR0_BASE, 6); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - mmr_unlock(MCU_CTRL_MMR0_BASE, 6); - - /* Unlock PADCFG_CTRL_MMR padconf registers */ - mmr_unlock(PADCFG_MMR0_BASE, 1); - mmr_unlock(PADCFG_MMR1_BASE, 1); -} - -static __maybe_unused void enable_mcu_esm_reset(void) -{ - /* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */ - u32 stat = readl(CTRLMMR_MCU_RST_CTRL); - - stat &= RST_CTRL_ESM_ERROR_RST_EN_Z_MASK; - writel(stat, CTRLMMR_MCU_RST_CTRL); -} - -/* - * RTC Erratum i2327 Workaround for Silicon Revision 1 - * - * Due to a bug in initial synchronization out of cold power on, - * IRQ status can get locked infinitely if we do not unlock RTC - * - * This workaround *must* be applied within 1 second of power on, - * So, this is closest point to be able to guarantee the max - * timing. - * - * https://www.ti.com/lit/er/sprz487c/sprz487c.pdf - */ -static __maybe_unused void rtc_erratumi2327_init(void) -{ - u32 counter; - - /* - * If counter has gone past 1, nothing we can do, leave - * system locked! This is the only way we know if RTC - * can be used for all practical purposes. - */ - counter = readl(REG_K3RTC_S_CNT_LSW); - if (counter > 1) - return; - /* - * Need to set this up at the very start - * MUST BE DONE under 1 second of boot. - */ - writel(K3RTC_KICK0_UNLOCK_VALUE, REG_K3RTC_KICK0); - writel(K3RTC_KICK1_UNLOCK_VALUE, REG_K3RTC_KICK1); -} - -#if CONFIG_IS_ENABLED(OF_CONTROL) -static int get_a53_cpu_clock_index(ofnode node) -{ - int count, i; - struct ofnode_phandle_args *args; - ofnode clknode; - - clknode = ofnode_path("/bus@f0000/system-controller@44043000/clock-controller"); - if (!ofnode_valid(clknode)) - return -1; - - count = ofnode_count_phandle_with_args(node, "assigned-clocks", "#clock-cells", 0); - - for (i = 0; i < count; i++) { - if (!ofnode_parse_phandle_with_args(node, "assigned-clocks", - "#clock-cells", 0, i, args)) { - if (ofnode_equal(clknode, args->node) && - args->args[0] == AM62X_DEV_A53SS0_CORE_0_DEV_ID) - return i; - } - } - - return -1; -} - -static void fixup_a53_cpu_freq_by_speed_grade(void) -{ - int index, size; - u32 *rates; - ofnode node; - - node = ofnode_path("/a53@0"); - if (!ofnode_valid(node)) - return; - - rates = fdt_getprop_w(ofnode_to_fdt(node), ofnode_to_offset(node), - "assigned-clock-rates", &size); - - index = get_a53_cpu_clock_index(node); - - if (!rates || index < 0 || index >= (size / sizeof(u32))) { - printf("Wrong A53 assigned-clocks configuration\n"); - return; - } - - rates[index] = cpu_to_fdt32(k3_get_a53_max_frequency()); - - printf("Changed A53 CPU frequency to %dHz (%c grade) in DT\n", - k3_get_a53_max_frequency(), k3_get_speed_grade()); -} -#else -static void fixup_a53_cpu_freq_by_speed_grade(void) -{ -} -#endif - -void board_init_f(ulong dummy) -{ - struct udevice *dev; - int ret; - - if (IS_ENABLED(CONFIG_CPU_V7R)) { - setup_k3_mpu_regions(); - rtc_erratumi2327_init(); - } - - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - ctrl_mmr_unlock(); - - /* Init DM early */ - spl_early_init(); - - /* - * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and - * MAIN_UART1 modules and continue regardless of the result of pinctrl. - * Do this without probing the device, but instead by searching the - * device that would request the given sequence number if probed. The - * UARTs will be used by the DM firmware and TIFS firmware images - * respectively and the firmware depend on SPL to initialize the pin - * settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - preloader_console_init(); - - /* - * Allow establishing an early console as required for example when - * doing a UART-based boot. Note that this console may not "survive" - * through a SYSFW PM-init step and will need a re-init in some way - * due to changing module clock frequencies. - */ - if (IS_ENABLED(CONFIG_K3_EARLY_CONS)) - early_console_init(); - - /* - * Configure and start up 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. - */ - if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { - ret = is_rom_loaded_sysfw(&bootdata); - if (!ret) - panic("ROM has not loaded TIFS firmware\n"); - - k3_sysfw_loader(true, NULL, NULL); - } - - /* - * Relocate boot information to OCRAM (after TIFS has opend this - * region for us) so the next bootloader stages can keep access to - * primary vs backup bootmodes. - */ - if (IS_ENABLED(CONFIG_CPU_V7R)) - writel(bootindex, K3_BOOT_PARAM_TABLE_INDEX_OCRAM); - - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done. - */ - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - printf("Failed to initialize clk-k3!\n"); - } - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - - if (IS_ENABLED(CONFIG_ESM_K3)) { - /* Probe/configure ESM0 */ - ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); - if (ret) - printf("esm main init failed: %d\n", ret); - - /* Probe/configure MCUESM */ - ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev); - if (ret) - printf("esm mcu init failed: %d\n", ret); - - enable_mcu_esm_reset(); - } - - if (IS_ENABLED(CONFIG_K3_AM64_DDRSS)) { - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); - } - spl_enable_cache(); - - fixup_a53_cpu_freq_by_speed_grade(); -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; - - switch (bootmode) { - case BOOT_DEVICE_EMMC: - if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) - return MMCSD_MODE_EMMCBOOT; - if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) - return MMCSD_MODE_FS; - return MMCSD_MODE_EMMCBOOT; - case BOOT_DEVICE_MMC: - if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK) - return MMCSD_MODE_RAW; - default: - return MMCSD_MODE_FS; - } -} - -u32 spl_boot_device(void) -{ - return get_boot_device(); -} diff --git a/arch/arm/mach-k3/am62a7_fdt.c b/arch/arm/mach-k3/am62a7_fdt.c deleted file mode 100644 index d67f012a5d..0000000000 --- a/arch/arm/mach-k3/am62a7_fdt.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ - */ - -#include -#include "common_fdt.h" -#include - -int ft_system_setup(void *blob, struct bd_info *bd) -{ - fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); - fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); - - return 0; -} diff --git a/arch/arm/mach-k3/am62a7_init.c b/arch/arm/mach-k3/am62a7_init.c deleted file mode 100644 index 658828cf75..0000000000 --- a/arch/arm/mach-k3/am62a7_init.c +++ /dev/null @@ -1,271 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * AM62A7: SoC specific initialization - * - * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ - */ - -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include - -struct fwl_data cbass_main_fwls[] = { - { "FSS_DAT_REG3", 7, 8 }, -}; - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - - if (IS_ENABLED(CONFIG_CPU_V7R)) { - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); - } -} - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 4); - mmr_unlock(CTRL_MMR0_BASE, 5); - mmr_unlock(CTRL_MMR0_BASE, 6); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - mmr_unlock(MCU_CTRL_MMR0_BASE, 6); - - /* Unlock PADCFG_CTRL_MMR padconf registers */ - mmr_unlock(PADCFG_MMR0_BASE, 1); - mmr_unlock(PADCFG_MMR1_BASE, 1); -} - -void board_init_f(ulong dummy) -{ - struct udevice *dev; - int ret; - -#if defined(CONFIG_CPU_V7R) - setup_k3_mpu_regions(); -#endif - - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - ctrl_mmr_unlock(); - - /* Init DM early */ - spl_early_init(); - - /* - * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and - * MAIN_UART1 modules and continue regardless of the result of pinctrl. - * Do this without probing the device, but instead by searching the - * device that would request the given sequence number if probed. The - * UARTs will be used by the DM firmware and TIFS firmware images - * respectively and the firmware depend on SPL to initialize the pin - * settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - -#ifdef CONFIG_K3_EARLY_CONS - /* - * Allow establishing an early console as required for example when - * doing a UART-based boot. Note that this console may not "survive" - * through a SYSFW PM-init step and will need a re-init in some way - * due to changing module clock frequencies. - */ - early_console_init(); -#endif - -#if defined(CONFIG_K3_LOAD_SYSFW) - /* - * Configure and start up 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. - */ - ret = is_rom_loaded_sysfw(&bootdata); - if (!ret) - 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) - /* - * Relocate boot information to OCRAM (after TIFS has opend this - * region for us) so the next bootloader stages can keep access to - * primary vs backup bootmodes. - */ - writel(bootindex, K3_BOOT_PARAM_TABLE_INDEX_OCRAM); -#endif - - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done. - */ - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - printf("Failed to initialize clk-k3!\n"); - } - - preloader_console_init(); - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - -#if defined(CONFIG_K3_AM62A_DDRSS) - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); -#endif - - setup_qos(); - - debug("am62a_init: %s done\n", __func__); -} - -static u32 __get_backup_bootmedia(u32 devstat) -{ - u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >> - MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT; - u32 bkup_bootmode_cfg = - (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT; - - switch (bkup_bootmode) { - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_USB; - - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - - case BACKUP_BOOT_DEVICE_MMC: - if (bkup_bootmode_cfg) - return BOOT_DEVICE_MMC2; - return BOOT_DEVICE_MMC1; - - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - - case BACKUP_BOOT_DEVICE_DFU: - if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK) - return BOOT_DEVICE_USB; - return BOOT_DEVICE_DFU; - }; - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 devstat) -{ - u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; - - switch (bootmode) { - case BOOT_DEVICE_OSPI: - fallthrough; - case BOOT_DEVICE_QSPI: - fallthrough; - case BOOT_DEVICE_XSPI: - fallthrough; - case BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - - case BOOT_DEVICE_ETHERNET_RGMII: - fallthrough; - case BOOT_DEVICE_ETHERNET_RMII: - return BOOT_DEVICE_ETHERNET; - - case BOOT_DEVICE_EMMC: - return BOOT_DEVICE_MMC1; - - case BOOT_DEVICE_SPI_NAND: - return BOOT_DEVICE_SPINAND; - - case BOOT_DEVICE_MMC: - if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >> - MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT) - return BOOT_DEVICE_MMC2; - return BOOT_DEVICE_MMC1; - - case BOOT_DEVICE_DFU: - if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT) - return BOOT_DEVICE_USB; - return BOOT_DEVICE_DFU; - - case BOOT_DEVICE_NOBOOT: - return BOOT_DEVICE_RAM; - } - - return bootmode; -} - -u32 spl_boot_device(void) -{ - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmedia; - - if (bootindex == K3_PRIMARY_BOOTMODE) - bootmedia = __get_primary_bootmedia(devstat); - else - bootmedia = __get_backup_bootmedia(devstat); - - debug("am62a_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n", - __func__, devstat, bootmedia, bootindex); - return bootmedia; -} diff --git a/arch/arm/mach-k3/am62ax/Makefile b/arch/arm/mach-k3/am62ax/Makefile new file mode 100644 index 0000000000..1717ca343d --- /dev/null +++ b/arch/arm/mach-k3/am62ax/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_OF_SYSTEM_SETUP) += am62a7_fdt.o +obj-$(CONFIG_SPL_BUILD) += am62a7_init.o diff --git a/arch/arm/mach-k3/am62ax/am62a7_fdt.c b/arch/arm/mach-k3/am62ax/am62a7_fdt.c new file mode 100644 index 0000000000..7f764ab36b --- /dev/null +++ b/arch/arm/mach-k3/am62ax/am62a7_fdt.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include +#include + +#include "../common_fdt.h" + +int ft_system_setup(void *blob, struct bd_info *bd) +{ + fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); + fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); + + return 0; +} diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c b/arch/arm/mach-k3/am62ax/am62a7_init.c new file mode 100644 index 0000000000..0f62f39075 --- /dev/null +++ b/arch/arm/mach-k3/am62ax/am62a7_init.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM62A7: SoC specific initialization + * + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +struct fwl_data cbass_main_fwls[] = { + { "FSS_DAT_REG3", 7, 8 }, +}; + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + + if (IS_ENABLED(CONFIG_CPU_V7R)) { + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); + } +} + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 4); + mmr_unlock(CTRL_MMR0_BASE, 5); + mmr_unlock(CTRL_MMR0_BASE, 6); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + + /* Unlock PADCFG_CTRL_MMR padconf registers */ + mmr_unlock(PADCFG_MMR0_BASE, 1); + mmr_unlock(PADCFG_MMR1_BASE, 1); +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + +#if defined(CONFIG_CPU_V7R) + setup_k3_mpu_regions(); +#endif + + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + ctrl_mmr_unlock(); + + /* Init DM early */ + spl_early_init(); + + /* + * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and + * MAIN_UART1 modules and continue regardless of the result of pinctrl. + * Do this without probing the device, but instead by searching the + * device that would request the given sequence number if probed. The + * UARTs will be used by the DM firmware and TIFS firmware images + * respectively and the firmware depend on SPL to initialize the pin + * settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + +#ifdef CONFIG_K3_EARLY_CONS + /* + * Allow establishing an early console as required for example when + * doing a UART-based boot. Note that this console may not "survive" + * through a SYSFW PM-init step and will need a re-init in some way + * due to changing module clock frequencies. + */ + early_console_init(); +#endif + +#if defined(CONFIG_K3_LOAD_SYSFW) + /* + * Configure and start up 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. + */ + ret = is_rom_loaded_sysfw(&bootdata); + if (!ret) + 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) + /* + * Relocate boot information to OCRAM (after TIFS has opend this + * region for us) so the next bootloader stages can keep access to + * primary vs backup bootmodes. + */ + writel(bootindex, K3_BOOT_PARAM_TABLE_INDEX_OCRAM); +#endif + + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done. + */ + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + printf("Failed to initialize clk-k3!\n"); + } + + preloader_console_init(); + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + +#if defined(CONFIG_K3_AM62A_DDRSS) + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); +#endif + + setup_qos(); + + debug("am62a_init: %s done\n", __func__); +} + +static u32 __get_backup_bootmedia(u32 devstat) +{ + u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >> + MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT; + u32 bkup_bootmode_cfg = + (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT; + + switch (bkup_bootmode) { + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_USB; + + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + + case BACKUP_BOOT_DEVICE_MMC: + if (bkup_bootmode_cfg) + return BOOT_DEVICE_MMC2; + return BOOT_DEVICE_MMC1; + + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + + case BACKUP_BOOT_DEVICE_DFU: + if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK) + return BOOT_DEVICE_USB; + return BOOT_DEVICE_DFU; + }; + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 devstat) +{ + u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; + + switch (bootmode) { + case BOOT_DEVICE_OSPI: + fallthrough; + case BOOT_DEVICE_QSPI: + fallthrough; + case BOOT_DEVICE_XSPI: + fallthrough; + case BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + + case BOOT_DEVICE_ETHERNET_RGMII: + fallthrough; + case BOOT_DEVICE_ETHERNET_RMII: + return BOOT_DEVICE_ETHERNET; + + case BOOT_DEVICE_EMMC: + return BOOT_DEVICE_MMC1; + + case BOOT_DEVICE_SPI_NAND: + return BOOT_DEVICE_SPINAND; + + case BOOT_DEVICE_MMC: + if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >> + MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT) + return BOOT_DEVICE_MMC2; + return BOOT_DEVICE_MMC1; + + case BOOT_DEVICE_DFU: + if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT) + return BOOT_DEVICE_USB; + return BOOT_DEVICE_DFU; + + case BOOT_DEVICE_NOBOOT: + return BOOT_DEVICE_RAM; + } + + return bootmode; +} + +u32 spl_boot_device(void) +{ + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmedia; + + if (bootindex == K3_PRIMARY_BOOTMODE) + bootmedia = __get_primary_bootmedia(devstat); + else + bootmedia = __get_backup_bootmedia(devstat); + + debug("am62a_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n", + __func__, devstat, bootmedia, bootindex); + return bootmedia; +} diff --git a/arch/arm/mach-k3/am62p5_init.c b/arch/arm/mach-k3/am62p5_init.c deleted file mode 100644 index aab99aa0c9..0000000000 --- a/arch/arm/mach-k3/am62p5_init.c +++ /dev/null @@ -1,281 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * AM62P5: SoC specific initialization - * - * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ - */ - -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include - -struct fwl_data cbass_main_fwls[] = { - { "FSS_DAT_REG3", 7, 8 }, -}; - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 4); - mmr_unlock(CTRL_MMR0_BASE, 5); - mmr_unlock(CTRL_MMR0_BASE, 6); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - mmr_unlock(MCU_CTRL_MMR0_BASE, 6); - - /* Unlock PADCFG_CTRL_MMR padconf registers */ - mmr_unlock(PADCFG_MMR0_BASE, 1); - mmr_unlock(PADCFG_MMR1_BASE, 1); -} - -void board_init_f(ulong dummy) -{ - struct udevice *dev; - int ret; - - if (IS_ENABLED(CONFIG_CPU_V7R)) - setup_k3_mpu_regions(); - - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - ctrl_mmr_unlock(); - - /* Init DM early */ - ret = spl_early_init(); - if (ret) - panic("spl_early_init() failed: %d\n", ret); - - /* - * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and - * MAIN_UART1 modules and continue regardless of the result of pinctrl. - * Do this without probing the device, but instead by searching the - * device that would request the given sequence number if probed. The - * UARTs will be used by the DM firmware and TIFS firmware images - * respectively and the firmware depend on SPL to initialize the pin - * settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - /* - * Allow establishing an early console as required for example when - * doing a UART-based boot. Note that this console may not "survive" - * through a SYSFW PM-init step and will need a re-init in some way - * due to changing module clock frequencies. - */ - if (IS_ENABLED(CONFIG_K3_EARLY_CONS)) { - ret = early_console_init(); - if (ret) - panic("early_console_init() failed: %d\n", ret); - } - - /* - * Configure and start up 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. - */ - if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { - ret = is_rom_loaded_sysfw(&bootdata); - if (!ret) - panic("ROM has not loaded TIFS firmware\n"); - - k3_sysfw_loader(true, NULL, NULL); - - /* Disable ROM configured firewalls */ - remove_fwl_configs(cbass_main_fwls, - ARRAY_SIZE(cbass_main_fwls)); - } - - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done. - */ - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - printf("Failed to initialize clk-k3!\n"); - } - - preloader_console_init(); - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - - if (IS_ENABLED(CONFIG_K3_AM62A_DDRSS)) { - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); - } - - spl_enable_cache(); - debug("am62px_init: %s done\n", __func__); -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; - - switch (bootmode) { - case BOOT_DEVICE_EMMC: - return MMCSD_MODE_EMMCBOOT; - case BOOT_DEVICE_MMC: - if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK) - return MMCSD_MODE_RAW; - default: - return MMCSD_MODE_FS; - } -} - -static u32 __get_backup_bootmedia(u32 devstat) -{ - u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >> - MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT; - u32 bkup_bootmode_cfg = - (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT; - - switch (bkup_bootmode) { - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_USB; - - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - - case BACKUP_BOOT_DEVICE_MMC: - if (bkup_bootmode_cfg) - return BOOT_DEVICE_MMC2; - return BOOT_DEVICE_MMC1; - - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - - case BACKUP_BOOT_DEVICE_DFU: - if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK) - return BOOT_DEVICE_USB; - return BOOT_DEVICE_DFU; - }; - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 devstat) -{ - u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> - MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; - - switch (bootmode) { - case BOOT_DEVICE_OSPI: - fallthrough; - case BOOT_DEVICE_QSPI: - fallthrough; - case BOOT_DEVICE_XSPI: - fallthrough; - case BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - - case BOOT_DEVICE_ETHERNET_RGMII: - fallthrough; - case BOOT_DEVICE_ETHERNET_RMII: - return BOOT_DEVICE_ETHERNET; - - case BOOT_DEVICE_EMMC: - return BOOT_DEVICE_MMC1; - - case BOOT_DEVICE_SPI_NAND: - return BOOT_DEVICE_SPINAND; - - case BOOT_DEVICE_MMC: - if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >> - MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT) - return BOOT_DEVICE_MMC2; - return BOOT_DEVICE_MMC1; - - case BOOT_DEVICE_DFU: - if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >> - MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT) - return BOOT_DEVICE_USB; - return BOOT_DEVICE_DFU; - - case BOOT_DEVICE_NOBOOT: - return BOOT_DEVICE_RAM; - } - - return bootmode; -} - -u32 spl_boot_device(void) -{ - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmedia; - - if (bootindex == K3_PRIMARY_BOOTMODE) - bootmedia = __get_primary_bootmedia(devstat); - else - bootmedia = __get_backup_bootmedia(devstat); - - debug("am62px_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n", - __func__, devstat, bootmedia, bootindex); - return bootmedia; -} diff --git a/arch/arm/mach-k3/am62px/Makefile b/arch/arm/mach-k3/am62px/Makefile new file mode 100644 index 0000000000..5902862b29 --- /dev/null +++ b/arch/arm/mach-k3/am62px/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_SPL_BUILD) += am62p5_init.o diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c b/arch/arm/mach-k3/am62px/am62p5_init.c new file mode 100644 index 0000000000..34ed01cd78 --- /dev/null +++ b/arch/arm/mach-k3/am62px/am62p5_init.c @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM62P5: SoC specific initialization + * + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +struct fwl_data cbass_main_fwls[] = { + { "FSS_DAT_REG3", 7, 8 }, +}; + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 4); + mmr_unlock(CTRL_MMR0_BASE, 5); + mmr_unlock(CTRL_MMR0_BASE, 6); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + + /* Unlock PADCFG_CTRL_MMR padconf registers */ + mmr_unlock(PADCFG_MMR0_BASE, 1); + mmr_unlock(PADCFG_MMR1_BASE, 1); +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + if (IS_ENABLED(CONFIG_CPU_V7R)) + setup_k3_mpu_regions(); + + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + ctrl_mmr_unlock(); + + /* Init DM early */ + ret = spl_early_init(); + if (ret) + panic("spl_early_init() failed: %d\n", ret); + + /* + * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and + * MAIN_UART1 modules and continue regardless of the result of pinctrl. + * Do this without probing the device, but instead by searching the + * device that would request the given sequence number if probed. The + * UARTs will be used by the DM firmware and TIFS firmware images + * respectively and the firmware depend on SPL to initialize the pin + * settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + /* + * Allow establishing an early console as required for example when + * doing a UART-based boot. Note that this console may not "survive" + * through a SYSFW PM-init step and will need a re-init in some way + * due to changing module clock frequencies. + */ + if (IS_ENABLED(CONFIG_K3_EARLY_CONS)) { + ret = early_console_init(); + if (ret) + panic("early_console_init() failed: %d\n", ret); + } + + /* + * Configure and start up 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. + */ + if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { + ret = is_rom_loaded_sysfw(&bootdata); + if (!ret) + panic("ROM has not loaded TIFS firmware\n"); + + k3_sysfw_loader(true, NULL, NULL); + + /* Disable ROM configured firewalls */ + remove_fwl_configs(cbass_main_fwls, + ARRAY_SIZE(cbass_main_fwls)); + } + + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done. + */ + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + printf("Failed to initialize clk-k3!\n"); + } + + preloader_console_init(); + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + + if (IS_ENABLED(CONFIG_K3_AM62A_DDRSS)) { + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); + } + + spl_enable_cache(); + debug("am62px_init: %s done\n", __func__); +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; + + switch (bootmode) { + case BOOT_DEVICE_EMMC: + return MMCSD_MODE_EMMCBOOT; + case BOOT_DEVICE_MMC: + if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK) + return MMCSD_MODE_RAW; + default: + return MMCSD_MODE_FS; + } +} + +static u32 __get_backup_bootmedia(u32 devstat) +{ + u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >> + MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT; + u32 bkup_bootmode_cfg = + (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT; + + switch (bkup_bootmode) { + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_USB; + + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + + case BACKUP_BOOT_DEVICE_MMC: + if (bkup_bootmode_cfg) + return BOOT_DEVICE_MMC2; + return BOOT_DEVICE_MMC1; + + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + + case BACKUP_BOOT_DEVICE_DFU: + if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK) + return BOOT_DEVICE_USB; + return BOOT_DEVICE_DFU; + }; + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 devstat) +{ + u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; + + switch (bootmode) { + case BOOT_DEVICE_OSPI: + fallthrough; + case BOOT_DEVICE_QSPI: + fallthrough; + case BOOT_DEVICE_XSPI: + fallthrough; + case BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + + case BOOT_DEVICE_ETHERNET_RGMII: + fallthrough; + case BOOT_DEVICE_ETHERNET_RMII: + return BOOT_DEVICE_ETHERNET; + + case BOOT_DEVICE_EMMC: + return BOOT_DEVICE_MMC1; + + case BOOT_DEVICE_SPI_NAND: + return BOOT_DEVICE_SPINAND; + + case BOOT_DEVICE_MMC: + if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >> + MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT) + return BOOT_DEVICE_MMC2; + return BOOT_DEVICE_MMC1; + + case BOOT_DEVICE_DFU: + if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT) + return BOOT_DEVICE_USB; + return BOOT_DEVICE_DFU; + + case BOOT_DEVICE_NOBOOT: + return BOOT_DEVICE_RAM; + } + + return bootmode; +} + +u32 spl_boot_device(void) +{ + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmedia; + + if (bootindex == K3_PRIMARY_BOOTMODE) + bootmedia = __get_primary_bootmedia(devstat); + else + bootmedia = __get_backup_bootmedia(devstat); + + debug("am62px_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n", + __func__, devstat, bootmedia, bootindex); + return bootmedia; +} diff --git a/arch/arm/mach-k3/am62x/Makefile b/arch/arm/mach-k3/am62x/Makefile index acf09c3426..8494cdda48 100644 --- a/arch/arm/mach-k3/am62x/Makefile +++ b/arch/arm/mach-k3/am62x/Makefile @@ -1,2 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_OF_SYSTEM_SETUP) += am625_fdt.o +obj-$(CONFIG_SPL_BUILD) += am625_init.o obj-y += boot.o diff --git a/arch/arm/mach-k3/am62x/am625_fdt.c b/arch/arm/mach-k3/am62x/am625_fdt.c new file mode 100644 index 0000000000..8fe200a423 --- /dev/null +++ b/arch/arm/mach-k3/am62x/am625_fdt.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2023 Toradex - https://www.toradex.com/ + */ + +#include +#include + +#include "../common_fdt.h" + +static void fdt_fixup_cores_nodes_am625(void *blob, int core_nr) +{ + char node_path[32]; + + if (core_nr < 1) + return; + + for (; core_nr < 4; core_nr++) { + snprintf(node_path, sizeof(node_path), "/cpus/cpu@%d", core_nr); + fdt_del_node_path(blob, node_path); + snprintf(node_path, sizeof(node_path), "/cpus/cpu-map/cluster0/core%d", core_nr); + fdt_del_node_path(blob, node_path); + snprintf(node_path, sizeof(node_path), "/bus@f0000/watchdog@e0%d0000", core_nr); + fdt_del_node_path(blob, node_path); + } +} + +static void fdt_fixup_gpu_nodes_am625(void *blob, int has_gpu) +{ + if (!has_gpu) { + fdt_del_node_path(blob, "/bus@f0000/gpu@fd00000"); + fdt_del_node_path(blob, "/bus@f0000/watchdog@e0f0000"); + } +} + +static void fdt_fixup_pru_node_am625(void *blob, int has_pru) +{ + if (!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()); + fdt_fixup_reserved(blob, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); + fdt_fixup_reserved(blob, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); + + return 0; +} diff --git a/arch/arm/mach-k3/am62x/am625_init.c b/arch/arm/mach-k3/am62x/am625_init.c new file mode 100644 index 0000000000..ed8d24e043 --- /dev/null +++ b/arch/arm/mach-k3/am62x/am625_init.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM625: SoC specific initialization + * + * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/ + * Suman Anna + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +#define RTC_BASE_ADDRESS 0x2b1f0000 +#define REG_K3RTC_S_CNT_LSW (RTC_BASE_ADDRESS + 0x18) +#define REG_K3RTC_KICK0 (RTC_BASE_ADDRESS + 0x70) +#define REG_K3RTC_KICK1 (RTC_BASE_ADDRESS + 0x74) + +/* Magic values for lock/unlock */ +#define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13 +#define K3RTC_KICK1_UNLOCK_VALUE 0x95a4f1e0 + +/* TISCI DEV ID for A53 Clock */ +#define AM62X_DEV_A53SS0_CORE_0_DEV_ID 135 + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 5); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 4); + mmr_unlock(CTRL_MMR0_BASE, 6); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + + /* Unlock PADCFG_CTRL_MMR padconf registers */ + mmr_unlock(PADCFG_MMR0_BASE, 1); + mmr_unlock(PADCFG_MMR1_BASE, 1); +} + +static __maybe_unused void enable_mcu_esm_reset(void) +{ + /* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */ + u32 stat = readl(CTRLMMR_MCU_RST_CTRL); + + stat &= RST_CTRL_ESM_ERROR_RST_EN_Z_MASK; + writel(stat, CTRLMMR_MCU_RST_CTRL); +} + +/* + * RTC Erratum i2327 Workaround for Silicon Revision 1 + * + * Due to a bug in initial synchronization out of cold power on, + * IRQ status can get locked infinitely if we do not unlock RTC + * + * This workaround *must* be applied within 1 second of power on, + * So, this is closest point to be able to guarantee the max + * timing. + * + * https://www.ti.com/lit/er/sprz487c/sprz487c.pdf + */ +static __maybe_unused void rtc_erratumi2327_init(void) +{ + u32 counter; + + /* + * If counter has gone past 1, nothing we can do, leave + * system locked! This is the only way we know if RTC + * can be used for all practical purposes. + */ + counter = readl(REG_K3RTC_S_CNT_LSW); + if (counter > 1) + return; + /* + * Need to set this up at the very start + * MUST BE DONE under 1 second of boot. + */ + writel(K3RTC_KICK0_UNLOCK_VALUE, REG_K3RTC_KICK0); + writel(K3RTC_KICK1_UNLOCK_VALUE, REG_K3RTC_KICK1); +} + +#if CONFIG_IS_ENABLED(OF_CONTROL) +static int get_a53_cpu_clock_index(ofnode node) +{ + int count, i; + struct ofnode_phandle_args *args; + ofnode clknode; + + clknode = ofnode_path("/bus@f0000/system-controller@44043000/clock-controller"); + if (!ofnode_valid(clknode)) + return -1; + + count = ofnode_count_phandle_with_args(node, "assigned-clocks", "#clock-cells", 0); + + for (i = 0; i < count; i++) { + if (!ofnode_parse_phandle_with_args(node, "assigned-clocks", + "#clock-cells", 0, i, args)) { + if (ofnode_equal(clknode, args->node) && + args->args[0] == AM62X_DEV_A53SS0_CORE_0_DEV_ID) + return i; + } + } + + return -1; +} + +static void fixup_a53_cpu_freq_by_speed_grade(void) +{ + int index, size; + u32 *rates; + ofnode node; + + node = ofnode_path("/a53@0"); + if (!ofnode_valid(node)) + return; + + rates = fdt_getprop_w(ofnode_to_fdt(node), ofnode_to_offset(node), + "assigned-clock-rates", &size); + + index = get_a53_cpu_clock_index(node); + + if (!rates || index < 0 || index >= (size / sizeof(u32))) { + printf("Wrong A53 assigned-clocks configuration\n"); + return; + } + + rates[index] = cpu_to_fdt32(k3_get_a53_max_frequency()); + + printf("Changed A53 CPU frequency to %dHz (%c grade) in DT\n", + k3_get_a53_max_frequency(), k3_get_speed_grade()); +} +#else +static void fixup_a53_cpu_freq_by_speed_grade(void) +{ +} +#endif + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + if (IS_ENABLED(CONFIG_CPU_V7R)) { + setup_k3_mpu_regions(); + rtc_erratumi2327_init(); + } + + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + ctrl_mmr_unlock(); + + /* Init DM early */ + spl_early_init(); + + /* + * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and + * MAIN_UART1 modules and continue regardless of the result of pinctrl. + * Do this without probing the device, but instead by searching the + * device that would request the given sequence number if probed. The + * UARTs will be used by the DM firmware and TIFS firmware images + * respectively and the firmware depend on SPL to initialize the pin + * settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + preloader_console_init(); + + /* + * Allow establishing an early console as required for example when + * doing a UART-based boot. Note that this console may not "survive" + * through a SYSFW PM-init step and will need a re-init in some way + * due to changing module clock frequencies. + */ + if (IS_ENABLED(CONFIG_K3_EARLY_CONS)) + early_console_init(); + + /* + * Configure and start up 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. + */ + if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { + ret = is_rom_loaded_sysfw(&bootdata); + if (!ret) + panic("ROM has not loaded TIFS firmware\n"); + + k3_sysfw_loader(true, NULL, NULL); + } + + /* + * Relocate boot information to OCRAM (after TIFS has opend this + * region for us) so the next bootloader stages can keep access to + * primary vs backup bootmodes. + */ + if (IS_ENABLED(CONFIG_CPU_V7R)) + writel(bootindex, K3_BOOT_PARAM_TABLE_INDEX_OCRAM); + + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done. + */ + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + printf("Failed to initialize clk-k3!\n"); + } + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + + if (IS_ENABLED(CONFIG_ESM_K3)) { + /* Probe/configure ESM0 */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); + if (ret) + printf("esm main init failed: %d\n", ret); + + /* Probe/configure MCUESM */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev); + if (ret) + printf("esm mcu init failed: %d\n", ret); + + enable_mcu_esm_reset(); + } + + if (IS_ENABLED(CONFIG_K3_AM64_DDRSS)) { + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); + } + spl_enable_cache(); + + fixup_a53_cpu_freq_by_speed_grade(); +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >> + MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT; + + switch (bootmode) { + case BOOT_DEVICE_EMMC: + if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) + return MMCSD_MODE_EMMCBOOT; + if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) + return MMCSD_MODE_FS; + return MMCSD_MODE_EMMCBOOT; + case BOOT_DEVICE_MMC: + if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_FS_RAW_MASK) + return MMCSD_MODE_RAW; + default: + return MMCSD_MODE_FS; + } +} + +u32 spl_boot_device(void) +{ + return get_boot_device(); +} diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c deleted file mode 100644 index f341b4f367..0000000000 --- a/arch/arm/mach-k3/am642_init.c +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * AM642: SoC specific initialization - * - * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/ - * Keerthy - * Dave Gerlach - */ - -#include -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include -#include -#include -#include - -#define CTRLMMR_MCU_RST_CTRL 0x04518170 - -#define CTRLMMR_MCU_RST_SRC (MCU_CTRL_MMR0_BASE + 0x18178) -#define COLD_BOOT 0 -#define SW_POR_MCU BIT(24) -#define SW_POR_MAIN BIT(25) - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all PADCFG_MMR1 module registers */ - mmr_unlock(PADCFG_MMR1_BASE, 1); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - mmr_unlock(MCU_CTRL_MMR0_BASE, 6); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 3); - mmr_unlock(CTRL_MMR0_BASE, 5); - mmr_unlock(CTRL_MMR0_BASE, 6); - - /* Unlock all MCU_PADCFG_MMR1 module registers */ - mmr_unlock(MCU_PADCFG_MMR1_BASE, 1); -} - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -#if defined(CONFIG_K3_LOAD_SYSFW) && CONFIG_IS_ENABLED(DM_MMC) -void k3_mmc_stop_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc->saved_clock = mmc->clock; - mmc_set_clock(mmc, 0, true); - } -} - -void k3_mmc_restart_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc_set_clock(mmc, mmc->saved_clock, false); - } -} -#else -void k3_mmc_stop_clock(void) {} -void k3_mmc_restart_clock(void) {} -#endif - -#ifdef CONFIG_SPL_OF_LIST -void do_dt_magic(void) -{ - int ret, rescan; - - /* Perform board detection */ - do_board_detect(); - - /* - * Board detection has been done. - * Let us see if another dtb wouldn't be a better match - * for our board - */ - if (IS_ENABLED(CONFIG_CPU_V7R)) { - ret = fdtdec_resetup(&rescan); - if (!ret && rescan) { - dm_uninit(); - dm_init_and_scan(true); - } - } -} -#endif - -#if CONFIG_IS_ENABLED(USB_STORAGE) -static int fixup_usb_boot(const void *fdt_blob) -{ - int ret = 0; - - switch (spl_boot_device()) { - case BOOT_DEVICE_USB: - /* - * If the boot mode is host, fixup the dr_mode to host - * before cdns3 bind takes place - */ - ret = fdt_find_and_setprop((void *)fdt_blob, - "/bus@f4000/cdns-usb@f900000/usb@f400000", - "dr_mode", "host", 5, 0); - if (ret) - printf("%s: fdt_find_and_setprop() failed:%d\n", - __func__, ret); - fallthrough; - default: - break; - } - - return ret; -} - -int fdtdec_board_setup(const void *fdt_blob) -{ - /* Can use the pointer from the function parameters */ - return fixup_usb_boot(fdt_blob); -} -#endif - -#if defined(CONFIG_ESM_K3) -static void enable_mcu_esm_reset(void) -{ - /* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */ - u32 stat = readl(CTRLMMR_MCU_RST_CTRL); - - stat &= 0xFFFDFFFF; - writel(stat, CTRLMMR_MCU_RST_CTRL); -} -#endif - -void board_init_f(ulong dummy) -{ -#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) || defined(CONFIG_ESM_K3) - struct udevice *dev; - int ret; - int rst_src; -#endif - -#if defined(CONFIG_CPU_V7R) - setup_k3_mpu_regions(); -#endif - - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - ctrl_mmr_unlock(); - - /* Init DM early */ - spl_early_init(); - - preloader_console_init(); - -#if defined(CONFIG_K3_LOAD_SYSFW) - /* - * Process pinctrl for serial3 a.k.a. MAIN UART1 module and continue - * regardless of the result of pinctrl. Do this without probing the - * device, but instead by searching the device that would request the - * given sequence number if probed. The UART will be used by the system - * firmware (SYSFW) image for various purposes and SYSFW depends on us - * to initialize its pin settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - /* - * Load, start up, and configure system controller firmware. - * This will determine whether or not ROM has already loaded - * system firmware and if so, will only perform needed config - * and not attempt to load firmware again. - */ - k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), k3_mmc_stop_clock, - k3_mmc_restart_clock); -#endif - -#if defined(CONFIG_CPU_V7R) - /* - * Errata ID i2331 CPSW: A device lockup can occur during the second - * read of any CPSW subsystem register after any MAIN domain power on - * reset (POR). A MAIN domain POR occurs using the hardware MCU_PORz - * signal, or via software using CTRLMMR_RST_CTRL.SW_MAIN_POR or - * CTRLMMR_MCU_RST_CTRL.SW_MAIN_POR. After these resets, the processor - * and internal bus structures may get into a state which is only - * recoverable with full device reset using MCU_PORz. - * Workaround(s): To avoid the lockup, a warm reset should be issued - * after a MAIN domain POR and before any access to the CPSW registers. - * The warm reset realigns internal clocks and prevents the lockup from - * happening. - */ - ret = uclass_get_device_by_driver(UCLASS_FIRMWARE, DM_DRIVER_GET(ti_sci), &dev); - if (ret) - printf("\n%s:uclass device error [%d]\n",__func__,ret); - - rst_src = readl(CTRLMMR_MCU_RST_SRC); - if (rst_src == COLD_BOOT || rst_src & (SW_POR_MCU | SW_POR_MAIN)) { - printf("Resetting on cold boot to workaround ErrataID:i2331\n"); - printf("Please resend tiboot3.bin in case of UART/DFU boot\n"); - do_reset(NULL, 0, 0, NULL); - } -#endif - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - - do_dt_magic(); - -#if defined(CONFIG_ESM_K3) - /* Probe/configure ESM0 */ - ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); - if (ret) - printf("esm main init failed: %d\n", ret); - - /* Probe/configure MCUESM */ - ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev); - if (ret) - printf("esm mcu init failed: %d\n", ret); - - enable_mcu_esm_reset(); -#endif - -#if defined(CONFIG_K3_AM64_DDRSS) - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); -#endif - if (IS_ENABLED(CONFIG_SPL_ETH) && IS_ENABLED(CONFIG_TI_AM65_CPSW_NUSS) && - spl_boot_device() == BOOT_DEVICE_ETHERNET) { - struct udevice *cpswdev; - - if (uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(am65_cpsw_nuss), &cpswdev)) - printf("Failed to probe am65_cpsw_nuss driver\n"); - } -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - switch (boot_device) { - case BOOT_DEVICE_MMC1: - return MMCSD_MODE_EMMCBOOT; - - case BOOT_DEVICE_MMC2: - return MMCSD_MODE_FS; - - default: - return MMCSD_MODE_RAW; - } -} - -u32 spl_boot_device(void) -{ - return get_boot_device(); -} diff --git a/arch/arm/mach-k3/am64x/Makefile b/arch/arm/mach-k3/am64x/Makefile index acf09c3426..d0b286276c 100644 --- a/arch/arm/mach-k3/am64x/Makefile +++ b/arch/arm/mach-k3/am64x/Makefile @@ -1,2 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_SPL_BUILD) += am642_init.o obj-y += boot.o diff --git a/arch/arm/mach-k3/am64x/am642_init.c b/arch/arm/mach-k3/am64x/am642_init.c new file mode 100644 index 0000000000..41812b7dbf --- /dev/null +++ b/arch/arm/mach-k3/am64x/am642_init.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM642: SoC specific initialization + * + * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/ + * Keerthy + * Dave Gerlach + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +#define CTRLMMR_MCU_RST_CTRL 0x04518170 + +#define CTRLMMR_MCU_RST_SRC (MCU_CTRL_MMR0_BASE + 0x18178) +#define COLD_BOOT 0 +#define SW_POR_MCU BIT(24) +#define SW_POR_MAIN BIT(25) + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all PADCFG_MMR1 module registers */ + mmr_unlock(PADCFG_MMR1_BASE, 1); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 3); + mmr_unlock(CTRL_MMR0_BASE, 5); + mmr_unlock(CTRL_MMR0_BASE, 6); + + /* Unlock all MCU_PADCFG_MMR1 module registers */ + mmr_unlock(MCU_PADCFG_MMR1_BASE, 1); +} + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +#if defined(CONFIG_K3_LOAD_SYSFW) && CONFIG_IS_ENABLED(DM_MMC) +void k3_mmc_stop_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc->saved_clock = mmc->clock; + mmc_set_clock(mmc, 0, true); + } +} + +void k3_mmc_restart_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc_set_clock(mmc, mmc->saved_clock, false); + } +} +#else +void k3_mmc_stop_clock(void) {} +void k3_mmc_restart_clock(void) {} +#endif + +#ifdef CONFIG_SPL_OF_LIST +void do_dt_magic(void) +{ + int ret, rescan; + + /* Perform board detection */ + do_board_detect(); + + /* + * Board detection has been done. + * Let us see if another dtb wouldn't be a better match + * for our board + */ + if (IS_ENABLED(CONFIG_CPU_V7R)) { + ret = fdtdec_resetup(&rescan); + if (!ret && rescan) { + dm_uninit(); + dm_init_and_scan(true); + } + } +} +#endif + +#if CONFIG_IS_ENABLED(USB_STORAGE) +static int fixup_usb_boot(const void *fdt_blob) +{ + int ret = 0; + + switch (spl_boot_device()) { + case BOOT_DEVICE_USB: + /* + * If the boot mode is host, fixup the dr_mode to host + * before cdns3 bind takes place + */ + ret = fdt_find_and_setprop((void *)fdt_blob, + "/bus@f4000/cdns-usb@f900000/usb@f400000", + "dr_mode", "host", 5, 0); + if (ret) + printf("%s: fdt_find_and_setprop() failed:%d\n", + __func__, ret); + fallthrough; + default: + break; + } + + return ret; +} + +int fdtdec_board_setup(const void *fdt_blob) +{ + /* Can use the pointer from the function parameters */ + return fixup_usb_boot(fdt_blob); +} +#endif + +#if defined(CONFIG_ESM_K3) +static void enable_mcu_esm_reset(void) +{ + /* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */ + u32 stat = readl(CTRLMMR_MCU_RST_CTRL); + + stat &= 0xFFFDFFFF; + writel(stat, CTRLMMR_MCU_RST_CTRL); +} +#endif + +void board_init_f(ulong dummy) +{ +#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) || defined(CONFIG_ESM_K3) + struct udevice *dev; + int ret; + int rst_src; +#endif + +#if defined(CONFIG_CPU_V7R) + setup_k3_mpu_regions(); +#endif + + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + ctrl_mmr_unlock(); + + /* Init DM early */ + spl_early_init(); + + preloader_console_init(); + +#if defined(CONFIG_K3_LOAD_SYSFW) + /* + * Process pinctrl for serial3 a.k.a. MAIN UART1 module and continue + * regardless of the result of pinctrl. Do this without probing the + * device, but instead by searching the device that would request the + * given sequence number if probed. The UART will be used by the system + * firmware (SYSFW) image for various purposes and SYSFW depends on us + * to initialize its pin settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 3, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + /* + * Load, start up, and configure system controller firmware. + * This will determine whether or not ROM has already loaded + * system firmware and if so, will only perform needed config + * and not attempt to load firmware again. + */ + k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), k3_mmc_stop_clock, + k3_mmc_restart_clock); +#endif + +#if defined(CONFIG_CPU_V7R) + /* + * Errata ID i2331 CPSW: A device lockup can occur during the second + * read of any CPSW subsystem register after any MAIN domain power on + * reset (POR). A MAIN domain POR occurs using the hardware MCU_PORz + * signal, or via software using CTRLMMR_RST_CTRL.SW_MAIN_POR or + * CTRLMMR_MCU_RST_CTRL.SW_MAIN_POR. After these resets, the processor + * and internal bus structures may get into a state which is only + * recoverable with full device reset using MCU_PORz. + * Workaround(s): To avoid the lockup, a warm reset should be issued + * after a MAIN domain POR and before any access to the CPSW registers. + * The warm reset realigns internal clocks and prevents the lockup from + * happening. + */ + ret = uclass_get_device_by_driver(UCLASS_FIRMWARE, DM_DRIVER_GET(ti_sci), &dev); + if (ret) + printf("\n%s:uclass device error [%d]\n",__func__,ret); + + rst_src = readl(CTRLMMR_MCU_RST_SRC); + if (rst_src == COLD_BOOT || rst_src & (SW_POR_MCU | SW_POR_MAIN)) { + printf("Resetting on cold boot to workaround ErrataID:i2331\n"); + printf("Please resend tiboot3.bin in case of UART/DFU boot\n"); + do_reset(NULL, 0, 0, NULL); + } +#endif + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + + do_dt_magic(); + +#if defined(CONFIG_ESM_K3) + /* Probe/configure ESM0 */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); + if (ret) + printf("esm main init failed: %d\n", ret); + + /* Probe/configure MCUESM */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev); + if (ret) + printf("esm mcu init failed: %d\n", ret); + + enable_mcu_esm_reset(); +#endif + +#if defined(CONFIG_K3_AM64_DDRSS) + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); +#endif + if (IS_ENABLED(CONFIG_SPL_ETH) && IS_ENABLED(CONFIG_TI_AM65_CPSW_NUSS) && + spl_boot_device() == BOOT_DEVICE_ETHERNET) { + struct udevice *cpswdev; + + if (uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(am65_cpsw_nuss), &cpswdev)) + printf("Failed to probe am65_cpsw_nuss driver\n"); + } +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + switch (boot_device) { + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_EMMCBOOT; + + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_FS; + + default: + return MMCSD_MODE_RAW; + } +} + +u32 spl_boot_device(void) +{ + return get_boot_device(); +} diff --git a/arch/arm/mach-k3/am654_fdt.c b/arch/arm/mach-k3/am654_fdt.c deleted file mode 100644 index 652fe8d32b..0000000000 --- a/arch/arm/mach-k3/am654_fdt.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2023 Toradex - https://www.toradex.com/ - */ - -#include "common_fdt.h" -#include - -int ft_system_setup(void *blob, struct bd_info *bd) -{ - return fdt_fixup_msmc_ram_k3(blob); -} diff --git a/arch/arm/mach-k3/am654_init.c b/arch/arm/mach-k3/am654_init.c deleted file mode 100644 index 7c2a143ed1..0000000000 --- a/arch/arm/mach-k3/am654_init.c +++ /dev/null @@ -1,353 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * AM6: SoC specific initialization - * - * Copyright (C) 2017-2018 Texas Instruments Incorporated - https://www.ti.com/ - * Lokesh Vutla - */ - -#include -#include -#include -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_K3_LOAD_SYSFW -struct fwl_data main_cbass_fwls[] = { - { "MMCSD1_CFG", 2057, 1 }, - { "MMCSD0_CFG", 2058, 1 }, - { "USB3SS0_SLV0", 2176, 2 }, - { "PCIE0_SLV", 2336, 8 }, - { "PCIE1_SLV", 2337, 8 }, - { "PCIE0_CFG", 2688, 1 }, - { "PCIE1_CFG", 2689, 1 }, -}, mcu_cbass_fwls[] = { - { "MCU_ARMSS0_CORE0_SLV", 1024, 1 }, - { "MCU_ARMSS0_CORE1_SLV", 1028, 1 }, - { "MCU_FSS0_S1", 1033, 8 }, - { "MCU_FSS0_S0", 1036, 8 }, - { "MCU_CPSW0", 1220, 1 }, -}; -#endif - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 6); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 3); - mmr_unlock(CTRL_MMR0_BASE, 6); - mmr_unlock(CTRL_MMR0_BASE, 7); -} - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); - -static void store_boot_index_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); -} - -#if defined(CONFIG_K3_LOAD_SYSFW) && CONFIG_IS_ENABLED(DM_MMC) -void k3_mmc_stop_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc->saved_clock = mmc->clock; - mmc_set_clock(mmc, 0, true); - } -} - -void k3_mmc_restart_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc_set_clock(mmc, mmc->saved_clock, false); - } -} -#else -void k3_mmc_stop_clock(void) {} -void k3_mmc_restart_clock(void) {} -#endif -#if CONFIG_IS_ENABLED(DFU) || CONFIG_IS_ENABLED(USB_STORAGE) -#define CTRLMMR_SERDES0_CTRL 0x00104080 -#define PCIE_LANE0 0x1 -static int fixup_usb_boot(void) -{ - int ret; - - switch (spl_boot_device()) { - case BOOT_DEVICE_USB: - /* - * If bootmode is Host bootmode, fixup the dr_mode to host - * before the dwc3 bind takes place - */ - ret = fdt_find_and_setprop((void *)gd->fdt_blob, - "/bus@100000/dwc3@4000000/usb@10000", - "dr_mode", "host", 5, 0); - if (ret) - printf("%s: fdt_find_and_setprop() failed:%d\n", __func__, - ret); - fallthrough; - case BOOT_DEVICE_DFU: - /* - * The serdes mux between PCIe and USB3 needs to be set to PCIe for - * accessing the interface at USB 2.0 - */ - writel(PCIE_LANE0, CTRLMMR_SERDES0_CTRL); - default: - break; - } - - return 0; -} - -int fdtdec_board_setup(const void *fdt_blob) -{ - return fixup_usb_boot(); -} -#endif - -static void setup_am654_navss_northbridge(void) -{ - /* - * NB0 is bridge to SRAM and NB1 is bridge to DDR. - * To ensure that SRAM transfers are not stalled due to - * delays during DDR refreshes, SRAM traffic should be higher - * priority (threadmap=2) than DDR traffic (threadmap=0). - */ - writel(0x2, NAVSS0_NBSS_NB0_CFG_BASE + NAVSS_NBSS_THREADMAP); - writel(0x0, NAVSS0_NBSS_NB1_CFG_BASE + NAVSS_NBSS_THREADMAP); -} - -void board_init_f(ulong dummy) -{ -#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) - struct udevice *dev; - size_t pool_size; - void *pool_addr; - int ret; -#endif - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_index_from_rom(); - - /* Make all control module registers accessible */ - ctrl_mmr_unlock(); - - setup_am654_navss_northbridge(); - -#ifdef CONFIG_CPU_V7R - disable_linefill_optimization(); - setup_k3_mpu_regions(); -#endif - - /* Init DM early in-order to invoke system controller */ - spl_early_init(); - -#ifdef CONFIG_K3_EARLY_CONS - /* - * Allow establishing an early console as required for example when - * doing a UART-based boot. Note that this console may not "survive" - * through a SYSFW PM-init step and will need a re-init in some way - * due to changing module clock frequencies. - */ - early_console_init(); -#endif - -#ifdef CONFIG_K3_LOAD_SYSFW - /* - * Initialize an early full malloc environment. Do so by allocating a - * new malloc area inside the currently active pre-relocation "first" - * malloc pool of which we use all that's left. - */ - pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr; - pool_addr = malloc(pool_size); - if (!pool_addr) - panic("ERROR: Can't allocate full malloc pool!\n"); - - mem_malloc_init((ulong)pool_addr, (ulong)pool_size); - gd->flags |= GD_FLG_FULL_MALLOC_INIT; - debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n", - __func__, (unsigned long)pool_addr, (unsigned long)pool_size); - /* - * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue - * regardless of the result of pinctrl. Do this without probing the - * device, but instead by searching the device that would request the - * given sequence number if probed. The UART will be used by the system - * firmware (SYSFW) image for various purposes and SYSFW depends on us - * to initialize its pin settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - /* - * Load, start up, and configure system controller firmware while - * also populating the SYSFW post-PM configuration callback hook. - */ - k3_sysfw_loader(false, k3_mmc_stop_clock, k3_mmc_restart_clock); - - /* Prepare console output */ - preloader_console_init(); - - /* Disable ROM configured firewalls right after loading sysfw */ - remove_fwl_configs(main_cbass_fwls, ARRAY_SIZE(main_cbass_fwls)); - remove_fwl_configs(mcu_cbass_fwls, ARRAY_SIZE(mcu_cbass_fwls)); -#else - /* Prepare console output */ - preloader_console_init(); -#endif - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - - /* Perform board detection */ - do_board_detect(); - -#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) - ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(k3_avs), - &dev); - if (ret) - printf("AVS init failed: %d\n", ret); -#endif - -#ifdef CONFIG_K3_AM654_DDRSS - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); -#endif - spl_enable_cache(); -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ -#if defined(CONFIG_SUPPORT_EMMC_BOOT) - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - - u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >> - CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT; - - /* eMMC boot0 mode is only supported for primary boot */ - if (bootindex == K3_PRIMARY_BOOTMODE && - bootmode == BOOT_DEVICE_MMC1) - return MMCSD_MODE_EMMCBOOT; -#endif - - /* Everything else use filesystem if available */ -#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4) - return MMCSD_MODE_FS; -#else - return MMCSD_MODE_RAW; -#endif -} - -static u32 __get_backup_bootmedia(u32 devstat) -{ - u32 bkup_boot = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> - CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; - - switch (bkup_boot) { - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_USB; - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - case BACKUP_BOOT_DEVICE_MMC2: - { - u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> - CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; - if (port == 0x0) - return BOOT_DEVICE_MMC1; - return BOOT_DEVICE_MMC2; - } - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - case BACKUP_BOOT_DEVICE_HYPERFLASH: - return BOOT_DEVICE_HYPERFLASH; - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - }; - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 devstat) -{ - u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >> - CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT; - - if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI) - bootmode = BOOT_DEVICE_SPI; - - if (bootmode == BOOT_DEVICE_MMC2) { - u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_MMC_PORT_MASK) >> - CTRLMMR_MAIN_DEVSTAT_MMC_PORT_SHIFT; - if (port == 0x0) - bootmode = BOOT_DEVICE_MMC1; - } else if (bootmode == BOOT_DEVICE_MMC1) { - u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_MASK) >> - CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_SHIFT; - if (port == 0x1) - bootmode = BOOT_DEVICE_MMC2; - } else if (bootmode == BOOT_DEVICE_DFU) { - u32 mode = (devstat & CTRLMMR_MAIN_DEVSTAT_USB_MODE_MASK) >> - CTRLMMR_MAIN_DEVSTAT_USB_MODE_SHIFT; - if (mode == 0x2) - bootmode = BOOT_DEVICE_USB; - } - - return bootmode; -} - -u32 spl_boot_device(void) -{ - u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - - if (bootindex == K3_PRIMARY_BOOTMODE) - return __get_primary_bootmedia(devstat); - else - return __get_backup_bootmedia(devstat); -} diff --git a/arch/arm/mach-k3/am65x/Makefile b/arch/arm/mach-k3/am65x/Makefile new file mode 100644 index 0000000000..20d5f1d3bf --- /dev/null +++ b/arch/arm/mach-k3/am65x/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_OF_SYSTEM_SETUP) += am654_fdt.o +obj-$(CONFIG_SPL_BUILD) += am654_init.o diff --git a/arch/arm/mach-k3/am65x/am654_fdt.c b/arch/arm/mach-k3/am65x/am654_fdt.c new file mode 100644 index 0000000000..bcb15208be --- /dev/null +++ b/arch/arm/mach-k3/am65x/am654_fdt.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2023 Toradex - https://www.toradex.com/ + */ + +#include + +#include "../common_fdt.h" + +int ft_system_setup(void *blob, struct bd_info *bd) +{ + return fdt_fixup_msmc_ram_k3(blob); +} diff --git a/arch/arm/mach-k3/am65x/am654_init.c b/arch/arm/mach-k3/am65x/am654_init.c new file mode 100644 index 0000000000..a4f038029d --- /dev/null +++ b/arch/arm/mach-k3/am65x/am654_init.c @@ -0,0 +1,354 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * AM6: SoC specific initialization + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - https://www.ti.com/ + * Lokesh Vutla + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_K3_LOAD_SYSFW +struct fwl_data main_cbass_fwls[] = { + { "MMCSD1_CFG", 2057, 1 }, + { "MMCSD0_CFG", 2058, 1 }, + { "USB3SS0_SLV0", 2176, 2 }, + { "PCIE0_SLV", 2336, 8 }, + { "PCIE1_SLV", 2337, 8 }, + { "PCIE0_CFG", 2688, 1 }, + { "PCIE1_CFG", 2689, 1 }, +}, mcu_cbass_fwls[] = { + { "MCU_ARMSS0_CORE0_SLV", 1024, 1 }, + { "MCU_ARMSS0_CORE1_SLV", 1028, 1 }, + { "MCU_FSS0_S1", 1033, 8 }, + { "MCU_FSS0_S0", 1036, 8 }, + { "MCU_CPSW0", 1220, 1 }, +}; +#endif + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 3); + mmr_unlock(CTRL_MMR0_BASE, 6); + mmr_unlock(CTRL_MMR0_BASE, 7); +} + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); + +static void store_boot_index_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); +} + +#if defined(CONFIG_K3_LOAD_SYSFW) && CONFIG_IS_ENABLED(DM_MMC) +void k3_mmc_stop_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc->saved_clock = mmc->clock; + mmc_set_clock(mmc, 0, true); + } +} + +void k3_mmc_restart_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc_set_clock(mmc, mmc->saved_clock, false); + } +} +#else +void k3_mmc_stop_clock(void) {} +void k3_mmc_restart_clock(void) {} +#endif +#if CONFIG_IS_ENABLED(DFU) || CONFIG_IS_ENABLED(USB_STORAGE) +#define CTRLMMR_SERDES0_CTRL 0x00104080 +#define PCIE_LANE0 0x1 +static int fixup_usb_boot(void) +{ + int ret; + + switch (spl_boot_device()) { + case BOOT_DEVICE_USB: + /* + * If bootmode is Host bootmode, fixup the dr_mode to host + * before the dwc3 bind takes place + */ + ret = fdt_find_and_setprop((void *)gd->fdt_blob, + "/bus@100000/dwc3@4000000/usb@10000", + "dr_mode", "host", 5, 0); + if (ret) + printf("%s: fdt_find_and_setprop() failed:%d\n", __func__, + ret); + fallthrough; + case BOOT_DEVICE_DFU: + /* + * The serdes mux between PCIe and USB3 needs to be set to PCIe for + * accessing the interface at USB 2.0 + */ + writel(PCIE_LANE0, CTRLMMR_SERDES0_CTRL); + default: + break; + } + + return 0; +} + +int fdtdec_board_setup(const void *fdt_blob) +{ + return fixup_usb_boot(); +} +#endif + +static void setup_am654_navss_northbridge(void) +{ + /* + * NB0 is bridge to SRAM and NB1 is bridge to DDR. + * To ensure that SRAM transfers are not stalled due to + * delays during DDR refreshes, SRAM traffic should be higher + * priority (threadmap=2) than DDR traffic (threadmap=0). + */ + writel(0x2, NAVSS0_NBSS_NB0_CFG_BASE + NAVSS_NBSS_THREADMAP); + writel(0x0, NAVSS0_NBSS_NB1_CFG_BASE + NAVSS_NBSS_THREADMAP); +} + +void board_init_f(ulong dummy) +{ +#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) + struct udevice *dev; + size_t pool_size; + void *pool_addr; + int ret; +#endif + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_index_from_rom(); + + /* Make all control module registers accessible */ + ctrl_mmr_unlock(); + + setup_am654_navss_northbridge(); + +#ifdef CONFIG_CPU_V7R + disable_linefill_optimization(); + setup_k3_mpu_regions(); +#endif + + /* Init DM early in-order to invoke system controller */ + spl_early_init(); + +#ifdef CONFIG_K3_EARLY_CONS + /* + * Allow establishing an early console as required for example when + * doing a UART-based boot. Note that this console may not "survive" + * through a SYSFW PM-init step and will need a re-init in some way + * due to changing module clock frequencies. + */ + early_console_init(); +#endif + +#ifdef CONFIG_K3_LOAD_SYSFW + /* + * Initialize an early full malloc environment. Do so by allocating a + * new malloc area inside the currently active pre-relocation "first" + * malloc pool of which we use all that's left. + */ + pool_size = CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr; + pool_addr = malloc(pool_size); + if (!pool_addr) + panic("ERROR: Can't allocate full malloc pool!\n"); + + mem_malloc_init((ulong)pool_addr, (ulong)pool_size); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; + debug("%s: initialized an early full malloc pool at 0x%08lx of 0x%lx bytes\n", + __func__, (unsigned long)pool_addr, (unsigned long)pool_size); + /* + * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue + * regardless of the result of pinctrl. Do this without probing the + * device, but instead by searching the device that would request the + * given sequence number if probed. The UART will be used by the system + * firmware (SYSFW) image for various purposes and SYSFW depends on us + * to initialize its pin settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + /* + * Load, start up, and configure system controller firmware while + * also populating the SYSFW post-PM configuration callback hook. + */ + k3_sysfw_loader(false, k3_mmc_stop_clock, k3_mmc_restart_clock); + + /* Prepare console output */ + preloader_console_init(); + + /* Disable ROM configured firewalls right after loading sysfw */ + remove_fwl_configs(main_cbass_fwls, ARRAY_SIZE(main_cbass_fwls)); + remove_fwl_configs(mcu_cbass_fwls, ARRAY_SIZE(mcu_cbass_fwls)); +#else + /* Prepare console output */ + preloader_console_init(); +#endif + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + + /* Perform board detection */ + do_board_detect(); + +#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(k3_avs), + &dev); + if (ret) + printf("AVS init failed: %d\n", ret); +#endif + +#ifdef CONFIG_K3_AM654_DDRSS + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); +#endif + spl_enable_cache(); +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ +#if defined(CONFIG_SUPPORT_EMMC_BOOT) + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + + u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >> + CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT; + + /* eMMC boot0 mode is only supported for primary boot */ + if (bootindex == K3_PRIMARY_BOOTMODE && + bootmode == BOOT_DEVICE_MMC1) + return MMCSD_MODE_EMMCBOOT; +#endif + + /* Everything else use filesystem if available */ +#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4) + return MMCSD_MODE_FS; +#else + return MMCSD_MODE_RAW; +#endif +} + +static u32 __get_backup_bootmedia(u32 devstat) +{ + u32 bkup_boot = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> + CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; + + switch (bkup_boot) { + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_USB; + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + case BACKUP_BOOT_DEVICE_MMC2: + { + u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> + CTRLMMR_MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; + if (port == 0x0) + return BOOT_DEVICE_MMC1; + return BOOT_DEVICE_MMC2; + } + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + case BACKUP_BOOT_DEVICE_HYPERFLASH: + return BOOT_DEVICE_HYPERFLASH; + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + }; + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 devstat) +{ + u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >> + CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT; + + if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI) + bootmode = BOOT_DEVICE_SPI; + + if (bootmode == BOOT_DEVICE_MMC2) { + u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_MMC_PORT_MASK) >> + CTRLMMR_MAIN_DEVSTAT_MMC_PORT_SHIFT; + if (port == 0x0) + bootmode = BOOT_DEVICE_MMC1; + } else if (bootmode == BOOT_DEVICE_MMC1) { + u32 port = (devstat & CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_MASK) >> + CTRLMMR_MAIN_DEVSTAT_EMMC_PORT_SHIFT; + if (port == 0x1) + bootmode = BOOT_DEVICE_MMC2; + } else if (bootmode == BOOT_DEVICE_DFU) { + u32 mode = (devstat & CTRLMMR_MAIN_DEVSTAT_USB_MODE_MASK) >> + CTRLMMR_MAIN_DEVSTAT_USB_MODE_SHIFT; + if (mode == 0x2) + bootmode = BOOT_DEVICE_USB; + } + + return bootmode; +} + +u32 spl_boot_device(void) +{ + u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); + + if (bootindex == K3_PRIMARY_BOOTMODE) + return __get_primary_bootmedia(devstat); + else + return __get_backup_bootmedia(devstat); +} diff --git a/arch/arm/mach-k3/j721e/Makefile b/arch/arm/mach-k3/j721e/Makefile new file mode 100644 index 0000000000..982b88db57 --- /dev/null +++ b/arch/arm/mach-k3/j721e/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_OF_SYSTEM_SETUP) += j721e_fdt.o +obj-$(CONFIG_SPL_BUILD) += j721e_init.o diff --git a/arch/arm/mach-k3/j721e/j721e_fdt.c b/arch/arm/mach-k3/j721e/j721e_fdt.c new file mode 100644 index 0000000000..bcb15208be --- /dev/null +++ b/arch/arm/mach-k3/j721e/j721e_fdt.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2023 Toradex - https://www.toradex.com/ + */ + +#include + +#include "../common_fdt.h" + +int ft_system_setup(void *blob, struct bd_info *bd) +{ + return fdt_fixup_msmc_ram_k3(blob); +} diff --git a/arch/arm/mach-k3/j721e/j721e_init.c b/arch/arm/mach-k3/j721e/j721e_init.c new file mode 100644 index 0000000000..c2024f2500 --- /dev/null +++ b/arch/arm/mach-k3/j721e/j721e_init.c @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * J721E: SoC specific initialization + * + * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/ + * Lokesh Vutla + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +#ifdef CONFIG_K3_LOAD_SYSFW +struct fwl_data cbass_hc_cfg0_fwls[] = { +#if defined(CONFIG_TARGET_J721E_R5_EVM) + { "PCIE0_CFG", 2560, 8 }, + { "PCIE1_CFG", 2561, 8 }, + { "USB3SS0_CORE", 2568, 4 }, + { "USB3SS1_CORE", 2570, 4 }, + { "EMMC8SS0_CFG", 2576, 4 }, + { "UFS_HCI0_CFG", 2580, 4 }, + { "SERDES0", 2584, 1 }, + { "SERDES1", 2585, 1 }, +#elif defined(CONFIG_TARGET_J7200_R5_EVM) + { "PCIE1_CFG", 2561, 7 }, +#endif +}, cbass_hc0_fwls[] = { +#if defined(CONFIG_TARGET_J721E_R5_EVM) + { "PCIE0_HP", 2528, 24 }, + { "PCIE0_LP", 2529, 24 }, + { "PCIE1_HP", 2530, 24 }, + { "PCIE1_LP", 2531, 24 }, +#endif +}, cbass_rc_cfg0_fwls[] = { + { "EMMCSD4SS0_CFG", 2380, 4 }, +}, cbass_rc0_fwls[] = { + { "GPMC0", 2310, 8 }, +}, infra_cbass0_fwls[] = { + { "PLL_MMR0", 8, 26 }, + { "CTRL_MMR0", 9, 16 }, +}, mcu_cbass0_fwls[] = { + { "MCU_R5FSS0_CORE0", 1024, 4 }, + { "MCU_R5FSS0_CORE0_CFG", 1025, 2 }, + { "MCU_R5FSS0_CORE1", 1028, 4 }, + { "MCU_FSS0_CFG", 1032, 12 }, + { "MCU_FSS0_S1", 1033, 8 }, + { "MCU_FSS0_S0", 1036, 8 }, + { "MCU_PSROM49152X32", 1048, 1 }, + { "MCU_MSRAM128KX64", 1050, 8 }, + { "MCU_CTRL_MMR0", 1200, 8 }, + { "MCU_PLL_MMR0", 1201, 3 }, + { "MCU_CPSW0", 1220, 2 }, +}, wkup_cbass0_fwls[] = { + { "WKUP_CTRL_MMR0", 131, 16 }, +}; +#endif + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 3); + mmr_unlock(CTRL_MMR0_BASE, 5); + if (soc_is_j721e()) + mmr_unlock(CTRL_MMR0_BASE, 6); + mmr_unlock(CTRL_MMR0_BASE, 7); +} + +#if defined(CONFIG_K3_LOAD_SYSFW) +void k3_mmc_stop_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc->saved_clock = mmc->clock; + mmc_set_clock(mmc, 0, true); + } +} + +void k3_mmc_restart_clock(void) +{ + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc_set_clock(mmc, mmc->saved_clock, false); + } +} +#endif + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +#ifdef CONFIG_SPL_OF_LIST +void do_dt_magic(void) +{ + int ret, rescan, mmc_dev = -1; + static struct mmc *mmc; + + /* Perform board detection */ + do_board_detect(); + + /* + * Board detection has been done. + * Let us see if another dtb wouldn't be a better match + * for our board + */ + if (IS_ENABLED(CONFIG_CPU_V7R)) { + ret = fdtdec_resetup(&rescan); + if (!ret && rescan) { + dm_uninit(); + dm_init_and_scan(true); + } + } + + /* + * Because of multi DTB configuration, the MMC device has + * to be re-initialized after reconfiguring FDT inorder to + * boot from MMC. Do this when boot mode is MMC and ROM has + * not loaded SYSFW. + */ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + mmc_dev = 0; + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + mmc_dev = 1; + break; + } + + if (mmc_dev > 0 && !is_rom_loaded_sysfw(&bootdata)) { + ret = mmc_init_device(mmc_dev); + if (!ret) { + mmc = find_mmc_device(mmc_dev); + if (mmc) { + ret = mmc_init(mmc); + if (ret) { + printf("mmc init failed with error: %d\n", ret); + } + } + } + } +} +#endif + +void board_init_f(ulong dummy) +{ +#if defined(CONFIG_K3_J721E_DDRSS) || defined(CONFIG_K3_LOAD_SYSFW) + struct udevice *dev; + int ret; +#endif + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + /* Make all control module registers accessible */ + ctrl_mmr_unlock(); + +#ifdef CONFIG_CPU_V7R + disable_linefill_optimization(); + setup_k3_mpu_regions(); +#endif + + /* Init DM early */ + spl_early_init(); + +#ifdef CONFIG_K3_LOAD_SYSFW + /* + * Process pinctrl for the serial0 a.k.a. MCU_UART0 module and continue + * regardless of the result of pinctrl. Do this without probing the + * device, but instead by searching the device that would request the + * given sequence number if probed. The UART will be used by the system + * firmware (SYSFW) image for various purposes and SYSFW depends on us + * to initialize its pin settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done. + */ + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + panic("Failed to initialize clk-k3!\n"); + } + + /* + * 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. + */ + k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), + k3_mmc_stop_clock, k3_mmc_restart_clock); + +#ifdef CONFIG_SPL_OF_LIST + do_dt_magic(); +#endif + + /* Prepare console output */ + preloader_console_init(); + + /* Disable ROM configured firewalls right after loading sysfw */ + remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); + remove_fwl_configs(cbass_hc0_fwls, ARRAY_SIZE(cbass_hc0_fwls)); + remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); + remove_fwl_configs(cbass_rc0_fwls, ARRAY_SIZE(cbass_rc0_fwls)); + remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); + remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); + remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); +#else + /* Prepare console output */ + preloader_console_init(); +#endif + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); + + /* Perform board detection */ + do_board_detect(); + +#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(k3_avs), + &dev); + if (ret) + printf("AVS init failed: %d\n", ret); +#endif + +#if defined(CONFIG_K3_J721E_DDRSS) + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM init failed: %d\n", ret); +#endif + spl_enable_cache(); +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + switch (boot_device) { + case BOOT_DEVICE_MMC1: + if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) { + if (spl_mmc_emmc_boot_partition(mmc)) + return MMCSD_MODE_EMMCBOOT; + return MMCSD_MODE_FS; + } + if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) + return MMCSD_MODE_FS; + return MMCSD_MODE_EMMCBOOT; + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_FS; + default: + return MMCSD_MODE_RAW; + } +} + +static u32 __get_backup_bootmedia(u32 main_devstat) +{ + u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> + MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; + + switch (bkup_boot) { + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_DFU; + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + case BACKUP_BOOT_DEVICE_MMC2: + { + u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> + MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; + if (port == 0x0) + return BOOT_DEVICE_MMC1; + return BOOT_DEVICE_MMC2; + } + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + } + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) +{ + + u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + + bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << + BOOT_MODE_B_SHIFT; + + if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || + bootmode == BOOT_DEVICE_XSPI) + bootmode = BOOT_DEVICE_SPI; + + if (bootmode == BOOT_DEVICE_MMC2) { + u32 port = (main_devstat & + MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> + MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; + if (port == 0x0) + bootmode = BOOT_DEVICE_MMC1; + } + + return bootmode; +} + +u32 spl_spi_boot_bus(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmode = ((wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT) | + ((main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << BOOT_MODE_B_SHIFT); + + return (bootmode == BOOT_DEVICE_QSPI) ? 1 : 0; +} + +u32 spl_boot_device(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat; + + if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) { + printf("ERROR: MCU only boot is not yet supported\n"); + return BOOT_DEVICE_RAM; + } + + /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ + main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + + if (bootindex == K3_PRIMARY_BOOTMODE) + return __get_primary_bootmedia(main_devstat, wkup_devstat); + else + return __get_backup_bootmedia(main_devstat); +} diff --git a/arch/arm/mach-k3/j721e_fdt.c b/arch/arm/mach-k3/j721e_fdt.c deleted file mode 100644 index 652fe8d32b..0000000000 --- a/arch/arm/mach-k3/j721e_fdt.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2023 Toradex - https://www.toradex.com/ - */ - -#include "common_fdt.h" -#include - -int ft_system_setup(void *blob, struct bd_info *bd) -{ - return fdt_fixup_msmc_ram_k3(blob); -} diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c deleted file mode 100644 index 7ee9b75de4..0000000000 --- a/arch/arm/mach-k3/j721e_init.c +++ /dev/null @@ -1,392 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * J721E: SoC specific initialization - * - * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/ - * Lokesh Vutla - */ - -#include -#include -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_K3_LOAD_SYSFW -struct fwl_data cbass_hc_cfg0_fwls[] = { -#if defined(CONFIG_TARGET_J721E_R5_EVM) - { "PCIE0_CFG", 2560, 8 }, - { "PCIE1_CFG", 2561, 8 }, - { "USB3SS0_CORE", 2568, 4 }, - { "USB3SS1_CORE", 2570, 4 }, - { "EMMC8SS0_CFG", 2576, 4 }, - { "UFS_HCI0_CFG", 2580, 4 }, - { "SERDES0", 2584, 1 }, - { "SERDES1", 2585, 1 }, -#elif defined(CONFIG_TARGET_J7200_R5_EVM) - { "PCIE1_CFG", 2561, 7 }, -#endif -}, cbass_hc0_fwls[] = { -#if defined(CONFIG_TARGET_J721E_R5_EVM) - { "PCIE0_HP", 2528, 24 }, - { "PCIE0_LP", 2529, 24 }, - { "PCIE1_HP", 2530, 24 }, - { "PCIE1_LP", 2531, 24 }, -#endif -}, cbass_rc_cfg0_fwls[] = { - { "EMMCSD4SS0_CFG", 2380, 4 }, -}, cbass_rc0_fwls[] = { - { "GPMC0", 2310, 8 }, -}, infra_cbass0_fwls[] = { - { "PLL_MMR0", 8, 26 }, - { "CTRL_MMR0", 9, 16 }, -}, mcu_cbass0_fwls[] = { - { "MCU_R5FSS0_CORE0", 1024, 4 }, - { "MCU_R5FSS0_CORE0_CFG", 1025, 2 }, - { "MCU_R5FSS0_CORE1", 1028, 4 }, - { "MCU_FSS0_CFG", 1032, 12 }, - { "MCU_FSS0_S1", 1033, 8 }, - { "MCU_FSS0_S0", 1036, 8 }, - { "MCU_PSROM49152X32", 1048, 1 }, - { "MCU_MSRAM128KX64", 1050, 8 }, - { "MCU_CTRL_MMR0", 1200, 8 }, - { "MCU_PLL_MMR0", 1201, 3 }, - { "MCU_CPSW0", 1220, 2 }, -}, wkup_cbass0_fwls[] = { - { "WKUP_CTRL_MMR0", 131, 16 }, -}; -#endif - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 3); - mmr_unlock(CTRL_MMR0_BASE, 5); - if (soc_is_j721e()) - mmr_unlock(CTRL_MMR0_BASE, 6); - mmr_unlock(CTRL_MMR0_BASE, 7); -} - -#if defined(CONFIG_K3_LOAD_SYSFW) -void k3_mmc_stop_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc->saved_clock = mmc->clock; - mmc_set_clock(mmc, 0, true); - } -} - -void k3_mmc_restart_clock(void) -{ - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc_set_clock(mmc, mmc->saved_clock, false); - } -} -#endif - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -#ifdef CONFIG_SPL_OF_LIST -void do_dt_magic(void) -{ - int ret, rescan, mmc_dev = -1; - static struct mmc *mmc; - - /* Perform board detection */ - do_board_detect(); - - /* - * Board detection has been done. - * Let us see if another dtb wouldn't be a better match - * for our board - */ - if (IS_ENABLED(CONFIG_CPU_V7R)) { - ret = fdtdec_resetup(&rescan); - if (!ret && rescan) { - dm_uninit(); - dm_init_and_scan(true); - } - } - - /* - * Because of multi DTB configuration, the MMC device has - * to be re-initialized after reconfiguring FDT inorder to - * boot from MMC. Do this when boot mode is MMC and ROM has - * not loaded SYSFW. - */ - switch (spl_boot_device()) { - case BOOT_DEVICE_MMC1: - mmc_dev = 0; - break; - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - mmc_dev = 1; - break; - } - - if (mmc_dev > 0 && !is_rom_loaded_sysfw(&bootdata)) { - ret = mmc_init_device(mmc_dev); - if (!ret) { - mmc = find_mmc_device(mmc_dev); - if (mmc) { - ret = mmc_init(mmc); - if (ret) { - printf("mmc init failed with error: %d\n", ret); - } - } - } - } -} -#endif - -void board_init_f(ulong dummy) -{ -#if defined(CONFIG_K3_J721E_DDRSS) || defined(CONFIG_K3_LOAD_SYSFW) - struct udevice *dev; - int ret; -#endif - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - /* Make all control module registers accessible */ - ctrl_mmr_unlock(); - -#ifdef CONFIG_CPU_V7R - disable_linefill_optimization(); - setup_k3_mpu_regions(); -#endif - - /* Init DM early */ - spl_early_init(); - -#ifdef CONFIG_K3_LOAD_SYSFW - /* - * Process pinctrl for the serial0 a.k.a. MCU_UART0 module and continue - * regardless of the result of pinctrl. Do this without probing the - * device, but instead by searching the device that would request the - * given sequence number if probed. The UART will be used by the system - * firmware (SYSFW) image for various purposes and SYSFW depends on us - * to initialize its pin settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done. - */ - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - panic("Failed to initialize clk-k3!\n"); - } - - /* - * 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. - */ - k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), - k3_mmc_stop_clock, k3_mmc_restart_clock); - -#ifdef CONFIG_SPL_OF_LIST - do_dt_magic(); -#endif - - /* Prepare console output */ - preloader_console_init(); - - /* Disable ROM configured firewalls right after loading sysfw */ - remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); - remove_fwl_configs(cbass_hc0_fwls, ARRAY_SIZE(cbass_hc0_fwls)); - remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); - remove_fwl_configs(cbass_rc0_fwls, ARRAY_SIZE(cbass_rc0_fwls)); - remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); - remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); - remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); -#else - /* Prepare console output */ - preloader_console_init(); -#endif - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); - - /* Perform board detection */ - do_board_detect(); - -#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0) - ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(k3_avs), - &dev); - if (ret) - printf("AVS init failed: %d\n", ret); -#endif - -#if defined(CONFIG_K3_J721E_DDRSS) - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM init failed: %d\n", ret); -#endif - spl_enable_cache(); -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - switch (boot_device) { - case BOOT_DEVICE_MMC1: - if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) { - if (spl_mmc_emmc_boot_partition(mmc)) - return MMCSD_MODE_EMMCBOOT; - return MMCSD_MODE_FS; - } - if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) - return MMCSD_MODE_FS; - return MMCSD_MODE_EMMCBOOT; - case BOOT_DEVICE_MMC2: - return MMCSD_MODE_FS; - default: - return MMCSD_MODE_RAW; - } -} - -static u32 __get_backup_bootmedia(u32 main_devstat) -{ - u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> - MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; - - switch (bkup_boot) { - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_DFU; - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - case BACKUP_BOOT_DEVICE_MMC2: - { - u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> - MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; - if (port == 0x0) - return BOOT_DEVICE_MMC1; - return BOOT_DEVICE_MMC2; - } - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - } - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) -{ - - u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - - bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << - BOOT_MODE_B_SHIFT; - - if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || - bootmode == BOOT_DEVICE_XSPI) - bootmode = BOOT_DEVICE_SPI; - - if (bootmode == BOOT_DEVICE_MMC2) { - u32 port = (main_devstat & - MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> - MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; - if (port == 0x0) - bootmode = BOOT_DEVICE_MMC1; - } - - return bootmode; -} - -u32 spl_spi_boot_bus(void) -{ - u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); - u32 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmode = ((wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT) | - ((main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << BOOT_MODE_B_SHIFT); - - return (bootmode == BOOT_DEVICE_QSPI) ? 1 : 0; -} - -u32 spl_boot_device(void) -{ - u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); - u32 main_devstat; - - if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) { - printf("ERROR: MCU only boot is not yet supported\n"); - return BOOT_DEVICE_RAM; - } - - /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ - main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); - - if (bootindex == K3_PRIMARY_BOOTMODE) - return __get_primary_bootmedia(main_devstat, wkup_devstat); - else - return __get_backup_bootmedia(main_devstat); -} diff --git a/arch/arm/mach-k3/j721s2/Makefile b/arch/arm/mach-k3/j721s2/Makefile new file mode 100644 index 0000000000..ceef68297c --- /dev/null +++ b/arch/arm/mach-k3/j721s2/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_OF_SYSTEM_SETUP) += j721s2_fdt.o +obj-$(CONFIG_SPL_BUILD) += j721s2_init.o diff --git a/arch/arm/mach-k3/j721s2/j721s2_fdt.c b/arch/arm/mach-k3/j721s2/j721s2_fdt.c new file mode 100644 index 0000000000..bcb15208be --- /dev/null +++ b/arch/arm/mach-k3/j721s2/j721s2_fdt.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2023 Toradex - https://www.toradex.com/ + */ + +#include + +#include "../common_fdt.h" + +int ft_system_setup(void *blob, struct bd_info *bd) +{ + return fdt_fixup_msmc_ram_k3(blob); +} diff --git a/arch/arm/mach-k3/j721s2/j721s2_init.c b/arch/arm/mach-k3/j721s2/j721s2_init.c new file mode 100644 index 0000000000..fe9766e9b4 --- /dev/null +++ b/arch/arm/mach-k3/j721s2/j721s2_init.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * J721E: SoC specific initialization + * + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ + * David Huang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +struct fwl_data cbass_hc_cfg0_fwls[] = { + { "PCIE0_CFG", 2577, 7 }, + { "EMMC8SS0_CFG", 2579, 4 }, + { "USB3SS0_CORE", 2580, 4 }, + { "USB3SS1_CORE", 2581, 1 }, +}, cbass_hc2_fwls[] = { + { "PCIE0", 2547, 24 }, + { "HC2_WIZ16B8M4CT2", 2552, 1 }, +}, cbass_rc_cfg0_fwls[] = { + { "EMMCSD4SS0_CFG", 2400, 4 }, +}, infra_cbass0_fwls[] = { + { "PSC0", 5, 1 }, + { "PLL_CTRL0", 6, 1 }, + { "PLL_MMR0", 8, 26 }, + { "CTRL_MMR0", 9, 16 }, + { "GPIO0", 16, 1 }, +}, mcu_cbass0_fwls[] = { + { "MCU_R5FSS0_CORE0", 1024, 4 }, + { "MCU_R5FSS0_CORE0_CFG", 1025, 3 }, + { "MCU_R5FSS0_CORE1", 1028, 4 }, + { "MCU_R5FSS0_CORE1_CFG", 1029, 1 }, + { "MCU_FSS0_CFG", 1032, 12 }, + { "MCU_FSS0_S1", 1033, 8 }, + { "MCU_FSS0_S0", 1036, 8 }, + { "MCU_PSROM49152X32", 1048, 1 }, + { "MCU_MSRAM128KX64", 1050, 8 }, + { "MCU_MSRAM128KX64_CFG", 1051, 1 }, + { "MCU_TIMER0", 1056, 1 }, + { "MCU_TIMER9", 1065, 1 }, + { "MCU_USART0", 1120, 1 }, + { "MCU_I2C0", 1152, 1 }, + { "MCU_CTRL_MMR0", 1200, 8 }, + { "MCU_PLL_MMR0", 1201, 3 }, + { "MCU_CPSW0", 1220, 2 }, +}, wkup_cbass0_fwls[] = { + { "WKUP_PSC0", 129, 1 }, + { "WKUP_PLL_CTRL0", 130, 1 }, + { "WKUP_CTRL_MMR0", 131, 16 }, + { "WKUP_GPIO0", 132, 1 }, + { "WKUP_I2C0", 144, 1 }, + { "WKUP_USART0", 160, 1 }, +}, navss_cbass0_fwls[] = { + { "NACSS_VIRT0", 6253, 1 }, +}; + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 3); + mmr_unlock(CTRL_MMR0_BASE, 5); + mmr_unlock(CTRL_MMR0_BASE, 7); +} + +void k3_mmc_stop_clock(void) +{ + if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc->saved_clock = mmc->clock; + mmc_set_clock(mmc, 0, true); + } + } +} + +void k3_mmc_restart_clock(void) +{ + if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { + if (spl_boot_device() == BOOT_DEVICE_MMC1) { + struct mmc *mmc = find_mmc_device(0); + + if (!mmc) + return; + + mmc_set_clock(mmc, mmc->saved_clock, false); + } + } +} + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __attribute__((section(".data"))); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +void k3_spl_init(void) +{ + struct udevice *dev; + int ret; + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + /* Make all control module registers accessible */ + ctrl_mmr_unlock(); + + if (IS_ENABLED(CONFIG_CPU_V7R)) { + disable_linefill_optimization(); + setup_k3_mpu_regions(); + } + + /* Init DM early */ + spl_early_init(); + + /* Prepare console output */ + preloader_console_init(); + + if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { + /* + * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue + * regardless of the result of pinctrl. Do this without probing the + * device, but instead by searching the device that would request the + * given sequence number if probed. The UART will be used by the system + * firmware (SYSFW) image for various purposes and SYSFW depends on us + * to initialize its pin settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + 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. + */ + k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), + k3_mmc_stop_clock, k3_mmc_restart_clock); + + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done for enabling PM services. + */ + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + panic("Failed to initialize clk-k3!\n"); + } + + remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); + remove_fwl_configs(cbass_hc2_fwls, ARRAY_SIZE(cbass_hc2_fwls)); + remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); + remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); + remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); + remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); + remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls)); + } + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); +} + +bool check_rom_loaded_sysfw(void) +{ + return is_rom_loaded_sysfw(&bootdata); +} + +void k3_mem_init(void) +{ + struct udevice *dev; + int ret; + + if (IS_ENABLED(CONFIG_K3_J721E_DDRSS)) { + ret = uclass_get_device_by_name(UCLASS_MISC, "msmc", &dev); + if (ret) + panic("Probe of msmc failed: %d\n", ret); + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM 0 init failed: %d\n", ret); + + ret = uclass_next_device_err(&dev); + if (ret && ret != -ENODEV) + panic("DRAM 1 init failed: %d\n", ret); + } + spl_enable_cache(); +} + +/* Support for the various EVM / SK families */ +#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) +void do_dt_magic(void) +{ + int ret, rescan, mmc_dev = -1; + static struct mmc *mmc; + + do_board_detect(); + + /* + * Board detection has been done. + * Let us see if another dtb wouldn't be a better match + * for our board + */ + if (IS_ENABLED(CONFIG_CPU_V7R)) { + ret = fdtdec_resetup(&rescan); + if (!ret && rescan) { + dm_uninit(); + dm_init_and_scan(true); + } + } + + /* + * Because of multi DTB configuration, the MMC device has + * to be re-initialized after reconfiguring FDT inorder to + * boot from MMC. Do this when boot mode is MMC and ROM has + * not loaded SYSFW. + */ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + mmc_dev = 0; + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + mmc_dev = 1; + break; + } + + if (mmc_dev > 0 && !check_rom_loaded_sysfw()) { + ret = mmc_init_device(mmc_dev); + if (!ret) { + mmc = find_mmc_device(mmc_dev); + if (mmc) { + ret = mmc_init(mmc); + if (ret) + printf("mmc init failed with error: %d\n", ret); + } + } + } +} +#endif + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + k3_spl_init(); +#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) + do_dt_magic(); +#endif + k3_mem_init(); +} +#endif + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + switch (boot_device) { + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_EMMCBOOT; + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_FS; + default: + return MMCSD_MODE_RAW; + } +} + +static u32 __get_backup_bootmedia(u32 main_devstat) +{ + u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> + MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; + + switch (bkup_boot) { + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_DFU; + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + case BACKUP_BOOT_DEVICE_MMC2: + { + u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> + MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; + if (port == 0x0) + return BOOT_DEVICE_MMC1; + return BOOT_DEVICE_MMC2; + } + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + } + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) +{ + u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + + bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << + BOOT_MODE_B_SHIFT; + + if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || + bootmode == BOOT_DEVICE_XSPI) + bootmode = BOOT_DEVICE_SPI; + + if (bootmode == BOOT_DEVICE_MMC2) { + u32 port = (main_devstat & + MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> + MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; + if (port == 0x0) + bootmode = BOOT_DEVICE_MMC1; + } + + return bootmode; +} + +u32 spl_boot_device(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat; + + if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) { + printf("ERROR: MCU only boot is not yet supported\n"); + return BOOT_DEVICE_RAM; + } + + /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ + main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + + if (bootindex == K3_PRIMARY_BOOTMODE) + return __get_primary_bootmedia(main_devstat, wkup_devstat); + else + return __get_backup_bootmedia(main_devstat); +} diff --git a/arch/arm/mach-k3/j721s2_fdt.c b/arch/arm/mach-k3/j721s2_fdt.c deleted file mode 100644 index 652fe8d32b..0000000000 --- a/arch/arm/mach-k3/j721s2_fdt.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2023 Toradex - https://www.toradex.com/ - */ - -#include "common_fdt.h" -#include - -int ft_system_setup(void *blob, struct bd_info *bd) -{ - return fdt_fixup_msmc_ram_k3(blob); -} diff --git a/arch/arm/mach-k3/j721s2_init.c b/arch/arm/mach-k3/j721s2_init.c deleted file mode 100644 index 3374889558..0000000000 --- a/arch/arm/mach-k3/j721s2_init.c +++ /dev/null @@ -1,381 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * J721E: SoC specific initialization - * - * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ - * David Huang - */ - -#include -#include -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include -#include -#include -#include - -struct fwl_data cbass_hc_cfg0_fwls[] = { - { "PCIE0_CFG", 2577, 7 }, - { "EMMC8SS0_CFG", 2579, 4 }, - { "USB3SS0_CORE", 2580, 4 }, - { "USB3SS1_CORE", 2581, 1 }, -}, cbass_hc2_fwls[] = { - { "PCIE0", 2547, 24 }, - { "HC2_WIZ16B8M4CT2", 2552, 1 }, -}, cbass_rc_cfg0_fwls[] = { - { "EMMCSD4SS0_CFG", 2400, 4 }, -}, infra_cbass0_fwls[] = { - { "PSC0", 5, 1 }, - { "PLL_CTRL0", 6, 1 }, - { "PLL_MMR0", 8, 26 }, - { "CTRL_MMR0", 9, 16 }, - { "GPIO0", 16, 1 }, -}, mcu_cbass0_fwls[] = { - { "MCU_R5FSS0_CORE0", 1024, 4 }, - { "MCU_R5FSS0_CORE0_CFG", 1025, 3 }, - { "MCU_R5FSS0_CORE1", 1028, 4 }, - { "MCU_R5FSS0_CORE1_CFG", 1029, 1 }, - { "MCU_FSS0_CFG", 1032, 12 }, - { "MCU_FSS0_S1", 1033, 8 }, - { "MCU_FSS0_S0", 1036, 8 }, - { "MCU_PSROM49152X32", 1048, 1 }, - { "MCU_MSRAM128KX64", 1050, 8 }, - { "MCU_MSRAM128KX64_CFG", 1051, 1 }, - { "MCU_TIMER0", 1056, 1 }, - { "MCU_TIMER9", 1065, 1 }, - { "MCU_USART0", 1120, 1 }, - { "MCU_I2C0", 1152, 1 }, - { "MCU_CTRL_MMR0", 1200, 8 }, - { "MCU_PLL_MMR0", 1201, 3 }, - { "MCU_CPSW0", 1220, 2 }, -}, wkup_cbass0_fwls[] = { - { "WKUP_PSC0", 129, 1 }, - { "WKUP_PLL_CTRL0", 130, 1 }, - { "WKUP_CTRL_MMR0", 131, 16 }, - { "WKUP_GPIO0", 132, 1 }, - { "WKUP_I2C0", 144, 1 }, - { "WKUP_USART0", 160, 1 }, -}, navss_cbass0_fwls[] = { - { "NACSS_VIRT0", 6253, 1 }, -}; - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 3); - mmr_unlock(CTRL_MMR0_BASE, 5); - mmr_unlock(CTRL_MMR0_BASE, 7); -} - -void k3_mmc_stop_clock(void) -{ - if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc->saved_clock = mmc->clock; - mmc_set_clock(mmc, 0, true); - } - } -} - -void k3_mmc_restart_clock(void) -{ - if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { - if (spl_boot_device() == BOOT_DEVICE_MMC1) { - struct mmc *mmc = find_mmc_device(0); - - if (!mmc) - return; - - mmc_set_clock(mmc, mmc->saved_clock, false); - } - } -} - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __attribute__((section(".data"))); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -void k3_spl_init(void) -{ - struct udevice *dev; - int ret; - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - /* Make all control module registers accessible */ - ctrl_mmr_unlock(); - - if (IS_ENABLED(CONFIG_CPU_V7R)) { - disable_linefill_optimization(); - setup_k3_mpu_regions(); - } - - /* Init DM early */ - spl_early_init(); - - /* Prepare console output */ - preloader_console_init(); - - if (IS_ENABLED(CONFIG_K3_LOAD_SYSFW)) { - /* - * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue - * regardless of the result of pinctrl. Do this without probing the - * device, but instead by searching the device that would request the - * given sequence number if probed. The UART will be used by the system - * firmware (SYSFW) image for various purposes and SYSFW depends on us - * to initialize its pin settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - 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. - */ - k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), - k3_mmc_stop_clock, k3_mmc_restart_clock); - - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done for enabling PM services. - */ - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - panic("Failed to initialize clk-k3!\n"); - } - - remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); - remove_fwl_configs(cbass_hc2_fwls, ARRAY_SIZE(cbass_hc2_fwls)); - remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); - remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); - remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); - remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); - remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls)); - } - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); -} - -bool check_rom_loaded_sysfw(void) -{ - return is_rom_loaded_sysfw(&bootdata); -} - -void k3_mem_init(void) -{ - struct udevice *dev; - int ret; - - if (IS_ENABLED(CONFIG_K3_J721E_DDRSS)) { - ret = uclass_get_device_by_name(UCLASS_MISC, "msmc", &dev); - if (ret) - panic("Probe of msmc failed: %d\n", ret); - - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM 0 init failed: %d\n", ret); - - ret = uclass_next_device_err(&dev); - if (ret && ret != -ENODEV) - panic("DRAM 1 init failed: %d\n", ret); - } - spl_enable_cache(); -} - -/* Support for the various EVM / SK families */ -#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) -void do_dt_magic(void) -{ - int ret, rescan, mmc_dev = -1; - static struct mmc *mmc; - - do_board_detect(); - - /* - * Board detection has been done. - * Let us see if another dtb wouldn't be a better match - * for our board - */ - if (IS_ENABLED(CONFIG_CPU_V7R)) { - ret = fdtdec_resetup(&rescan); - if (!ret && rescan) { - dm_uninit(); - dm_init_and_scan(true); - } - } - - /* - * Because of multi DTB configuration, the MMC device has - * to be re-initialized after reconfiguring FDT inorder to - * boot from MMC. Do this when boot mode is MMC and ROM has - * not loaded SYSFW. - */ - switch (spl_boot_device()) { - case BOOT_DEVICE_MMC1: - mmc_dev = 0; - break; - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - mmc_dev = 1; - break; - } - - if (mmc_dev > 0 && !check_rom_loaded_sysfw()) { - ret = mmc_init_device(mmc_dev); - if (!ret) { - mmc = find_mmc_device(mmc_dev); - if (mmc) { - ret = mmc_init(mmc); - if (ret) - printf("mmc init failed with error: %d\n", ret); - } - } - } -} -#endif - -#ifdef CONFIG_SPL_BUILD -void board_init_f(ulong dummy) -{ - k3_spl_init(); -#if defined(CONFIG_SPL_OF_LIST) && defined(CONFIG_TI_I2C_BOARD_DETECT) - do_dt_magic(); -#endif - k3_mem_init(); -} -#endif - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - switch (boot_device) { - case BOOT_DEVICE_MMC1: - return MMCSD_MODE_EMMCBOOT; - case BOOT_DEVICE_MMC2: - return MMCSD_MODE_FS; - default: - return MMCSD_MODE_RAW; - } -} - -static u32 __get_backup_bootmedia(u32 main_devstat) -{ - u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> - MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; - - switch (bkup_boot) { - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_DFU; - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - case BACKUP_BOOT_DEVICE_MMC2: - { - u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> - MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; - if (port == 0x0) - return BOOT_DEVICE_MMC1; - return BOOT_DEVICE_MMC2; - } - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - } - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) -{ - u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - - bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << - BOOT_MODE_B_SHIFT; - - if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || - bootmode == BOOT_DEVICE_XSPI) - bootmode = BOOT_DEVICE_SPI; - - if (bootmode == BOOT_DEVICE_MMC2) { - u32 port = (main_devstat & - MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> - MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; - if (port == 0x0) - bootmode = BOOT_DEVICE_MMC1; - } - - return bootmode; -} - -u32 spl_boot_device(void) -{ - u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); - u32 main_devstat; - - if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) { - printf("ERROR: MCU only boot is not yet supported\n"); - return BOOT_DEVICE_RAM; - } - - /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ - main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); - - if (bootindex == K3_PRIMARY_BOOTMODE) - return __get_primary_bootmedia(main_devstat, wkup_devstat); - else - return __get_backup_bootmedia(main_devstat); -} diff --git a/arch/arm/mach-k3/j784s4/Makefile b/arch/arm/mach-k3/j784s4/Makefile new file mode 100644 index 0000000000..6d1841e3f9 --- /dev/null +++ b/arch/arm/mach-k3/j784s4/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ +# Andrew Davis + +obj-$(CONFIG_OF_SYSTEM_SETUP) += j784s4_fdt.o +obj-$(CONFIG_SPL_BUILD) += j784s4_init.o diff --git a/arch/arm/mach-k3/j784s4/j784s4_fdt.c b/arch/arm/mach-k3/j784s4/j784s4_fdt.c new file mode 100644 index 0000000000..e127509705 --- /dev/null +++ b/arch/arm/mach-k3/j784s4/j784s4_fdt.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * J784S4: SoC specific initialization + * + * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/ + * Apurva Nandan + */ + +#include + +#include "../common_fdt.h" + +int ft_system_setup(void *blob, struct bd_info *bd) +{ + return fdt_fixup_msmc_ram_k3(blob); +} diff --git a/arch/arm/mach-k3/j784s4/j784s4_init.c b/arch/arm/mach-k3/j784s4/j784s4_init.c new file mode 100644 index 0000000000..1ce13e0f49 --- /dev/null +++ b/arch/arm/mach-k3/j784s4/j784s4_init.c @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * J784S4: SoC specific initialization + * + * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/ + * Hari Nagalla + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../sysfw-loader.h" +#include "../common.h" + +#define J784S4_MAX_DDR_CONTROLLERS 4 + +struct fwl_data infra_cbass0_fwls[] = { + { "PSC0", 5, 1 }, + { "PLL_CTRL0", 6, 1 }, + { "PLL_MMR0", 8, 26 }, + { "CTRL_MMR0", 9, 16 }, + { "GPIO0", 16, 1 }, +}, wkup_cbass0_fwls[] = { + { "WKUP_PSC0", 129, 1 }, + { "WKUP_PLL_CTRL0", 130, 1 }, + { "WKUP_CTRL_MMR0", 131, 16 }, + { "WKUP_GPIO0", 132, 1 }, + { "WKUP_I2C0", 144, 1 }, + { "WKUP_USART0", 160, 1 }, +}, mcu_cbass0_fwls[] = { + { "MCU_R5FSS0_CORE0", 1024, 4 }, + { "MCU_R5FSS0_CORE0_CFG", 1025, 3 }, + { "MCU_R5FSS0_CORE1", 1028, 4 }, + { "MCU_R5FSS0_CORE1_CFG", 1029, 1 }, + { "MCU_FSS0_CFG", 1032, 12 }, + { "MCU_FSS0_S1", 1033, 8 }, + { "MCU_FSS0_S0", 1036, 8 }, + { "MCU_PSROM49152X32", 1048, 1 }, + { "MCU_MSRAM128KX64", 1050, 8 }, + { "MCU_MSRAM128KX64_CFG", 1051, 1 }, + { "MCU_TIMER0", 1056, 1 }, + { "MCU_TIMER9", 1065, 1 }, + { "MCU_USART0", 1120, 1 }, + { "MCU_I2C0", 1152, 1 }, + { "MCU_CTRL_MMR0", 1200, 8 }, + { "MCU_PLL_MMR0", 1201, 3 }, + { "MCU_CPSW0", 1220, 2 }, +}, cbass_rc_cfg0_fwls[] = { + { "EMMCSD4SS0_CFG", 2400, 4 }, +}, cbass_hc2_fwls[] = { + { "PCIE0", 2547, 24 }, +}, cbass_hc_cfg0_fwls[] = { + { "PCIE0_CFG", 2577, 7 }, + { "EMMC8SS0_CFG", 2579, 4 }, + { "USB3SS0_CORE", 2580, 4 }, + { "USB3SS1_CORE", 2581, 1 }, +}, navss_cbass0_fwls[] = { + { "NACSS_VIRT0", 6253, 1 }, +}; + +static void ctrl_mmr_unlock(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); + mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + + /* Unlock all CTRL_MMR0 module registers */ + mmr_unlock(CTRL_MMR0_BASE, 0); + mmr_unlock(CTRL_MMR0_BASE, 1); + mmr_unlock(CTRL_MMR0_BASE, 2); + mmr_unlock(CTRL_MMR0_BASE, 3); + mmr_unlock(CTRL_MMR0_BASE, 5); + mmr_unlock(CTRL_MMR0_BASE, 7); +} + +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); + +static void store_boot_info_from_rom(void) +{ + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, + sizeof(struct rom_extended_boot_data)); +} + +void k3_spl_init(void) +{ + struct udevice *dev; + int ret; + + /* + * Cannot delay this further as there is a chance that + * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. + */ + store_boot_info_from_rom(); + + /* Make all control module registers accessible */ + ctrl_mmr_unlock(); + + if (IS_ENABLED(CONFIG_CPU_V7R)) { + disable_linefill_optimization(); + setup_k3_mpu_regions(); + } + + /* Init DM early */ + ret = spl_early_init(); + + /* Prepare console output */ + preloader_console_init(); + + if (IS_ENABLED(CONFIG_CPU_V7R)) { + /* + * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue + * regardless of the result of pinctrl. Do this without probing the + * device, but instead by searching the device that would request the + * given sequence number if probed. The UART will be used by the system + * firmware (TIFS) image for various purposes and TIFS depends on us + * to initialize its pin settings. + */ + ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); + if (!ret) + pinctrl_select_state(dev, "default"); + + /* + * Load, start up, and configure system controller firmware. Provide + * the U-Boot console init function to the TIFS post-PM configuration + * callback hook, effectively switching on (or over) the console + * output. + */ + k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), NULL, NULL); + + if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { + /* + * Force probe of clk_k3 driver here to ensure basic default clock + * configuration is always done for enabling PM services. + */ + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(ti_clk), + &dev); + if (ret) + panic("Failed to initialize clk-k3!\n"); + } + + remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); + remove_fwl_configs(cbass_hc2_fwls, ARRAY_SIZE(cbass_hc2_fwls)); + remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); + remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); + remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); + remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); + remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls)); + } + + /* Output System Firmware version info */ + k3_sysfw_print_ver(); +} + +void k3_mem_init(void) +{ + struct udevice *dev; + int ret, ctrl = 0; + + if (IS_ENABLED(CONFIG_K3_J721E_DDRSS)) { + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("DRAM 0 init failed: %d\n", ret); + ctrl++; + + while (ctrl < J784S4_MAX_DDR_CONTROLLERS) { + ret = uclass_next_device_err(&dev); + if (ret == -ENODEV) + break; + + if (ret) + panic("DRAM %d init failed: %d\n", ctrl, ret); + ctrl++; + } + printf("Initialized %d DRAM controllers\n", ctrl); + } + + spl_enable_cache(); +} + +void board_init_f(ulong dummy) +{ + k3_spl_init(); + k3_mem_init(); +} + +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) +{ + switch (boot_device) { + case BOOT_DEVICE_MMC1: + if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) + return MMCSD_MODE_EMMCBOOT; + if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) + return MMCSD_MODE_FS; + return MMCSD_MODE_EMMCBOOT; + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_FS; + default: + return MMCSD_MODE_RAW; + } +} + +static u32 __get_backup_bootmedia(u32 main_devstat) +{ + u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> + MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; + + switch (bkup_boot) { + case BACKUP_BOOT_DEVICE_USB: + return BOOT_DEVICE_DFU; + case BACKUP_BOOT_DEVICE_UART: + return BOOT_DEVICE_UART; + case BACKUP_BOOT_DEVICE_ETHERNET: + return BOOT_DEVICE_ETHERNET; + case BACKUP_BOOT_DEVICE_MMC2: + { + u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> + MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; + if (port == 0x0) + return BOOT_DEVICE_MMC1; + return BOOT_DEVICE_MMC2; + } + case BACKUP_BOOT_DEVICE_SPI: + return BOOT_DEVICE_SPI; + case BACKUP_BOOT_DEVICE_I2C: + return BOOT_DEVICE_I2C; + } + + return BOOT_DEVICE_RAM; +} + +static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) +{ + u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; + + bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << + BOOT_MODE_B_SHIFT; + + if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || + bootmode == BOOT_DEVICE_XSPI) + bootmode = BOOT_DEVICE_SPI; + + if (bootmode == BOOT_DEVICE_MMC2) { + u32 port = (main_devstat & + MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> + MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; + if (port == 0x0) + bootmode = BOOT_DEVICE_MMC1; + } + + return bootmode; +} + +u32 spl_spi_boot_bus(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmode = ((wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT) | + ((main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << BOOT_MODE_B_SHIFT); + + return (bootmode == BOOT_DEVICE_QSPI) ? 1 : 0; +} + +u32 spl_boot_device(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat; + + if (wkup_devstat & WKUP_DEVSTAT_MCU_ONLY_MASK) { + printf("ERROR: MCU only boot is not yet supported\n"); + return BOOT_DEVICE_RAM; + } + + /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ + main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + + if (bootindex == K3_PRIMARY_BOOTMODE) + return __get_primary_bootmedia(main_devstat, wkup_devstat); + else + return __get_backup_bootmedia(main_devstat); +} diff --git a/arch/arm/mach-k3/j784s4_fdt.c b/arch/arm/mach-k3/j784s4_fdt.c deleted file mode 100644 index d05ed8b991..0000000000 --- a/arch/arm/mach-k3/j784s4_fdt.c +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * J784S4: SoC specific initialization - * - * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/ - * Apurva Nandan - */ - -#include "common_fdt.h" -#include - -int ft_system_setup(void *blob, struct bd_info *bd) -{ - return fdt_fixup_msmc_ram_k3(blob); -} diff --git a/arch/arm/mach-k3/j784s4_init.c b/arch/arm/mach-k3/j784s4_init.c deleted file mode 100644 index ae4420362d..0000000000 --- a/arch/arm/mach-k3/j784s4_init.c +++ /dev/null @@ -1,310 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * J784S4: SoC specific initialization - * - * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/ - * Hari Nagalla - */ - -#include -#include -#include -#include -#include -#include "sysfw-loader.h" -#include "common.h" -#include -#include -#include -#include -#include -#include - -#define J784S4_MAX_DDR_CONTROLLERS 4 - -struct fwl_data infra_cbass0_fwls[] = { - { "PSC0", 5, 1 }, - { "PLL_CTRL0", 6, 1 }, - { "PLL_MMR0", 8, 26 }, - { "CTRL_MMR0", 9, 16 }, - { "GPIO0", 16, 1 }, -}, wkup_cbass0_fwls[] = { - { "WKUP_PSC0", 129, 1 }, - { "WKUP_PLL_CTRL0", 130, 1 }, - { "WKUP_CTRL_MMR0", 131, 16 }, - { "WKUP_GPIO0", 132, 1 }, - { "WKUP_I2C0", 144, 1 }, - { "WKUP_USART0", 160, 1 }, -}, mcu_cbass0_fwls[] = { - { "MCU_R5FSS0_CORE0", 1024, 4 }, - { "MCU_R5FSS0_CORE0_CFG", 1025, 3 }, - { "MCU_R5FSS0_CORE1", 1028, 4 }, - { "MCU_R5FSS0_CORE1_CFG", 1029, 1 }, - { "MCU_FSS0_CFG", 1032, 12 }, - { "MCU_FSS0_S1", 1033, 8 }, - { "MCU_FSS0_S0", 1036, 8 }, - { "MCU_PSROM49152X32", 1048, 1 }, - { "MCU_MSRAM128KX64", 1050, 8 }, - { "MCU_MSRAM128KX64_CFG", 1051, 1 }, - { "MCU_TIMER0", 1056, 1 }, - { "MCU_TIMER9", 1065, 1 }, - { "MCU_USART0", 1120, 1 }, - { "MCU_I2C0", 1152, 1 }, - { "MCU_CTRL_MMR0", 1200, 8 }, - { "MCU_PLL_MMR0", 1201, 3 }, - { "MCU_CPSW0", 1220, 2 }, -}, cbass_rc_cfg0_fwls[] = { - { "EMMCSD4SS0_CFG", 2400, 4 }, -}, cbass_hc2_fwls[] = { - { "PCIE0", 2547, 24 }, -}, cbass_hc_cfg0_fwls[] = { - { "PCIE0_CFG", 2577, 7 }, - { "EMMC8SS0_CFG", 2579, 4 }, - { "USB3SS0_CORE", 2580, 4 }, - { "USB3SS1_CORE", 2581, 1 }, -}, navss_cbass0_fwls[] = { - { "NACSS_VIRT0", 6253, 1 }, -}; - -static void ctrl_mmr_unlock(void) -{ - /* Unlock all WKUP_CTRL_MMR0 module registers */ - mmr_unlock(WKUP_CTRL_MMR0_BASE, 0); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 1); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 2); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 3); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 4); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 6); - mmr_unlock(WKUP_CTRL_MMR0_BASE, 7); - - /* Unlock all MCU_CTRL_MMR0 module registers */ - mmr_unlock(MCU_CTRL_MMR0_BASE, 0); - mmr_unlock(MCU_CTRL_MMR0_BASE, 1); - mmr_unlock(MCU_CTRL_MMR0_BASE, 2); - mmr_unlock(MCU_CTRL_MMR0_BASE, 3); - mmr_unlock(MCU_CTRL_MMR0_BASE, 4); - - /* Unlock all CTRL_MMR0 module registers */ - mmr_unlock(CTRL_MMR0_BASE, 0); - mmr_unlock(CTRL_MMR0_BASE, 1); - mmr_unlock(CTRL_MMR0_BASE, 2); - mmr_unlock(CTRL_MMR0_BASE, 3); - mmr_unlock(CTRL_MMR0_BASE, 5); - mmr_unlock(CTRL_MMR0_BASE, 7); -} - -/* - * This uninitialized global variable would normal end up in the .bss section, - * but the .bss is cleared between writing and reading this variable, so move - * it to the .data section. - */ -u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(".data"); - -static void store_boot_info_from_rom(void) -{ - bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); - memcpy(&bootdata, (uintptr_t *)ROM_EXTENDED_BOOT_DATA_INFO, - sizeof(struct rom_extended_boot_data)); -} - -void k3_spl_init(void) -{ - struct udevice *dev; - int ret; - - /* - * Cannot delay this further as there is a chance that - * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. - */ - store_boot_info_from_rom(); - - /* Make all control module registers accessible */ - ctrl_mmr_unlock(); - - if (IS_ENABLED(CONFIG_CPU_V7R)) { - disable_linefill_optimization(); - setup_k3_mpu_regions(); - } - - /* Init DM early */ - ret = spl_early_init(); - - /* Prepare console output */ - preloader_console_init(); - - if (IS_ENABLED(CONFIG_CPU_V7R)) { - /* - * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue - * regardless of the result of pinctrl. Do this without probing the - * device, but instead by searching the device that would request the - * given sequence number if probed. The UART will be used by the system - * firmware (TIFS) image for various purposes and TIFS depends on us - * to initialize its pin settings. - */ - ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, &dev); - if (!ret) - pinctrl_select_state(dev, "default"); - - /* - * Load, start up, and configure system controller firmware. Provide - * the U-Boot console init function to the TIFS post-PM configuration - * callback hook, effectively switching on (or over) the console - * output. - */ - k3_sysfw_loader(is_rom_loaded_sysfw(&bootdata), NULL, NULL); - - if (IS_ENABLED(CONFIG_SPL_CLK_K3)) { - /* - * Force probe of clk_k3 driver here to ensure basic default clock - * configuration is always done for enabling PM services. - */ - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(ti_clk), - &dev); - if (ret) - panic("Failed to initialize clk-k3!\n"); - } - - remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls)); - remove_fwl_configs(cbass_hc2_fwls, ARRAY_SIZE(cbass_hc2_fwls)); - remove_fwl_configs(cbass_rc_cfg0_fwls, ARRAY_SIZE(cbass_rc_cfg0_fwls)); - remove_fwl_configs(infra_cbass0_fwls, ARRAY_SIZE(infra_cbass0_fwls)); - remove_fwl_configs(mcu_cbass0_fwls, ARRAY_SIZE(mcu_cbass0_fwls)); - remove_fwl_configs(wkup_cbass0_fwls, ARRAY_SIZE(wkup_cbass0_fwls)); - remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls)); - } - - /* Output System Firmware version info */ - k3_sysfw_print_ver(); -} - -void k3_mem_init(void) -{ - struct udevice *dev; - int ret, ctrl = 0; - - if (IS_ENABLED(CONFIG_K3_J721E_DDRSS)) { - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("DRAM 0 init failed: %d\n", ret); - ctrl++; - - while (ctrl < J784S4_MAX_DDR_CONTROLLERS) { - ret = uclass_next_device_err(&dev); - if (ret == -ENODEV) - break; - - if (ret) - panic("DRAM %d init failed: %d\n", ctrl, ret); - ctrl++; - } - printf("Initialized %d DRAM controllers\n", ctrl); - } - - spl_enable_cache(); -} - -void board_init_f(ulong dummy) -{ - k3_spl_init(); - k3_mem_init(); -} - -u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device) -{ - switch (boot_device) { - case BOOT_DEVICE_MMC1: - if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) - return MMCSD_MODE_EMMCBOOT; - if (IS_ENABLED(CONFIG_SPL_FS_FAT) || IS_ENABLED(CONFIG_SPL_FS_EXT4)) - return MMCSD_MODE_FS; - return MMCSD_MODE_EMMCBOOT; - case BOOT_DEVICE_MMC2: - return MMCSD_MODE_FS; - default: - return MMCSD_MODE_RAW; - } -} - -static u32 __get_backup_bootmedia(u32 main_devstat) -{ - u32 bkup_boot = (main_devstat & MAIN_DEVSTAT_BKUP_BOOTMODE_MASK) >> - MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT; - - switch (bkup_boot) { - case BACKUP_BOOT_DEVICE_USB: - return BOOT_DEVICE_DFU; - case BACKUP_BOOT_DEVICE_UART: - return BOOT_DEVICE_UART; - case BACKUP_BOOT_DEVICE_ETHERNET: - return BOOT_DEVICE_ETHERNET; - case BACKUP_BOOT_DEVICE_MMC2: - { - u32 port = (main_devstat & MAIN_DEVSTAT_BKUP_MMC_PORT_MASK) >> - MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT; - if (port == 0x0) - return BOOT_DEVICE_MMC1; - return BOOT_DEVICE_MMC2; - } - case BACKUP_BOOT_DEVICE_SPI: - return BOOT_DEVICE_SPI; - case BACKUP_BOOT_DEVICE_I2C: - return BOOT_DEVICE_I2C; - } - - return BOOT_DEVICE_RAM; -} - -static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) -{ - u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT; - - bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << - BOOT_MODE_B_SHIFT; - - if (bootmode == BOOT_DEVICE_OSPI || bootmode == BOOT_DEVICE_QSPI || - bootmode == BOOT_DEVICE_XSPI) - bootmode = BOOT_DEVICE_SPI; - - if (bootmode == BOOT_DEVICE_MMC2) { - u32 port = (main_devstat & - MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >> - MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT; - if (port == 0x0) - bootmode = BOOT_DEVICE_MMC1; - } - - return bootmode; -} - -u32 spl_spi_boot_bus(void) -{ - u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); - u32 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootmode = ((wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> - WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT) | - ((main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << BOOT_MODE_B_SHIFT); - - return (bootmode == BOOT_DEVICE_QSPI) ? 1 : 0; -} - -u32 spl_boot_device(void) -{ - u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); - u32 main_devstat; - - if (wkup_devstat & WKUP_DEVSTAT_MCU_ONLY_MASK) { - printf("ERROR: MCU only boot is not yet supported\n"); - return BOOT_DEVICE_RAM; - } - - /* MAIN CTRL MMR can only be read if MCU ONLY is 0 */ - main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); - - if (bootindex == K3_PRIMARY_BOOTMODE) - return __get_primary_bootmedia(main_devstat, wkup_devstat); - else - return __get_backup_bootmedia(main_devstat); -}