diff options
| author | Tom Rini <[email protected]> | 2025-09-26 11:36:52 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-09-26 11:36:52 -0600 |
| commit | edce3c2905a2a9561d10bdb03e587a93e273758d (patch) | |
| tree | 0f989cfc4b576121496541d8f62f17c6cbc977b7 | |
| parent | 97f2f941e77cdfb7a0d6c2eae1d2e0cde8192523 (diff) | |
| parent | 1566f803bff58f472c38e2e34204753529d01136 (diff) | |
Merge tag 'u-boot-imx-next-20250926' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx into next
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/27737
- Add support for i.MX94 EVK.
- Set CONFIG_ETHPRIME to eth0 on phycore-imx93.
- Expand the nxp_fspi support to i.MX8QXP/8DXL/8ULP.
30 files changed, 1233 insertions, 34 deletions
diff --git a/arch/arm/dts/imx943-evk-u-boot.dtsi b/arch/arm/dts/imx943-evk-u-boot.dtsi new file mode 100644 index 00000000000..5496385dc4d --- /dev/null +++ b/arch/arm/dts/imx943-evk-u-boot.dtsi @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 NXP + */ + +#include "imx943-u-boot.dtsi" + +&lpuart1 { + bootph-pre-ram; +}; + +®_usdhc2_vmmc { + bootph-pre-ram; +}; + +&usdhc1 { + bootph-pre-ram; +}; + +&usdhc2 { + bootph-pre-ram; +}; + +&wdog3 { + status = "disabled"; +}; + +&pinctrl_reg_usdhc2_vmmc { + bootph-pre-ram; +}; + +&pinctrl_uart1 { + bootph-pre-ram; +}; + +&pinctrl_usdhc1 { + bootph-pre-ram; +}; + +&pinctrl_usdhc1_100mhz { + bootph-pre-ram; +}; + +&pinctrl_usdhc1_200mhz { + bootph-pre-ram; +}; + +&pinctrl_usdhc2 { + bootph-pre-ram; +}; + +&pinctrl_usdhc2_100mhz { + bootph-pre-ram; +}; + +&pinctrl_usdhc2_200mhz { + bootph-pre-ram; +}; + +&pinctrl_usdhc2_gpio { + bootph-pre-ram; +}; diff --git a/arch/arm/dts/imx943-u-boot.dtsi b/arch/arm/dts/imx943-u-boot.dtsi new file mode 100644 index 00000000000..9c4882f7d79 --- /dev/null +++ b/arch/arm/dts/imx943-u-boot.dtsi @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 NXP + */ + +/ { + binman { + multiple-images; + + m33-oei-ddrfw { + pad-byte = <0x00>; + align-size = <0x8>; + filename = "m33-oei-ddrfw.bin"; + + oei-m33-ddr { + align-size = <0x4>; + filename = "oei-m33-ddr.bin"; + type = "blob-ext"; + }; + + imx-lpddr { + type = "nxp-header-ddrfw"; + + imx-lpddr-imem { + filename = "lpddr5_imem_v202409.bin"; + type = "blob-ext"; + }; + + imx-lpddr-dmem { + filename = "lpddr5_dmem_v202409.bin"; + type = "blob-ext"; + }; + }; + + imx-lpddr-qb { + type = "nxp-header-ddrfw"; + + imx-lpddr-imem-qb { + filename = "lpddr5_imem_qb_v202409.bin"; + type = "blob-ext"; + }; + + imx-lpddr-dmem-qb { + filename = "lpddr5_dmem_qb_v202409.bin"; + type = "blob-ext"; + }; + }; + }; + + imx-boot { + filename = "flash.bin"; + pad-byte = <0x00>; + + spl { + type = "nxp-imx9image"; + cfg-path = "spl/u-boot-spl.cfgout"; + args; + + cntr-version = <2>; + boot-from = "sd"; + soc-type = "IMX9"; + append = "mx943a0-ahab-container.img"; + container; + dummy-ddr; + image0 = "oei", "m33-oei-ddrfw.bin", "0x1ffc0000"; + hold = <0x10000>; + image1 = "m33", "m33_image.bin", "0x1ffc0000"; + image2 = "a55", "spl/u-boot-spl.bin", "0x20480000"; + dummy-v2x = <0x8b000000>; + }; + + u-boot { + type = "nxp-imx9image"; + cfg-path = "u-boot-container.cfgout"; + args; + + cntr-version = <2>; + boot-from = "sd"; + soc-type = "IMX9"; + container; + image0 = "a55", "bl31.bin", "0x8a200000"; + image1 = "a55", "u-boot.bin", "0x90200000"; + }; + }; + }; +}; + +&cpu0 { + clocks = <&scmi_clk IMX94_CLK_ARMPLL_PFD0>; + /delete-property/ power-domains; +}; + +&cpu1 { + clocks = <&scmi_clk IMX94_CLK_ARMPLL_PFD0>; + /delete-property/ power-domains; +}; + +&cpu2 { + clocks = <&scmi_clk IMX94_CLK_ARMPLL_PFD0>; + /delete-property/ power-domains; +}; + +&cpu3 { + clocks = <&scmi_clk IMX94_CLK_ARMPLL_PFD0>; + /delete-property/ power-domains; +}; + +&aips1 { + bootph-all; +}; + +&aips2 { + bootph-all; +}; + +&aips3 { + bootph-all; +}; + +&clk_ext1 { + bootph-all; +}; + +&dummy { + bootph-all; +}; + +&{/firmware} { + bootph-all; +}; + +&{/firmware/scmi} { + bootph-all; +}; + +&{/firmware/scmi/protocol@11} { + bootph-all; +}; + +&{/firmware/scmi/protocol@13} { + bootph-all; +}; + +&{/firmware/scmi/protocol@14} { + bootph-all; +}; + +&{/firmware/scmi/protocol@19} { + bootph-all; +}; + +&gpio2 { + bootph-pre-ram; +}; + +&gpio3 { + bootph-pre-ram; +}; + +&gpio4 { + bootph-pre-ram; +}; + +&gpio5 { + bootph-pre-ram; +}; + +&gpio6 { + bootph-pre-ram; +}; + +&gpio7 { + bootph-pre-ram; +}; + +&mu2 { + bootph-all; +}; + +&osc_24m { + bootph-all; +}; + +&scmi_buf0 { + bootph-all; +}; + +&scmi_buf1 { + bootph-all; +}; + +&{/soc} { + bootph-all; + + elemu1: mailbox@47530000 { + compatible = "fsl,imx93-mu-s4"; + reg = <0x0 0x47530000 0x0 0x10000>; + bootph-all; + status = "okay"; + }; + + elemu3: mailbox@47550000 { + compatible = "fsl,imx93-mu-s4"; + reg = <0x0 0x47550000 0x0 0x10000>; + bootph-all; + status = "okay"; + }; +}; + +&sram0 { + bootph-all; +}; diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index 1f669c72d00..1af9778f8ce 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -78,6 +78,8 @@ #define MXC_CPU_IMX95 0x1C1 /* dummy ID */ +#define MXC_CPU_IMX94 0x1C2 /* dummy ID */ + #define MXC_SOC_MX6 0x60 #define MXC_SOC_MX7 0x70 #define MXC_SOC_IMX8M 0x80 diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h index 5127fe8f286..e641ed299c0 100644 --- a/arch/arm/include/asm/arch-imx9/imx-regs.h +++ b/arch/arm/include/asm/arch-imx9/imx-regs.h @@ -17,14 +17,23 @@ #define ANATOP_BASE_ADDR 0x44480000UL +#ifdef CONFIG_IMX94 +#define WDG3_BASE_ADDR 0x49220000UL +#define WDG4_BASE_ADDR 0x49230000UL +#else #define WDG3_BASE_ADDR 0x42490000UL #define WDG4_BASE_ADDR 0x424a0000UL +#endif #define WDG5_BASE_ADDR 0x424b0000UL #define GPIO2_BASE_ADDR 0x43810000UL #define GPIO3_BASE_ADDR 0x43820000UL #define GPIO4_BASE_ADDR 0x43840000UL #define GPIO5_BASE_ADDR 0x43850000UL +#ifdef CONFIG_IMX94 +#define GPIO6_BASE_ADDR 0x43860000UL +#define GPIO7_BASE_ADDR 0x43870000UL +#endif #define FSB_BASE_ADDR 0x47510000UL @@ -48,7 +57,7 @@ #define SRC_MIX_SLICE_FUNC_STAT_SSAR_STAT BIT(8) #define SRC_MIX_SLICE_FUNC_STAT_MEM_STAT BIT(12) -#define IMG_CONTAINER_BASE (0x80000000UL) +#define IMG_CONTAINER_BASE CFG_SYS_SDRAM_BASE #define BCTRL_GPR_ENET_QOS_INTF_MODE_MASK GENMASK(3, 1) #define BCTRL_GPR_ENET_QOS_INTF_SEL_MII (0x0 << 1) diff --git a/arch/arm/include/asm/arch-imx9/sys_proto.h b/arch/arm/include/asm/arch-imx9/sys_proto.h index 455aa95339e..dead7a99a66 100644 --- a/arch/arm/include/asm/arch-imx9/sys_proto.h +++ b/arch/arm/include/asm/arch-imx9/sys_proto.h @@ -21,6 +21,7 @@ int m33_prepare(void); int low_drive_freq_update(void *blob); enum imx9_soc_voltage_mode soc_target_voltage_mode(void); +int get_reset_reason(bool sys, bool lm); #define is_voltage_mode(mode) (soc_target_voltage_mode() == (mode)) diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 0780f99b49a..46da7a1eff5 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -97,6 +97,7 @@ struct bd_info; #define is_imx9302() (is_cpu_type(MXC_CPU_IMX9302)) #define is_imx9301() (is_cpu_type(MXC_CPU_IMX9301)) +#define is_imx94() (is_cpu_type(MXC_CPU_IMX94)) #define is_imx95() (is_cpu_type(MXC_CPU_IMX95)) #define is_imx9121() (is_cpu_type(MXC_CPU_IMX9121)) diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index fa2cdaba144..1efe690e876 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -223,7 +223,7 @@ endif ifeq ($(CONFIG_ARCH_IMX9)$(CONFIG_ARCH_IMX8ULP), y) -ifneq ($(and $(CONFIG_IMX95),$(CONFIG_BINMAN)),) +ifneq ($(and $(CONFIG_BINMAN),$(or $(CONFIG_IMX95),$(CONFIG_IMX94))),) SPL: spl/u-boot-spl.bin FORCE $(call if_changed,mkimage) else diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c index 647daeb6562..38e671e3935 100644 --- a/arch/arm/mach-imx/ele_ahab.c +++ b/arch/arm/mach-imx/ele_ahab.c @@ -411,6 +411,54 @@ static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } +#if IS_ENABLED(CONFIG_IMX95) || IS_ENABLED(CONFIG_IMX94) +#define FSB_LC_OFFSET 0x414 +#define LC_OEM_OPEN 0x10 +static void display_life_cycle(u32 lc) +{ + printf("Lifecycle: 0x%08X, ", lc); + switch (lc) { + case 0x1: + printf("BLANK\n\n"); + break; + case 0x2: + printf("FAB Default\n\n"); + break; + case 0x4: + printf("FAB\n\n"); + break; + case 0x8: + printf("NXP Provisioned\n\n"); + break; + case 0x10: + printf("OEM Open\n\n"); + break; + case 0x20: + printf("OEM secure world closed\n\n"); + break; + case 0x40: + printf("OEM closed\n\n"); + break; + case 0x80: + printf("OEM Locked\n\n"); + break; + case 0x100: + printf("Field Return OEM\n\n"); + break; + case 0x200: + printf("Field Return NXP\n\n"); + break; + case 0x400: + printf("BRICKED\n\n"); + break; + default: + printf("Unknown\n\n"); + break; + } +} +#else +#define FSB_LC_OFFSET 0x41c +#define LC_OEM_OPEN 0x8 static void display_life_cycle(u32 lc) { printf("Lifecycle: 0x%08X, ", lc); @@ -447,6 +495,7 @@ static void display_life_cycle(u32 lc) break; } } +#endif static int confirm_close(void) { @@ -474,10 +523,10 @@ static int do_ahab_close(struct cmd_tbl *cmdtp, int flag, int argc, if (!confirm_close()) return -EACCES; - lc = readl(FSB_BASE_ADDR + 0x41c); + lc = readl(FSB_BASE_ADDR + FSB_LC_OFFSET); lc &= 0x3ff; - if (lc != 0x8) { + if (lc != LC_OEM_OPEN) { puts("Current lifecycle is NOT OEM open, can't move to OEM closed\n"); display_life_cycle(lc); return -EPERM; @@ -540,7 +589,7 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const u32 cnt = AHAB_MAX_EVENTS; int ret; - lc = readl(FSB_BASE_ADDR + 0x41c); + lc = readl(FSB_BASE_ADDR + FSB_LC_OFFSET); lc &= 0x3ff; display_life_cycle(lc); diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c index 3a9e6dcf225..78f2488cf6d 100644 --- a/arch/arm/mach-imx/image-container.c +++ b/arch/arm/mach-imx/image-container.c @@ -297,7 +297,7 @@ static ulong get_imageset_end(void *dev, int dev_type) debug("seco container size 0x%x\n", value_container[0]); - if (is_imx95()) { + if (is_imx95() || is_imx94()) { offset[1] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[0]; value_container[1] = get_dev_container_size(dev, dev_type, offset[1], &hdr_length, &v2x_fw); @@ -321,7 +321,7 @@ static ulong get_imageset_end(void *dev, int dev_type) value_container[2] = get_dev_container_size(dev, dev_type, offset[2], &hdr_length, NULL); if (value_container[2] < 0) { debug("Parse scu container image failed %d, only seco container\n", value_container[2]); - if (is_imx95()) + if (is_imx95() || is_imx94()) return value_container[1] + offset[1]; /* return seco + v2x container total size */ else return value_container[0] + offset[0]; /* return seco container total size */ diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index b6acbb20ff0..48f458fa55c 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -38,6 +38,15 @@ config IMX95 select SPL_IMX_CONTAINER_USE_TRAMPOLINE select IMX_PQC_SUPPORT if !IMX95_A0 +config IMX94 + bool + select ARMV8_SPL_EXCEPTION_VECTORS + select DM_MAILBOX + select IMX9 + select IMX_PQC_SUPPORT + select SCMI_FIRMWARE + select SPL_IMX_CONTAINER_USE_TRAMPOLINE + config SYS_SOC default "imx9" @@ -97,6 +106,13 @@ config TARGET_IMX95_19X19_EVK imply BOOTSTD_FULL imply OF_UPSTREAM +config TARGET_IMX943_EVK + bool "imx943_evk" + select IMX94 + imply BOOTSTD_BOOTCOMMAND + imply BOOTSTD_FULL + imply OF_UPSTREAM + endchoice source "board/freescale/imx91_evk/Kconfig" @@ -105,6 +121,7 @@ source "board/freescale/imx93_frdm/Kconfig" source "board/freescale/imx93_qsb/Kconfig" source "board/phytec/phycore_imx93/Kconfig" source "board/variscite/imx93_var_som/Kconfig" +source "board/freescale/imx94_evk/Kconfig" source "board/freescale/imx95_evk/Kconfig" endif diff --git a/arch/arm/mach-imx/imx9/scmi/Makefile b/arch/arm/mach-imx/imx9/scmi/Makefile index 4534db08d28..b98744e1ecb 100644 --- a/arch/arm/mach-imx/imx9/scmi/Makefile +++ b/arch/arm/mach-imx/imx9/scmi/Makefile @@ -2,5 +2,8 @@ # # Copyright 2025 NXP +# Add include path for NXP device tree header files from Linux. +ccflags-y += -I$(srctree)/dts/upstream/src/arm64/freescale/ + obj-y += soc.o obj-y += clock_scmi.o clock.o diff --git a/arch/arm/mach-imx/imx9/scmi/clock.c b/arch/arm/mach-imx/imx9/scmi/clock.c index 6e6541eaa31..951d47bd9d7 100644 --- a/arch/arm/mach-imx/imx9/scmi/clock.c +++ b/arch/arm/mach-imx/imx9/scmi/clock.c @@ -6,16 +6,17 @@ #include <asm/arch/clock.h> #include <dm/uclass.h> #include <scmi_agent.h> -#include "../../../../../dts/upstream/src/arm64/freescale/imx95-clock.h" +#include <scmi_nxp_protocols.h> +#include "common.h" u32 get_arm_core_clk(void) { u32 val; - val = imx_clk_scmi_get_rate(IMX95_CLK_SEL_A55C0); + val = imx_clk_scmi_get_rate(SCMI_CLK(SEL_A55C0)); if (val) return val; - return imx_clk_scmi_get_rate(IMX95_CLK_A55); + return imx_clk_scmi_get_rate(SCMI_CLK(A55)); } void init_uart_clk(u32 index) @@ -24,13 +25,13 @@ void init_uart_clk(u32 index) switch (index) { case 0: - clock_id = IMX95_CLK_LPUART1; + clock_id = SCMI_CLK(LPUART1); break; case 1: - clock_id = IMX95_CLK_LPUART2; + clock_id = SCMI_CLK(LPUART2); break; case 2: - clock_id = IMX95_CLK_LPUART3; + clock_id = SCMI_CLK(LPUART3); break; default: return; @@ -38,7 +39,7 @@ void init_uart_clk(u32 index) /* 24MHz */ imx_clk_scmi_enable(clock_id, false); - imx_clk_scmi_set_parent(clock_id, IMX95_CLK_24M); + imx_clk_scmi_set_parent(clock_id, SCMI_CLK(24M)); imx_clk_scmi_set_rate(clock_id, 24000000); imx_clk_scmi_enable(clock_id, true); } @@ -49,19 +50,19 @@ unsigned int mxc_get_clock(enum mxc_clock clk) case MXC_ARM_CLK: return get_arm_core_clk(); case MXC_IPG_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_BUSWAKEUP); + return imx_clk_scmi_get_rate(SCMI_CLK(BUSWAKEUP)); case MXC_CSPI_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_LPSPI1); + return imx_clk_scmi_get_rate(SCMI_CLK(LPSPI1)); case MXC_ESDHC_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_USDHC1); + return imx_clk_scmi_get_rate(SCMI_CLK(USDHC1)); case MXC_ESDHC2_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_USDHC2); + return imx_clk_scmi_get_rate(SCMI_CLK(USDHC2)); case MXC_ESDHC3_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_USDHC3); + return imx_clk_scmi_get_rate(SCMI_CLK(USDHC3)); case MXC_UART_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_LPUART1); + return imx_clk_scmi_get_rate(SCMI_CLK(LPUART1)); case MXC_FLEXSPI_CLK: - return imx_clk_scmi_get_rate(IMX95_CLK_FLEXSPI1); + return imx_clk_scmi_get_rate(SCMI_CLK(FLEXSPI1)); default: return -1; }; diff --git a/arch/arm/mach-imx/imx9/scmi/common.h b/arch/arm/mach-imx/imx9/scmi/common.h new file mode 100644 index 00000000000..dd4675402c7 --- /dev/null +++ b/arch/arm/mach-imx/imx9/scmi/common.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2025 NXP + */ + +#ifndef _SCMI_CLOCK_COMMON_H_ +#define _SCMI_CLOCK_COMMON_H_ + +#ifdef CONFIG_IMX94 +#define IMX_PLAT 94 +#include <imx94-clock.h> +#include <imx94-power.h> + +#define IMX94_CLK_FLEXSPI1 IMX94_CLK_XSPI1 +#endif + +#ifdef CONFIG_IMX95 +#define IMX_PLAT 95 +#include <imx95-clock.h> +#include <imx95-power.h> + +#define IMX95_PD_M70 IMX95_PD_M7 +#endif + +#define IMX_PLAT_STR__(plat) # plat +#define IMX_PLAT_STR_(IMX_PLAT) IMX_PLAT_STR__(IMX_PLAT) +#define IMX_PLAT_STR IMX_PLAT_STR_(IMX_PLAT) + +#define SCMI_CLK__(plat, clk) IMX ## plat ## _CLK_ ## clk +#define SCMI_CLK_(plat, clk) SCMI_CLK__(plat, clk) +#define SCMI_CLK(clk) SCMI_CLK_(IMX_PLAT, clk) + +#define SCMI_PD__(plat, pd) IMX ## plat ## _PD_ ## pd +#define SCMI_PD_(plat, pd) SCMI_PD__(plat, pd) +#define SCMI_PD(pd) SCMI_PD_(IMX_PLAT, pd) + +#define SCMI_CPU__(plat) MXC_CPU_IMX ## plat +#define SCMI_CPU_(plat) SCMI_CPU__(plat) +#define SCMI_CPU SCMI_CPU_(IMX_PLAT) + +#endif diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index f973652d0cb..dbaa19a9e6e 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -17,8 +17,11 @@ #include <env_internal.h> #include <fuse.h> #include <imx_thermal.h> +#include <linux/bitfield.h> #include <linux/iopoll.h> #include <scmi_agent.h> +#include <scmi_nxp_protocols.h> +#include "common.h" DECLARE_GLOBAL_DATA_PTR; @@ -174,7 +177,7 @@ u32 get_cpu_rev(void) { u32 rev = (gd->arch.soc_rev >> 24) - 0xa0; - return (MXC_CPU_IMX95 << 12) | (CHIP_REV_1_0 + rev); + return (SCMI_CPU << 12) | (CHIP_REV_1_0 + rev); } #define UNLOCK_WORD 0xD928C520 @@ -254,6 +257,30 @@ static struct mm_region imx9_mem_map[] = { PTE_BLOCK_OUTER_SHARE }, { #endif + /* PCIE2 ECAM */ + .virt = 0x880000000UL, + .phys = 0x880000000UL, + .size = 0x10000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE1 Outbound */ + .virt = 0x900000000UL, + .phys = 0x900000000UL, + .size = 0x100000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE2 Outbound */ + .virt = 0xA00000000UL, + .phys = 0xA00000000UL, + .size = 0x100000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { /* empty entry to split table entry 5 if needed when TEEs are used */ 0, }, { @@ -435,12 +462,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) { u32 val[2] = {}; int ret, num_of_macs; + u32 bank = 40; + + if (is_imx94()) + bank = 66; - ret = fuse_read(40, 5, &val[0]); + ret = fuse_read(bank, 5, &val[0]); if (ret) goto err; - ret = fuse_read(40, 6, &val[1]); + ret = fuse_read(bank, 6, &val[1]); if (ret) goto err; @@ -456,10 +487,32 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) mac[3] = (val[0] >> 24) & 0xff; mac[4] = val[1] & 0xff; mac[5] = (val[1] >> 8) & 0xff; - if (dev_id == 1) - mac[5] = mac[5] + 3; - if (dev_id == 2) - mac[5] = mac[5] + 6; + + if (is_imx94()) { + /* + * i.MX94 uses the following mac address offset list: + * | No. | Module | Mac address user | + * |--------|-------------|---------------------------| + * | 0 ~ 1 | ethercat | port0/port1 | + * | 2 | netc switch | internal enetc3 mac/swp0 | + * | 3 ~ 6 | | enetc3 vf1~3/swp1 | + * | 7 | enetc mac | enetc0 pf | + * | 8 | | enetc1 pf | + * | 9 | | enetc2 pf | + * | 10 | netc switch | swp2 | + */ + if (dev_id == 0) + mac[5] = mac[5] + 2; /* enetc3 mac/swp0 */ + if (dev_id == 1) + mac[5] = mac[5] + 8; /* enetc1 */ + if (dev_id == 2) + mac[5] = mac[5] + 9; /* enetc2 */ + } else { + if (dev_id == 1) + mac[5] = mac[5] + 3; + if (dev_id == 2) + mac[5] = mac[5] + 6; + } debug("%s: MAC%d: %pM\n", __func__, dev_id, mac); return; @@ -468,11 +521,149 @@ err: printf("%s: fuse read err: %d\n", __func__, ret); } +static char *rst_string[32] = { + "cm33_lockup", + "cm33_swreq", + "cm7_lockup", + "cm7_swreq", + "fccu", + "jtag_sw", + "ele", + "tempsense", + "wdog1", + "wdog2", + "wdog3", + "wdog4", + "wdog5", + "jtag", + "cm33_exc", + "bbm", + "sw", + "sm_err", "fusa_sreco", "pmic", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", + "por" +}; + +static char *rst_string_imx94[32] = { + "cm33_lockup", + "cm33_swreq", + "cm70_lockup", + "cm70_swreq", + "fccu", + "jtag_sw", + "ele", + "tempsense", + "wdog1", + "wdog2", + "wdog3", + "wdog4", + "wdog5", + "jtag", + "wdog6", + "wdog7", + "wdog8", + "wo_netc", "cm33s_lockup", "cm33s_swreq", "cm71_lockup", "cm71_swreq", "cm33_exc", + "bbm", "sw", "sm_err", "fusa_sreco", "pmic", "unused", + "unused", "unused", + "por" +}; + +int get_reset_reason(bool sys, bool lm) +{ + struct scmi_imx_misc_reset_reason_in in = { + .flags = MISC_REASON_FLAG_SYSTEM, + }; + + struct scmi_imx_misc_reset_reason_out out = { 0 }; + struct scmi_msg msg = { + .protocol_id = SCMI_PROTOCOL_ID_IMX_MISC, + .message_id = SCMI_IMX_MISC_RESET_REASON, + .in_msg = (u8 *)&in, + .in_msg_sz = sizeof(in), + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; + int ret; + + struct udevice *dev; + char **rst; + + if (is_imx94()) + rst = rst_string_imx94; + else + rst = rst_string; + + ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev); + if (ret) + return ret; + + if (sys) { + ret = devm_scmi_process_msg(dev, &msg); + if (out.status) { + printf("%s:%d for SYS\n", __func__, out.status); + return ret; + } + + if (out.bootflags & MISC_BOOT_FLAG_VLD) { + printf("SYS Boot reason: %s, origin: %ld, errid: %ld\n", + rst[out.bootflags & MISC_BOOT_FLAG_REASON], + out.bootflags & MISC_BOOT_FLAG_ORG_VLD ? + FIELD_GET(MISC_BOOT_FLAG_ORIGIN, out.bootflags) : -1, + out.bootflags & MISC_BOOT_FLAG_ERR_VLD ? + FIELD_GET(MISC_BOOT_FLAG_ERR_ID, out.bootflags) : -1 + ); + } + if (out.shutdownflags & MISC_SHUTDOWN_FLAG_VLD) { + printf("SYS shutdown reason: %s, origin: %ld, errid: %ld\n", + rst[out.bootflags & MISC_SHUTDOWN_FLAG_REASON], + out.bootflags & MISC_SHUTDOWN_FLAG_ORG_VLD ? + FIELD_GET(MISC_SHUTDOWN_FLAG_ORIGIN, out.bootflags) : -1, + out.bootflags & MISC_SHUTDOWN_FLAG_ERR_VLD ? + FIELD_GET(MISC_SHUTDOWN_FLAG_ERR_ID, out.bootflags) : -1 + ); + } + } + + if (lm) { + in.flags = 0; + memset(&out, 0, sizeof(struct scmi_imx_misc_reset_reason_out)); + + ret = devm_scmi_process_msg(dev, &msg); + if (out.status) { + printf("%s:%d for LM\n", __func__, out.status); + return ret; + } + + if (out.bootflags & MISC_BOOT_FLAG_VLD) { + printf("LM Boot reason: %s, origin: %ld, errid: %ld\n", + rst[out.bootflags & MISC_BOOT_FLAG_REASON], + out.bootflags & MISC_BOOT_FLAG_ORG_VLD ? + FIELD_GET(MISC_BOOT_FLAG_ORIGIN, out.bootflags) : -1, + out.bootflags & MISC_BOOT_FLAG_ERR_VLD ? + FIELD_GET(MISC_BOOT_FLAG_ERR_ID, out.bootflags) : -1 + ); + } + + if (out.shutdownflags & MISC_SHUTDOWN_FLAG_VLD) { + printf("LM shutdown reason: %s, origin: %ld, errid: %ld\n", + rst[out.bootflags & MISC_SHUTDOWN_FLAG_REASON], + out.bootflags & MISC_SHUTDOWN_FLAG_ORG_VLD ? + FIELD_GET(MISC_SHUTDOWN_FLAG_ORIGIN, out.bootflags) : -1, + out.bootflags & MISC_SHUTDOWN_FLAG_ERR_VLD ? + FIELD_GET(MISC_SHUTDOWN_FLAG_ERR_ID, out.bootflags) : -1 + ); + } + } + + return 0; +} + const char *get_imx_type(u32 imxtype) { switch (imxtype) { - case MXC_CPU_IMX95: - return "95";/* iMX95 FULL */ + case SCMI_CPU: + return IMX_PLAT_STR; default: return "??"; } @@ -553,6 +744,10 @@ int arch_cpu_init(void) gpio_reset(GPIO3_BASE_ADDR); gpio_reset(GPIO4_BASE_ADDR); gpio_reset(GPIO5_BASE_ADDR); +#ifdef CONFIG_IMX94 + gpio_reset(GPIO6_BASE_ADDR); + gpio_reset(GPIO7_BASE_ADDR); +#endif } return 0; diff --git a/board/freescale/imx94_evk/Kconfig b/board/freescale/imx94_evk/Kconfig new file mode 100644 index 00000000000..a4237244ace --- /dev/null +++ b/board/freescale/imx94_evk/Kconfig @@ -0,0 +1,12 @@ +if TARGET_IMX943_EVK + +config SYS_BOARD + default "imx94_evk" + +config SYS_VENDOR + default "freescale" + +config SYS_CONFIG_NAME + default "imx94_evk" + +endif diff --git a/board/freescale/imx94_evk/MAINTAINERS b/board/freescale/imx94_evk/MAINTAINERS new file mode 100644 index 00000000000..95309430734 --- /dev/null +++ b/board/freescale/imx94_evk/MAINTAINERS @@ -0,0 +1,6 @@ +i.MX94 EVK BOARD +M: Alice Guo <[email protected]> +S: Maintained +F: board/freescale/imx94_evk/ +F: include/configs/imx94_evk.h +F: configs/imx943_evk_defconfig diff --git a/board/freescale/imx94_evk/Makefile b/board/freescale/imx94_evk/Makefile new file mode 100644 index 00000000000..ca31602f6ba --- /dev/null +++ b/board/freescale/imx94_evk/Makefile @@ -0,0 +1,11 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += imx94_evk.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +endif diff --git a/board/freescale/imx94_evk/imx94_evk.c b/board/freescale/imx94_evk/imx94_evk.c new file mode 100644 index 00000000000..28d512ac5f3 --- /dev/null +++ b/board/freescale/imx94_evk/imx94_evk.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 NXP + */ + +#include <asm/arch/clock.h> +#include <asm/gpio.h> +#include <asm/mach-imx/sys_proto.h> +#include <env.h> +#include <fdt_support.h> + +int board_early_init_f(void) +{ + init_uart_clk(0); + return 0; +} + +int board_init(void) +{ + return 0; +} + +int board_late_init(void) +{ + if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC)) + board_late_mmc_env_init(); + + env_set("sec_boot", "no"); + + if (IS_ENABLED(CONFIG_AHAB_BOOT)) + env_set("sec_boot", "yes"); + + return 0; +} + +int board_phys_sdram_size(phys_size_t *size) +{ + *size = PHYS_SDRAM_SIZE + PHYS_SDRAM_2_SIZE; + + return 0; +} diff --git a/board/freescale/imx94_evk/imx94_evk.env b/board/freescale/imx94_evk/imx94_evk.env new file mode 100644 index 00000000000..2baf1bbadcb --- /dev/null +++ b/board/freescale/imx94_evk/imx94_evk.env @@ -0,0 +1,100 @@ +#ifdef CONFIG_AHAB_BOOT +sec_boot=yes +#else +sec_boot=no +#endif + +jh_root_dtb=imx943-evk-root.dtb +jh_mmcboot=setenv fdtfile ${jh_root_dtb}; + setenv jh_clk kvm.enable_virt_at_load=false cpuidle.off=1 clk_ignore_unused kvm-arm.mode=nvhe; + setenv jh_root_mem 0x60000000@0x90000000,0x100000000@0x100000000; + if run loadimage; then + run mmcboot; + else run jh_netboot; fi; +jh_netboot=setenv fdtfile ${jh_root_dtb}; + setenv jh_root_mem 0x60000000@0x90000000,0x100000000@0x100000000; + setenv jh_clk kvm.enable_virt_at_load=false cpuidle.off=1 clk_ignore_unused kvm-arm.mode=nvhe; run netboot; + +initrd_addr=0x93800000 +emmc_dev=0 +sd_dev=1 +scriptaddr=0x93500000 +kernel_addr_r=CONFIG_SYS_LOAD_ADDR +image=Image +splashimage=0xA0000000 +console=ttyLP0,115200 earlycon +fdt_addr_r=0x93000000 +fdt_addr=0x93000000 +cntr_addr=0xA8000000 +cntr_file=os_cntr_signed.bin +boot_fit=no +fdtfile=CONFIG_DEFAULT_FDT_FILE +bootm_size=0x10000000 +mmcdev=CONFIG_SYS_MMC_ENV_DEV +mmcautodetect=yes +mmcargs=setenv bootargs ${jh_clk} ${mcore_args} console=${console} root=${mmcroot} +prepare_mcore=setenv mcore_args pd_ignore_unused; +loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}; +bootscript=echo Running bootscript from mmc ...; source +loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image} +loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile} +loadcntr=fatload mmc ${mmcdev}:${mmcpart} ${cntr_addr} ${cntr_file} +auth_os=booti ${cntr_addr} +boot_os=booti ${loadaddr} - ${fdt_addr_r}; +mmcboot=echo Booting from mmc ...; + run mmcargs; + if test ${sec_boot} = yes; then + run auth_os; + else + if test ${boot_fit} = yes || test ${boot_fit} = try; then + bootm ${loadaddr}; + else + if run loadfdt; then + run boot_os; + else + echo WARN: Cannot load the DT; + fi; + fi; + fi; +netargs=setenv bootargs ${jh_clk} ${mcore_args} console=${console} root=/dev/nfs + ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp +netboot=echo Booting from net ...; + run netargs; + if test ${ip_dyn} = yes; then + setenv get_cmd dhcp; + else + setenv get_cmd tftp; + fi; + if test ${sec_boot} = yes; then + ${get_cmd} ${cntr_addr} ${cntr_file}; + run auth_os; + else + ${get_cmd} ${loadaddr} ${image}; + if test ${boot_fit} = yes || test ${boot_fit} = try; then + bootm ${loadaddr}; + else + if ${get_cmd} ${fdt_addr_r} ${fdtfile}; then + run boot_os; + else + echo WARN: Cannot load the DT; + fi; + fi; + fi; +bsp_bootcmd=echo Running BSP bootcmd ...; + mmc dev ${mmcdev}; if mmc rescan; then + if run loadbootscript; then + run bootscript; + else + if test ${sec_boot} = yes; then + if run loadcntr; then + run mmcboot; + else run netboot; + fi; + else + if run loadimage; then + run mmcboot; + else run netboot; + fi; + fi; + fi; + fi; diff --git a/board/freescale/imx94_evk/spl.c b/board/freescale/imx94_evk/spl.c new file mode 100644 index 00000000000..341b165b3c8 --- /dev/null +++ b/board/freescale/imx94_evk/spl.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 NXP + */ + +#include <asm/arch/clock.h> +#include <asm/arch/mu.h> +#include <asm/arch/sys_proto.h> +#include <asm/gpio.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/ele_api.h> +#include <asm/sections.h> +#include <hang.h> +#include <init.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +int spl_board_boot_device(enum boot_device boot_dev_spl) +{ + switch (boot_dev_spl) { + case SD1_BOOT: + case MMC1_BOOT: + return BOOT_DEVICE_MMC1; + case SD2_BOOT: + case MMC2_BOOT: + return BOOT_DEVICE_MMC2; + case USB_BOOT: + return BOOT_DEVICE_BOARD; + case QSPI_BOOT: + return BOOT_DEVICE_SPI; + default: + return BOOT_DEVICE_NONE; + } +} + +void spl_board_init(void) +{ + int ret; + + puts("Normal Boot\n"); + + ret = ele_start_rng(); + if (ret) + printf("Fail to start RNG: %d\n", ret); +} + +/* SCMI support by default */ +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + if (IS_ENABLED(CONFIG_SPL_RECOVER_DATA_SECTION) && + IS_ENABLED(CONFIG_SPL_BUILD)) + spl_save_restore_data(); + + timer_init(); + + spl_early_init(); + + /* Need enable SCMI drivers and ELE driver before enabling console */ + ret = imx9_probe_mu(); + if (ret) + hang(); /* if MU not probed, nothing can output, just hang here */ + + arch_cpu_init(); + + board_early_init_f(); + + preloader_console_init(); + + debug("SOC: 0x%x\n", gd->arch.soc_rev); + debug("LC: 0x%x\n", gd->arch.lifecycle); + + get_reset_reason(true, false); + + board_init_r(NULL, 0); +} diff --git a/board/freescale/imx95_evk/spl.c b/board/freescale/imx95_evk/spl.c index 08f4da0bb73..3d64097b4c7 100644 --- a/board/freescale/imx95_evk/spl.c +++ b/board/freescale/imx95_evk/spl.c @@ -5,6 +5,7 @@ #include <asm/arch/clock.h> #include <asm/arch/mu.h> +#include <asm/arch/sys_proto.h> #include <asm/mach-imx/boot_mode.h> #include <asm/sections.h> #include <hang.h> @@ -65,5 +66,7 @@ void board_init_f(ulong dummy) debug("SOC: 0x%x\n", gd->arch.soc_rev); debug("LC: 0x%x\n", gd->arch.lifecycle); + get_reset_reason(true, false); + board_init_r(NULL, 0); } diff --git a/configs/imx93-phycore_defconfig b/configs/imx93-phycore_defconfig index 0acdfd2bf53..4c952e966d1 100644 --- a/configs/imx93-phycore_defconfig +++ b/configs/imx93-phycore_defconfig @@ -89,7 +89,7 @@ CONFIG_ENV_REDUNDANT=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_ENV_MMC_DEVICE_INDEX=1 CONFIG_USE_ETHPRIME=y -CONFIG_ETHPRIME="eth1" +CONFIG_ETHPRIME="eth0" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y diff --git a/configs/imx943_evk_defconfig b/configs/imx943_evk_defconfig new file mode 100644 index 00000000000..27230ed3207 --- /dev/null +++ b/configs/imx943_evk_defconfig @@ -0,0 +1,115 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX9=y +CONFIG_TEXT_BASE=0x90200000 +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SOURCE_FILE="imx94_evk" +CONFIG_ENV_SIZE=0x4000 +CONFIG_ENV_OFFSET=0x700000 +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="freescale/imx943-evk" +CONFIG_TARGET_IMX943_EVK=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SYS_MONITOR_LEN=524288 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_TEXT_BASE=0x20480000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x204d6000 +CONFIG_SPL_BSS_MAX_SIZE=0x2000 +CONFIG_SYS_LOAD_ADDR=0x90400000 +CONFIG_SPL=y +CONFIG_SPL_RECOVER_DATA_SECTION=y +CONFIG_PCI=y +CONFIG_OF_BOARD_FIXUP=y +CONFIG_SYS_MEMTEST_START=0x90000000 +CONFIG_SYS_MEMTEST_END=0xA0000000 +CONFIG_REMAKE_ELF=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTCOMMAND="bootflow scan -l; run bsp_bootcmd" +CONFIG_DEFAULT_FDT_FILE="imx943-evk.dtb" +CONFIG_SYS_CBSIZE=2048 +CONFIG_SYS_PBSIZE=2074 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_SPL_MAX_SIZE=0x30000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_LOAD_IMX_CONTAINER=y +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_SYS_MALLOC=y +CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y +CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x93200000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x80000 +CONFIG_SPL_SYS_MMCSD_RAW_MODE=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040 +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_THERMAL=y +CONFIG_SPL_WATCHDOG=y +CONFIG_SYS_PROMPT="u-boot=> " +CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CRC32_VERIFY=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_SNTP=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_RTC=y +CONFIG_CMD_TIME=y +CONFIG_CMD_GETTIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_HASH=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_NOWHERE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_CLK_CCF=y +CONFIG_CLK_SCMI=y +CONFIG_SPL_CLK_SCMI=y +CONFIG_SPL_FIRMWARE=y +# CONFIG_SCMI_AGENT_SMCCC is not set +CONFIG_IMX_RGPIO2P=y +CONFIG_IMX_MU_MBOX=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_FSL_USDHC=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_PINCTRL_IMX_SCMI=y +CONFIG_POWER_DOMAIN=y +CONFIG_SCMI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_RTC=y +CONFIG_DM_SERIAL=y +CONFIG_FSL_LPUART=y +CONFIG_ULP_WATCHDOG=y diff --git a/doc/board/nxp/imx943_evk.rst b/doc/board/nxp/imx943_evk.rst new file mode 100644 index 00000000000..651db08a0f7 --- /dev/null +++ b/doc/board/nxp/imx943_evk.rst @@ -0,0 +1,112 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +imx943_evk +======================= + +U-Boot for the NXP i.MX943 19x19 EVK board + +Quick Start +----------- + +- Get ahab-container.img +- Get DDR PHY Firmware Images +- Get and Build OEI Images +- Get and Build System Manager Image +- Get and Build the ARM Trusted Firmware +- Build the Bootloader Image +- Boot + +Get ahab-container.img +-------------------------------------- + +Note: srctree is U-Boot source directory + +.. code-block:: bash + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-2.0.2-89161a8.bin + $ sh firmware-ele-imx-2.0.2-89161a8.bin --auto-accept + $ cp firmware-ele-imx-2.0.2-89161a8/mx943a0-ahab-container.img $(srctree) + +Get DDR PHY Firmware Images +-------------------------------------- + +Note: srctree is U-Boot source directory + +.. code-block:: bash + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.28-994fa14.bin + $ sh firmware-imx-8.28-994fa14.bin --auto-accept + $ cp firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr5*v202409.bin $(srctree) + +Get and Build OEI Images +-------------------------------------- + +Note: srctree is U-Boot source directory +Get OEI from: https://github.com/nxp-imx/imx-oei +branch: master + +.. code-block:: bash + + $ sudo apt -y install make gcc g++-multilib srecord + $ wget https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + $ tar xvf arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + $ export TOOLS=$PWD + $ git clone -b master https://github.com/nxp-imx/imx-oei.git + $ cd imx-oei + $ make board=mx943lp5-19 oei=ddr DEBUG=1 all + $ cp build/mx943lp5-19/ddr/oei-m33-ddr.bin $(srctree) + +Get and Build System Manager Image +-------------------------------------- + +Note: srctree is U-Boot source directory +Get System Manager from: https://github.com/nxp-imx/imx-sm +branch: master + +.. code-block:: bash + + $ sudo apt -y install make gcc g++-multilib srecord + $ wget https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + $ tar xvf arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz + $ export TOOLS=$PWD + $ git clone -b master https://github.com/nxp-imx/imx-sm.git + $ cd imx-sm + $ make config=mx94evk all + $ cp build/mx94evk/m33_image.bin $(srctree) + +Get and Build the ARM Trusted Firmware +-------------------------------------- + +Note: srctree is U-Boot source directory +Get ATF from: https://github.com/nxp-imx/imx-atf/ +branch: lf_v2.12 + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-poky-linux- + $ unset LDFLAGS + $ unset AS + $ git clone -b lf_v2.12 https://github.com/nxp-imx/imx-atf.git + $ cd imx-atf + $ make PLAT=imx94 bl31 + $ cp build/imx94/release/bl31.bin $(srctree) + +Build the Bootloader Image +-------------------------- + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-poky-linux- + $ make imx943_evk_defconfig + $ make + +Copy flash.bin to the MicroSD card: + +.. code-block:: bash + + $ sudo dd if=flash.bin of=/dev/sd[x] bs=1k seek=32 conv=fsync + +Boot +---- + +Set i.MX943 boot device to MicroSD card diff --git a/doc/board/nxp/index.rst b/doc/board/nxp/index.rst index aa7d857346d..670501164b5 100644 --- a/doc/board/nxp/index.rst +++ b/doc/board/nxp/index.rst @@ -16,6 +16,7 @@ NXP Semiconductors imx93_9x9_qsb imx93_11x11_evk imx93_frdm + imx943_evk imx95_evk imxrt1020-evk imxrt1050-evk diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 950630453f9..630919a3642 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -113,6 +113,8 @@ static const char *get_imx_type_str(u32 imxtype) return "91(01)";/* iMX91 9x9 Specific feature */ case MXC_CPU_IMX95: return "95"; + case MXC_CPU_IMX94: + return "94"; default: return "??"; } diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c index aed47be337d..781835c6852 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c +++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c @@ -16,6 +16,7 @@ #include "pinctrl-imx.h" #define DAISY_OFFSET_IMX95 0x408 +#define DAISY_OFFSET_IMX94 0x608 /* SCMI pin control types */ #define PINCTRL_TYPE_MUX 192 @@ -133,6 +134,8 @@ static int imx_scmi_pinctrl_probe(struct udevice *dev) if (IS_ENABLED(CONFIG_IMX95)) priv->daisy_offset = DAISY_OFFSET_IMX95; + else if (IS_ENABLED(CONFIG_IMX94)) + priv->daisy_offset = DAISY_OFFSET_IMX94; else return -EINVAL; @@ -141,7 +144,7 @@ static int imx_scmi_pinctrl_probe(struct udevice *dev) static int imx_scmi_pinctrl_bind(struct udevice *dev) { - if (IS_ENABLED(CONFIG_IMX95)) + if (IS_ENABLED(CONFIG_IMX95) || IS_ENABLED(CONFIG_IMX94)) return 0; return -ENODEV; diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c index 6d97b8eefc9..7086a2a264a 100644 --- a/drivers/spi/nxp_fspi.c +++ b/drivers/spi/nxp_fspi.c @@ -337,6 +337,33 @@ static struct nxp_fspi_devtype_data imxrt1170_data = { .little_endian = true, }; +static const struct nxp_fspi_devtype_data imx8qxp_data = { + .rxfifo = SZ_512, /* (64 * 64 bits) */ + .txfifo = SZ_1K, /* (128 * 64 bits) */ + .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ + .quirks = 0, + .lut_num = 32, + .little_endian = true, /* little-endian */ +}; + +static const struct nxp_fspi_devtype_data imx8dxl_data = { + .rxfifo = SZ_512, /* (64 * 64 bits) */ + .txfifo = SZ_1K, /* (128 * 64 bits) */ + .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ + .quirks = FSPI_QUIRK_USE_IP_ONLY, + .lut_num = 32, + .little_endian = true, /* little-endian */ +}; + +static const struct nxp_fspi_devtype_data imx8ulp_data = { + .rxfifo = SZ_1K, /* (128 * 64 bits) */ + .txfifo = SZ_1K, /* (128 * 64 bits) */ + .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ + .quirks = 0, + .lut_num = 16, + .little_endian = true, /* little-endian */ +}; + struct nxp_fspi { struct udevice *dev; void __iomem *iobase; @@ -539,6 +566,15 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f, fspi_writel(f, lutval[i], base + target_lut_reg); } + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN && + op->addr.nbytes) { + lut_offset = (f->devtype_data->lut_num - 2) * 4 * 4; + for (i = 0; i < ARRAY_SIZE(lutval); i++) { + target_lut_reg = FSPI_LUT_BASE + lut_offset + i * 4; + fspi_writel(f, lutval[i], base + target_lut_reg); + } + } + dev_dbg(f->dev, "CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x], size: 0x%08x\n", op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3], op->data.nbytes); @@ -943,9 +979,10 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) /* * The driver only uses one single LUT entry, that is updated on * each call of exec_op(). Index 0 is preset at boot with a basic - * read operation, so let's use the last entry. + * read operation, last entry is used for dynamic lut, the second + * last entry is used for AHB read. */ - seqid_lut = f->devtype_data->lut_num - 1; + seqid_lut = f->devtype_data->lut_num - 2; /* AHB Read - Set lut sequence ID for all CS. */ fspi_writel(f, seqid_lut, base + FSPI_FLSHA1CR2); fspi_writel(f, seqid_lut, base + FSPI_FLSHA2CR2); @@ -1071,6 +1108,9 @@ static const struct udevice_id nxp_fspi_ids[] = { { .compatible = "nxp,lx2160a-fspi", .data = (ulong)&lx2160a_data, }, { .compatible = "nxp,imx8mm-fspi", .data = (ulong)&imx8mm_data, }, { .compatible = "nxp,imx8mp-fspi", .data = (ulong)&imx8mm_data, }, + { .compatible = "nxp,imx8qxp-fspi", .data = (ulong)&imx8qxp_data, }, + { .compatible = "nxp,imx8dxl-fspi", .data = (ulong)&imx8dxl_data, }, + { .compatible = "nxp,imx8ulp-fspi", .data = (ulong)&imx8ulp_data, }, { .compatible = "nxp,imxrt1170-fspi", .data = (ulong)&imxrt1170_data, }, { } }; diff --git a/include/configs/imx94_evk.h b/include/configs/imx94_evk.h new file mode 100644 index 00000000000..f93c3c4e4a8 --- /dev/null +++ b/include/configs/imx94_evk.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2025 NXP + */ + +#ifndef __IMX94_EVK_H +#define __IMX94_EVK_H + +#include <linux/sizes.h> +#include <linux/stringify.h> +#include <asm/arch/imx-regs.h> + +#define CFG_SYS_INIT_RAM_ADDR 0x90000000 +#define CFG_SYS_INIT_RAM_SIZE 0x200000 + +#define CFG_SYS_SDRAM_BASE 0x90000000 +#define PHYS_SDRAM 0x90000000 +#define PHYS_SDRAM_SIZE 0x70000000UL /* 2GB - 256MB DDR */ +#define PHYS_SDRAM_2_SIZE 0x180000000 /* 8GB */ + +/* Using ULP WDOG for reset */ +#define WDOG_BASE_ADDR WDG3_BASE_ADDR + +#endif diff --git a/include/scmi_nxp_protocols.h b/include/scmi_nxp_protocols.h new file mode 100644 index 00000000000..fe6ecd6a7cf --- /dev/null +++ b/include/scmi_nxp_protocols.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright 2025 NXP + */ + +#ifndef _SCMI_NXP_PROTOCOLS_H +#define _SCMI_NXP_PROTOCOLS_H + +#include <asm/types.h> +#include <linux/bitops.h> + +enum scmi_imx_protocol { + SCMI_IMX_PROTOCOL_ID_MISC = 0x84, +}; + +#define SCMI_PAYLOAD_LEN 100 + +#define SCMI_ARRAY(X, Y) ((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y)) + +#define SCMI_IMX_MISC_RESET_REASON 0xA + +struct scmi_imx_misc_reset_reason_in { +#define MISC_REASON_FLAG_SYSTEM BIT(0) + u32 flags; +}; + +struct scmi_imx_misc_reset_reason_out { + s32 status; + /* Boot reason flags */ +#define MISC_BOOT_FLAG_VLD BIT(31) +#define MISC_BOOT_FLAG_ORG_VLD BIT(28) +#define MISC_BOOT_FLAG_ORIGIN GENMASK(27, 24) +#define MISC_BOOT_FLAG_O_SHIFT 24 +#define MISC_BOOT_FLAG_ERR_VLD BIT(23) +#define MISC_BOOT_FLAG_ERR_ID GENMASK(22, 8) +#define MISC_BOOT_FLAG_E_SHIFT 8 +#define MISC_BOOT_FLAG_REASON GENMASK(7, 0) + u32 bootflags; + /* Shutdown reason flags */ +#define MISC_SHUTDOWN_FLAG_VLD BIT(31) +#define MISC_SHUTDOWN_FLAG_EXT_LEN GENMASK(30, 29) +#define MISC_SHUTDOWN_FLAG_ORG_VLD BIT(28) +#define MISC_SHUTDOWN_FLAG_ORIGIN GENMASK(27, 24) +#define MISC_SHUTDOWN_FLAG_O_SHIFT 24 +#define MISC_SHUTDOWN_FLAG_ERR_VLD BIT(23) +#define MISC_SHUTDOWN_FLAG_ERR_ID GENMASK(22, 8) +#define MISC_SHUTDOWN_FLAG_E_SHIFT 8 +#define MISC_SHUTDOWN_FLAG_REASON GENMASK(7, 0) + u32 shutdownflags; + /* Array of extended info words */ +#define MISC_MAX_EXTINFO SCMI_ARRAY(16, u32) + u32 extInfo[MISC_MAX_EXTINFO]; +}; + +#endif |
