diff options
Diffstat (limited to 'arch/arm/mach-k3/am642_init.c')
-rw-r--r-- | arch/arm/mach-k3/am642_init.c | 96 |
1 files changed, 38 insertions, 58 deletions
diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c index 1bf7e163cc4..c871e92330b 100644 --- a/arch/arm/mach-k3/am642_init.c +++ b/arch/arm/mach-k3/am642_init.c @@ -12,19 +12,23 @@ #include <spl.h> #include <asm/io.h> #include <asm/arch/hardware.h> -#include <asm/arch/sysfw-loader.h> -#include <asm/arch/sys_proto.h> +#include "sysfw-loader.h" #include "common.h" -#include <asm/arch/sys_proto.h> #include <linux/soc/ti/ti_sci_protocol.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/pinctrl.h> #include <mmc.h> #include <dm/root.h> +#include <command.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 */ @@ -100,8 +104,8 @@ void do_dt_magic(void) { int ret, rescan; - if (IS_ENABLED(CONFIG_K3_BOARD_DETECT)) - do_board_detect(); + /* Perform board detection */ + do_board_detect(); /* * Board detection has been done. @@ -166,6 +170,7 @@ 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) @@ -185,8 +190,6 @@ void board_init_f(ulong dummy) preloader_console_init(); - do_dt_magic(); - #if defined(CONFIG_K3_LOAD_SYSFW) /* * Process pinctrl for serial3 a.k.a. MAIN UART1 module and continue @@ -210,9 +213,37 @@ void board_init_f(ulong dummy) 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_first_device_err(UCLASS_SYSRESET, &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); @@ -346,54 +377,3 @@ u32 spl_boot_device(void) else return __get_backup_bootmedia(devstat); } - -#if defined(CONFIG_SYS_K3_SPL_ATF) - -#define AM64X_DEV_RTI8 127 -#define AM64X_DEV_RTI9 128 -#define AM64X_DEV_R5FSS0_CORE0 121 -#define AM64X_DEV_R5FSS0_CORE1 122 - -void release_resources_for_core_shutdown(void) -{ - struct ti_sci_handle *ti_sci = get_ti_sci_handle(); - struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops; - struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops; - int ret; - u32 i; - - const u32 put_device_ids[] = { - AM64X_DEV_RTI9, - AM64X_DEV_RTI8, - }; - - /* Iterate through list of devices to put (shutdown) */ - for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { - u32 id = put_device_ids[i]; - - ret = dev_ops->put_device(ti_sci, id); - if (ret) - panic("Failed to put device %u (%d)\n", id, ret); - } - - const u32 put_core_ids[] = { - AM64X_DEV_R5FSS0_CORE1, - AM64X_DEV_R5FSS0_CORE0, /* Handle CPU0 after CPU1 */ - }; - - /* Iterate through list of cores to put (shutdown) */ - for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { - u32 id = put_core_ids[i]; - - /* - * Queue up the core shutdown request. Note that this call - * needs to be followed up by an actual invocation of an WFE - * or WFI CPU instruction. - */ - ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); - if (ret) - panic("Failed sending core %u shutdown message (%d)\n", - id, ret); - } -} -#endif |