diff options
-rw-r--r-- | arch/arm/include/asm/arch-imx8ulp/sys_proto.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/global_data.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8ulp/soc.c | 104 | ||||
-rw-r--r-- | board/freescale/imx8ulp_evk/imx8ulp_evk.c | 8 |
4 files changed, 93 insertions, 23 deletions
diff --git a/arch/arm/include/asm/arch-imx8ulp/sys_proto.h b/arch/arm/include/asm/arch-imx8ulp/sys_proto.h index ff49c626d8..5bbae21e37 100644 --- a/arch/arm/include/asm/arch-imx8ulp/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8ulp/sys_proto.h @@ -14,6 +14,7 @@ int xrdc_config_pdac_openacc(u32 bridge, u32 index); void set_lpav_qos(void); void load_lposc_fuse(void); bool m33_image_booted(void); +bool is_m33_handshake_necessary(void); int m33_image_handshake(ulong timeout_ms); int imx8ulp_dm_post_init(void); #endif diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 9e746e380a..86987838f4 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -97,6 +97,9 @@ struct arch_global_data { u32 uid[4]; #endif +#ifdef CONFIG_ARCH_IMX8ULP + bool m33_handshake_done; +#endif }; #include <asm-generic/global_data.h> diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index 0d7858a02d..8424332f42 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -104,14 +104,70 @@ enum bt_mode get_boot_mode(void) bool m33_image_booted(void) { - u32 gp6; + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + u32 gp6 = 0; + + /* DGO_GP6 */ + gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); + if (gp6 & BIT(5)) + return true; + + return false; + } else { + u32 gpr0 = readl(SIM1_BASE_ADDR); + if (gpr0 & BIT(0)) + return true; + + return false; + } +} + +bool rdc_enabled_in_boot(void) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + u32 val = 0; + int ret; + bool rdc_en = true; /* Default assume DBD_EN is set */ + + /* Read DBD_EN fuse */ + ret = fuse_read(8, 1, &val); + if (!ret) + rdc_en = !!(val & 0x200); /* only A1 part uses DBD_EN, so check DBD_EN new place*/ + + return rdc_en; + } else { + u32 gpr0 = readl(SIM1_BASE_ADDR); + if (gpr0 & 0x2) + return true; + + return false; + } +} + +static void spl_pass_boot_info(void) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + bool m33_booted = m33_image_booted(); + bool rdc_en = rdc_enabled_in_boot(); + u32 val = 0; - /* DGO_GP6 */ - gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); - if (gp6 & BIT(5)) - return true; + if (m33_booted) + val |= 0x1; - return false; + if (rdc_en) + val |= 0x2; + + writel(val, SIM1_BASE_ADDR); + } +} + +bool is_m33_handshake_necessary(void) +{ + /* Only need handshake in u-boot */ + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + return (m33_image_booted() || rdc_enabled_in_boot()); + else + return false; } int m33_image_handshake(ulong timeout_ms) @@ -661,10 +717,6 @@ void set_lpav_qos(void) int arch_cpu_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) { - u32 val = 0; - int ret; - bool rdc_en = true; /* Default assume DBD_EN is set */ - /* Enable System Reset Interrupt using WDOG_AD */ setbits_le32(CMC1_BASE_ADDR + 0x8C, BIT(13)); /* Clear AD_PERIPH Power switch domain out of reset interrupt flag */ @@ -681,31 +733,51 @@ int arch_cpu_init(void) /* Disable wdog */ init_wdog(); - /* Read DBD_EN fuse */ - ret = fuse_read(8, 1, &val); - if (!ret) - rdc_en = !!(val & 0x4000); - if (get_boot_mode() == SINGLE_BOOT) lpav_configure(false); else lpav_configure(true); /* Release xrdc, then allow A35 to write SRAM2 */ - if (rdc_en) + if (rdc_enabled_in_boot()) release_rdc(RDC_XRDC); xrdc_mrc_region_set_access(2, CONFIG_SPL_TEXT_BASE, 0xE00); clock_init_early(); + + spl_pass_boot_info(); } else { + int ret; /* reconfigure core0 reset vector to ROM */ set_core0_reset_vector(0x1000); + + if (is_m33_handshake_necessary()) { + /* Start handshake with M33 to ensure TRDC configuration completed */ + ret = m33_image_handshake(1000); + if (!ret) + gd->arch.m33_handshake_done = true; + else /* Skip and go through to panic in checkcpu as console is ready then */ + gd->arch.m33_handshake_done = false; + } } return 0; } +int checkcpu(void) +{ + if (is_m33_handshake_necessary()) { + if (!gd->arch.m33_handshake_done) { + puts("M33 Sync: Timeout, Boot Stop!\n"); + hang(); + } else { + puts("M33 Sync: OK\n"); + } + } + return 0; +} + int imx8ulp_dm_post_init(void) { struct udevice *devp; diff --git a/board/freescale/imx8ulp_evk/imx8ulp_evk.c b/board/freescale/imx8ulp_evk/imx8ulp_evk.c index 5aad1074a8..b58f143f6e 100644 --- a/board/freescale/imx8ulp_evk/imx8ulp_evk.c +++ b/board/freescale/imx8ulp_evk/imx8ulp_evk.c @@ -101,18 +101,12 @@ void mipi_dsi_panel_backlight(void) int board_init(void) { - int sync = -ENODEV; if (IS_ENABLED(CONFIG_FEC_MXC)) setup_fec(); - if (m33_image_booted()) { - sync = m33_image_handshake(1000); - printf("M33 Sync: %s\n", sync ? "Timeout" : "OK"); - } - /* When sync with M33 is failed, use local driver to set for video */ - if (sync != 0 && IS_ENABLED(CONFIG_VIDEO)) { + if (!is_m33_handshake_necessary() && IS_ENABLED(CONFIG_VIDEO)) { mipi_dsi_mux_panel(); mipi_dsi_panel_backlight(); } |