summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2025-09-26 11:36:52 -0600
committerTom Rini <[email protected]>2025-09-26 11:36:52 -0600
commitedce3c2905a2a9561d10bdb03e587a93e273758d (patch)
tree0f989cfc4b576121496541d8f62f17c6cbc977b7
parent97f2f941e77cdfb7a0d6c2eae1d2e0cde8192523 (diff)
parent1566f803bff58f472c38e2e34204753529d01136 (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.
-rw-r--r--arch/arm/dts/imx943-evk-u-boot.dtsi62
-rw-r--r--arch/arm/dts/imx943-u-boot.dtsi212
-rw-r--r--arch/arm/include/asm/arch-imx/cpu.h2
-rw-r--r--arch/arm/include/asm/arch-imx9/imx-regs.h11
-rw-r--r--arch/arm/include/asm/arch-imx9/sys_proto.h1
-rw-r--r--arch/arm/include/asm/mach-imx/sys_proto.h1
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/ele_ahab.c55
-rw-r--r--arch/arm/mach-imx/image-container.c4
-rw-r--r--arch/arm/mach-imx/imx9/Kconfig17
-rw-r--r--arch/arm/mach-imx/imx9/scmi/Makefile3
-rw-r--r--arch/arm/mach-imx/imx9/scmi/clock.c29
-rw-r--r--arch/arm/mach-imx/imx9/scmi/common.h41
-rw-r--r--arch/arm/mach-imx/imx9/scmi/soc.c213
-rw-r--r--board/freescale/imx94_evk/Kconfig12
-rw-r--r--board/freescale/imx94_evk/MAINTAINERS6
-rw-r--r--board/freescale/imx94_evk/Makefile11
-rw-r--r--board/freescale/imx94_evk/imx94_evk.c41
-rw-r--r--board/freescale/imx94_evk/imx94_evk.env100
-rw-r--r--board/freescale/imx94_evk/spl.c81
-rw-r--r--board/freescale/imx95_evk/spl.c3
-rw-r--r--configs/imx93-phycore_defconfig2
-rw-r--r--configs/imx943_evk_defconfig115
-rw-r--r--doc/board/nxp/imx943_evk.rst112
-rw-r--r--doc/board/nxp/index.rst1
-rw-r--r--drivers/cpu/imx8_cpu.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx-scmi.c5
-rw-r--r--drivers/spi/nxp_fspi.c44
-rw-r--r--include/configs/imx94_evk.h24
-rw-r--r--include/scmi_nxp_protocols.h55
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;
+};
+
+&reg_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