]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imx: imx8ulp: Adjust handshake to sync TRDC and XRDC completion
authorYe Li <ye.li@nxp.com>
Tue, 31 Jan 2023 08:42:17 +0000 (16:42 +0800)
committerStefano Babic <sbabic@denx.de>
Wed, 29 Mar 2023 18:15:42 +0000 (20:15 +0200)
To fit the DBD_EN fused part, we re-design the TRDC and XRDC assignment.
M33 will be the TRDC owner and needs to configure TRDC. A35 is the
XRDC owner, ATF will configure XRDC.

The handshake between U-boot and M33 image is used to sync TRDC and
XRDC configuration completion. Once the handshake is done, A35 and M33
can access the allowed resources in others domain.

The handshake is needed when M33 is booted or DBD_EN fused, because both
cases will enable the TRDC. If handshake is timeout, the boot will hang.
We use SIM GPR0 to pass the info from SPL to u-boot, because before the
handshake, u-boot can't access SEC SIM and FSB.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Jacky Bai <ping.bai@nxp.com>
arch/arm/include/asm/arch-imx8ulp/sys_proto.h
arch/arm/include/asm/global_data.h
arch/arm/mach-imx/imx8ulp/soc.c
board/freescale/imx8ulp_evk/imx8ulp_evk.c

index ff49c626d820279679f7c0860b7fd555b94fb6b9..5bbae21e37c7e9ac0305c589a0b769395c36fa91 100644 (file)
@@ -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
index 9e746e380a21393845324c82150a202639c4de8d..86987838f46bb4c8852e3b7d35f1c7d5599355e3 100644 (file)
@@ -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>
index 0d7858a02d4a2e4892d2203c07423002e631fbca..8424332f429960b3f90527bcb176e8c6868a0141 100644 (file)
@@ -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;
index 5aad1074a86c256ac3aa5d96bf167fb01b4d39ac..b58f143f6ea60d46deb0f1b49660cd7583efa0db 100644 (file)
@@ -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();
        }