[PATCH v3 05/12] imx9: scmi: Update the files under arch/arm/mach-imx/imx9/scmi/ to support i.MX94

Alice Guo (OSS) alice.guo at oss.nxp.com
Tue Sep 23 04:14:57 CEST 2025


From: Ye Li <ye.li at nxp.com>

- Add base addresses for WDG3, WDG4, GPIO6, and GPIO7 for i.MX94.
- Introduce common.h with macros of clock IDs, power domains, and CPU
  types for platform-specific replacement (e.g., i.MX94, i.MX95).
- Extend imx_get_mac_from_fuse() to support i.MX94.

Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Alice Guo <alice.guo at nxp.com>
Acked-by: Peng Fan <peng.fan at nxp.com>
Reviewed-by: Jacky Bai <ping.bai at nxp.com>
---
 arch/arm/include/asm/arch-imx9/imx-regs.h |  9 ++++++
 arch/arm/mach-imx/imx9/scmi/Makefile      |  3 ++
 arch/arm/mach-imx/imx9/scmi/clock.c       | 29 +++++++++---------
 arch/arm/mach-imx/imx9/scmi/common.h      | 41 +++++++++++++++++++++++++
 arch/arm/mach-imx/imx9/scmi/soc.c         | 50 ++++++++++++++++++++++++-------
 5 files changed, 108 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h
index 5127fe8f286..a44fa6663c3 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
 
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 07022c65b88..5c1e13c9842 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -21,6 +21,7 @@
 #include <linux/iopoll.h>
 #include <scmi_agent.h>
 #include <scmi_nxp_protocols.h>
+#include "common.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -176,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
@@ -437,12 +438,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 {
 	u32 val[2] = {};
 	int ret, num_of_macs;
+	u32 bank = 40;
 
-	ret = fuse_read(40, 5, &val[0]);
+	if (is_imx94())
+		bank = 66;
+
+	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;
 
@@ -458,10 +463,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;
@@ -518,7 +545,6 @@ static char *rst_string_imx94[32] = {
 	"por"
 };
 
-
 int get_reset_reason(bool sys, bool lm)
 {
 	struct scmi_imx_misc_reset_reason_in in = {
@@ -612,8 +638,8 @@ int get_reset_reason(bool sys, bool lm)
 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 "??";
 	}
@@ -694,6 +720,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;

-- 
2.43.0



More information about the U-Boot mailing list