#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 */
#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)
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();