summaryrefslogtreecommitdiff
path: root/arch/arm/mach-k3/am642_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-k3/am642_init.c')
-rw-r--r--arch/arm/mach-k3/am642_init.c96
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