diff options
Diffstat (limited to 'arch/arm/mach-imx/imx8ulp/soc.c')
-rw-r--r-- | arch/arm/mach-imx/imx8ulp/soc.c | 196 |
1 files changed, 159 insertions, 37 deletions
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index dc1fa70e3c..6e20b11801 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -13,8 +13,8 @@ #include <efi_loader.h> #include <spl.h> #include <asm/arch/rdc.h> -#include <asm/arch/s400_api.h> -#include <asm/arch/mu_hal.h> +#include <asm/mach-imx/s400_api.h> +#include <asm/mach-imx/mu_hal.h> #include <cpu_func.h> #include <asm/setup.h> #include <dm.h> @@ -152,9 +152,18 @@ int board_usb_gadget_port_auto(void) } #endif +static void set_cpu_info(struct sentinel_get_info_data *info) +{ + gd->arch.soc_rev = info->soc; + gd->arch.lifecycle = info->lc; + memcpy((void *)&gd->arch.uid, &info->uid, 4 * sizeof(u32)); +} + u32 get_cpu_rev(void) { - return (MXC_CPU_IMX8ULP << 12) | CHIP_REV_1_0; + u32 rev = (gd->arch.soc_rev >> 24) - 0xa0; + + return (MXC_CPU_IMX8ULP << 12) | (CHIP_REV_1_0 + rev); } enum bt_mode get_boot_mode(void) @@ -177,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; + + return false; + } else { + u32 gpr0 = readl(SIM1_BASE_ADDR); + if (gpr0 & 0x1) + 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 */ - /* DGO_GP6 */ - gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); - if (gp6 & (1 << 5)) - return true; + /* 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); + } +} - return false; +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) @@ -290,7 +355,7 @@ int print_cpuinfo(void) (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, mxc_get_clock(MXC_ARM_CLK) / 1000000); -#if defined(CONFIG_IMX_PMC_TEMPERATURE) +#if defined(CONFIG_SCMI_THERMAL) struct udevice *udev; int ret, temp; @@ -632,33 +697,65 @@ static void set_core0_reset_vector(u32 entry) setbits_le32(SIM1_BASE_ADDR + 0x8, (0x1 << 26)); } -static int trdc_set_access(void) +/* Not used now */ +int trdc_set_access(void) { /* * TRDC mgr + 4 MBC + 2 MRC. - * S400 should already configure when release RDC - * A35 only map non-secure region for pbridge0 and 1, set sec_access to false */ - trdc_mbc_set_access(2, 7, 0, 49, false); - trdc_mbc_set_access(2, 7, 0, 50, false); - trdc_mbc_set_access(2, 7, 0, 51, false); - trdc_mbc_set_access(2, 7, 0, 52, false); - trdc_mbc_set_access(2, 7, 0, 53, false); - trdc_mbc_set_access(2, 7, 0, 54, false); - - /* CGC0: PBridge0 slot 47 */ + trdc_mbc_set_access(2, 7, 0, 49, true); + trdc_mbc_set_access(2, 7, 0, 50, true); + trdc_mbc_set_access(2, 7, 0, 51, true); + trdc_mbc_set_access(2, 7, 0, 52, true); + trdc_mbc_set_access(2, 7, 0, 53, true); + trdc_mbc_set_access(2, 7, 0, 54, true); + + /* 0x1fff8000 used for resource table by remoteproc */ + trdc_mbc_set_access(0, 7, 2, 31, false); + + /* CGC0: PBridge0 slot 47 and PCC0 slot 48 */ trdc_mbc_set_access(2, 7, 0, 47, false); + trdc_mbc_set_access(2, 7, 0, 48, false); + + /* PCC1 */ + trdc_mbc_set_access(2, 7, 1, 17, false); + trdc_mbc_set_access(2, 7, 1, 34, false); /* Iomuxc0: : PBridge1 slot 33 */ trdc_mbc_set_access(2, 7, 1, 33, false); /* flexspi0 */ + trdc_mbc_set_access(2, 7, 0, 57, false); trdc_mrc_region_set_access(0, 7, 0x04000000, 0x0c000000, false); /* tpm0: PBridge1 slot 21 */ trdc_mbc_set_access(2, 7, 1, 21, false); /* lpi2c0: PBridge1 slot 24 */ trdc_mbc_set_access(2, 7, 1, 24, false); + + /* Allow M33 to access TRDC MGR */ + trdc_mbc_set_access(2, 6, 0, 49, true); + trdc_mbc_set_access(2, 6, 0, 50, true); + trdc_mbc_set_access(2, 6, 0, 51, true); + trdc_mbc_set_access(2, 6, 0, 52, true); + trdc_mbc_set_access(2, 6, 0, 53, true); + trdc_mbc_set_access(2, 6, 0, 54, true); + + /* Set SAI0 for eDMA 0, NS */ + trdc_mbc_set_access(2, 0, 1, 28, false); + + /* Set SSRAM for eDMA0 access */ + trdc_mbc_set_access(0, 0, 2, 0, false); + trdc_mbc_set_access(0, 0, 2, 1, false); + trdc_mbc_set_access(0, 0, 2, 2, false); + trdc_mbc_set_access(0, 0, 2, 3, false); + trdc_mbc_set_access(0, 0, 2, 4, false); + trdc_mbc_set_access(0, 0, 2, 5, false); + trdc_mbc_set_access(0, 0, 2, 6, false); + trdc_mbc_set_access(0, 0, 2, 7, false); + + writel(0x800000a0, 0x28031840); + return 0; } @@ -705,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 */ @@ -725,29 +818,21 @@ 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) { - if (rdc_en) - release_rdc(RDC_TRDC); - - trdc_set_access(); - 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 { /* reconfigure core0 reset vector to ROM */ set_core0_reset_vector(0x1000); @@ -756,10 +841,36 @@ int arch_cpu_init(void) 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 arch_cpu_init_dm(void) { struct udevice *devp; int node, ret; + 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"); @@ -769,6 +880,16 @@ int arch_cpu_init_dm(void) return ret; } + ret = ahab_get_info(&info, &res); + if (ret) { + printf("ahab_get_info failed %d\n", ret); + /* fallback to A0.1 revision */ + memset((void *)&info, 0, sizeof(struct sentinel_get_info_data)); + info.soc = 0xa000084d; + } + + set_cpu_info(&info); + return 0; } @@ -856,7 +977,8 @@ int (*card_emmc_is_boot_part_en)(void) = (void *)0x67cc; u32 spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev) { /* Hard code for eMMC image_offset on 8ULP ROM, need fix by ROM, temp workaround */ - if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && card_emmc_is_boot_part_en()) + if (is_soc_rev(CHIP_REV_1_0) && ((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_MMC && + card_emmc_is_boot_part_en()) image_offset = 0; return image_offset; |