From f9c4fd387179187dd81a34f6f78df448f1e8cbfa Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 23 Sep 2025 10:14:57 +0800 Subject: [PATCH] imx9: scmi: Update the files under arch/arm/mach-imx/imx9/scmi/ to support i.MX94 - 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 Signed-off-by: Alice Guo Acked-by: Peng Fan Reviewed-by: Jacky Bai --- 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(-) create mode 100644 arch/arm/mach-imx/imx9/scmi/common.h 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 #include #include -#include "../../../../../dts/upstream/src/arm64/freescale/imx95-clock.h" +#include +#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 +#include + +#define IMX94_CLK_FLEXSPI1 IMX94_CLK_XSPI1 +#endif + +#ifdef CONFIG_IMX95 +#define IMX_PLAT 95 +#include +#include + +#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 #include #include +#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.47.3