summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/imx8ulp
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2022-07-28 18:23:40 +0800
committerYe Li <ye.li@nxp.com>2022-07-29 10:00:01 +0800
commitdeae2764bdc79b7c7ee97684912cc1aa3887a4f7 (patch)
tree8f60f8a1c5eed279e9a6f2864c39e6224489784a /arch/arm/mach-imx/imx8ulp
parent5b087998ed1f6aad531707c645810a2f68809213 (diff)
LF-6692-3 imx8ulp: Adjust handshake to sync TRDC and XRDC completion
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 panic. We use SIM GPR0 to pass the info from SPL to u-boot, as 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>
Diffstat (limited to 'arch/arm/mach-imx/imx8ulp')
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c103
1 files changed, 87 insertions, 16 deletions
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c
index 62915e03166..2a3f417ab94 100644
--- a/arch/arm/mach-imx/imx8ulp/soc.c
+++ b/arch/arm/mach-imx/imx8ulp/soc.c
@@ -186,14 +186,70 @@ enum bt_mode get_boot_mode(void)
bool m33_image_booted(void)
{
- u32 gp6 = 0;
+ if (IS_ENABLED(CONFIG_SPL_BUILD)) {
+ u32 gp6 = 0;
+
+ /* DGO_GP6 */
+ gp6 = readl(SIM_SEC_BASE_ADDR + 0x28);
+ if (gp6 & (1 << 5))
+ return true;
- /* DGO_GP6 */
- gp6 = readl(SIM_SEC_BASE_ADDR + 0x28);
- if (gp6 & (1 << 5))
- return true;
+ return false;
+ } else {
+ u32 gpr0 = readl(SIM1_BASE_ADDR);
+ if (gpr0 & 0x1)
+ return true;
- return false;
+ 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;
+
+ if (m33_booted)
+ val |= 0x1;
+
+ 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)
@@ -746,10 +802,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 */
@@ -766,11 +818,6 @@ 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 {
@@ -778,12 +825,14 @@ int arch_cpu_init(void)
}
/* 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 {
/* reconfigure core0 reset vector to ROM */
set_core0_reset_vector(0x1000);
@@ -792,6 +841,17 @@ int arch_cpu_init(void)
return 0;
}
+int checkcpu(void)
+{
+ if (is_m33_handshake_necessary()) {
+ if (!gd->arch.m33_handshake_done)
+ panic("M33 Sync: Timeout, Boot Stop!\n");
+ else
+ puts("M33 Sync: OK\n");
+ }
+ return 0;
+}
+
int arch_cpu_init_dm(void)
{
struct udevice *devp;
@@ -799,6 +859,17 @@ int arch_cpu_init_dm(void)
u32 res;
struct sentinel_get_info_data info;
+ if (!IS_ENABLED(CONFIG_SPL_BUILD) && 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 {
+ gd->arch.m33_handshake_done = false;
+ return 0; /* Skip and go through to panic in checkcpu as console is ready then */
+ }
+ }
+
node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8ulp-mu");
ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp);