diff options
Diffstat (limited to 'arch/arm/mach-imx/imx8ulp/soc.c')
-rw-r--r-- | arch/arm/mach-imx/imx8ulp/soc.c | 197 |
1 files changed, 189 insertions, 8 deletions
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c index e6d417ed48b..35020c9714d 100644 --- a/arch/arm/mach-imx/imx8ulp/soc.c +++ b/arch/arm/mach-imx/imx8ulp/soc.c @@ -26,6 +26,9 @@ #include <dm/uclass-internal.h> #include <fuse.h> #include <thermal.h> +#include <linux/iopoll.h> +#include <env.h> +#include <env_internal.h> DECLARE_GLOBAL_DATA_PTR; @@ -137,6 +140,38 @@ enum bt_mode get_boot_mode(void) return LOW_POWER_BOOT; } +bool m33_image_booted(void) +{ + u32 gp6; + + /* DGO_GP6 */ + gp6 = readl(SIM_SEC_BASE_ADDR + 0x28); + if (gp6 & BIT(5)) + return true; + + return false; +} + +int m33_image_handshake(ulong timeout_ms) +{ + u32 fsr; + int ret; + ulong timeout_us = timeout_ms * 1000; + + /* Notify m33 that it's ready to do init srtm(enable mu receive interrupt and so on) */ + setbits_le32(MU0_B_BASE_ADDR + 0x100, BIT(0)); /* set FCR F0 flag of MU0_MUB */ + + /* + * Wait m33 to set FCR F0 flag of MU0_MUA + * Clear FCR F0 flag of MU0_MUB after m33 has set FCR F0 flag of MU0_MUA + */ + ret = readl_poll_sleep_timeout(MU0_B_BASE_ADDR + 0x104, fsr, fsr & BIT(0), 10, timeout_us); + if (!ret) + clrbits_le32(MU0_B_BASE_ADDR + 0x100, BIT(0)); + + return ret; +} + #define CMC_SRS_TAMPER BIT(31) #define CMC_SRS_SECURITY BIT(30) #define CMC_SRS_TZWDG BIT(29) @@ -380,6 +415,17 @@ static struct mm_region imx8ulp_arm64_mem_map[] = { struct mm_region *mem_map = imx8ulp_arm64_mem_map; +static unsigned int imx8ulp_find_dram_entry_in_mem_map(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(imx8ulp_arm64_mem_map); i++) + if (imx8ulp_arm64_mem_map[i].phys == CONFIG_SYS_SDRAM_BASE) + return i; + + hang(); /* Entry not found, this must never happen. */ +} + /* simplify the page table size to enhance boot speed */ #define MAX_PTE_ENTRIES 512 #define MAX_MEM_MAP_REGIONS 16 @@ -411,19 +457,106 @@ u64 get_page_table_size(void) void enable_caches(void) { - /* TODO: add TEE memmap region */ + /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */ + if (rom_pointer[1]) { + /* + * TEE are loaded, So the ddr bank structures + * have been modified update mmu table accordingly + */ + int i = 0; + int entry = imx8ulp_find_dram_entry_in_mem_map(); + u64 attrs = imx8ulp_arm64_mem_map[entry].attrs; + + while (i < CONFIG_NR_DRAM_BANKS && + entry < ARRAY_SIZE(imx8ulp_arm64_mem_map)) { + if (gd->bd->bi_dram[i].start == 0) + break; + imx8ulp_arm64_mem_map[entry].phys = gd->bd->bi_dram[i].start; + imx8ulp_arm64_mem_map[entry].virt = gd->bd->bi_dram[i].start; + imx8ulp_arm64_mem_map[entry].size = gd->bd->bi_dram[i].size; + imx8ulp_arm64_mem_map[entry].attrs = attrs; + debug("Added memory mapping (%d): %llx %llx\n", entry, + imx8ulp_arm64_mem_map[entry].phys, imx8ulp_arm64_mem_map[entry].size); + i++; entry++; + } + } icache_enable(); dcache_enable(); } +__weak int board_phys_sdram_size(phys_size_t *size) +{ + if (!size) + return -EINVAL; + + *size = PHYS_SDRAM_SIZE; + return 0; +} + int dram_init(void) { - gd->ram_size = PHYS_SDRAM_SIZE; + unsigned int entry = imx8ulp_find_dram_entry_in_mem_map(); + phys_size_t sdram_size; + int ret; + + ret = board_phys_sdram_size(&sdram_size); + if (ret) + return ret; + + /* rom_pointer[1] contains the size of TEE occupies */ + if (rom_pointer[1]) + gd->ram_size = sdram_size - rom_pointer[1]; + else + gd->ram_size = sdram_size; + /* also update the SDRAM size in the mem_map used externally */ + imx8ulp_arm64_mem_map[entry].size = sdram_size; return 0; } +int dram_init_banksize(void) +{ + int bank = 0; + int ret; + phys_size_t sdram_size; + + ret = board_phys_sdram_size(&sdram_size); + if (ret) + return ret; + + gd->bd->bi_dram[bank].start = PHYS_SDRAM; + if (rom_pointer[1]) { + phys_addr_t optee_start = (phys_addr_t)rom_pointer[0]; + phys_size_t optee_size = (size_t)rom_pointer[1]; + + gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start; + if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) { + if (++bank >= CONFIG_NR_DRAM_BANKS) { + puts("CONFIG_NR_DRAM_BANKS is not enough\n"); + return -1; + } + + gd->bd->bi_dram[bank].start = optee_start + optee_size; + gd->bd->bi_dram[bank].size = PHYS_SDRAM + + sdram_size - gd->bd->bi_dram[bank].start; + } + } else { + gd->bd->bi_dram[bank].size = sdram_size; + } + + return 0; +} + +phys_size_t get_effective_memsize(void) +{ + /* return the first bank as effective memory */ + if (rom_pointer[1]) + return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM); + + return gd->ram_size; +} + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG void get_board_serial(struct tag_serialnr *serialnr) { @@ -491,10 +624,10 @@ static int trdc_set_access(void) return 0; } -void lpav_configure(void) +void lpav_configure(bool lpav_to_m33) { - /* LPAV to APD */ - setbits_le32(SIM_SEC_BASE_ADDR + 0x44, BIT(7)); + if (!lpav_to_m33) + setbits_le32(SIM_SEC_BASE_ADDR + 0x44, BIT(7)); /* LPAV to APD */ /* PXP/GPU 2D/3D/DCNANO/MIPI_DSI/EPDC/HIFI4 to APD */ setbits_le32(SIM_SEC_BASE_ADDR + 0x4c, 0x7F); @@ -538,6 +671,19 @@ int arch_cpu_init(void) 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 */ + setbits_le32(CMC1_BASE_ADDR + 0x70, BIT(4)); + + if (readl(CMC1_BASE_ADDR + 0x90) & BIT(13)) { + /* Clear System Reset Interrupt Flag Register of WDOG_AD */ + setbits_le32(CMC1_BASE_ADDR + 0x90, BIT(13)); + /* Reset WDOG to clear reset request */ + pcc_reset_peripheral(3, WDOG3_PCC3_SLOT, true); + pcc_reset_peripheral(3, WDOG3_PCC3_SLOT, false); + } + /* Disable wdog */ init_wdog(); @@ -551,8 +697,9 @@ int arch_cpu_init(void) release_rdc(RDC_TRDC); trdc_set_access(); - - lpav_configure(); + lpav_configure(false); + } else { + lpav_configure(true); } /* Release xrdc, then allow A35 to write SRAM2 */ @@ -561,7 +708,7 @@ int arch_cpu_init(void) xrdc_mrc_region_set_access(2, CONFIG_SPL_TEXT_BASE, 0xE00); - clock_init(); + clock_init_early(); } else { /* reconfigure core0 reset vector to ROM */ set_core0_reset_vector(0x1000); @@ -642,3 +789,37 @@ u32 spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev) return image_offset; } + +enum env_location env_get_location(enum env_operation op, int prio) +{ + enum boot_device dev = get_boot_device(); + enum env_location env_loc = ENVL_UNKNOWN; + + if (prio) + return env_loc; + + switch (dev) { +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + case QSPI_BOOT: + env_loc = ENVL_SPI_FLASH; + break; +#endif +#ifdef CONFIG_ENV_IS_IN_MMC + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: + env_loc = ENVL_MMC; + break; +#endif + default: +#if defined(CONFIG_ENV_IS_NOWHERE) + env_loc = ENVL_NOWHERE; +#endif + break; + } + + return env_loc; +} |