summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/imx8ulp/soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/imx8ulp/soc.c')
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c196
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;