aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-imx8ulp/sys_proto.h1
-rw-r--r--arch/arm/include/asm/global_data.h3
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c104
-rw-r--r--board/freescale/imx8ulp_evk/imx8ulp_evk.c8
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();
}