diff options
Diffstat (limited to 'arch/arm/mach-imx')
| -rw-r--r-- | arch/arm/mach-imx/cmd_dek.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-imx/cpu.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8/Kconfig | 7 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8/cpu.c | 18 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8m/Kconfig | 44 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8m/clock_imx8mm.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8m/soc.c | 361 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8ulp/Kconfig | 7 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8ulp/cgc.c | 106 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8ulp/clock.c | 95 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8ulp/pcc.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-imx/imx8ulp/soc.c | 197 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx6/Kconfig | 10 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx6/ddr.c | 13 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx6/soc.c | 13 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx7/Kconfig | 1 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx7/soc.c | 12 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx7ulp/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mx7ulp/soc.c | 18 | ||||
| -rw-r--r-- | arch/arm/mach-imx/parse-container.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-imx/spl_imx_romapi.c | 10 |
21 files changed, 765 insertions, 158 deletions
diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c index 89da89c51d5..04c4b20a84b 100644 --- a/arch/arm/mach-imx/cmd_dek.c +++ b/arch/arm/mach-imx/cmd_dek.c @@ -9,6 +9,7 @@ #include <command.h> #include <log.h> #include <malloc.h> +#include <memalign.h> #include <asm/byteorder.h> #include <linux/compiler.h> #include <fsl_sec.h> diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 8eb05c8dd67..ba386c24b4a 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -106,6 +106,8 @@ const char *get_imx_type(u32 imxtype) return "8MP Lite[4]"; /* Quad-core Lite version of the imx8mp */ case MXC_CPU_IMX8MP6: return "8MP[6]"; /* Quad-core version of the imx8mp, NPU fused */ + case MXC_CPU_IMX8MPUL: + return "8MP UltraLite"; /* Quad-core UltraLite version of the imx8mp */ case MXC_CPU_IMX8MN: return "8MNano Quad"; /* Quad-core version */ case MXC_CPU_IMX8MND: diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index b43739e5c64..f969833baba 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -8,6 +8,7 @@ config AHAB_BOOT config IMX8 bool + select HAS_CAAM config MU_BASE_SPL hex "MU base address used in SPL" @@ -72,6 +73,9 @@ config TARGET_IMX8QM_MEK bool "Support i.MX8QM MEK board" select BOARD_LATE_INIT select IMX8QM + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_CONGA_QMX8 bool "Support congatec conga-QMX8 board" @@ -89,6 +93,9 @@ config TARGET_IMX8QXP_MEK bool "Support i.MX8QXP MEK board" select BOARD_LATE_INIT select IMX8QXP + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL endchoice diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 359f8c796eb..0858ea5f057 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018 NXP + * Copyright 2018, 2021 NXP */ #include <common.h> @@ -91,6 +91,22 @@ static int imx8_init_mu(void *ctx, struct event *event) } EVENT_SPY(EVT_DM_POST_INIT, imx8_init_mu); +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } + + return 0; +} +#endif + int print_bootinfo(void) { enum boot_device bt_dev = get_boot_device(); diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index fae70499953..55db25062a9 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -39,6 +39,9 @@ config TARGET_IMX8MQ_EVK select BINMAN select IMX8MQ select IMX8M_LPDDR4 + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_IMX8MQ_PHANBELL bool "imx8mq_phanbell" @@ -46,12 +49,22 @@ config TARGET_IMX8MQ_PHANBELL select IMX8MQ select IMX8M_LPDDR4 +config TARGET_IMX8MM_DATA_MODUL_EDM_SBC + bool "Data Modul eDM SBC i.MX8M Mini" + select BINMAN + select IMX8MM + select IMX8M_LPDDR4 + select SUPPORT_SPL + config TARGET_IMX8MM_EVK bool "imx8mm LPDDR4 EVK board" select BINMAN select IMX8MM select SUPPORT_SPL select IMX8M_LPDDR4 + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_IMX8MM_ICORE_MX8MM bool "Engicam i.Core MX8M Mini SOM" @@ -71,6 +84,13 @@ config TARGET_IMX8MM_ICORE_MX8MM * i.Core MX8M Mini needs to mount on top of this Carrier board for creating complete i.Core MX8M Mini C.TOUCH 2.0 board. +config TARGET_IMX8MM_MX8MENLO + bool "Support i.MX8M Mini MX8Menlo board based on Toradex Verdin SoM" + select BINMAN + select IMX8MM + select SUPPORT_SPL + select IMX8M_LPDDR4 + config TARGET_IMX8MM_VENICE bool "Support Gateworks Venice iMX8M Mini module" select BINMAN @@ -85,12 +105,28 @@ config TARGET_KONTRON_MX8MM select SUPPORT_SPL select IMX8M_LPDDR4 +config TARGET_IMX8MN_BSH_SMM_S2 + bool "imx8mn-bsh-smm-s2" + select BINMAN + select IMX8MN + select SUPPORT_SPL + select IMX8M_DDR3L + +config TARGET_IMX8MN_BSH_SMM_S2PRO + bool "imx8mn-bsh-smm-s2pro" + select BINMAN + select IMX8MN + select SUPPORT_SPL + select IMX8M_DDR3L + config TARGET_IMX8MN_EVK bool "imx8mn LPDDR4 EVK board" select BINMAN select IMX8MN select SUPPORT_SPL select IMX8M_LPDDR4 + select FSL_CAAM + select SPL_CRYPTO if SPL config TARGET_IMX8MN_DDR4_EVK bool "imx8mn DDR4 EVK board" @@ -98,6 +134,8 @@ config TARGET_IMX8MN_DDR4_EVK select IMX8MN select SUPPORT_SPL select IMX8M_DDR4 + select FSL_CAAM + select SPL_CRYPTO if SPL config TARGET_IMX8MN_VENICE bool "Support Gateworks Venice iMX8M Nano module" @@ -112,6 +150,9 @@ config TARGET_IMX8MP_EVK select IMX8MP select SUPPORT_SPL select IMX8M_LPDDR4 + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_PICO_IMX8MQ bool "Support Technexion Pico iMX8MQ" @@ -208,7 +249,9 @@ endchoice source "board/advantech/imx8mp_rsb3720a1/Kconfig" source "board/beacon/imx8mm/Kconfig" source "board/beacon/imx8mn/Kconfig" +source "board/bsh/imx8mn_smm_s2/Kconfig" source "board/compulab/imx8mm-cl-iot-gate/Kconfig" +source "board/data_modul/imx8mm_edm_sbc/Kconfig" source "board/engicam/imx8mm/Kconfig" source "board/freescale/imx8mq_evk/Kconfig" source "board/freescale/imx8mm_evk/Kconfig" @@ -218,6 +261,7 @@ source "board/gateworks/venice/Kconfig" source "board/google/imx8mq_phanbell/Kconfig" source "board/kontron/pitx_imx8m/Kconfig" source "board/kontron/sl-mx8mm/Kconfig" +source "board/menlo/mx8menlo/Kconfig" source "board/phytec/phycore_imx8mm/Kconfig" source "board/phytec/phycore_imx8mp/Kconfig" source "board/ronetix/imx8mq-cm/Kconfig" diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 76132defc21..4db55f86081 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -48,6 +48,7 @@ int enable_i2c_clk(unsigned char enable, unsigned i2c_num) #ifdef CONFIG_SPL_BUILD static struct imx_int_pll_rate_table imx8mm_fracpll_tbl[] = { PLL_1443X_RATE(1000000000U, 250, 3, 1, 0), + PLL_1443X_RATE(933000000U, 311, 4, 1, 0), PLL_1443X_RATE(800000000U, 300, 9, 0, 0), PLL_1443X_RATE(750000000U, 250, 8, 0, 0), PLL_1443X_RATE(650000000U, 325, 3, 2, 0), diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 7397b99a1ee..8171631db10 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017-2019 NXP + * Copyright 2017-2019, 2021 NXP * * Peng Fan <peng.fan@nxp.com> */ @@ -21,6 +21,7 @@ #include <asm/ptrace.h> #include <asm/armv8/mmu.h> #include <dm/uclass.h> +#include <dm/device.h> #include <efi_loader.h> #include <env.h> #include <env_internal.h> @@ -28,7 +29,6 @@ #include <fdt_support.h> #include <fsl_wdog.h> #include <imx_sip.h> -#include <linux/arm-smccc.h> #include <linux/bitops.h> DECLARE_GLOBAL_DATA_PTR; @@ -72,7 +72,7 @@ void enable_tzc380(void) * According to TRM, TZASC_ID_SWAP_BYPASS should be set in * order to avoid AXI Bus errors when GPU is in use */ - if (is_imx8mm() || is_imx8mn() || is_imx8mp()) + if (is_imx8mq() || is_imx8mm() || is_imx8mn() || is_imx8mp()) setbits_le32(&gpr->gpr[10], GPR_TZASC_ID_SWAP_BYPASS); /* @@ -188,32 +188,29 @@ static unsigned int imx8m_find_dram_entry_in_mem_map(void) void enable_caches(void) { - /* 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; - /* - * please make sure that entry initial value matches - * imx8m_mem_map for DRAM1 - */ - int entry = imx8m_find_dram_entry_in_mem_map(); - u64 attrs = imx8m_mem_map[entry].attrs; - - while (i < CONFIG_NR_DRAM_BANKS && - entry < ARRAY_SIZE(imx8m_mem_map)) { - if (gd->bd->bi_dram[i].start == 0) - break; - imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start; - imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start; - imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size; - imx8m_mem_map[entry].attrs = attrs; - debug("Added memory mapping (%d): %llx %llx\n", entry, - imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size); - i++; entry++; - } + /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch + * If OPTEE does not run, still update the MMU table according to dram banks structure + * to set correct dram size from board_phys_sdram_size + */ + int i = 0; + /* + * please make sure that entry initial value matches + * imx8m_mem_map for DRAM1 + */ + int entry = imx8m_find_dram_entry_in_mem_map(); + u64 attrs = imx8m_mem_map[entry].attrs; + + while (i < CONFIG_NR_DRAM_BANKS && + entry < ARRAY_SIZE(imx8m_mem_map)) { + if (gd->bd->bi_dram[i].start == 0) + break; + imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start; + imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start; + imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size; + imx8m_mem_map[entry].attrs = attrs; + debug("Added memory mapping (%d): %llx %llx\n", entry, + imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size); + i++; entry++; } icache_enable(); @@ -226,12 +223,15 @@ __weak int board_phys_sdram_size(phys_size_t *size) return -EINVAL; *size = PHYS_SDRAM_SIZE; + +#ifdef PHYS_SDRAM_2_SIZE + *size += PHYS_SDRAM_2_SIZE; +#endif return 0; } int dram_init(void) { - unsigned int entry = imx8m_find_dram_entry_in_mem_map(); phys_size_t sdram_size; int ret; @@ -245,13 +245,6 @@ int dram_init(void) else gd->ram_size = sdram_size; - /* also update the SDRAM size in the mem_map used externally */ - imx8m_mem_map[entry].size = sdram_size; - -#ifdef PHYS_SDRAM_2_SIZE - gd->ram_size += PHYS_SDRAM_2_SIZE; -#endif - return 0; } @@ -260,18 +253,28 @@ int dram_init_banksize(void) int bank = 0; int ret; phys_size_t sdram_size; + phys_size_t sdram_b1_size, sdram_b2_size; ret = board_phys_sdram_size(&sdram_size); if (ret) return ret; + /* Bank 1 can't cross over 4GB space */ + if (sdram_size > 0xc0000000) { + sdram_b1_size = 0xc0000000; + sdram_b2_size = sdram_size - 0xc0000000; + } else { + sdram_b1_size = sdram_size; + sdram_b2_size = 0; + } + 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 ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) { if (++bank >= CONFIG_NR_DRAM_BANKS) { puts("CONFIG_NR_DRAM_BANKS is not enough\n"); return -1; @@ -279,35 +282,51 @@ int dram_init_banksize(void) 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; + sdram_b1_size - gd->bd->bi_dram[bank].start; } } else { - gd->bd->bi_dram[bank].size = sdram_size; + gd->bd->bi_dram[bank].size = sdram_b1_size; } -#ifdef PHYS_SDRAM_2_SIZE - if (++bank >= CONFIG_NR_DRAM_BANKS) { - puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n"); - return -1; + if (sdram_b2_size) { + if (++bank >= CONFIG_NR_DRAM_BANKS) { + puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n"); + return -1; + } + gd->bd->bi_dram[bank].start = 0x100000000UL; + gd->bd->bi_dram[bank].size = sdram_b2_size; } - gd->bd->bi_dram[bank].start = PHYS_SDRAM_2; - gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE; -#endif 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); + int ret; + phys_size_t sdram_size; + phys_size_t sdram_b1_size; + ret = board_phys_sdram_size(&sdram_size); + if (!ret) { + /* Bank 1 can't cross over 4GB space */ + if (sdram_size > 0xc0000000) { + sdram_b1_size = 0xc0000000; + } else { + sdram_b1_size = sdram_size; + } -#ifdef PHYS_SDRAM_2_SIZE - return gd->ram_size - PHYS_SDRAM_2_SIZE; -#else - return gd->ram_size; -#endif + if (rom_pointer[1]) { + /* We will relocate u-boot to Top of dram1. Tee position has two cases: + * 1. At the top of dram1, Then return the size removed optee size. + * 2. In the middle of dram1, return the size of dram1. + */ + if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size)) + return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM); + } + + return sdram_b1_size; + } else { + return PHYS_SDRAM_SIZE; + } } ulong board_get_usable_ram_top(ulong total_size) @@ -408,13 +427,27 @@ static u32 get_cpu_variant_type(u32 type) /* npu disabled*/ if ((value & 0x8) == 0x8) - flag |= (1 << 1); + flag |= BIT(1); /* isp disabled */ if ((value & 0x3) == 0x3) - flag |= (1 << 2); + flag |= BIT(2); + + /* gpu disabled */ + if ((value & 0xc0) == 0xc0) + flag |= BIT(3); + + /* lvds disabled */ + if ((value & 0x180000) == 0x180000) + flag |= BIT(4); + + /* mipi dsi disabled */ + if ((value & 0x60000) == 0x60000) + flag |= BIT(5); switch (flag) { + case 0x3f: + return MXC_CPU_IMX8MPUL; case 7: return MXC_CPU_IMX8MPL; case 2: @@ -517,6 +550,11 @@ EVENT_SPY(EVT_DM_POST_INIT, imx8m_check_clock); int arch_cpu_init(void) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + +#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) + icache_enable(); +#endif + /* * ROM might disable clock for SCTR, * enable the clock before timer_init. @@ -599,6 +637,9 @@ enum boot_device get_boot_device(void) case BT_DEV_TYPE_FLEXSPINOR: boot_dev = QSPI_BOOT; break; + case BT_DEV_TYPE_SPI_NOR: + boot_dev = SPI_NOR_BOOT; + break; case BT_DEV_TYPE_USB: boot_dev = USB_BOOT; break; @@ -893,6 +934,90 @@ static int low_drive_gpu_freq(void *blob) } #endif +static bool check_remote_endpoint(void *blob, const char *ep1, const char *ep2) +{ + int lookup_node; + int nodeoff; + + nodeoff = fdt_path_offset(blob, ep1); + if (nodeoff) { + lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint"); + nodeoff = fdt_path_offset(blob, ep2); + + if (nodeoff > 0 && nodeoff == lookup_node) + return true; + } + + return false; +} + +int disable_dsi_lcdif_nodes(void *blob) +{ + int ret; + + static const char * const dsi_path_8mp[] = { + "/soc@0/bus@32c00000/mipi_dsi@32e60000" + }; + + static const char * const lcdif_path_8mp[] = { + "/soc@0/bus@32c00000/lcd-controller@32e80000" + }; + + static const char * const lcdif_ep_path_8mp[] = { + "/soc@0/bus@32c00000/lcd-controller@32e80000/port@0/endpoint" + }; + static const char * const dsi_ep_path_8mp[] = { + "/soc@0/bus@32c00000/mipi_dsi@32e60000/port@0/endpoint" + }; + + ret = disable_fdt_nodes(blob, dsi_path_8mp, ARRAY_SIZE(dsi_path_8mp)); + if (ret) + return ret; + + if (check_remote_endpoint(blob, dsi_ep_path_8mp[0], lcdif_ep_path_8mp[0])) { + /* Disable lcdif node */ + return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp)); + } + + return 0; +} + +int disable_lvds_lcdif_nodes(void *blob) +{ + int ret, i; + + static const char * const ldb_path_8mp[] = { + "/soc@0/bus@32c00000/ldb@32ec005c", + "/soc@0/bus@32c00000/phy@32ec0128" + }; + + static const char * const lcdif_path_8mp[] = { + "/soc@0/bus@32c00000/lcd-controller@32e90000" + }; + + static const char * const lcdif_ep_path_8mp[] = { + "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@0", + "/soc@0/bus@32c00000/lcd-controller@32e90000/port@0/endpoint@1" + }; + static const char * const ldb_ep_path_8mp[] = { + "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@0/port@0/endpoint", + "/soc@0/bus@32c00000/ldb@32ec005c/lvds-channel@1/port@0/endpoint" + }; + + ret = disable_fdt_nodes(blob, ldb_path_8mp, ARRAY_SIZE(ldb_path_8mp)); + if (ret) + return ret; + + for (i = 0; i < ARRAY_SIZE(ldb_ep_path_8mp); i++) { + if (check_remote_endpoint(blob, ldb_ep_path_8mp[i], lcdif_ep_path_8mp[i])) { + /* Disable lcdif node */ + return disable_fdt_nodes(blob, lcdif_path_8mp, ARRAY_SIZE(lcdif_path_8mp)); + } + } + + return 0; +} + int disable_gpu_nodes(void *blob) { static const char * const nodes_path_8mn[] = { @@ -900,7 +1025,15 @@ int disable_gpu_nodes(void *blob) "/soc@/gpu@38000000" }; - return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn)); + static const char * const nodes_path_8mp[] = { + "/gpu3d@38000000", + "/gpu2d@38008000" + }; + + if (is_imx8mp()) + return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); + else + return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn)); } int disable_npu_nodes(void *blob) @@ -1042,6 +1175,37 @@ static int disable_cpu_nodes(void *blob, u32 disabled_cores) return 0; } +static int cleanup_nodes_for_efi(void *blob) +{ + static const char * const path[][2] = { + { "/soc@0/bus@32c00000/usb@32e40000", "extcon" }, + { "/soc@0/bus@32c00000/usb@32e50000", "extcon" }, + { "/soc@0/bus@30800000/ethernet@30be0000", "phy-reset-gpios" }, + { "/soc@0/bus@30800000/ethernet@30bf0000", "phy-reset-gpios" } + }; + int nodeoff, i, rc; + + for (i = 0; i < ARRAY_SIZE(path); i++) { + nodeoff = fdt_path_offset(blob, path[i][0]); + if (nodeoff < 0) + continue; /* Not found, skip it */ + debug("Found %s node\n", path[i][0]); + + rc = fdt_delprop(blob, nodeoff, path[i][1]); + if (rc == -FDT_ERR_NOTFOUND) + continue; + if (rc) { + printf("Unable to update property %s:%s, err=%s\n", + path[i][0], path[i][1], fdt_strerror(rc)); + return rc; + } + + printf("Remove %s:%s\n", path[i][0], path[i][1]); + } + + return 0; +} + int ft_system_setup(void *blob, struct bd_info *bd) { #ifdef CONFIG_IMX8MQ @@ -1156,26 +1320,72 @@ usb_modify_speed: disable_cpu_nodes(blob, 3); #elif defined(CONFIG_IMX8MP) - if (is_imx8mpl()) + if (is_imx8mpul()) { + /* Disable GPU */ + disable_gpu_nodes(blob); + + /* Disable DSI */ + disable_dsi_lcdif_nodes(blob); + + /* Disable LVDS */ + disable_lvds_lcdif_nodes(blob); + } + + if (is_imx8mpul() || is_imx8mpl()) disable_vpu_nodes(blob); - if (is_imx8mpl() || is_imx8mp6()) + if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6()) disable_npu_nodes(blob); - if (is_imx8mpl()) + if (is_imx8mpul() || is_imx8mpl()) disable_isp_nodes(blob); - if (is_imx8mpl() || is_imx8mp6()) + if (is_imx8mpul() || is_imx8mpl() || is_imx8mp6()) disable_dsp_nodes(blob); if (is_imx8mpd()) disable_cpu_nodes(blob, 2); #endif + cleanup_nodes_for_efi(blob); return 0; } #endif +#ifdef CONFIG_OF_BOARD_FIXUP +#ifndef CONFIG_SPL_BUILD +int board_fix_fdt(void *fdt) +{ + if (is_imx8mpul()) { + int i = 0; + int nodeoff, ret; + const char *status = "disabled"; + static const char * const dsi_nodes[] = { + "/soc@0/bus@32c00000/mipi_dsi@32e60000", + "/soc@0/bus@32c00000/lcd-controller@32e80000", + "/dsi-host" + }; + + for (i = 0; i < ARRAY_SIZE(dsi_nodes); i++) { + nodeoff = fdt_path_offset(fdt, dsi_nodes[i]); + if (nodeoff > 0) { +set_status: + ret = fdt_setprop(fdt, nodeoff, "status", status, + strlen(status) + 1); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(fdt, 512); + if (!ret) + goto set_status; + } + } + } + } + + return 0; +} +#endif +#endif + #if !CONFIG_IS_ENABLED(SYSRESET) void reset_cpu(void) { @@ -1193,26 +1403,16 @@ void reset_cpu(void) #endif #if defined(CONFIG_ARCH_MISC_INIT) -static void acquire_buildinfo(void) -{ - u64 atf_commit = 0; - struct arm_smccc_res res; - - /* Get ARM Trusted Firmware commit id */ - arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH, - 0, 0, 0, 0, 0, 0, &res); - atf_commit = res.a0; - if (atf_commit == 0xffffffff) { - debug("ATF does not support build info\n"); - atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ - } - - printf("\n BuildInfo:\n - ATF %s\n\n", (char *)&atf_commit); -} - int arch_misc_init(void) { - acquire_buildinfo(); + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } return 0; } @@ -1337,6 +1537,7 @@ enum env_location env_get_location(enum env_operation op, int prio) switch (dev) { case QSPI_BOOT: + case SPI_NOR_BOOT: if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) return ENVL_SPI_FLASH; return ENVL_NOWHERE; diff --git a/arch/arm/mach-imx/imx8ulp/Kconfig b/arch/arm/mach-imx/imx8ulp/Kconfig index 963fc93d34f..bbdeaac07b3 100644 --- a/arch/arm/mach-imx/imx8ulp/Kconfig +++ b/arch/arm/mach-imx/imx8ulp/Kconfig @@ -2,11 +2,16 @@ if ARCH_IMX8ULP config IMX8ULP bool - select ARMV8_SPL_EXCEPTION_VECTORS config SYS_SOC default "imx8ulp" +config IMX8ULP_LD_MODE + bool + +config IMX8ULP_ND_MODE + bool "i.MX8ULP Low Driver Mode" + choice prompt "i.MX8ULP board select" optional diff --git a/arch/arm/mach-imx/imx8ulp/cgc.c b/arch/arm/mach-imx/imx8ulp/cgc.c index 38bcbb91e6e..d240abaee46 100644 --- a/arch/arm/mach-imx/imx8ulp/cgc.c +++ b/arch/arm/mach-imx/imx8ulp/cgc.c @@ -9,9 +9,11 @@ #include <errno.h> #include <asm/arch/imx-regs.h> #include <asm/arch/cgc.h> +#include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> #include <asm/global_data.h> #include <linux/delay.h> +#include <hang.h> DECLARE_GLOBAL_DATA_PTR; @@ -29,7 +31,7 @@ void cgc1_soscdiv_init(void) clrbits_le32(&cgc1_regs->frodiv, BIT(7)); } -void cgc1_pll2_init(void) +void cgc1_pll2_init(ulong freq) { u32 reg; @@ -44,8 +46,8 @@ void cgc1_pll2_init(void) while ((readl(&cgc1_regs->pll2csr) & BIT(24))) ; - /* Select SOSC as source, freq = 31 * 24 =744mhz */ - reg = 31 << 16; + /* Select SOSC as source */ + reg = (freq / MHZ(24)) << 16; writel(reg, &cgc1_regs->pll2cfg); /* Enable PLL2 */ @@ -74,7 +76,7 @@ static void cgc1_set_a35_clk(u32 clk_src, u32 div_core) ; } -void cgc1_init_core_clk(void) +void cgc1_init_core_clk(ulong freq) { u32 reg = readl(&cgc1_regs->ca35clk); @@ -82,8 +84,7 @@ void cgc1_init_core_clk(void) if (((reg >> 28) & 0x3) == 0x1) cgc1_set_a35_clk(0, 1); - /* Set pll2 to 750Mhz for 1V */ - cgc1_pll2_init(); + cgc1_pll2_init(freq); /* Set A35 clock to pll2 */ cgc1_set_a35_clk(1, 1); @@ -94,7 +95,7 @@ void cgc1_enet_stamp_sel(u32 clk_src) writel((clk_src & 0x7) << 24, &cgc1_regs->enetstamp); } -void cgc1_pll3_init(void) +void cgc1_pll3_init(ulong freq) { /* Gate off VCO */ setbits_le32(&cgc1_regs->pll3div_vco, BIT(7)); @@ -115,11 +116,15 @@ void cgc1_pll3_init(void) /* Select SOSC as source */ clrbits_le32(&cgc1_regs->pll3cfg, BIT(0)); - //setbits_le32(&cgc1_regs->pll3cfg, 22 << 16); - writel(22 << 16, &cgc1_regs->pll3cfg); - - writel(578, &cgc1_regs->pll3num); - writel(1000, &cgc1_regs->pll3denom); + switch (freq) { + case 540672000: + writel(0x16 << 16, &cgc1_regs->pll3cfg); + writel(0x16e3600, &cgc1_regs->pll3denom); + writel(0xc15c00, &cgc1_regs->pll3num); + break; + default: + hang(); + } /* Enable PLL3 */ setbits_le32(&cgc1_regs->pll3csr, BIT(0)); @@ -130,23 +135,30 @@ void cgc1_pll3_init(void) /* Gate on VCO */ clrbits_le32(&cgc1_regs->pll3div_vco, BIT(7)); - /* - * PFD0: 380MHz/396/396/328 - */ clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F); - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0); + + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0); + clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 3 << 21); /* 195M */ + } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + setbits_le32(&cgc1_regs->pll3pfdcfg, 21 << 0); + clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); /* 231M */ + } else { + setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* 324M */ + } + clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(6))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 8); - setbits_le32(&cgc1_regs->pll3pfdcfg, 24 << 8); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(14))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 16); - setbits_le32(&cgc1_regs->pll3pfdcfg, 24 << 16); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 16); clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(22))) ; @@ -166,10 +178,25 @@ void cgc1_pll3_init(void) clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(15)); clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(23)); clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(31)); + + if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + /* nicclk select pll3 pfd0 */ + clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(29, 28), BIT(28)); + while (!(readl(&cgc1_regs->nicclk) & BIT(27))) + ; + } } -void cgc2_pll4_init(void) +void cgc2_pll4_init(bool pll4_reset) { + /* Check the NICLPAV first to ensure not from PLL4 PFD1 clock */ + if ((readl(&cgc2_regs->niclpavclk) & GENMASK(29, 28)) == BIT(28)) { + /* switch to FRO 192 first */ + clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28)); + while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) + ; + } + /* Disable PFD DIV and clear DIV */ writel(0x80808080, &cgc2_regs->pll4div_pfd0); writel(0x80808080, &cgc2_regs->pll4div_pfd1); @@ -177,22 +204,35 @@ void cgc2_pll4_init(void) /* Gate off and clear PFD */ writel(0x80808080, &cgc2_regs->pll4pfdcfg); - /* Disable PLL4 */ - writel(0x0, &cgc2_regs->pll4csr); + if (pll4_reset) { + /* Disable PLL4 */ + writel(0x0, &cgc2_regs->pll4csr); - /* Configure PLL4 to 528Mhz and clock source from SOSC */ - writel(22 << 16, &cgc2_regs->pll4cfg); - writel(0x1, &cgc2_regs->pll4csr); + /* Configure PLL4 to 528Mhz and clock source from SOSC */ + writel(22 << 16, &cgc2_regs->pll4cfg); + writel(0x1, &cgc2_regs->pll4csr); - /* wait for PLL4 output valid */ - while (!(readl(&cgc2_regs->pll4csr) & BIT(24))) - ; + /* wait for PLL4 output valid */ + while (!(readl(&cgc2_regs->pll4csr) & BIT(24))) + ; + } /* Enable all 4 PFDs */ - setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0); - setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ - setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16); - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); + setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0); /* 528 */ + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); + /* 99Mhz for NIC_LPAV */ + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 3 << 21); + } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); + /* 198Mhz for NIC_LPAV */ + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); + } else { + setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ + clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21)); + } + setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16); /* 792 */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396 */ clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) | BIT(15) | BIT(23) | BIT(31)); @@ -203,6 +243,10 @@ void cgc2_pll4_init(void) /* Enable PFD DIV */ clrbits_le32(&cgc2_regs->pll4div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31)); clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31)); + + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28)); + while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) + ; } void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd) diff --git a/arch/arm/mach-imx/imx8ulp/clock.c b/arch/arm/mach-imx/imx8ulp/clock.c index 91580b2c29c..3e71a4f6c3b 100644 --- a/arch/arm/mach-imx/imx8ulp/clock.c +++ b/arch/arm/mach-imx/imx8ulp/clock.c @@ -101,8 +101,8 @@ void init_clk_ddr(void) writel(0xc0000000, PCC5_LPDDR4_ADDR); /* enable pll4 and ddrclk*/ - cgc2_pll4_init(); - cgc2_ddrclk_config(1, 1); + cgc2_pll4_init(true); + cgc2_ddrclk_config(4, 1); /* enable ddr pcc */ writel(0xd0000000, PCC5_LPDDR4_ADDR); @@ -153,30 +153,69 @@ int set_ddr_clk(u32 phy_freq_mhz) return 0; } -void clock_init(void) +void clock_init_early(void) { cgc1_soscdiv_init(); - cgc1_init_core_clk(); init_clk_lpuart(); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); + /* Enable upower mu1 clk */ + pcc_clock_enable(3, UPOWER_PCC3_SLOT, true); +} - pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); +/* This will be invoked after pmic voltage setting */ +void clock_init_late(void) +{ - pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) + cgc1_init_core_clk(MHZ(500)); + else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) + cgc1_init_core_clk(MHZ(750)); + else + cgc1_init_core_clk(MHZ(960)); - /* Enable upower mu1 clk */ - pcc_clock_enable(3, UPOWER_PCC3_SLOT, true); + /* + * Audio use this frequency in kernel dts, + * however nic use pll3 pfd0, we have to + * make the freqency same as kernel to make nic + * not being disabled + */ + cgc1_pll3_init(540672000); + + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD2_DIV2); + pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV2); + pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV2); + pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); + } else { + pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2); + pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1); + pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1); + pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); + } + + /* enable MU0_MUB clock before access the register of MU0_MUB */ + pcc_clock_enable(3, MU0_B_PCC3_SLOT, true); /* * Enable clock division @@ -237,6 +276,26 @@ u32 imx_get_i2cclk(u32 i2c_num) } #endif +#if IS_ENABLED(CONFIG_SYS_I2C_IMX_I3C) +int enable_i3c_clk(unsigned char enable, u32 i3c_num) +{ + if (enable) { + pcc_clock_enable(3, I3C2_PCC3_SLOT, false); + pcc_clock_sel(3, I3C2_PCC3_SLOT, SOSC_DIV2); + pcc_clock_enable(3, I3C2_PCC3_SLOT, true); + pcc_reset_peripheral(3, I3C2_PCC3_SLOT, false); + } else { + pcc_clock_enable(3, I3C2_PCC3_SLOT, false); + } + return 0; +} + +u32 imx_get_i3cclk(u32 i3c_num) +{ + return pcc_clock_get_rate(3, I3C2_PCC3_SLOT); +} +#endif + void enable_usboh3_clk(unsigned char enable) { if (enable) { diff --git a/arch/arm/mach-imx/imx8ulp/pcc.c b/arch/arm/mach-imx/imx8ulp/pcc.c index 7909d770afe..e3c6d6760be 100644 --- a/arch/arm/mach-imx/imx8ulp/pcc.c +++ b/arch/arm/mach-imx/imx8ulp/pcc.c @@ -135,6 +135,7 @@ static struct pcc_entry pcc3_arrays[] = { {PCC3_RBASE, UPOWER_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, {PCC3_RBASE, WDOG3_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, {PCC3_RBASE, WDOG4_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV, PCC_HAS_RST_B}, + {PCC3_RBASE, CAAM_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_HAS_RST_B}, {PCC3_RBASE, XRDC_MGR_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, {PCC3_RBASE, SEMA42_1_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV, PCC_NO_RST_B}, {PCC3_RBASE, ROMCP1_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV, PCC_NO_RST_B}, 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; +} diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index 98df4d4e428..3d675fcd73e 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -354,6 +354,8 @@ config TARGET_MX6SABREAUTO select DM_THERMAL select SUPPORT_SPL imply CMD_DM + select FSL_CAAM + select ARCH_MISC_INIT config TARGET_MX6SABRESD bool "mx6sabresd" @@ -364,6 +366,8 @@ config TARGET_MX6SABRESD select DM_THERMAL select SUPPORT_SPL imply CMD_DM + select FSL_CAAM + select ARCH_MISC_INIT config TARGET_MX6SLEVK bool "mx6slevk" @@ -386,6 +390,8 @@ config TARGET_MX6SXSABRESD select DM select DM_THERMAL select SUPPORT_SPL + select FSL_CAAM + select ARCH_MISC_INIT config TARGET_MX6SXSABREAUTO bool "mx6sxsabreauto" @@ -404,6 +410,8 @@ config TARGET_MX6UL_9X9_EVK select DM_THERMAL select SUPPORT_SPL imply CMD_DM + select FSL_CAAM + select ARCH_MISC_INIT config TARGET_MX6UL_14X14_EVK bool "mx6ul_14x14_evk" @@ -413,6 +421,8 @@ config TARGET_MX6UL_14X14_EVK select DM_THERMAL select SUPPORT_SPL imply CMD_DM + select FSL_CAAM + select ARCH_MISC_INIT config TARGET_MX6UL_ENGICAM bool "Support Engicam GEAM6UL/Is.IoT" diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c index f872bfdab31..73a637c42d6 100644 --- a/arch/arm/mach-imx/mx6/ddr.c +++ b/arch/arm/mach-imx/mx6/ddr.c @@ -108,7 +108,7 @@ int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo) { struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - u32 esdmisc_val, zq_val; + u32 esdmisc_val, zq_val, mdmisc_val; u32 errors = 0; u32 ldectrl[4] = {0}; u32 ddr_mr1 = 0x4; @@ -131,6 +131,9 @@ int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo) /* disable Adopt power down timer */ setbits_le32(&mmdc0->mapsr, 0x1); + /* Save old RALAT and WALAT values */ + mdmisc_val = readl(&mmdc0->mdmisc); + debug("Starting write leveling calibration.\n"); /* @@ -217,6 +220,9 @@ int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo) writel(esdmisc_val, &mmdc0->mdref); writel(zq_val, &mmdc0->mpzqhwctrl); + /* restore WALAT/RALAT */ + writel(mdmisc_val, &mmdc0->mdmisc); + debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08x\n", readl(&mmdc0->mpwldectrl0)); debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08x\n", @@ -1520,6 +1526,11 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, ((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ /* Step 8: Write Mode Registers to Init DDR3 devices */ + mdelay(1); /* Wait before issuing the first MRS command. + * Minimum wait time is (tXPR + 500us), + * with max tXPR value 360ns, and 500us wait required after + * RESET_n is de-asserted. + */ for (cs = 0; cs < sysinfo->ncs; cs++) { /* MR2 */ val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index 03d6b8c1ce9..2434bcfa987 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -4,6 +4,7 @@ * Sascha Hauer, Pengutronix * * (C) Copyright 2009 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ #include <common.h> @@ -23,7 +24,6 @@ #include <asm/arch/mxc_hdmi.h> #include <asm/arch/crm_regs.h> #include <dm.h> -#include <fsl_sec.h> #include <imx_thermal.h> #include <mmc.h> @@ -738,9 +738,14 @@ static void setup_serial_number(void) int arch_misc_init(void) { -#ifdef CONFIG_FSL_CAAM - sec_init(); -#endif + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } setup_serial_number(); return 0; } diff --git a/arch/arm/mach-imx/mx7/Kconfig b/arch/arm/mach-imx/mx7/Kconfig index 0cad825287c..4f9f51c9b05 100644 --- a/arch/arm/mach-imx/mx7/Kconfig +++ b/arch/arm/mach-imx/mx7/Kconfig @@ -68,6 +68,7 @@ config TARGET_MX7DSABRESD select DM_THERMAL select MX7D imply CMD_DM + select FSL_CAAM config TARGET_PICO_IMX7D bool "pico-imx7d" diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index f6aec5a3aa2..dc9ac31eb0f 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ #include <common.h> @@ -20,7 +21,6 @@ #include <dm.h> #include <env.h> #include <imx_thermal.h> -#include <fsl_sec.h> #include <asm/setup.h> #include <linux/delay.h> @@ -356,9 +356,13 @@ int arch_misc_init(void) env_set("serial#", serial_string); #endif -#ifdef CONFIG_FSL_CAAM - sec_init(); -#endif + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + struct udevice *dev; + int ret; + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } return 0; } diff --git a/arch/arm/mach-imx/mx7ulp/Kconfig b/arch/arm/mach-imx/mx7ulp/Kconfig index 15c3ab6dae0..615d75bdd0b 100644 --- a/arch/arm/mach-imx/mx7ulp/Kconfig +++ b/arch/arm/mach-imx/mx7ulp/Kconfig @@ -40,6 +40,8 @@ config TARGET_MX7ULP_EVK bool "Support mx7ulp EVK board" select MX7ULP select SYS_ARCH_TIMER + select FSL_CAAM + select ARCH_MISC_INIT endchoice diff --git a/arch/arm/mach-imx/mx7ulp/soc.c b/arch/arm/mach-imx/mx7ulp/soc.c index bc41cbc6871..08bdc0c4af5 100644 --- a/arch/arm/mach-imx/mx7ulp/soc.c +++ b/arch/arm/mach-imx/mx7ulp/soc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2021 NXP */ #include <common.h> @@ -16,6 +17,7 @@ #include <asm/mach-imx/sys_proto.h> #include <asm/setup.h> #include <linux/bitops.h> +#include <dm.h> #define PMC0_BASE_ADDR 0x410a1000 #define PMC0_CTRL 0x28 @@ -82,6 +84,22 @@ int arch_cpu_init(void) return 0; } +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } + + return 0; +} +#endif + #ifdef CONFIG_BOARD_POSTCLK_INIT int board_postclk_init(void) { diff --git a/arch/arm/mach-imx/parse-container.c b/arch/arm/mach-imx/parse-container.c index 039a4c73035..a4214d53768 100644 --- a/arch/arm/mach-imx/parse-container.c +++ b/arch/arm/mach-imx/parse-container.c @@ -142,12 +142,12 @@ static int read_auth_container(struct spl_image_info *spl_image, return -EIO; if (container->tag != 0x87 && container->version != 0x0) { - printf("Wrong container header"); + printf("Wrong container header\n"); return -ENOENT; } if (!container->num_images) { - printf("Wrong container, no image found"); + printf("Wrong container, no image found\n"); return -ENOENT; } diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index d827de375a6..c47f5a6bdb4 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -38,14 +38,8 @@ ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf) ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev) { - u32 offset; - - if (((rom_bt_dev >> 16) & 0xff) == BT_DEV_TYPE_FLEXSPINOR) - offset = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512; - else - offset = image_offset + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000; - - return offset; + return image_offset + + (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512 - 0x8000); } static int is_boot_from_stream_device(u32 boot) |
