* [PATCH v8 00/19] imx: add i.MX95 support
@ 2025-03-21 7:15 Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable Alice Guo (OSS)
` (19 more replies)
0 siblings, 20 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Viorel Suman, Ye Li, Ranjani Vaidyanathan, Peng Fan,
Frank Li, Ji Luo, Jindong Yue, Ranjani Vaidyanathan
Changes for v7:
- separate i.MX Messaging Unit driver patch from this patch set
- add U_BOOT_SCMI_PROTO_DRIVER() to avoid putting i.MX related code in scmi_agent-uclass.c.
- update drivers/clk/clk_scmi.c according to comment
- dynamically allocate the size of struct scmi_base_discover_list_protocols_out
Changes for v8:
- add a comma to enum scmi_clock_message_id
- use readl_poll_timeout instead of while to avoid to silent hang in
disable_wdog()
- use the format "%pM" to print a MAC address
- use "%u" to match the data type u32
- add a comma enum imx8image_cmd, enum imx8image_core_type and so on
- add a line at end of container.cfg, imximage.cfg and imx95_19x19_evk.env
- update arch/arm/mach-imx/imx9/scmi/soc.c
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
Alice Guo (9):
pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
firmware: scmi_agent: add SCMI pin control protocol support
clk: scmi: check the clock state/parent/rate control permissions
sandbox: add SCMI clock control permissions to sandbox
imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95
binman: add a new entry type for packing DDR PHY firmware images
tools: imx8image: add i.MX95 support
doc: imx: add document for i.MX95 Image Container Format
Makefile: add some files to CLEAN_FILES
Peng Fan (4):
scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data
scmi_protocols: add SCMI Performance domain management protocol message IDs
clk: scmi: add the command CLOCK_PARENT_SET
imx9: scmi: add i.MX95 SoC and clock related code
Viorel Suman (1):
firmware: scmi: smt: Interrupt communication enable
Ye Li (5):
scmi_protocols: update struct scmi_base_discover_list_protocols_out
spl: imx: use trampoline buffer to load images to secure region
imx9: add i.MX95 Kconfig and Makefile
imx: container: add V2X container support for i.MX95
imx95_evk: add i.MX95 19x19 EVK board basic support
Makefile | 3 +-
arch/arm/dts/imx95-19x19-evk-u-boot.dtsi | 62 ++
arch/arm/dts/imx95-u-boot.dtsi | 157 +++++
arch/arm/include/asm/arch-imx/cpu.h | 2 +
arch/arm/include/asm/arch-imx9/clock.h | 10 +
arch/arm/include/asm/arch-imx9/imx-regs.h | 6 +
arch/arm/include/asm/arch-imx9/sys_proto.h | 1 +
arch/arm/include/asm/mach-imx/sys_proto.h | 39 ++
arch/arm/mach-imx/Kconfig | 2 +-
arch/arm/mach-imx/image-container.c | 119 +++-
arch/arm/mach-imx/imx9/Kconfig | 16 +
arch/arm/mach-imx/imx9/Makefile | 9 +-
arch/arm/mach-imx/imx9/scmi/Makefile | 6 +
arch/arm/mach-imx/imx9/scmi/clock.c | 70 +++
arch/arm/mach-imx/imx9/scmi/clock_scmi.c | 133 +++++
arch/arm/mach-imx/imx9/scmi/container.cfg | 10 +
arch/arm/mach-imx/imx9/scmi/imximage.cfg | 15 +
arch/arm/mach-imx/imx9/scmi/soc.c | 793 ++++++++++++++++++++++++++
arch/sandbox/include/asm/scmi_test.h | 4 +-
board/freescale/imx95_evk/Kconfig | 12 +
board/freescale/imx95_evk/MAINTAINERS | 6 +
board/freescale/imx95_evk/Makefile | 11 +
board/freescale/imx95_evk/imx95_19x19_evk.env | 91 +++
board/freescale/imx95_evk/imx95_evk.c | 36 ++
board/freescale/imx95_evk/spl.c | 69 +++
common/spl/Kconfig | 6 +
common/spl/spl_imx_container.c | 41 +-
configs/imx95_19x19_evk_defconfig | 152 +++++
doc/board/nxp/imx95_evk.rst | 114 ++++
doc/board/nxp/index.rst | 1 +
doc/imx/imx95_container.txt | 136 +++++
drivers/clk/clk_scmi.c | 191 ++++++-
drivers/firmware/scmi/Kconfig | 6 +
drivers/firmware/scmi/base.c | 24 +-
drivers/firmware/scmi/sandbox-scmi_agent.c | 56 +-
drivers/firmware/scmi/scmi_agent-uclass.c | 25 +
drivers/firmware/scmi/smt.c | 13 +
drivers/pinctrl/nxp/Kconfig | 13 +
drivers/pinctrl/nxp/Makefile | 1 +
drivers/pinctrl/nxp/pinctrl-imx-scmi.c | 159 ++++++
include/configs/imx95_evk.h | 24 +
include/imx8image.h | 19 +-
include/scmi_agent-uclass.h | 17 +
include/scmi_protocols.h | 104 +++-
tools/binman/entries.rst | 10 +
tools/binman/etype/nxp_header_ddrfw.py | 29 +
tools/binman/ftest.py | 11 +
tools/binman/test/346_nxp_ddrfw_imx95.dts | 24 +
tools/imx8image.c | 147 ++++-
tools/imx9_image.sh | 8 +
50 files changed, 2937 insertions(+), 76 deletions(-)
---
base-commit: 8543664bffdbc49d9fbd600131c21a7c4b5ca935
change-id: 20250321-imx95-aec019806ab6
Best regards,
--
Alice Guo <alice.guo@oss.nxp.com>
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 0:38 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol Alice Guo (OSS)
` (18 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Viorel Suman, Ye Li
From: Viorel Suman <viorel.suman@nxp.com>
i.MX95 System Manager uses interrupt driven communication which requires
the caller to set Bit[0] of channel flags to 1. When transmission
completes and the previous general purpose interrupt has been processed
by the other core, i.MX95 System Manager will set General Purpose
Interrupt Control Register (GCR). U-Boot polls General-purpose Status
(GSR) to check if the operation is finished.
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
---
drivers/firmware/scmi/Kconfig | 6 ++++++
drivers/firmware/scmi/smt.c | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig
index 8cf85f0d7a1..eb62b88615b 100644
--- a/drivers/firmware/scmi/Kconfig
+++ b/drivers/firmware/scmi/Kconfig
@@ -41,3 +41,9 @@ config SCMI_AGENT_OPTEE
help
Enable the SCMI communication channel based on OP-TEE transport
for compatible "linaro,scmi-optee".
+
+config SCMI_TRANSPORT_SMT_INTR
+ bool
+ depends on SCMI_FIRMWARE
+ help
+ Enable interrupt communication of shared memory based transport.
diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c
index 67d2f450024..a0489f9718a 100644
--- a/drivers/firmware/scmi/smt.c
+++ b/drivers/firmware/scmi/smt.c
@@ -20,6 +20,16 @@
#include "smt.h"
+static void scmi_smt_enable_intr(struct scmi_smt *smt, bool enable)
+{
+ struct scmi_smt_header *hdr = (void *)smt->buf;
+
+ if (enable)
+ hdr->flags |= SCMI_SHMEM_FLAG_INTR_ENABLED;
+ else
+ hdr->flags &= ~SCMI_SHMEM_FLAG_INTR_ENABLED;
+}
+
/**
* Get shared memory configuration defined by the referred DT phandle
* Return with a errno compliant value.
@@ -48,6 +58,9 @@ int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt)
if (!smt->buf)
return -ENOMEM;
+ if (IS_ENABLED(CONFIG_SCMI_TRANSPORT_SMT_INTR))
+ scmi_smt_enable_intr(smt, true);
+
#ifdef CONFIG_ARM
if (dcache_status())
mmu_set_region_dcache_behaviour(ALIGN_DOWN((uintptr_t)smt->buf, MMU_SECTION_SIZE),
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 0:46 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support Alice Guo (OSS)
` (17 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ranjani Vaidyanathan, Peng Fan, Ye Li
From: Alice Guo <alice.guo@nxp.com>
This patch provides a pinctrl driver based on SCMI pin control protocol.
Currently, only the PINCTRL_CONFIG_SET command is implemented.
Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
---
drivers/pinctrl/nxp/Kconfig | 13 +++
drivers/pinctrl/nxp/Makefile | 1 +
drivers/pinctrl/nxp/pinctrl-imx-scmi.c | 152 +++++++++++++++++++++++++++++++++
include/scmi_protocols.h | 36 ++++++++
4 files changed, 202 insertions(+)
diff --git a/drivers/pinctrl/nxp/Kconfig b/drivers/pinctrl/nxp/Kconfig
index d13c5f2a6d5..84d9a3641ff 100644
--- a/drivers/pinctrl/nxp/Kconfig
+++ b/drivers/pinctrl/nxp/Kconfig
@@ -139,6 +139,19 @@ config PINCTRL_IMXRT
only parses the 'fsl,pins' property and configure related
registers.
+config PINCTRL_IMX_SCMI
+ bool "IMX pinctrl SCMI driver"
+ depends on ARCH_IMX9 && PINCTRL_FULL
+ select PINCTRL_IMX
+ help
+ This provides a simple pinctrl driver for i.MX SoC which supports
+ SCMI. This feature depends on device tree configuration. This driver
+ is different from the linux one, this is a simple implementation,
+ only parses the 'fsl,pins' property and configure related
+ registers.
+
+ Say Y here to enable the imx pinctrl SCMI driver
+
config PINCTRL_VYBRID
bool "Vybrid (vf610) pinctrl driver"
depends on ARCH_VF610 && PINCTRL_FULL
diff --git a/drivers/pinctrl/nxp/Makefile b/drivers/pinctrl/nxp/Makefile
index 44e37c631e5..7d861ae52c1 100644
--- a/drivers/pinctrl/nxp/Makefile
+++ b/drivers/pinctrl/nxp/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_PINCTRL_IMX93) += pinctrl-imx93.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_VYBRID) += pinctrl-vf610.o
obj-$(CONFIG_PINCTRL_IMXRT) += pinctrl-imxrt.o
+obj-$(CONFIG_PINCTRL_IMX_SCMI) += pinctrl-imx-scmi.o
diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
new file mode 100644
index 00000000000..0ed971369a3
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <asm/io.h>
+#include <asm/mach-imx/sys_proto.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/pinctrl.h>
+#include <scmi_agent.h>
+#include <scmi_protocols.h>
+
+#include "pinctrl-imx.h"
+
+#define DAISY_OFFSET_IMX93 0x360
+#define DAISY_OFFSET_IMX95 0x408
+
+/* SCMI pin control types */
+#define PINCTRL_TYPE_MUX 192
+#define PINCTRL_TYPE_CONFIG 193
+#define PINCTRL_TYPE_DAISY_ID 194
+#define PINCTRL_TYPE_DAISY_CFG 195
+#define PINCTRL_NUM_CFGS_SHIFT 2
+
+struct imx_scmi_pinctrl_priv {
+ u16 daisy_offset;
+};
+
+static int imx_pinconf_scmi_set(struct udevice *dev, u32 mux_ofs, u32 mux, u32 config_val,
+ u32 input_ofs, u32 input_val)
+{
+ struct imx_scmi_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret, num_cfgs = 0;
+ struct scmi_msg msg;
+
+ /* Call SCMI API to set the pin mux and configuration. */
+ struct scmi_pinctrl_config_set_out out;
+ struct scmi_pinctrl_config_set_in in = {
+ .identifier = mux_ofs / 4,
+ .function_id = 0xFFFFFFFF,
+ .attributes = 0,
+ };
+
+ if (mux_ofs) {
+ in.configs[num_cfgs].type = PINCTRL_TYPE_MUX;
+ in.configs[num_cfgs].val = mux;
+ num_cfgs++;
+ }
+
+ if (config_val) {
+ in.configs[num_cfgs].type = PINCTRL_TYPE_CONFIG;
+ in.configs[num_cfgs].val = config_val;
+ num_cfgs++;
+ }
+
+ if (input_ofs) {
+ in.configs[num_cfgs].type = PINCTRL_TYPE_DAISY_ID;
+ in.configs[num_cfgs].val = (input_ofs - priv->daisy_offset) / 4;
+ num_cfgs++;
+ in.configs[num_cfgs].type = PINCTRL_TYPE_DAISY_CFG;
+ in.configs[num_cfgs].val = input_val;
+ num_cfgs++;
+ }
+
+ /* Update the number of configs sent in this call. */
+ in.attributes = num_cfgs << PINCTRL_NUM_CFGS_SHIFT;
+
+ msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_PINCTRL,
+ SCMI_MSG_PINCTRL_CONFIG_SET, in, out);
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret || out.status) {
+ dev_err(dev, "Failed to set PAD = %d, daisy = %d, scmi_err = %d, ret = %d\n",
+ mux_ofs / 4, input_ofs / 4, out.status, ret);
+ }
+
+ return ret;
+}
+
+static int imx_pinctrl_set_state_scmi(struct udevice *dev, struct udevice *config)
+{
+ int mux_ofs, mux, config_val, input_reg, input_val;
+ u32 *pin_data;
+ int i, j = 0;
+ int npins;
+ int ret;
+
+ ret = imx_pinctrl_set_state_common(dev, config, FSL_PIN_SIZE,
+ &pin_data, &npins);
+ if (ret)
+ return ret;
+
+ /*
+ * Refer to linux documentation for details:
+ * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
+ */
+ for (i = 0; i < npins; i++) {
+ mux_ofs = pin_data[j++];
+ /* Skip config_reg */
+ j++;
+ input_reg = pin_data[j++];
+
+ mux = pin_data[j++];
+ input_val = pin_data[j++];
+ config_val = pin_data[j++];
+
+ if (config_val & IMX_PAD_SION)
+ mux |= IOMUXC_CONFIG_SION;
+
+ config_val &= ~IMX_PAD_SION;
+
+ ret = imx_pinconf_scmi_set(dev, mux_ofs, mux, config_val, input_reg, input_val);
+ if (ret && ret != -EPERM) {
+ dev_err(dev, "Set pin %d, mux %d, val %d, error\n",
+ mux_ofs, mux, config_val);
+ }
+ }
+
+ return ret;
+}
+
+static const struct pinctrl_ops imx_scmi_pinctrl_ops = {
+ .set_state = imx_pinctrl_set_state_scmi,
+};
+
+static int imx_scmi_pinctrl_probe(struct udevice *dev)
+{
+ struct imx_scmi_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->daisy_offset = is_imx93() ? DAISY_OFFSET_IMX93 : DAISY_OFFSET_IMX95;
+
+ return devm_scmi_of_get_channel(dev);
+}
+
+static int imx_scmi_pinctrl_bind(struct udevice *dev)
+{
+ if (IS_ENABLED(CONFIG_IMX95))
+ return 0;
+
+ return -ENODEV;
+}
+
+U_BOOT_DRIVER(scmi_pinctrl_imx) = {
+ .name = "scmi_pinctrl_imx",
+ .id = UCLASS_PINCTRL,
+ .bind = imx_scmi_pinctrl_bind,
+ .probe = imx_scmi_pinctrl_probe,
+ .priv_auto = sizeof(struct imx_scmi_pinctrl_priv),
+ .ops = &imx_scmi_pinctrl_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 7abb2a6f36b..279ebbad440 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -24,6 +24,7 @@ enum scmi_std_protocol {
SCMI_PROTOCOL_ID_SENSOR = 0x15,
SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
+ SCMI_PROTOCOL_ID_PINCTRL = 0x19,
};
enum scmi_status_code {
@@ -1005,4 +1006,39 @@ struct scmi_voltd_level_get_out {
s32 voltage_level;
};
+/* SCMI Pinctrl Protocol */
+enum scmi_pinctrl_message_id {
+ SCMI_MSG_PINCTRL_CONFIG_SET = 0x6
+};
+
+struct scmi_pin_config {
+ u32 type;
+ u32 val;
+};
+
+/**
+ * struct scmi_pad_config_set_in - Message payload for PAD_CONFIG_SET command
+ * @identifier: Identifier for the pin or group.
+ * @function_id: Identifier for the function selected to be enabled
+ * for the selected pin or group. This field is set to
+ * 0xFFFFFFFF if no function should be enabled by the
+ * pin or group.
+ * @attributes: Bits[31:11] Reserved, must be zero.
+ * Bit[10] Function valid.
+ * Bits[9:2] Number of configurations to set.
+ * Bits[1:0] Selector: Whether the identifier field
+ * refers to a pin or a group.
+ * @configs: Array of configurations.
+ */
+struct scmi_pinctrl_config_set_in {
+ u32 identifier;
+ u32 function_id;
+ u32 attributes;
+ struct scmi_pin_config configs[4];
+};
+
+struct scmi_pinctrl_config_set_out {
+ s32 status;
+};
+
#endif /* _SCMI_PROTOCOLS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data Alice Guo (OSS)
` (16 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
This patch adds SCMI pin control protocol support to make the pin
controller driver based on SCMI, such as
drivers/pinctrl/nxp/pinctrl-imx-scmi.c, can be bound to the SCMI agent
device whose protocol id is 0x19.
Add U_BOOT_SCMI_PROTO_DRIVER() so that the SCMI agent device can choose
which SCMI protocol driver to bind by the bind function of struct
driver. This can avoid putting i.MX related code in scmi_agent-uclass.c.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
drivers/firmware/scmi/scmi_agent-uclass.c | 25 +++++++++++++++++++++++++
drivers/pinctrl/nxp/pinctrl-imx-scmi.c | 7 +++++++
include/scmi_agent-uclass.h | 17 +++++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 8c907c3b032..2ffdd5c881e 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -97,6 +97,9 @@ struct udevice *scmi_get_protocol(struct udevice *dev,
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
proto = priv->voltagedom_dev;
break;
+ case SCMI_PROTOCOL_ID_PINCTRL:
+ proto = priv->pinctrl_dev;
+ break;
default:
dev_err(dev, "Protocol not supported\n");
proto = NULL;
@@ -147,6 +150,9 @@ static int scmi_add_protocol(struct udevice *dev,
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
priv->voltagedom_dev = proto;
break;
+ case SCMI_PROTOCOL_ID_PINCTRL:
+ priv->pinctrl_dev = proto;
+ break;
default:
dev_err(dev, "Protocol not supported\n");
return -EPROTO;
@@ -352,6 +358,22 @@ static int scmi_fill_base_info(struct udevice *agent, struct udevice *dev)
return 0;
}
+static struct driver *scmi_proto_driver_get(unsigned int proto_id)
+{
+ struct scmi_proto_driver *start, *entry;
+ int n_ents;
+
+ start = ll_entry_start(struct scmi_proto_driver, scmi_proto_driver);
+ n_ents = ll_entry_count(struct scmi_proto_driver, scmi_proto_driver);
+
+ for (entry = start; entry != start + n_ents; entry++) {
+ if (entry->match->proto_id == proto_id)
+ return entry->driver;
+ }
+
+ return NULL;
+}
+
/*
* SCMI agent devices binds devices of various uclasses depending on
* the FDT description. scmi_bind_protocol() is a generic bind sequence
@@ -436,6 +458,9 @@ static int scmi_bind_protocols(struct udevice *dev)
drv = DM_DRIVER_GET(scmi_voltage_domain);
}
break;
+ case SCMI_PROTOCOL_ID_PINCTRL:
+ drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL);
+ break;
default:
break;
}
diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
index 0ed971369a3..dbd6ff437e5 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
@@ -9,6 +9,7 @@
#include <dm/device_compat.h>
#include <dm/pinctrl.h>
#include <scmi_agent.h>
+#include <scmi_agent-uclass.h>
#include <scmi_protocols.h>
#include "pinctrl-imx.h"
@@ -150,3 +151,9 @@ U_BOOT_DRIVER(scmi_pinctrl_imx) = {
.ops = &imx_scmi_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};
+
+static struct scmi_proto_match match = {
+ .proto_id = SCMI_PROTOCOL_ID_PINCTRL,
+};
+
+U_BOOT_SCMI_PROTO_DRIVER(scmi_pinctrl_imx, &match);
diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h
index 33e0e18c30d..d6586eb3ff9 100644
--- a/include/scmi_agent-uclass.h
+++ b/include/scmi_agent-uclass.h
@@ -27,6 +27,7 @@ struct scmi_channel;
* @clock_dev: SCMI clock protocol device
* @resetdom_dev: SCMI reset domain protocol device
* @voltagedom_dev: SCMI voltage domain protocol device
+ * @pinctrl_dev: SCMI pin control protocol device
*/
struct scmi_agent_priv {
u32 version;
@@ -43,6 +44,7 @@ struct scmi_agent_priv {
struct udevice *clock_dev;
struct udevice *resetdom_dev;
struct udevice *voltagedom_dev;
+ struct udevice *pinctrl_dev;
};
static inline u32 scmi_version(struct udevice *dev)
@@ -115,4 +117,19 @@ struct scmi_agent_ops {
struct scmi_msg *msg);
};
+struct scmi_proto_match {
+ unsigned int proto_id;
+};
+
+struct scmi_proto_driver {
+ struct driver *driver;
+ const struct scmi_proto_match *match;
+};
+
+#define U_BOOT_SCMI_PROTO_DRIVER(__name, __match) \
+ ll_entry_declare(struct scmi_proto_driver, __name, scmi_proto_driver) = { \
+ .driver = llsym(struct driver, __name, driver), \
+ .match = __match, \
+ }
+
#endif /* _SCMI_TRANSPORT_UCLASS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (2 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs Alice Guo (OSS)
` (15 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
From: Peng Fan <peng.fan@nxp.com>
SCMI misc protocol is intended for miscellaneous functions which are
device specific and are usually defined to access bit fields. It is i.MX
specific. This patch adds SCMI misc protocol protocol_id and message_id
for getting the ROM passover data.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
---
include/scmi_protocols.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 279ebbad440..06de4a601f8 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -25,6 +25,7 @@ enum scmi_std_protocol {
SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
SCMI_PROTOCOL_ID_PINCTRL = 0x19,
+ SCMI_PROTOCOL_ID_IMX_MISC = 0x84,
};
enum scmi_status_code {
@@ -50,6 +51,10 @@ enum scmi_discovery_id {
SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
};
+enum scmi_imx_misc_message_id {
+ SCMI_MISC_ROM_PASSOVER_GET = 0x7
+};
+
/*
* SCMI Base Protocol
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (3 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET Alice Guo (OSS)
` (14 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
From: Peng Fan <peng.fan@nxp.com>
SCMI Performance domain management protocol is intended for performance
management of groups of devices or APs that run in the same performance
domain. The functionality provided by the callee-side can be used by
passing the corresponding message_id.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
---
include/scmi_protocols.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 06de4a601f8..34f272c448c 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -1046,4 +1046,22 @@ struct scmi_pinctrl_config_set_out {
s32 status;
};
+/* SCMI Perf Protocol */
+enum scmi_perf_message_id {
+ SCMI_PERF_DOMAIN_ATTRIBUTES = 0x3,
+ SCMI_PERF_DESCRIBE_LEVELS = 0x4,
+ SCMI_PERF_LIMITS_SET = 0x5,
+ SCMI_PERF_LIMITS_GET = 0x6,
+ SCMI_PERF_LEVEL_SET = 0x7,
+ SCMI_PERF_LEVEL_GET = 0x8
+};
+
+struct scmi_perf_in {
+ u32 domain_id;
+ u32 perf_level;
+};
+
+struct scmi_perf_out {
+ s32 status;
+};
#endif /* _SCMI_PROTOCOLS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (4 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 1:57 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions Alice Guo (OSS)
` (13 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
From: Peng Fan <peng.fan@nxp.com>
This patch adds the command CLOCK_PARENT_SET that can be used to set the
parent of a clock. ARM SCMI Version 3.2 supports to change the parent of
a clock device.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
---
drivers/clk/clk_scmi.c | 20 ++++++++++++++++++++
include/scmi_protocols.h | 19 +++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index e42d2032d45..84333cdd0cc 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -178,11 +178,31 @@ static int scmi_clk_probe(struct udevice *dev)
return 0;
}
+static int scmi_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct scmi_clk_parent_set_in in = {
+ .clock_id = clk->id,
+ .parent_clk = parent->id,
+ };
+ struct scmi_clk_parent_set_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_PARENT_SET,
+ in, out);
+ int ret;
+
+ ret = devm_scmi_process_msg(clk->dev, &msg);
+ if (ret < 0)
+ return ret;
+
+ return scmi_to_linux_errno(out.status);
+}
+
static const struct clk_ops scmi_clk_ops = {
.enable = scmi_clk_enable,
.disable = scmi_clk_disable,
.get_rate = scmi_clk_get_rate,
.set_rate = scmi_clk_set_rate,
+ .set_parent = scmi_clk_set_parent,
};
U_BOOT_DRIVER(scmi_clock) = {
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 34f272c448c..342a65ae7f4 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -737,6 +737,7 @@ enum scmi_clock_message_id {
SCMI_CLOCK_RATE_SET = 0x5,
SCMI_CLOCK_RATE_GET = 0x6,
SCMI_CLOCK_CONFIG_SET = 0x7,
+ SCMI_CLOCK_PARENT_SET = 0xD,
};
#define SCMI_CLK_PROTO_ATTR_COUNT_MASK GENMASK(15, 0)
@@ -839,6 +840,24 @@ struct scmi_clk_rate_set_out {
s32 status;
};
+/**
+ * struct scmi_clk_parent_state_in - Message payload for CLOCK_PARENT_SET command
+ * @clock_id: SCMI clock ID
+ * @parent_clk: SCMI clock ID
+ */
+struct scmi_clk_parent_set_in {
+ u32 clock_id;
+ u32 parent_clk;
+};
+
+/**
+ * struct scmi_clk_parent_set_out - Response payload for CLOCK_PARENT_SET command
+ * @status: SCMI command status
+ */
+struct scmi_clk_parent_set_out {
+ s32 status;
+};
+
/*
* SCMI Reset Domain Protocol
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (5 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 2:02 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 08/19] sandbox: add SCMI clock control permissions to sandbox Alice Guo (OSS)
` (12 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
From: Alice Guo <alice.guo@nxp.com>
Clock driver based on SCMI clock management protocol in Linux checks
clock state, parent and rate control permissions. To be consistent with
the kernel driver, add this check here.
When using common clock framework (CCF), use the clock signal ID to get
the clock registered by clk_register() in scmi_clk_probe(), and then
obatin the struct clk_scmi variable with container_of().
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/clk_scmi.c | 173 +++++++++++++++++++++++++++++++++++++++++++----
include/scmi_protocols.h | 24 +++++++
2 files changed, 185 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 84333cdd0cc..d120c1eba06 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -12,6 +12,56 @@
#include <asm/types.h>
#include <linux/clk-provider.h>
+struct clk_scmi {
+ struct clk clk;
+ u32 ctrl_flags;
+};
+
+static int scmi_clk_get_permissions(struct udevice *dev, int clkid, u32 *perm)
+{
+ u32 version;
+ int ret;
+
+ struct scmi_clk_get_permissions_in in = {
+ .clock_id = clkid,
+ };
+ struct scmi_clk_get_permissions_out out;
+ struct scmi_msg msg = {
+ .protocol_id = SCMI_PROTOCOL_ID_CLOCK,
+ .message_id = SCMI_CLOCK_GET_PERMISSIONS,
+ .in_msg = (u8 *)&in,
+ .in_msg_sz = sizeof(in),
+ .out_msg = (u8 *)&out,
+ .out_msg_sz = sizeof(out),
+ };
+
+ ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK, &version);
+ if (ret) {
+ log_debug("%s: get SCMI clock management protocol version failed\n", __func__);
+ return ret;
+ }
+
+ if (version < CLOCK_PROTOCOL_VERSION_3_0) {
+ log_debug("%s: SCMI clock management protocol version is less than 3.0.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret) {
+ log_debug("%s: get SCMI clock management protocol permissions failed\n", __func__);
+ return ret;
+ }
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0) {
+ log_debug("%s: the status code of getting permissions: %d\n", __func__, ret);
+ return ret;
+ }
+
+ *perm = out.permissions;
+ return 0;
+}
+
static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
{
struct scmi_clk_protocol_attr_out out;
@@ -32,7 +82,8 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
return 0;
}
-static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
+static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name,
+ u32 *attr)
{
struct scmi_clk_attribute_in in = {
.clock_id = clkid,
@@ -53,6 +104,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
return ret;
*name = strdup(out.clock_name);
+ *attr = out.attributes;
return 0;
}
@@ -78,12 +130,48 @@ static int scmi_clk_gate(struct clk *clk, int enable)
static int scmi_clk_enable(struct clk *clk)
{
- return scmi_clk_gate(clk, 1);
+ struct clk_scmi *clkscmi;
+ struct clk *c;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(CLK_CCF))
+ return scmi_clk_gate(clk, 1);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ clkscmi = container_of(c, struct clk_scmi, clk);
+
+ if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
+ return scmi_clk_gate(clk, 1);
+
+ /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
+ log_debug("%s: SCMI CLOCK: the clock cannot be enabled by the agent.\n", __func__);
+ return 0;
}
static int scmi_clk_disable(struct clk *clk)
{
- return scmi_clk_gate(clk, 0);
+ struct clk_scmi *clkscmi;
+ struct clk *c;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(CLK_CCF))
+ return scmi_clk_gate(clk, 0);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ clkscmi = container_of(c, struct clk_scmi, clk);
+
+ if (clkscmi->ctrl_flags & SUPPORT_CLK_STAT_CONTROL)
+ return scmi_clk_gate(clk, 0);
+
+ /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
+ log_debug("%s: SCMI CLOCK: the clock cannot be disabled by the agent.\n", __func__);
+ return 0;
}
static ulong scmi_clk_get_rate(struct clk *clk)
@@ -108,7 +196,7 @@ static ulong scmi_clk_get_rate(struct clk *clk)
return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
}
-static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
+static ulong __scmi_clk_set_rate(struct clk *clk, ulong rate)
{
struct scmi_clk_rate_set_in in = {
.clock_id = clk->id,
@@ -133,9 +221,32 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
return scmi_clk_get_rate(clk);
}
+static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct clk_scmi *clkscmi;
+ struct clk *c;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(CLK_CCF))
+ return __scmi_clk_set_rate(clk, rate);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ clkscmi = container_of(c, struct clk_scmi, clk);
+
+ if (clkscmi->ctrl_flags & SUPPORT_CLK_RATE_CONTROL)
+ return __scmi_clk_set_rate(clk, rate);
+
+ /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
+ log_debug("%s: SCMI CLOCK: the clock rate cannot be changed by the agent.\n", __func__);
+ return 0;
+}
+
static int scmi_clk_probe(struct udevice *dev)
{
- struct clk *clk;
+ struct clk_scmi *clk_scmi;
size_t num_clocks, i;
int ret;
@@ -156,29 +267,44 @@ static int scmi_clk_probe(struct udevice *dev)
for (i = 0; i < num_clocks; i++) {
char *clock_name;
+ u32 attributes;
- if (!scmi_clk_get_attibute(dev, i, &clock_name)) {
- clk = kzalloc(sizeof(*clk), GFP_KERNEL);
- if (!clk || !clock_name)
+ if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
+ clk_scmi = kzalloc(sizeof(*clk_scmi), GFP_KERNEL);
+ if (!clk_scmi || !clock_name)
ret = -ENOMEM;
else
- ret = clk_register(clk, dev->driver->name,
+ ret = clk_register(&clk_scmi->clk, dev->driver->name,
clock_name, dev->name);
if (ret) {
- free(clk);
+ free(clk_scmi);
free(clock_name);
+ free(&attributes);
return ret;
}
- clk_dm(i, clk);
+ clk_dm(i, &clk_scmi->clk);
+
+ if (CLK_HAS_RESTRICTIONS(attributes)) {
+ u32 perm;
+
+ ret = scmi_clk_get_permissions(dev, i, &perm);
+ if (ret < 0)
+ clk_scmi->ctrl_flags = 0;
+ else
+ clk_scmi->ctrl_flags = perm;
+ } else {
+ clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | SUPPORT_CLK_PARENT_CONTROL |
+ SUPPORT_CLK_RATE_CONTROL;
+ }
}
}
return 0;
}
-static int scmi_clk_set_parent(struct clk *clk, struct clk *parent)
+static int __scmi_clk_set_parent(struct clk *clk, struct clk *parent)
{
struct scmi_clk_parent_set_in in = {
.clock_id = clk->id,
@@ -197,6 +323,29 @@ static int scmi_clk_set_parent(struct clk *clk, struct clk *parent)
return scmi_to_linux_errno(out.status);
}
+static int scmi_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk_scmi *clkscmi;
+ struct clk *c;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(CLK_CCF))
+ return -ENOTSUPP;
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ clkscmi = container_of(c, struct clk_scmi, clk);
+
+ if (clkscmi->ctrl_flags & SUPPORT_CLK_PARENT_CONTROL)
+ return __scmi_clk_set_parent(clk, parent);
+
+ /* Following Linux drivers/clk/clk-scmi.c, directly return 0 if agent has no permission. */
+ log_debug("%s: SCMI CLOCK: the clock's parent cannot be changed by the agent.\n", __func__);
+ return 0;
+}
+
static const struct clk_ops scmi_clk_ops = {
.enable = scmi_clk_enable,
.disable = scmi_clk_disable,
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 342a65ae7f4..519b906b4ce 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -731,6 +731,7 @@ int scmi_pwd_name_get(struct udevice *dev, u32 domain_id, u8 **name);
/*
* SCMI Clock Protocol
*/
+#define CLOCK_PROTOCOL_VERSION_3_0 0x30000
enum scmi_clock_message_id {
SCMI_CLOCK_ATTRIBUTES = 0x3,
@@ -738,6 +739,7 @@ enum scmi_clock_message_id {
SCMI_CLOCK_RATE_GET = 0x6,
SCMI_CLOCK_CONFIG_SET = 0x7,
SCMI_CLOCK_PARENT_SET = 0xD,
+ SCMI_CLOCK_GET_PERMISSIONS = 0xF,
};
#define SCMI_CLK_PROTO_ATTR_COUNT_MASK GENMASK(15, 0)
@@ -776,6 +778,7 @@ struct scmi_clk_attribute_in {
struct scmi_clk_attribute_out {
s32 status;
u32 attributes;
+#define CLK_HAS_RESTRICTIONS(x) ((x) & BIT(1))
char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX];
};
@@ -858,6 +861,27 @@ struct scmi_clk_parent_set_out {
s32 status;
};
+/**
+ * @clock_id: Identifier for the clock device.
+ */
+struct scmi_clk_get_permissions_in {
+ u32 clock_id;
+};
+
+/**
+ * @status: Negative 32-bit integers are used to return error status codes.
+ * @permissions: Bit[31] Clock state control, Bit[30] Clock parent control,
+ * Bit[29] Clock rate control, Bits[28:0] Reserved, must be zero.
+ */
+struct scmi_clk_get_permissions_out {
+ s32 status;
+ u32 permissions;
+};
+
+#define SUPPORT_CLK_STAT_CONTROL BIT(31)
+#define SUPPORT_CLK_PARENT_CONTROL BIT(30)
+#define SUPPORT_CLK_RATE_CONTROL BIT(29)
+
/*
* SCMI Reset Domain Protocol
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 08/19] sandbox: add SCMI clock control permissions to sandbox
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (6 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out Alice Guo (OSS)
` (11 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
This patch is used to add SCMI clock control permissions to sandbox for
testing.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
arch/sandbox/include/asm/scmi_test.h | 2 ++
drivers/firmware/scmi/sandbox-scmi_agent.c | 56 ++++++++++++++++++++++++++++--
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h
index 619f8f5098c..b30e536a357 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -27,10 +27,12 @@ struct sandbox_scmi_pwd {
* @id: Identifier of the clock used in the SCMI protocol
* @enabled: Clock state: true if enabled, false if disabled
* @rate: Clock rate in Hertz
+ * @perm: Indicating state/parent/rate permission
*/
struct sandbox_scmi_clk {
bool enabled;
ulong rate;
+ u32 perm;
};
/**
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 19be280ec44..74a87832dcb 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -80,9 +80,9 @@ static struct sandbox_scmi_pwd scmi_pwdom[] = {
};
static struct sandbox_scmi_clk scmi_clk[] = {
- { .rate = 333 },
- { .rate = 200 },
- { .rate = 1000 },
+ { .rate = 333, .perm = 0xE0000000 },
+ { .rate = 200, .perm = 0xE0000000 },
+ { .rate = 1000, .perm = 0xE0000000 },
};
static struct sandbox_scmi_reset scmi_reset[] = {
@@ -700,6 +700,21 @@ static int sandbox_scmi_pwd_name_get(struct udevice *dev, struct scmi_msg *msg)
/* Clock Protocol */
+static int sandbox_scmi_clock_protocol_version(struct udevice *dev,
+ struct scmi_msg *msg)
+{
+ struct scmi_protocol_version_out *out = NULL;
+
+ if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ out = (struct scmi_protocol_version_out *)msg->out_msg;
+ out->version = 0x30000;
+ out->status = SCMI_SUCCESS;
+
+ return 0;
+}
+
static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
struct scmi_msg *msg)
{
@@ -740,6 +755,9 @@ static int sandbox_scmi_clock_attribs(struct udevice *dev, struct scmi_msg *msg)
if (clk_state->enabled)
out->attributes = 1;
+ /* Restricted clock */
+ out->attributes |= BIT(1);
+
ret = snprintf(out->clock_name, sizeof(out->clock_name),
"clk%u", in->clock_id);
assert(ret > 0 && ret < sizeof(out->clock_name));
@@ -837,6 +855,34 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
return 0;
}
+static int sandbox_scmi_clock_permissions_get(struct udevice *dev,
+ struct scmi_msg *msg)
+{
+ struct scmi_clk_get_permissions_in *in = NULL;
+ struct scmi_clk_get_permissions_out *out = NULL;
+ struct sandbox_scmi_clk *clk_state = NULL;
+
+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
+ !msg->out_msg || msg->out_msg_sz < sizeof(*out))
+ return -EINVAL;
+
+ in = (struct scmi_clk_get_permissions_in *)msg->in_msg;
+ out = (struct scmi_clk_get_permissions_out *)msg->out_msg;
+
+ clk_state = get_scmi_clk_state(in->clock_id);
+ if (!clk_state) {
+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
+
+ out->status = SCMI_NOT_FOUND;
+ } else {
+ out->permissions = clk_state->perm;
+
+ out->status = SCMI_SUCCESS;
+ }
+
+ return 0;
+}
+
static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
{
struct scmi_rd_attr_in *in = NULL;
@@ -1193,6 +1239,8 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
return sandbox_proto_not_supported(msg);
switch (msg->message_id) {
+ case SCMI_PROTOCOL_VERSION:
+ return sandbox_scmi_clock_protocol_version(dev, msg);
case SCMI_PROTOCOL_ATTRIBUTES:
return sandbox_scmi_clock_protocol_attribs(dev, msg);
case SCMI_CLOCK_ATTRIBUTES:
@@ -1203,6 +1251,8 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
return sandbox_scmi_clock_rate_get(dev, msg);
case SCMI_CLOCK_CONFIG_SET:
return sandbox_scmi_clock_gate(dev, msg);
+ case SCMI_CLOCK_GET_PERMISSIONS:
+ return sandbox_scmi_clock_permissions_get(dev, msg);
default:
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (7 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 08/19] sandbox: add SCMI clock control permissions to sandbox Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 2:10 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 10/19] imx9: scmi: add i.MX95 SoC and clock related code Alice Guo (OSS)
` (10 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li
From: Ye Li <ye.li@nxp.com>
@protocols is an array of protocol identifiers that are implemented,
excluding the Base protocol. The number of elements of @protocols is
specified by callee-side.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
drivers/firmware/scmi/base.c | 24 +++++++++++++++++-------
include/scmi_protocols.h | 2 +-
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/scmi/base.c b/drivers/firmware/scmi/base.c
index f4e3974ff5b..3943d90fd40 100644
--- a/drivers/firmware/scmi/base.c
+++ b/drivers/firmware/scmi/base.c
@@ -258,7 +258,7 @@ static int scmi_base_discover_impl_version_int(struct udevice *dev,
static int scmi_base_discover_list_protocols_int(struct udevice *dev,
u8 **protocols)
{
- struct scmi_base_discover_list_protocols_out out;
+ struct scmi_base_discover_list_protocols_out *out;
int cur;
struct scmi_msg msg = {
.protocol_id = SCMI_PROTOCOL_ID_BASE,
@@ -268,7 +268,7 @@ static int scmi_base_discover_list_protocols_int(struct udevice *dev,
.out_msg = (u8 *)&out,
.out_msg_sz = sizeof(out),
};
- u32 num_agents, num_protocols;
+ u32 num_agents, num_protocols, out_size;
u8 *buf;
int i, ret;
@@ -276,22 +276,31 @@ static int scmi_base_discover_list_protocols_int(struct udevice *dev,
if (ret)
return ret;
+ out_size = sizeof(*out) + sizeof(u32) * (1 + (num_protocols - 1) / 4);
+ out = calloc(1, out_size);
+ if (!out)
+ return -ENOMEM;
+ msg.out_msg = (u8 *)out;
+ msg.out_msg_sz = out_size;
+
buf = calloc(sizeof(u8), num_protocols);
- if (!buf)
+ if (!buf) {
+ free(out);
return -ENOMEM;
+ }
cur = 0;
do {
ret = devm_scmi_process_msg(dev, &msg);
if (ret)
goto err;
- if (out.status) {
- ret = scmi_to_linux_errno(out.status);
+ if (out->status) {
+ ret = scmi_to_linux_errno(out->status);
goto err;
}
- for (i = 0; i < out.num_protocols; i++, cur++)
- buf[cur] = out.protocols[i / 4] >> ((i % 4) * 8);
+ for (i = 0; i < out->num_protocols; i++, cur++)
+ buf[cur] = out->protocols[i / 4] >> ((i % 4) * 8);
} while (cur < num_protocols);
*protocols = buf;
@@ -299,6 +308,7 @@ static int scmi_base_discover_list_protocols_int(struct udevice *dev,
return num_protocols;
err:
free(buf);
+ free(out);
return ret;
}
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 519b906b4ce..9046de7e3e7 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -145,7 +145,7 @@ struct scmi_base_discover_impl_version_out {
struct scmi_base_discover_list_protocols_out {
s32 status;
u32 num_protocols;
- u32 protocols[3];
+ u32 protocols[];
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 10/19] imx9: scmi: add i.MX95 SoC and clock related code
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (8 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region Alice Guo (OSS)
` (9 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Peng Fan, Frank Li, Ji Luo, Jindong Yue,
Ranjani Vaidyanathan, Ye Li
From: Peng Fan <peng.fan@nxp.com>
This patch adds i.MX95 SoC and clock related code. Because they are
based on SCMI, put them in the scmi subfolder.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Ji Luo <ji.luo@nxp.com>
Signed-off-by: Jindong Yue <jindong.yue@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Ranjani Vaidyanathan <ranjani.vaidyanathan@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
---
arch/arm/include/asm/arch-imx/cpu.h | 2 +
arch/arm/include/asm/arch-imx9/clock.h | 10 +
arch/arm/include/asm/arch-imx9/imx-regs.h | 6 +
arch/arm/include/asm/arch-imx9/sys_proto.h | 1 +
arch/arm/include/asm/mach-imx/sys_proto.h | 39 ++
arch/arm/mach-imx/imx9/scmi/Makefile | 6 +
arch/arm/mach-imx/imx9/scmi/clock.c | 70 +++
arch/arm/mach-imx/imx9/scmi/clock_scmi.c | 133 +++++
arch/arm/mach-imx/imx9/scmi/soc.c | 775 +++++++++++++++++++++++++++++
arch/sandbox/include/asm/scmi_test.h | 2 +-
10 files changed, 1043 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h
index 0d7a5734616..1f669c72d00 100644
--- a/arch/arm/include/asm/arch-imx/cpu.h
+++ b/arch/arm/include/asm/arch-imx/cpu.h
@@ -76,6 +76,8 @@
#define MXC_CPU_IMX9111 0xCD /* dummy ID */
#define MXC_CPU_IMX9101 0xCE /* dummy ID */
+#define MXC_CPU_IMX95 0x1C1 /* 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/clock.h b/arch/arm/include/asm/arch-imx9/clock.h
index 60d48b13b11..ffaf6b5f7d8 100644
--- a/arch/arm/include/asm/arch-imx9/clock.h
+++ b/arch/arm/include/asm/arch-imx9/clock.h
@@ -255,5 +255,15 @@ int ccm_shared_gpr_tz_access(u32 gpr, bool non_secure, bool user_mode, bool lock
void enable_usboh3_clk(unsigned char enable);
int set_clk_enet(enum enet_freq type);
int set_clk_eqos(enum enet_freq type);
+
+int imx_clk_scmi_enable(u32 clock_id, bool enable);
+ulong imx_clk_scmi_set_rate(u32 clock_id, ulong rate);
+ulong imx_clk_scmi_get_rate(u32 clock_id);
+int imx_clk_scmi_set_parent(u32 clock_id, u32 parent_id);
void set_arm_clk(ulong freq);
+
+int imx_clk_scmi_enable(u32 clock_id, bool enable);
+ulong imx_clk_scmi_set_rate(u32 clock_id, ulong rate);
+ulong imx_clk_scmi_get_rate(u32 clock_id);
+int imx_clk_scmi_set_parent(u32 clock_id, u32 parent_id);
#endif
diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h
index ef9538bd42e..5127fe8f286 100644
--- a/arch/arm/include/asm/arch-imx9/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx9/imx-regs.h
@@ -13,6 +13,7 @@
#define CCM_BASE_ADDR 0x44450000UL
#define CCM_CCGR_BASE_ADDR 0x44458000UL
#define SYSCNT_CTRL_BASE_ADDR 0x44290000
+#define SYSCNT_CMP_BASE_ADDR (SYSCNT_CTRL_BASE_ADDR + 0x10000)
#define ANATOP_BASE_ADDR 0x44480000UL
@@ -20,6 +21,11 @@
#define WDG4_BASE_ADDR 0x424a0000UL
#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
+
#define FSB_BASE_ADDR 0x47510000UL
#define ANATOP_BASE_ADDR 0x44480000UL
diff --git a/arch/arm/include/asm/arch-imx9/sys_proto.h b/arch/arm/include/asm/arch-imx9/sys_proto.h
index e4bf6a63424..df2148a53c7 100644
--- a/arch/arm/include/asm/arch-imx9/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx9/sys_proto.h
@@ -12,6 +12,7 @@ enum imx9_soc_voltage_mode {
VOLT_LOW_DRIVE = 0,
VOLT_NOMINAL_DRIVE,
VOLT_OVER_DRIVE,
+ VOLT_SUPER_OVER_DRIVE,
};
void soc_power_init(void);
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 109a806852a..0780f99b49a 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -97,6 +97,8 @@ struct bd_info;
#define is_imx9302() (is_cpu_type(MXC_CPU_IMX9302))
#define is_imx9301() (is_cpu_type(MXC_CPU_IMX9301))
+#define is_imx95() (is_cpu_type(MXC_CPU_IMX95))
+
#define is_imx9121() (is_cpu_type(MXC_CPU_IMX9121))
#define is_imx9111() (is_cpu_type(MXC_CPU_IMX9111))
#define is_imx9101() (is_cpu_type(MXC_CPU_IMX9101))
@@ -216,6 +218,43 @@ ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev);
u32 rom_api_download_image(u8 *dest, u32 offset, u32 size);
u32 rom_api_query_boot_infor(u32 info_type, u32 *info);
+#if IS_ENABLED(CONFIG_SCMI_FIRMWARE)
+typedef struct rom_passover {
+ u16 tag; // Tag
+ u8 len; // Fixed value of 0x80
+ u8 ver; // Version
+ u32 boot_mode; // Boot mode
+ u32 card_addr_mode; // SD card address mode
+ u32 bad_blks_of_img_set0; // NAND bad block count skipped 1
+ u32 ap_mu_id; // AP MU ID
+ u32 bad_blks_of_img_set1; // NAND bad block count skipped 1
+ u8 boot_stage; // Boot stage
+ u8 img_set_sel; // Image set booted from
+ u8 rsv0[2]; // Reserved
+ u32 img_set_end; // Offset of Image End
+ u32 rom_version; // ROM version
+ u8 boot_dev_state; // Boot device state
+ u8 boot_dev_inst; // Boot device type
+ u8 boot_dev_type; // Boot device instance
+ u8 rsv1; // Reserved
+ u32 dev_page_size; // Boot device page size
+ u32 cnt_header_ofs; // Container header offset
+ u32 img_ofs; // Image offset
+} __packed rom_passover_t;
+
+/**
+ * struct scmi_rom_passover_out - Response payload for ROM_PASSOVER_GET command
+ * @status: SCMI clock ID
+ * @attributes: Attributes of the targets clock state
+ */
+struct scmi_rom_passover_get_out {
+ u32 status;
+ u32 numPassover;
+ u32 passover[(sizeof(rom_passover_t) + 8) / 4];
+};
+
+#endif
+
/* For i.MX ULP */
#define BT0CFG_LPBOOT_MASK 0x1
#define BT0CFG_DUALBOOT_MASK 0x2
diff --git a/arch/arm/mach-imx/imx9/scmi/Makefile b/arch/arm/mach-imx/imx9/scmi/Makefile
new file mode 100644
index 00000000000..4534db08d28
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2025 NXP
+
+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
new file mode 100644
index 00000000000..6e6541eaa31
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/clock.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <asm/arch/clock.h>
+#include <dm/uclass.h>
+#include <scmi_agent.h>
+#include "../../../../../dts/upstream/src/arm64/freescale/imx95-clock.h"
+
+u32 get_arm_core_clk(void)
+{
+ u32 val;
+
+ val = imx_clk_scmi_get_rate(IMX95_CLK_SEL_A55C0);
+ if (val)
+ return val;
+ return imx_clk_scmi_get_rate(IMX95_CLK_A55);
+}
+
+void init_uart_clk(u32 index)
+{
+ u32 clock_id;
+
+ switch (index) {
+ case 0:
+ clock_id = IMX95_CLK_LPUART1;
+ break;
+ case 1:
+ clock_id = IMX95_CLK_LPUART2;
+ break;
+ case 2:
+ clock_id = IMX95_CLK_LPUART3;
+ break;
+ default:
+ return;
+ }
+
+ /* 24MHz */
+ imx_clk_scmi_enable(clock_id, false);
+ imx_clk_scmi_set_parent(clock_id, IMX95_CLK_24M);
+ imx_clk_scmi_set_rate(clock_id, 24000000);
+ imx_clk_scmi_enable(clock_id, true);
+}
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return get_arm_core_clk();
+ case MXC_IPG_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_BUSWAKEUP);
+ case MXC_CSPI_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_LPSPI1);
+ case MXC_ESDHC_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_USDHC1);
+ case MXC_ESDHC2_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_USDHC2);
+ case MXC_ESDHC3_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_USDHC3);
+ case MXC_UART_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_LPUART1);
+ case MXC_FLEXSPI_CLK:
+ return imx_clk_scmi_get_rate(IMX95_CLK_FLEXSPI1);
+ default:
+ return -1;
+ };
+
+ return -1;
+};
diff --git a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c
new file mode 100644
index 00000000000..fa15b5f8df9
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <dm/uclass.h>
+#include <scmi_agent.h>
+
+int imx_clk_scmi_enable(u32 clock_id, bool enable)
+{
+ struct scmi_clk_state_in in = {
+ .clock_id = clock_id,
+ .attributes = (enable) ? 1 : 0,
+ };
+ struct scmi_clk_state_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in, out);
+ int ret;
+ struct udevice *dev;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret)
+ return ret;
+
+ return scmi_to_linux_errno(out.status);
+}
+
+ulong imx_clk_scmi_set_rate(u32 clock_id, ulong rate)
+{
+ struct scmi_clk_rate_set_in in = {
+ .clock_id = clock_id,
+ .flags = SCMI_CLK_RATE_ROUND_CLOSEST,
+ .rate_lsb = (u32)rate,
+ .rate_msb = (u32)((u64)rate >> 32),
+ };
+ struct scmi_clk_rate_set_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_SET,
+ in, out);
+ int ret;
+ struct udevice *dev;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0)
+ return ret;
+
+ struct scmi_clk_rate_get_in in_rate = {
+ .clock_id = clock_id,
+ };
+ struct scmi_clk_rate_get_out out_rate;
+
+ msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, SCMI_CLOCK_RATE_GET, in_rate, out_rate);
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out_rate.status);
+ if (ret < 0)
+ return ret;
+
+ return (ulong)(((u64)out_rate.rate_msb << 32) | out_rate.rate_lsb);
+}
+
+ulong imx_clk_scmi_get_rate(u32 clock_id)
+{
+ struct scmi_clk_rate_get_in in = {
+ .clock_id = clock_id,
+ };
+ struct scmi_clk_rate_get_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_GET,
+ in, out);
+ int ret;
+ struct udevice *dev;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0)
+ return ret;
+
+ return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
+}
+
+int imx_clk_scmi_set_parent(u32 clock_id, u32 parent_id)
+{
+ struct scmi_clk_parent_set_in in = {
+ .clock_id = clock_id,
+ .parent_clk = parent_id,
+ };
+ struct scmi_clk_parent_set_out out;
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_PARENT_SET,
+ in, out);
+ int ret;
+ struct udevice *dev;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret < 0)
+ return ret;
+
+ ret = scmi_to_linux_errno(out.status);
+ if (ret < 0 && ret != -EACCES)
+ printf("%s: %d, clock_id %u\n", __func__, ret, clock_id);
+
+ return ret;
+}
diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c
new file mode 100644
index 00000000000..388147118ca
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -0,0 +1,775 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/ddr.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/armv8/mmu.h>
+#include <asm/mach-imx/boot_mode.h>
+#include <asm/mach-imx/ele_api.h>
+#include <asm/setup.h>
+#include <dm/uclass.h>
+#include <dm/device.h>
+#include <env_internal.h>
+#include <fuse.h>
+#include <imx_thermal.h>
+#include <linux/iopoll.h>
+#include <scmi_agent.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static rom_passover_t rom_passover_data = {0};
+
+uint32_t scmi_get_rom_data(rom_passover_t *rom_data)
+{
+ /* Read ROM passover data */
+ struct scmi_rom_passover_get_out out;
+ struct scmi_msg msg = {
+ .protocol_id = SCMI_PROTOCOL_ID_IMX_MISC,
+ .message_id = SCMI_MISC_ROM_PASSOVER_GET,
+ .in_msg = (u8 *)NULL,
+ .in_msg_sz = 0,
+ .out_msg = (u8 *)&out,
+ .out_msg_sz = sizeof(out),
+ };
+ int ret;
+ struct udevice *dev;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (ret == 0 && out.status == 0) {
+ memcpy(rom_data, (struct rom_passover_t *)out.passover, sizeof(rom_passover_t));
+ } else {
+ printf("Failed to get ROM passover data, scmi_err = %d, size_of(out) = %ld\n",
+ out.status, sizeof(out));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
+__weak int board_mmc_get_env_dev(int devno)
+{
+ return devno;
+}
+
+int mmc_get_env_dev(void)
+{
+ int ret;
+ u16 boot_type;
+ u8 boot_instance;
+
+ volatile gd_t *pgd = gd;
+ rom_passover_t *rdata;
+
+#if IS_ENABLED(CONFIG_XPL_BUILD)
+ rdata = &rom_passover_data;
+#else
+ rom_passover_t rom_data = {0};
+
+ if (!pgd->reloc_off)
+ rdata = &rom_data;
+ else
+ rdata = &rom_passover_data;
+#endif
+ if (rdata->tag == 0) {
+ ret = scmi_get_rom_data(rdata);
+ if (ret != 0) {
+ puts("SCMI: failure at rom_boot_info\n");
+ return CONFIG_SYS_MMC_ENV_DEV;
+ }
+ }
+ boot_type = rdata->boot_dev_type;
+ boot_instance = rdata->boot_dev_inst;
+ set_gd(pgd);
+
+ debug("boot_type %d, instance %d\n", boot_type, boot_instance);
+
+ /* If not boot from sd/mmc, use default value */
+ if (boot_type != BOOT_TYPE_SD && boot_type != BOOT_TYPE_MMC)
+ return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV);
+
+ return board_mmc_get_env_dev(boot_instance);
+}
+#endif
+
+u32 get_cpu_speed_grade_hz(void)
+{
+ u32 speed, max_speed;
+ int ret;
+ u32 val, word, offset;
+
+ word = 17;
+ offset = 14;
+
+ ret = fuse_read(word / 8, word % 8, &val);
+ if (ret)
+ val = 0; /* If read fuse failed, return as blank fuse */
+
+ val >>= offset;
+ val &= 0xf;
+
+ max_speed = 2300000000;
+ speed = max_speed - val * 100000000;
+
+ if (is_imx95())
+ max_speed = 2000000000;
+
+ /* In case the fuse of speed grade not programmed */
+ if (speed > max_speed)
+ speed = max_speed;
+
+ return speed;
+}
+
+u32 get_cpu_temp_grade(int *minc, int *maxc)
+{
+ int ret;
+ u32 val, word, offset;
+
+ word = 17;
+ offset = 12;
+
+ ret = fuse_read(word / 8, word % 8, &val);
+ if (ret)
+ val = 0; /* If read fuse failed, return as blank fuse */
+
+ val >>= offset;
+ val &= 0x3;
+
+ if (minc && maxc) {
+ if (val == TEMP_AUTOMOTIVE) {
+ *minc = -40;
+ *maxc = 125;
+ } else if (val == TEMP_INDUSTRIAL) {
+ *minc = -40;
+ *maxc = 105;
+ } else if (val == TEMP_EXTCOMMERCIAL) {
+ *minc = -20;
+ *maxc = 105;
+ } else {
+ *minc = 0;
+ *maxc = 95;
+ }
+ }
+ return val;
+}
+
+static void set_cpu_info(struct ele_get_info_data *info)
+{
+ gd->arch.soc_rev = info->soc;
+ gd->arch.lifecycle = info->lc;
+ memcpy((void *)&gd->arch.uid, &info->uid, 4 * sizeof(u32));
+}
+
+u32 get_cpu_rev(void)
+{
+ u32 rev = (gd->arch.soc_rev >> 24) - 0xa0;
+
+ return (MXC_CPU_IMX95 << 12) | (CHIP_REV_1_0 + rev);
+}
+
+#define UNLOCK_WORD 0xD928C520
+#define REFRESH_WORD 0xB480A602
+
+static void disable_wdog(void __iomem *wdog_base)
+{
+ u32 val_cs = readl(wdog_base + 0x00);
+ int ret = 0;
+
+ if (!(val_cs & 0x80))
+ return;
+
+ /* default is 32bits cmd */
+ writel(REFRESH_WORD, (wdog_base + 0x04)); /* Refresh the CNT */
+
+ if (!(val_cs & 0x800)) {
+ writel(UNLOCK_WORD, (wdog_base + 0x04));
+ while (!(readl(wdog_base + 0x00) & 0x800))
+ ;
+ }
+ writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */
+ writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */
+ writel(0x2120, (wdog_base + 0x00)); /* Disable it and set update */
+
+ ret = readl_poll_timeout(wdog_base, val_cs, val_cs & 0x400, 100000);
+ if (ret < 0)
+ debug("%s timeout\n", __func__);
+}
+
+static struct mm_region imx9_mem_map[] = {
+ {
+ /* M7 TCM */
+ .virt = 0x203c0000UL,
+ .phys = 0x203c0000UL,
+ .size = 0x80000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* OCRAM */
+ .virt = 0x20480000UL,
+ .phys = 0x20480000UL,
+ .size = 0xA0000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE
+ }, {
+ /* AIPS */
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* Flexible Serial Peripheral Interface */
+ .virt = 0x28000000UL,
+ .phys = 0x28000000UL,
+ .size = 0x8000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* DRAM1 */
+ .virt = PHYS_SDRAM,
+ .phys = PHYS_SDRAM,
+ .size = PHYS_SDRAM_SIZE,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE
+ }, {
+#ifdef PHYS_SDRAM_2_SIZE
+ /* DRAM2 */
+ .virt = 0x100000000UL,
+ .phys = 0x100000000UL,
+ .size = PHYS_SDRAM_2_SIZE,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE
+ }, {
+#endif
+ /* empty entry to split table entry 5 if needed when TEEs are used */
+ 0,
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = imx9_mem_map;
+
+static unsigned int imx9_find_dram_entry_in_mem_map(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx9_mem_map); i++)
+ if (imx9_mem_map[i].phys == CFG_SYS_SDRAM_BASE)
+ return i;
+
+ hang(); /* Entry not found, this must never happen. */
+}
+
+void enable_caches(void)
+{
+ /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
+ * If OPTEE does not run, still update the MMU table according to dram banks structure
+ * to set correct dram size from board_phys_sdram_size
+ */
+ int i = 0;
+ /*
+ * please make sure that entry initial value matches
+ * imx9_mem_map for DRAM1
+ */
+ int entry = imx9_find_dram_entry_in_mem_map();
+ u64 attrs = imx9_mem_map[entry].attrs;
+
+ while (i < CONFIG_NR_DRAM_BANKS &&
+ entry < ARRAY_SIZE(imx9_mem_map)) {
+ if (gd->bd->bi_dram[i].start == 0)
+ break;
+ imx9_mem_map[entry].phys = gd->bd->bi_dram[i].start;
+ imx9_mem_map[entry].virt = gd->bd->bi_dram[i].start;
+ imx9_mem_map[entry].size = gd->bd->bi_dram[i].size;
+ imx9_mem_map[entry].attrs = attrs;
+ debug("Added memory mapping (%d): %llx %llx\n", entry,
+ imx9_mem_map[entry].phys, imx9_mem_map[entry].size);
+ i++; entry++;
+ }
+
+ icache_enable();
+ dcache_enable();
+}
+
+__weak int board_phys_sdram_size(phys_size_t *size)
+{
+ phys_size_t start, end;
+ phys_size_t val;
+
+ if (!size)
+ return -EINVAL;
+
+ val = readl(REG_DDR_CS0_BNDS);
+ start = (val >> 16) << 24;
+ end = (val & 0xFFFF);
+ end = end ? end + 1 : 0;
+ end = end << 24;
+ *size = end - start;
+
+ val = readl(REG_DDR_CS1_BNDS);
+ start = (val >> 16) << 24;
+ end = (val & 0xFFFF);
+ end = end ? end + 1 : 0;
+ end = end << 24;
+ *size += end - start;
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ phys_size_t sdram_size;
+ int ret;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ /* rom_pointer[1] contains the size of TEE occupies */
+ if (rom_pointer[1] && PHYS_SDRAM < (phys_addr_t)rom_pointer[0])
+ gd->ram_size = sdram_size - rom_pointer[1];
+ else
+ gd->ram_size = sdram_size;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ int bank = 0;
+ int ret;
+ phys_size_t sdram_size;
+ phys_size_t sdram_b1_size, sdram_b2_size;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (ret)
+ return ret;
+
+ /* Bank 1 can't cross over 4GB space */
+ if (sdram_size > 0x80000000) {
+ sdram_b1_size = 0x100000000UL - PHYS_SDRAM;
+ sdram_b2_size = sdram_size - sdram_b1_size;
+ } else {
+ sdram_b1_size = sdram_size;
+ sdram_b2_size = 0;
+ }
+
+ gd->bd->bi_dram[bank].start = PHYS_SDRAM;
+ if (rom_pointer[1] && PHYS_SDRAM < (phys_addr_t)rom_pointer[0]) {
+ phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
+ phys_size_t optee_size = (size_t)rom_pointer[1];
+
+ gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
+ if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough\n");
+ return -1;
+ }
+
+ gd->bd->bi_dram[bank].start = optee_start + optee_size;
+ gd->bd->bi_dram[bank].size = PHYS_SDRAM +
+ sdram_b1_size - gd->bd->bi_dram[bank].start;
+ }
+ } else {
+ gd->bd->bi_dram[bank].size = sdram_b1_size;
+ }
+
+ if (sdram_b2_size) {
+ if (++bank >= CONFIG_NR_DRAM_BANKS) {
+ puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
+ return -1;
+ }
+ gd->bd->bi_dram[bank].start = 0x100000000UL;
+ gd->bd->bi_dram[bank].size = sdram_b2_size;
+ }
+
+ return 0;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+ int ret;
+ phys_size_t sdram_size;
+ phys_size_t sdram_b1_size;
+
+ ret = board_phys_sdram_size(&sdram_size);
+ if (!ret) {
+ /* Bank 1 can't cross over 4GB space */
+ if (sdram_size > 0x80000000)
+ sdram_b1_size = 0x100000000UL - PHYS_SDRAM;
+ else
+ sdram_b1_size = sdram_size;
+
+ if (rom_pointer[1]) {
+ /* We will relocate u-boot to Top of dram1. Tee position has three cases:
+ * 1. At the top of dram1, Then return the size removed optee size.
+ * 2. In the middle of dram1, return the size of dram1.
+ * 3. Not in the scope of dram1, return the size of dram1.
+ */
+ if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
+ return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
+ }
+
+ return sdram_b1_size;
+ } else {
+ return PHYS_SDRAM_SIZE;
+ }
+}
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ u32 val[2] = {};
+ int ret, num_of_macs;
+
+ ret = fuse_read(40, 5, &val[0]);
+ if (ret)
+ goto err;
+
+ ret = fuse_read(40, 6, &val[1]);
+ if (ret)
+ goto err;
+
+ num_of_macs = (val[1] >> 24) & 0xff;
+ if (num_of_macs <= (dev_id * 3)) {
+ printf("WARNING: no MAC address assigned for MAC%d\n", dev_id);
+ goto err;
+ }
+
+ mac[0] = val[0] & 0xff;
+ mac[1] = (val[0] >> 8) & 0xff;
+ mac[2] = (val[0] >> 16) & 0xff;
+ 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;
+
+ debug("%s: MAC%d: %pM\n", __func__, dev_id, mac);
+ return;
+err:
+ memset(mac, 0, 6);
+ printf("%s: fuse read err: %d\n", __func__, ret);
+}
+
+const char *get_imx_type(u32 imxtype)
+{
+ switch (imxtype) {
+ case MXC_CPU_IMX95:
+ return "95";/* iMX95 FULL */
+ default:
+ return "??";
+ }
+}
+
+int print_cpuinfo(void)
+{
+ u32 cpurev, max_freq;
+ int minc, maxc;
+
+ cpurev = get_cpu_rev();
+
+ printf("CPU: i.MX%s rev%u.%u",
+ get_imx_type((cpurev & 0x1FF000) >> 12),
+ (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0);
+
+ max_freq = get_cpu_speed_grade_hz();
+ if (!max_freq || max_freq == mxc_get_clock(MXC_ARM_CLK)) {
+ printf(" at %uMHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ } else {
+ printf(" %u MHz (running at %u MHz)\n", max_freq / 1000000,
+ mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ }
+
+ puts("CPU: ");
+ switch (get_cpu_temp_grade(&minc, &maxc)) {
+ case TEMP_AUTOMOTIVE:
+ puts("Automotive temperature grade ");
+ break;
+ case TEMP_INDUSTRIAL:
+ puts("Industrial temperature grade ");
+ break;
+ case TEMP_EXTCOMMERCIAL:
+ if (is_imx93())
+ puts("Extended Industrial temperature grade ");
+ else
+ puts("Extended Consumer temperature grade ");
+ break;
+ default:
+ puts("Consumer temperature grade ");
+ break;
+ }
+ printf("(%dC to %dC)", minc, maxc);
+
+ puts("\n");
+
+ return 0;
+}
+
+void build_info(void)
+{
+ u32 fw_version, sha1, res = 0, status;
+ int ret;
+
+ printf("\nBuildInfo:\n");
+
+ ret = ele_get_fw_status(&status, &res);
+ if (ret) {
+ printf(" - ELE firmware status failed %d, 0x%x\n", ret, res);
+ } else if ((status & 0xff) == 1) {
+ ret = ele_get_fw_version(&fw_version, &sha1, &res);
+ if (ret) {
+ printf(" - ELE firmware version failed %d, 0x%x\n", ret, res);
+ } else {
+ printf(" - ELE firmware version %u.%u.%u-%x",
+ (fw_version & (0x00ff0000)) >> 16,
+ (fw_version & (0x0000fff0)) >> 4,
+ (fw_version & (0x0000000f)), sha1);
+ ((fw_version & (0x80000000)) >> 31) == 1 ? puts("-dirty\n") : puts("\n");
+ }
+ } else {
+ printf(" - ELE firmware not included\n");
+ }
+ puts("\n");
+}
+
+int arch_misc_init(void)
+{
+ build_info();
+ return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_SPL_BUILD)
+int board_fix_fdt(void *fdt)
+{
+ return 0;
+}
+#endif
+
+int ft_system_setup(void *blob, struct bd_info *bd)
+{
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+ printf("UID: %08x%08x%08x%08x\n", __be32_to_cpu(gd->arch.uid[0]),
+ __be32_to_cpu(gd->arch.uid[1]), __be32_to_cpu(gd->arch.uid[2]),
+ __be32_to_cpu(gd->arch.uid[3]));
+
+ serialnr->low = __be32_to_cpu(gd->arch.uid[1]);
+ serialnr->high = __be32_to_cpu(gd->arch.uid[0]);
+}
+#endif
+
+static void gpio_reset(ulong gpio_base)
+{
+ writel(0, gpio_base + 0x10);
+ writel(0, gpio_base + 0x14);
+ writel(0, gpio_base + 0x18);
+ writel(0, gpio_base + 0x1c);
+}
+
+int arch_cpu_init(void)
+{
+ if (IS_ENABLED(CONFIG_SPL_BUILD)) {
+ disable_wdog((void __iomem *)WDG3_BASE_ADDR);
+ disable_wdog((void __iomem *)WDG4_BASE_ADDR);
+
+ gpio_reset(GPIO2_BASE_ADDR);
+ gpio_reset(GPIO3_BASE_ADDR);
+ gpio_reset(GPIO4_BASE_ADDR);
+ gpio_reset(GPIO5_BASE_ADDR);
+ }
+
+ return 0;
+}
+
+int imx9_probe_mu(void)
+{
+ struct udevice *dev;
+ int ret;
+ u32 res;
+ struct ele_get_info_data info;
+
+ ret = uclass_get_device_by_driver(UCLASS_SCMI_AGENT, DM_DRIVER_GET(scmi_mbox), &dev);
+ if (ret)
+ return ret;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ ret = devm_scmi_of_get_channel(dev);
+ if (ret)
+ return ret;
+
+ ret = uclass_get_device_by_name(UCLASS_PINCTRL, "protocol@19", &dev);
+ if (ret)
+ return ret;
+
+#if defined(CONFIG_SPL_BUILD)
+ ret = uclass_get_device_by_name(UCLASS_MISC, "mailbox@47530000", &dev);
+#else
+ ret = uclass_get_device_by_name(UCLASS_MISC, "mailbox@47550000", &dev);
+#endif
+ if (ret)
+ return ret;
+
+ if (gd->flags & GD_FLG_RELOC)
+ return 0;
+
+ ret = ele_get_info(&info, &res);
+ if (ret)
+ return ret;
+
+ set_cpu_info(&info);
+
+ return 0;
+}
+
+EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, imx9_probe_mu);
+EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_R, imx9_probe_mu);
+
+int timer_init(void)
+{
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD)) {
+ unsigned long freq = 24000000;
+
+ asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory");
+
+ /* Clear the compare frame interrupt */
+ unsigned long sctr_cmpcr_addr = SYSCNT_CMP_BASE_ADDR + 0x2c;
+ unsigned long sctr_cmpcr = readl(sctr_cmpcr_addr);
+
+ sctr_cmpcr &= ~0x1;
+ writel(sctr_cmpcr, sctr_cmpcr_addr);
+ }
+
+ return 0;
+}
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ enum boot_device dev = get_boot_device();
+ enum env_location env_loc = ENVL_UNKNOWN;
+
+ if (prio)
+ return env_loc;
+
+ switch (dev) {
+ case QSPI_BOOT:
+ env_loc = ENVL_SPI_FLASH;
+ break;
+ case SD1_BOOT:
+ case SD2_BOOT:
+ case SD3_BOOT:
+ case MMC1_BOOT:
+ case MMC2_BOOT:
+ case MMC3_BOOT:
+ env_loc = ENVL_MMC;
+ break;
+ default:
+ env_loc = ENVL_NOWHERE;
+ break;
+ }
+
+ return env_loc;
+}
+
+enum imx9_soc_voltage_mode soc_target_voltage_mode(void)
+{
+ u32 speed = get_cpu_speed_grade_hz();
+ enum imx9_soc_voltage_mode voltage = VOLT_OVER_DRIVE;
+
+ if (is_imx95()) {
+ if (speed == 2000000000)
+ voltage = VOLT_SUPER_OVER_DRIVE;
+ else if (speed == 1800000000)
+ voltage = VOLT_OVER_DRIVE;
+ else if (speed == 1400000000)
+ voltage = VOLT_NOMINAL_DRIVE;
+ else /* boot not support low drive mode according to AS */
+ printf("Unexpected A55 freq %u, default to OD\n", speed);
+ }
+
+ return voltage;
+}
+
+#if IS_ENABLED(CONFIG_SCMI_FIRMWARE)
+enum boot_device get_boot_device(void)
+{
+ volatile gd_t *pgd = gd;
+ int ret;
+ u16 boot_type;
+ u8 boot_instance;
+ enum boot_device boot_dev = 0;
+ rom_passover_t *rdata;
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+ rdata = &rom_passover_data;
+#else
+ rom_passover_t rom_data = {0};
+
+ if (pgd->reloc_off == 0)
+ rdata = &rom_data;
+ else
+ rdata = &rom_passover_data;
+#endif
+ if (rdata->tag == 0) {
+ ret = scmi_get_rom_data(rdata);
+ if (ret != 0) {
+ puts("SCMI: failure at rom_boot_info\n");
+ return -1;
+ }
+ }
+ boot_type = rdata->boot_dev_type;
+ boot_instance = rdata->boot_dev_inst;
+
+ set_gd(pgd);
+
+ switch (boot_type) {
+ case BT_DEV_TYPE_SD:
+ boot_dev = boot_instance + SD1_BOOT;
+ break;
+ case BT_DEV_TYPE_MMC:
+ boot_dev = boot_instance + MMC1_BOOT;
+ break;
+ case BT_DEV_TYPE_NAND:
+ boot_dev = NAND_BOOT;
+ break;
+ case BT_DEV_TYPE_FLEXSPINOR:
+ boot_dev = QSPI_BOOT;
+ break;
+ case BT_DEV_TYPE_USB:
+ boot_dev = boot_instance + USB_BOOT;
+ if (IS_ENABLED(CONFIG_IMX95))
+ boot_dev -= 3; //iMX95 usb instance start at 3
+ break;
+ default:
+ break;
+ }
+
+ return boot_dev;
+}
+#endif
diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h
index b30e536a357..c9717118bcb 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -110,7 +110,7 @@ struct sandbox_scmi_devices {
size_t regul_count;
};
-#ifdef CONFIG_SCMI_FIRMWARE
+#if IS_ENABLED(CONFIG_SCMI_FIRMWARE)
/**
* sandbox_scmi_channel_id - Get the channel id
* @dev: Reference to the SCMI protocol device
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (9 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 10/19] imx9: scmi: add i.MX95 SoC and clock related code Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 2:14 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 12/19] imx9: add i.MX95 Kconfig and Makefile Alice Guo (OSS)
` (8 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
From: Ye Li <ye.li@nxp.com>
When SPL loading image to secure region, for example, ATF and tee to
DDR secure region. Because the USDHC controller is non-secure master,
it can't access this region and will cause loading issue.
So use a trampoline buffer in non-secure region, then use CPU to copy the
image from trampoline buffer to destination secure region.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm/mach-imx/imx9/scmi/soc.c | 18 +++++++++++++++++
common/spl/Kconfig | 6 ++++++
common/spl/spl_imx_container.c | 41 +++++++++++++++++++++++++++++++++------
3 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c
index 388147118ca..738ef9a1a45 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -773,3 +773,21 @@ enum boot_device get_boot_device(void)
return boot_dev;
}
#endif
+
+bool arch_check_dst_in_secure(void *start, ulong size)
+{
+ ulong ns_end = CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE;
+#ifdef PHYS_SDRAM_2_SIZE
+ ns_end += PHYS_SDRAM_2_SIZE;
+#endif
+
+ if ((ulong)start < CFG_SYS_SDRAM_BASE || (ulong)start + size > ns_end)
+ return true;
+
+ return false;
+}
+
+void *arch_get_container_trampoline(void)
+{
+ return (void *)((ulong)CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE - SZ_16M);
+}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 97f542fcc8a..fbdc2f91010 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -362,6 +362,12 @@ config SPL_LOAD_IMX_CONTAINER
Support booting U-Boot from an i.MX8 container image. If you are not
using i.MX8, say 'n'.
+config SPL_IMX_CONTAINER_USE_TRAMPOLINE
+ bool
+ depends on SPL
+ help
+ Enable SPL load reader to load data to a trampoline buffer.
+
config IMX_CONTAINER_CFG
string "i.MX8 Container config file"
depends on SPL && SPL_LOAD_IMX_CONTAINER
diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c
index 2c31777fcd3..47fb2e65e34 100644
--- a/common/spl/spl_imx_container.c
+++ b/common/spl/spl_imx_container.c
@@ -14,6 +14,16 @@
#include <asm/mach-imx/ahab.h>
#endif
+__weak bool arch_check_dst_in_secure(void *start, ulong size)
+{
+ return false;
+}
+
+__weak void *arch_get_container_trampoline(void)
+{
+ return NULL;
+}
+
static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
struct spl_load_info *info,
struct container_hdr *container,
@@ -22,6 +32,7 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
{
struct boot_img_t *images;
ulong offset, overhead, size;
+ void *buf, *trampoline;
if (image_index > container->num_images) {
debug("Invalid image number\n");
@@ -42,12 +53,30 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
debug("%s: container: %p offset: %lu size: %lu\n", __func__,
container, offset, size);
- if (info->read(info, offset, size,
- map_sysmem(images[image_index].dst - overhead,
- images[image_index].size)) <
- images[image_index].size) {
- printf("%s wrong\n", __func__);
- return NULL;
+
+ buf = map_sysmem(images[image_index].dst - overhead, images[image_index].size);
+ if (IS_ENABLED(CONFIG_SPL_IMX_CONTAINER_USE_TRAMPOLINE) &&
+ arch_check_dst_in_secure(buf, size)) {
+ trampoline = arch_get_container_trampoline();
+ if (!trampoline) {
+ printf("%s: trampoline size is zero\n", __func__);
+ return NULL;
+ }
+
+ if (info->read(info, offset, size, trampoline) < images[image_index].size) {
+ printf("%s wrong\n", __func__);
+ return NULL;
+ }
+
+ memcpy(buf, trampoline, images[image_index].size);
+ } else {
+ if (info->read(info, offset, size,
+ map_sysmem(images[image_index].dst - overhead,
+ images[image_index].size)) <
+ images[image_index].size) {
+ printf("%s wrong\n", __func__);
+ return NULL;
+ }
}
#ifdef CONFIG_AHAB_BOOT
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 12/19] imx9: add i.MX95 Kconfig and Makefile
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (10 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95 Alice Guo (OSS)
` (7 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
From: Ye Li <ye.li@nxp.com>
This patch adds i.MX95 Kconfig and Makefile. i.MX95 uses SCMI.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm/mach-imx/imx9/Kconfig | 8 ++++++++
arch/arm/mach-imx/imx9/Makefile | 9 +++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig
index 49220c0955e..ef364ca1a2f 100644
--- a/arch/arm/mach-imx/imx9/Kconfig
+++ b/arch/arm/mach-imx/imx9/Kconfig
@@ -21,6 +21,14 @@ config IMX91
select IMX9
select ARMV8_SPL_EXCEPTION_VECTORS
+config IMX95
+ bool
+ select ARMV8_SPL_EXCEPTION_VECTORS
+ select IMX9
+ select DM_MAILBOX
+ select SCMI_FIRMWARE
+ select SCMI_TRANSPORT_SMT_INTR
+ select SPL_IMX_CONTAINER_USE_TRAMPOLINE
config SYS_SOC
default "imx9"
diff --git a/arch/arm/mach-imx/imx9/Makefile b/arch/arm/mach-imx/imx9/Makefile
index 45a9105a75a..53cc97c6b47 100644
--- a/arch/arm/mach-imx/imx9/Makefile
+++ b/arch/arm/mach-imx/imx9/Makefile
@@ -3,8 +3,13 @@
# Copyright 2022 NXP
obj-y += lowlevel_init.o
+
+ifeq ($(CONFIG_SCMI_FIRMWARE),y)
+obj-y += scmi/
+else
obj-y += soc.o clock.o clock_root.o trdc.o
+endif
-#ifndef CONFIG_XPL_BUILD
+ifneq ($(CONFIG_SPL_BUILD),y)
obj-y += imx_bootaux.o
-#endif
+endif
\ No newline at end of file
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (11 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 12/19] imx9: add i.MX95 Kconfig and Makefile Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 2:15 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 14/19] binman: add a new entry type for packing DDR PHY firmware images Alice Guo (OSS)
` (6 subsequent siblings)
19 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
i.MX95 only supports low power boot, which means A55 is kicked by M33.
There is no ROM runs on A55 in such case so that deselect IMX8_ROMAPI
for i.MX95.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
arch/arm/mach-imx/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 134e42028c3..f38f3b2d338 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -180,7 +180,7 @@ config DDRMC_VF610_CALIBRATION
config IMX8_ROMAPI
def_bool y
- depends on IMX8MN || IMX8MP || IMX8ULP || IMX9
+ depends on IMX8MN || IMX8MP || IMX8ULP || IMX93 || IMX91
config SPL_IMX_ROMAPI_LOADADDR
hex "Default load address to load image through ROM API"
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 14/19] binman: add a new entry type for packing DDR PHY firmware images
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (12 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95 Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 15/19] tools: imx8image: add i.MX95 support Alice Guo (OSS)
` (5 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
i.MX95 needs to combine DDR PHY firmware images and their byte counts
together, so add a new entry type nxp-header-ddrfw for this requirement.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
tools/binman/entries.rst | 10 ++++++++++
| 29 +++++++++++++++++++++++++++++
tools/binman/ftest.py | 11 +++++++++++
tools/binman/test/346_nxp_ddrfw_imx95.dts | 24 ++++++++++++++++++++++++
4 files changed, 74 insertions(+)
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 780e9817fb6..4f05aa0a323 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1663,6 +1663,16 @@ Properties / Entry arguments:
+.. _etype_nxp_header_ddrfw:
+
+Entry: nxp-header-ddrfw: add a header to DDR PHY firmware images
+----------------------------------------------------------------
+
+This entry is used to combine DDR PHY firmware images and their byte counts
+together. See imx95_evk.rst for how to get DDR PHY Firmware Images.
+
+
+
.. _etype_opensbi:
Entry: opensbi: RISC-V OpenSBI fw_dynamic blob
--git a/tools/binman/etype/nxp_header_ddrfw.py b/tools/binman/etype/nxp_header_ddrfw.py
new file mode 100644
index 00000000000..655699e6ffa
--- /dev/null
+++ b/tools/binman/etype/nxp_header_ddrfw.py
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2025 NXP
+
+from binman.etype.section import Entry_section
+
+class Entry_nxp_header_ddrfw(Entry_section):
+ """Add a header to DDR PHY firmware images
+
+ This entry is used for i.MX95 to combine DDR PHY firmware images and their
+ byte counts together.
+
+ See imx95_evk.rst for how to get DDR PHY Firmware Images.
+ """
+
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+
+ def BuildSectionData(self, required):
+ section_data = bytearray()
+ header_data = bytearray()
+
+ for entry in self._entries.values():
+ entry_data = entry.GetData(required)
+
+ section_data += entry_data
+ header_data += entry.contents_size.to_bytes(4, 'little')
+
+ return header_data + section_data
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 1a92a99b511..301e4927886 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -104,6 +104,8 @@ PRE_LOAD_VERSION = 0x11223344.to_bytes(4, 'big')
PRE_LOAD_HDR_SIZE = 0x00001000.to_bytes(4, 'big')
TI_BOARD_CONFIG_DATA = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
TI_UNSECURE_DATA = b'unsecuredata'
+IMX_LPDDR_IMEM_DATA = b'qwertyuiop1234567890'
+IMX_LPDDR_DMEM_DATA = b'asdfghjklzxcvbnm'
# Subdirectory of the input dir to use to put test FDTs
TEST_FDT_SUBDIR = 'fdts'
@@ -202,6 +204,8 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA)
TestFunctional._MakeInputFile('fsp_s.bin', FSP_S_DATA)
TestFunctional._MakeInputFile('fsp_t.bin', FSP_T_DATA)
+ TestFunctional._MakeInputFile('lpddr5_imem.bin', IMX_LPDDR_IMEM_DATA)
+ TestFunctional._MakeInputFile('lpddr5_dmem.bin', IMX_LPDDR_DMEM_DATA)
cls._elf_testdir = os.path.join(cls._indir, 'elftest')
elf_test.BuildElfTestFiles(cls._elf_testdir)
@@ -7845,6 +7849,13 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
"""Test that binman can produce an iMX8 image"""
self._DoTestFile('339_nxp_imx8.dts')
+ def testNxpHeaderDdrfw(self):
+ """Test that binman can add a header to DDR PHY firmware images"""
+ data = self._DoReadFile('346_nxp_ddrfw_imx95.dts')
+ self.assertEqual(len(IMX_LPDDR_IMEM_DATA).to_bytes(4, 'little') +
+ len(IMX_LPDDR_DMEM_DATA).to_bytes(4, 'little') +
+ IMX_LPDDR_IMEM_DATA + IMX_LPDDR_DMEM_DATA, data)
+
def testFitSignSimple(self):
"""Test that image with FIT and signature nodes can be signed"""
if not elf.ELF_TOOLS:
diff --git a/tools/binman/test/346_nxp_ddrfw_imx95.dts b/tools/binman/test/346_nxp_ddrfw_imx95.dts
new file mode 100644
index 00000000000..889f6f29860
--- /dev/null
+++ b/tools/binman/test/346_nxp_ddrfw_imx95.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ imx-lpddr {
+ type = "nxp-header-ddrfw";
+
+ imx-lpddr-imem {
+ filename = "lpddr5_imem.bin";
+ type = "blob-ext";
+ };
+
+ imx-lpddr-dmem {
+ filename = "lpddr5_dmem.bin";
+ type = "blob-ext";
+ };
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 15/19] tools: imx8image: add i.MX95 support
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (13 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 14/19] binman: add a new entry type for packing DDR PHY firmware images Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 16/19] imx: container: add V2X container support for i.MX95 Alice Guo (OSS)
` (4 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
i.MX95 uses binman to invoke mkimage to create image container. 2 image
containers are needed currently. The first one is composed of
ahab-container.img, LPDDR firmware images, OEI images, System Manager
image and u-boot-spl.bin. The second one is consisted of ARM Trusted
firmware and u-boot.bin.
Because DDR OEI image and LPDDR firmware images have to be packaged
together and named as m33-oei-ddrfw.bin by binman, so imx9_image.sh does
not check if m33-oei-ddrfw.bin exists.
When using "make imx95_19x19_evk_defconfig; make", imx9_image.sh will
delete the line for u-boot.bin in container.cfg. In fact, binman is
always called after the u-boot.bin is built, so imx9_image.sh does not
check if u-boot.bin exists.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
include/imx8image.h | 19 +++++--
tools/imx8image.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++------
tools/imx9_image.sh | 8 +++
3 files changed, 155 insertions(+), 19 deletions(-)
diff --git a/include/imx8image.h b/include/imx8image.h
index 6b95e93fb50..e0d25c5b6c9 100644
--- a/include/imx8image.h
+++ b/include/imx8image.h
@@ -157,7 +157,9 @@ enum imx8image_cmd {
CMD_SOC_TYPE,
CMD_CONTAINER,
CMD_IMAGE,
- CMD_DATA
+ CMD_DATA,
+ CMD_DUMMY_V2X,
+ CMD_HOLD,
};
enum imx8image_core_type {
@@ -169,7 +171,9 @@ enum imx8image_core_type {
CFG_A35,
CFG_A55,
CFG_A53,
- CFG_A72
+ CFG_A72,
+ CFG_M33,
+ CFG_OEI,
};
enum imx8image_fld_types {
@@ -208,7 +212,10 @@ typedef enum option_type {
FILEOFF,
MSG_BLOCK,
SENTINEL,
- UPOWER
+ UPOWER,
+ OEI,
+ DUMMY_V2X,
+ HOLD,
} option_type_t;
typedef struct {
@@ -227,12 +234,16 @@ typedef struct {
#define CORE_CA35 4
#define CORE_CA72 5
#define CORE_SECO 6
+#define CORE_M33 7
#define CORE_ULP_CM33 0x1
#define CORE_ULP_CA35 0x2
#define CORE_ULP_UPOWER 0x4
#define CORE_ULP_SENTINEL 0x6
+#define CORE_IMX95_M33P 0
+#define CORE_IMX95_A55C0 2
+
#define SC_R_OTP 357U
#define SC_R_DEBUG 354U
#define SC_R_ROM_0 236U
@@ -246,10 +257,12 @@ typedef struct {
#define IMG_TYPE_EXEC 0x03 /* Executable image type */
#define IMG_TYPE_DATA 0x04 /* Data image type */
#define IMG_TYPE_DCD_DDR 0x05 /* DCD/DDR image type */
+#define IMG_TYPE_OEI 0x05 /* Optional Executable image type */
#define IMG_TYPE_SECO 0x06 /* SECO image type */
#define IMG_TYPE_SENTINEL 0x06 /* SENTINEL image type */
#define IMG_TYPE_PROV 0x07 /* Provisioning image type */
#define IMG_TYPE_DEK 0x08 /* DEK validation type */
+#define IMG_TYPE_V2X_DUMMY 0x0E /* V2X Dummy image */
#define IMG_TYPE_SHIFT 0
#define IMG_TYPE_MASK 0x1f
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 0135b190951..a333ded46e2 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -7,6 +7,7 @@
#include "imx8image.h"
#include <image.h>
+#include <linux/sizes.h>
static int p_idx;
static int sector_size;
@@ -54,7 +55,9 @@ static table_entry_t imx8image_cmds[] = {
{CMD_CONTAINER, "CONTAINER", "new container", },
{CMD_IMAGE, "IMAGE", "new image", },
{CMD_DATA, "DATA", "new data", },
- {-1, "", "", },
+ {CMD_DUMMY_V2X, "DUMMY_V2X", "v2x", },
+ {CMD_HOLD, "HOLD", "hold", },
+ {-1, "", "", }
};
static table_entry_t imx8image_core_entries[] = {
@@ -66,7 +69,9 @@ static table_entry_t imx8image_core_entries[] = {
{CFG_A55, "A55", "A55 core", },
{CFG_A53, "A53", "A53 core", },
{CFG_A72, "A72", "A72 core", },
- {-1, "", "", },
+ {CFG_OEI, "OEI", "OEI", },
+ {CFG_M33, "M33", "M33 core", },
+ {-1, "", "", }
};
static table_entry_t imx8image_sector_size[] = {
@@ -144,6 +149,14 @@ static void parse_cfg_cmd(image_t *param_stack, int32_t cmd, char *token,
exit(EXIT_FAILURE);
}
break;
+ case CMD_DUMMY_V2X:
+ param_stack[p_idx].option = DUMMY_V2X;
+ param_stack[p_idx++].entry = (uint32_t)strtoll(token, NULL, 0);
+ break;
+ case CMD_HOLD:
+ param_stack[p_idx].option = HOLD;
+ param_stack[p_idx].entry = (uint32_t)strtoll(token, NULL, 0);
+ param_stack[p_idx++].filename = NULL;
default:
break;
}
@@ -221,6 +234,16 @@ static void parse_cfg_fld(image_t *param_stack, int32_t *cmd, char *token,
(*cmd == CMD_DATA) ? DATA : AP;
param_stack[p_idx].filename = token;
break;
+ case CFG_OEI:
+ param_stack[p_idx].option = OEI;
+ param_stack[p_idx].filename = token;
+ param_stack[p_idx].ext = CORE_CM4_0;
+ break;
+ case CFG_M33:
+ param_stack[p_idx].option = M40;
+ param_stack[p_idx].ext = 0;
+ param_stack[p_idx].filename = token;
+ break;
}
break;
case CFG_LOAD_ADDR:
@@ -238,9 +261,15 @@ static void parse_cfg_fld(image_t *param_stack, int32_t *cmd, char *token,
case CFG_A53:
case CFG_A55:
case CFG_A72:
+ case CFG_M33:
param_stack[p_idx++].entry =
(uint32_t)strtoll(token, NULL, 0);
break;
+ case CFG_OEI:
+ param_stack[p_idx].dst = (uint32_t)strtoll(token, NULL, 0);
+ param_stack[p_idx].entry = param_stack[p_idx].dst + 1;
+ p_idx++;
+ break;
}
default:
break;
@@ -549,6 +578,7 @@ static void set_image_array_entry(flash_header_v3_t *container,
char *tmp_filename, bool dcd_skip)
{
uint64_t entry = image_stack->entry;
+ uint64_t dst = image_stack->dst;
uint64_t core = image_stack->ext;
uint32_t meta;
char *tmp_name = "";
@@ -558,7 +588,9 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->offset = offset; /* Is re-adjusted later */
img->size = size;
- set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT);
+ if (type != DUMMY_V2X) {
+ set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT);
+ }
switch (type) {
case SECO:
@@ -580,6 +612,27 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->dst = 0xe4000000; /* S400 IRAM base */
img->entry = 0xe4000000;
break;
+ case OEI:
+ if (soc != IMX9) {
+ fprintf(stderr, "Error: invalid core id: %" PRIi64 "\n", core);
+ exit(EXIT_FAILURE);
+ }
+
+ img->hab_flags |= IMG_TYPE_OEI;
+ if (core == CORE_CM4_0) {
+ img->hab_flags |= CORE_ULP_CM33 << BOOT_IMG_FLAGS_CORE_SHIFT;
+ meta = CORE_IMX95_M33P;
+
+ } else {
+ img->hab_flags |= CORE_ULP_CA35 << BOOT_IMG_FLAGS_CORE_SHIFT;
+ meta = CORE_IMX95_A55C0;
+ }
+ tmp_name = "OEI";
+ img->dst = (dst ? dst : entry);
+ img->entry = entry;
+ img->meta = meta;
+ custom_partition = 0;
+ break;
case AP:
if (soc == QX && core == CORE_CA35) {
meta = IMAGE_A35_DEFAULT_META(custom_partition);
@@ -587,8 +640,10 @@ static void set_image_array_entry(flash_header_v3_t *container,
meta = IMAGE_A53_DEFAULT_META(custom_partition);
} else if (soc == QM && core == CORE_CA72) {
meta = IMAGE_A72_DEFAULT_META(custom_partition);
- } else if (((soc == ULP) || (soc == IMX9)) && core == CORE_CA35) {
+ } else if ((soc == ULP) && core == CORE_CA35) {
meta = 0;
+ } else if ((soc == IMX9) && core == CORE_CA35) {
+ meta = CORE_IMX95_A55C0;
} else {
fprintf(stderr,
"Error: invalid AP core id: %" PRIu64 "\n",
@@ -687,6 +742,15 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->entry = 0x28300200;
}
break;
+ case DUMMY_V2X:
+ img->hab_flags |= IMG_TYPE_V2X_DUMMY;
+ img->hab_flags |= CORE_SC << BOOT_IMG_FLAGS_CORE_SHIFT;
+ tmp_name = "V2X Dummy";
+ set_image_hash(img, "/dev/null", IMAGE_HASH_ALGO_DEFAULT);
+ img->dst = entry;
+ img->entry = entry;
+ img->size = 0; /* dummy image has no size */
+ break;
default:
fprintf(stderr, "unrecognized image type (%d)\n", type);
exit(EXIT_FAILURE);
@@ -709,15 +773,26 @@ void set_container(flash_header_v3_t *container, uint16_t sw_version,
fprintf(stdout, "container flags: 0x%x\n", container->flags);
}
-static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
+static int get_container_image_start_pos(image_t *image_stack, uint32_t align, uint32_t *v2x)
{
image_t *img_sp = image_stack;
/*8K total container header*/
int file_off = CONTAINER_IMAGE_ARRAY_START_OFFSET;
FILE *fd = NULL;
- flash_header_v3_t header;
+ flash_header_v3_t *header;
+ flash_header_v3_t *header2;
+ void *p;
int ret;
+ p = calloc(1, SZ_4K);
+ if (!p) {
+ fprintf(stderr, "Fail to alloc 4K memory\n");
+ exit(EXIT_FAILURE);
+ }
+
+ header = p;
+ header2 = p + FIRST_CONTAINER_HEADER_LENGTH;
+
while (img_sp->option != NO_IMG) {
if (img_sp->option == APPEND) {
fd = fopen(img_sp->filename, "r");
@@ -726,7 +801,7 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
exit(EXIT_FAILURE);
}
- ret = fread(&header, sizeof(header), 1, fd);
+ ret = fread(header, SZ_4K, 1, fd);
if (ret != 1) {
printf("Failure Read header %d\n", ret);
exit(EXIT_FAILURE);
@@ -734,19 +809,27 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
fclose(fd);
- if (header.tag != IVT_HEADER_TAG_B0) {
- fprintf(stderr, "header tag mismatched file %s\n", img_sp->filename);
+ if (header->tag != IVT_HEADER_TAG_B0) {
+ fprintf(stderr, "header tag mismatched \n");
exit(EXIT_FAILURE);
} else {
- file_off +=
- header.img[header.num_images - 1].size;
- file_off = ALIGN(file_off, align);
+ if (header2->tag != IVT_HEADER_TAG_B0) {
+ file_off += header->img[header->num_images - 1].size;
+ file_off = ALIGN(file_off, align);
+ } else {
+ file_off = header2->img[header2->num_images - 1].offset + FIRST_CONTAINER_HEADER_LENGTH;
+ file_off += header2->img[header2->num_images - 1].size;
+ file_off = ALIGN(file_off, align);
+ fprintf(stderr, "Has 2nd container %x\n", file_off);
+ *v2x = true;
+ }
}
}
img_sp++;
}
+ free(p);
return file_off;
}
@@ -838,6 +921,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
char *tmp_filename = NULL;
uint32_t size = 0;
uint32_t file_padding = 0;
+ uint32_t v2x = false;
int ret;
int container = -1;
@@ -861,7 +945,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
set_imx_hdr_v3(&imx_header, 0);
set_imx_hdr_v3(&imx_header, 1);
- file_off = get_container_image_start_pos(image_stack, sector_size);
+ file_off = get_container_image_start_pos(image_stack, sector_size, &v2x);
fprintf(stdout, "container image offset (aligned):%x\n", file_off);
/* step through image stack and generate the header */
@@ -870,6 +954,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
/* stop once we reach null terminator */
while (img_sp->option != NO_IMG) {
switch (img_sp->option) {
+ case OEI:
case AP:
case M40:
case M41:
@@ -892,6 +977,30 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
file_off += ALIGN(sbuf.st_size, sector_size);
break;
+ case DUMMY_V2X:
+ if (container < 0) {
+ fprintf(stderr, "No container found\n");
+ exit(EXIT_FAILURE);
+ }
+ tmp_filename = "dummy";
+ set_image_array_entry(&imx_header.fhdr[container],
+ soc,
+ img_sp,
+ file_off,
+ 0,
+ tmp_filename,
+ dcd_skip);
+ img_sp->src = file_off;
+ break;
+
+ case HOLD:
+ if (container < 0) {
+ fprintf(stderr, "No container found\n");
+ exit(EXIT_FAILURE);
+ }
+ file_off += ALIGN(img_sp->entry, sector_size);
+ break;
+
case SECO:
case SENTINEL:
if (container < 0) {
@@ -963,11 +1072,15 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
do {
if (img_sp->option == APPEND) {
copy_file(ofd, img_sp->filename, 0, 0);
- file_padding += FIRST_CONTAINER_HEADER_LENGTH;
+ if (v2x)
+ file_padding += FIRST_CONTAINER_HEADER_LENGTH * 2;
+ else
+ file_padding += FIRST_CONTAINER_HEADER_LENGTH;
}
img_sp++;
} while (img_sp->option != NO_IMG);
+ fprintf(stderr, "%s: %x %d\n", __func__, file_padding, v2x);
/* Add padding or skip appended container */
ret = lseek(ofd, file_padding, SEEK_SET);
if (ret < 0) {
@@ -980,6 +1093,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
/* Note: Image offset are not contained in the image */
tmp = flatten_container_header(&imx_header, container + 1,
&size, file_padding);
+ fprintf(stderr, "error writing image hdr %x\n", size);
/* Write image header */
if (write(ofd, tmp, size) != size) {
fprintf(stderr, "error writing image hdr\n");
@@ -1000,7 +1114,8 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
img_sp->option == AP || img_sp->option == DATA ||
img_sp->option == SCD || img_sp->option == SCFW ||
img_sp->option == SECO || img_sp->option == MSG_BLOCK ||
- img_sp->option == UPOWER || img_sp->option == SENTINEL) {
+ img_sp->option == UPOWER || img_sp->option == SENTINEL ||
+ img_sp->option == OEI) {
copy_file_aligned(ofd, img_sp->filename, img_sp->src,
sector_size);
}
@@ -1031,7 +1146,7 @@ int imx8image_copy_image(int outfd, struct image_tool_params *mparams)
fprintf(stdout, "CONTAINER SW VERSION:\t0x%04x\n", sw_version);
build_container(soc, sector_size, emmc_fastboot,
- img_sp, dcd_skip, fuse_version, sw_version, outfd);
+ img_sp, false, fuse_version, sw_version, outfd);
return 0;
}
diff --git a/tools/imx9_image.sh b/tools/imx9_image.sh
index ca78a57a19a..6523d1a0ad1 100755
--- a/tools/imx9_image.sh
+++ b/tools/imx9_image.sh
@@ -18,6 +18,14 @@ for f in $blobs; do
continue
fi
+ if [ $f = "m33-oei-ddrfw.bin" ]; then
+ continue
+ fi
+
+ if [ $f = "u-boot.bin" ]; then
+ continue
+ fi
+
if [ ! -f $tmp ]; then
echo "WARNING '$tmp' not found, resulting binary may be not-functional" >&2
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 16/19] imx: container: add V2X container support for i.MX95
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (14 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 15/19] tools: imx8image: add i.MX95 support Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 17/19] doc: imx: add document for i.MX95 Image Container Format Alice Guo (OSS)
` (3 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
From: Ye Li <ye.li@nxp.com>
This patch adds V2X container support for i.MX95. Since V2X container
may not be included in ahab-container.img of i.MX95, check if V2X
container exists in order to get the correct image end.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm/mach-imx/image-container.c | 119 ++++++++++++++++++++++++++++--------
1 file changed, 95 insertions(+), 24 deletions(-)
diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c
index 2afe9d38a06..f84e23f4b2a 100644
--- a/arch/arm/mach-imx/image-container.c
+++ b/arch/arm/mach-imx/image-container.c
@@ -41,6 +41,52 @@
#define FUSE_IMG_SET_OFF_WORD 720
#endif
+#define MAX_V2X_CTNR_IMG_NUM (4)
+#define MIN_V2X_CTNR_IMG_NUM (2)
+
+#define IMG_FLAGS_IMG_TYPE_SHIFT (0u)
+#define IMG_FLAGS_IMG_TYPE_MASK (0xfU)
+#define IMG_FLAGS_IMG_TYPE(x) (((x) & IMG_FLAGS_IMG_TYPE_MASK) >> \
+ IMG_FLAGS_IMG_TYPE_SHIFT)
+
+#define IMG_FLAGS_CORE_ID_SHIFT (4u)
+#define IMG_FLAGS_CORE_ID_MASK (0xf0U)
+#define IMG_FLAGS_CORE_ID(x) (((x) & IMG_FLAGS_CORE_ID_MASK) >> \
+ IMG_FLAGS_CORE_ID_SHIFT)
+
+#define IMG_TYPE_V2X_PRI_FW (0x0Bu) /* Primary V2X FW */
+#define IMG_TYPE_V2X_SND_FW (0x0Cu) /* Secondary V2X FW */
+
+#define CORE_V2X_PRI 9
+#define CORE_V2X_SND 10
+
+static bool is_v2x_fw_container(ulong addr)
+{
+ struct container_hdr *phdr;
+ struct boot_img_t *img_entry;
+
+ phdr = (struct container_hdr *)addr;
+ if (phdr->tag != 0x87 || phdr->version != 0x0) {
+ debug("Wrong container header\n");
+ return false;
+ }
+
+ if (phdr->num_images >= MIN_V2X_CTNR_IMG_NUM && phdr->num_images <= MAX_V2X_CTNR_IMG_NUM) {
+ img_entry = (struct boot_img_t *)(addr + sizeof(struct container_hdr));
+
+ if (IMG_FLAGS_IMG_TYPE(img_entry->hab_flags) == IMG_TYPE_V2X_PRI_FW &&
+ IMG_FLAGS_CORE_ID(img_entry->hab_flags) == CORE_V2X_PRI) {
+ img_entry++;
+
+ if (IMG_FLAGS_IMG_TYPE(img_entry->hab_flags) == IMG_TYPE_V2X_SND_FW &&
+ IMG_FLAGS_CORE_ID(img_entry->hab_flags) == CORE_V2X_SND)
+ return true;
+ }
+ }
+
+ return false;
+}
+
int get_container_size(ulong addr, u16 *header_length)
{
struct container_hdr *phdr;
@@ -83,7 +129,7 @@ int get_container_size(ulong addr, u16 *header_length)
return max_offset;
}
-static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, u16 *header_length)
+static int get_dev_container_size(void *dev, int dev_type, unsigned long offset, u16 *header_length, bool *v2x_cntr)
{
u8 *buf = malloc(CONTAINER_HDR_ALIGNMENT);
int ret = 0;
@@ -150,6 +196,9 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset,
ret = get_container_size((ulong)buf, header_length);
+ if (v2x_cntr)
+ *v2x_cntr = is_v2x_fw_container((ulong)buf);
+
free(buf);
return ret;
@@ -231,45 +280,67 @@ static unsigned long get_boot_device_offset(void *dev, int dev_type)
return offset;
}
-static int get_imageset_end(void *dev, int dev_type)
+static ulong get_imageset_end(void *dev, int dev_type)
{
- unsigned long offset1 = 0, offset2 = 0;
- int value_container[2];
+ unsigned long offset[3] = {};
+ int value_container[3] = {};
u16 hdr_length;
+ bool v2x_fw = false;
- offset1 = get_boot_device_offset(dev, dev_type);
- offset2 = CONTAINER_HDR_ALIGNMENT + offset1;
+ offset[0] = get_boot_device_offset(dev, dev_type);
- value_container[0] = get_dev_container_size(dev, dev_type, offset1, &hdr_length);
+ value_container[0] = get_dev_container_size(dev, dev_type, offset[0], &hdr_length, NULL);
if (value_container[0] < 0) {
printf("Parse seco container failed %d\n", value_container[0]);
- return value_container[0];
+ return 0;
}
debug("seco container size 0x%x\n", value_container[0]);
- value_container[1] = get_dev_container_size(dev, dev_type, offset2, &hdr_length);
- if (value_container[1] < 0) {
- debug("Parse scu container failed %d, only seco container\n",
- value_container[1]);
- /* return seco container total size */
- return value_container[0] + offset1;
+ if (is_imx95()) {
+ 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);
+ if (value_container[1] < 0) {
+ printf("Parse v2x container failed %d\n", value_container[1]);
+ return value_container[0] + offset[0]; /* return seco container total size */
+ }
+
+ if (v2x_fw) {
+ debug("v2x container size 0x%x\n", value_container[1]);
+ offset[2] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[1];
+ } else {
+ printf("no v2x container included\n");
+ offset[2] = offset[1];
+ }
+ } else {
+ /* Skip offset[1] */
+ offset[2] = ALIGN(hdr_length, CONTAINER_HDR_ALIGNMENT) + offset[0];
+ }
+
+ 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())
+ return value_container[1] + offset[1]; /* return seco + v2x container total size */
+ else
+ return value_container[0] + offset[0]; /* return seco container total size */
}
- debug("scu container size 0x%x\n", value_container[1]);
+ debug("scu container size 0x%x\n", value_container[2]);
- return value_container[1] + offset2;
+ return value_container[2] + offset[2];
}
#ifdef CONFIG_SPL_SPI_LOAD
unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)
{
- int end;
+ ulong end;
end = get_imageset_end(flash, QSPI_DEV);
end = ROUND(end, SZ_1K);
- printf("Load image from QSPI 0x%x\n", end);
+ printf("Load image from QSPI 0x%lx\n", end);
return end;
}
@@ -279,12 +350,12 @@ unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)
unsigned long arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
unsigned long raw_sect)
{
- int end;
+ ulong end;
end = get_imageset_end(mmc, MMC_DEV);
end = ROUND(end, SZ_1K);
- printf("Load image from MMC/SD 0x%x\n", end);
+ printf("Load image from MMC/SD 0x%lx\n", end);
return end / mmc->read_bl_len;
}
@@ -312,12 +383,12 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc)
#ifdef CONFIG_SPL_NAND_SUPPORT
uint32_t spl_nand_get_uboot_raw_page(void)
{
- int end;
+ ulong end;
end = get_imageset_end((void *)NULL, NAND_DEV);
end = ROUND(end, SZ_16K);
- printf("Load image from NAND 0x%x\n", end);
+ printf("Load image from NAND 0x%lx\n", end);
return end;
}
@@ -326,7 +397,7 @@ uint32_t spl_nand_get_uboot_raw_page(void)
#ifdef CONFIG_SPL_NOR_SUPPORT
unsigned long spl_nor_get_uboot_base(void)
{
- int end;
+ ulong end;
/* Calculate the image set end,
* if it is less than CFG_SYS_UBOOT_BASE(0x8281000),
@@ -339,7 +410,7 @@ unsigned long spl_nor_get_uboot_base(void)
else
end = ROUND(end, SZ_1K);
- printf("Load image from NOR 0x%x\n", end);
+ printf("Load image from NOR 0x%lx\n", end);
return end;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 17/19] doc: imx: add document for i.MX95 Image Container Format
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (15 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 16/19] imx: container: add V2X container support for i.MX95 Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 18/19] imx95_evk: add i.MX95 19x19 EVK board basic support Alice Guo (OSS)
` (2 subsequent siblings)
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
This patch add a document for i.MX95 Image Container Format.
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
doc/imx/imx95_container.txt | 136 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
diff --git a/doc/imx/imx95_container.txt b/doc/imx/imx95_container.txt
new file mode 100644
index 00000000000..2ad57345069
--- /dev/null
+++ b/doc/imx/imx95_container.txt
@@ -0,0 +1,136 @@
+i.MX95 Image Container Format
+-----------------------------
+
+The image container set consists of some image containers, and image container
+contains boot images. Each image container has its own container header which is
+defined in Figure 1. All container headers are placed together in a continuous
+8KB space at the beginning of the image container set - image container set header.
+
+ROM code addresses image containers in image container set one by one based on
+their headers’ order in image container set header.
+
+If ELE container exists, its container header must be the 1st one in the image
+container set header.
+
+If V2X container exists, its container header must be the 2nd one in the image
+container set header. V2X must be combined with ELE container.
+
+The information of boot images are recorded in image container header. System
+ROM code needs to retrieve the information from the image container header, like
+the offset on boot source, the target address in RAM, the length of boot image.
+The order of ROM code handling these boot images is based on the order of each
+boot image information present in image container header.
+
+Figure 1:
+------------------- +--------------+--------------+--------------+--------------+
+ ^ |Tag |Length |Length |Version |
+ | +--------------+--------------+--------------+--------------+
+ | | Flags |
+ | +--------------+--------------+--------------+--------------+
+ | |# of Images |Fuse version |SW version |
+Image | +--------------+--------------+--------------+--------------+
+Conatiner | |Reserved |Signature Block Offset |
+Header | ------- +--------------+--------------+--------------+--------------+
+ | ^ |Image0: Offset, Size, LoadAddr, EntryPoint, Flags, Hash, IV|
+ | | +--------------+--------------+--------------+--------------+
+ | Image | |Image1: Offset, Size, LoadAddr, EntryPoint, Flags, Hash, IV|
+ | Array | +--------------+--------------+--------------+--------------+
+ | | | ... |
+ | | +--------------+--------------+--------------+--------------+
+ v v |ImageN: Offset, Size, LoadAddr, EntryPoint, Flags, Hash, IV|
+------------------- +--------------+--------------+--------------+--------------+
+ | ... |
+ ----------- +--------------+--------------+--------------+--------------+ <-- SignOffset
+ ^ |Tag |Length |Length |Version |
+ | +--------------+--------------+--------------+--------------+
+ | |SRK table offset |Certificate Offset |
+ | +--------------+--------------+--------------+--------------+
+ | |Blob Offset |Signature Offset |
+ | +--------------+--------------+--------------+--------------+
+ Signature | | SRK Table |
+ Block | +--------------+--------------+--------------+--------------+
+ | | Signature |
+ | +--------------+--------------+--------------+--------------+
+ | | Certificate (optional) |
+ | +--------------+--------------+--------------+--------------+
+ v | Blob (optional) |
+ ----------- +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+ <-- Image0Offset
+ | Image0 |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+ <-- ImageNOffset
+ | ImageN |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+
+i.MX95 Low Power Boot Image Sets Layout
+---------------------------------------
+
+ Image container sets are handled by M33 ROM.
+
+ --------------- +--------------+--------------+--------------+--------------+
+ ^ | 1st Container Header |
+ | +--------------+--------------+--------------+--------------+
+ ELE + | | Padding for 1KB alignment |
+ OEM | +--------------+--------------+--------------+--------------+
+ Conatiner | | 2nd Container Header |
+ Set | +--------------+--------------+--------------+--------------+
+ Header | | Padding for 1KB alignment |
+ | +--------------+--------------+--------------+--------------+
+ | | 3rd Container Header |
+ | +--------------+--------------+--------------+--------------+
+ v | Padding for 1KB alignment |
+ --------------- +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | mx95a0-ahab-container.img |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+------------------- +--------------+--------------+--------------+--------------+
+ ^ | oei-m33-ddr.bin |
+ | +--------------+--------------+--------------+--------------+
+ | | ddrfw-header.bin |
+ | +--------------+--------------+--------------+--------------+
+ | | lpddr5_imem_v202311.bin |
+ | +--------------+--------------+--------------+--------------+
+m33-oei-ddrfw.bin | | lpddr5_dmem_v202311.bin |
+ | +--------------+--------------+--------------+--------------+
+ | | ddrfw-qb-header.bin |
+ | +--------------+--------------+--------------+--------------+
+ | | lpddr5_imem_qb_v202311.bin |
+ | +--------------+--------------+--------------+--------------+
+ v | lpddr5_dmem_qb_v202311.bin |
+------------------- +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | oei-m33-tcm.bin |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | m33_image.bin |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | u-boot-spl.bin |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+
+ --------------- +--------------+--------------+--------------+--------------+
+ u-boot-atf ^ | 1st Container Header |
+ Container | +--------------+--------------+--------------+--------------+
+ Header v | Padding for 1KB alignment |
+ --------------- +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | bl31.bin |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
+ | u-boot.bin |
+ +--------------+--------------+--------------+--------------+
+ | ... |
+ +--------------+--------------+--------------+--------------+
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 18/19] imx95_evk: add i.MX95 19x19 EVK board basic support
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (16 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 17/19] doc: imx: add document for i.MX95 Image Container Format Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 19/19] Makefile: add some files to CLEAN_FILES Alice Guo (OSS)
2025-03-22 2:20 ` [PATCH v8 00/19] imx: add i.MX95 support Marek Vasut
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
From: Ye Li <ye.li@nxp.com>
This patch adds i.MX95 19x19 EVK board basic support.
Messaging unit for EdgeLock Secure Enclave, messaging unit for System
Manager, uSDHC for SD Card, gpio, lpuart are supported now.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm/dts/imx95-19x19-evk-u-boot.dtsi | 62 ++++++++++
arch/arm/dts/imx95-u-boot.dtsi | 157 ++++++++++++++++++++++++++
arch/arm/mach-imx/imx9/Kconfig | 8 ++
arch/arm/mach-imx/imx9/scmi/container.cfg | 10 ++
arch/arm/mach-imx/imx9/scmi/imximage.cfg | 15 +++
board/freescale/imx95_evk/Kconfig | 12 ++
board/freescale/imx95_evk/MAINTAINERS | 6 +
board/freescale/imx95_evk/Makefile | 11 ++
board/freescale/imx95_evk/imx95_19x19_evk.env | 91 +++++++++++++++
board/freescale/imx95_evk/imx95_evk.c | 36 ++++++
board/freescale/imx95_evk/spl.c | 69 +++++++++++
configs/imx95_19x19_evk_defconfig | 152 +++++++++++++++++++++++++
doc/board/nxp/imx95_evk.rst | 114 +++++++++++++++++++
doc/board/nxp/index.rst | 1 +
include/configs/imx95_evk.h | 24 ++++
15 files changed, 768 insertions(+)
diff --git a/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
new file mode 100644
index 00000000000..2d1f02baa5f
--- /dev/null
+++ b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include "imx95-u-boot.dtsi"
+
+&lpuart1 {
+ bootph-pre-ram;
+};
+
+®_usdhc2_vmmc {
+ bootph-pre-ram;
+};
+
+&usdhc1 {
+ bootph-pre-ram;
+};
+
+&usdhc2 {
+ bootph-pre-ram;
+};
+
+&wdog3 {
+ status = "disabled";
+};
+
+&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;
+};
+
+&pinctrl_reg_usdhc2_vmmc {
+ bootph-pre-ram;
+};
diff --git a/arch/arm/dts/imx95-u-boot.dtsi b/arch/arm/dts/imx95-u-boot.dtsi
new file mode 100644
index 00000000000..84361d215e2
--- /dev/null
+++ b/arch/arm/dts/imx95-u-boot.dtsi
@@ -0,0 +1,157 @@
+// 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_v202311.bin";
+ type = "blob-ext";
+ };
+
+ imx-lpddr-dmem {
+ filename = "lpddr5_dmem_v202311.bin";
+ type = "blob-ext";
+ };
+ };
+
+ imx-lpddr-qb {
+ type = "nxp-header-ddrfw";
+
+ imx-lpddr-imem-qb {
+ filename = "lpddr5_imem_qb_v202311.bin";
+ type = "blob-ext";
+ };
+
+ imx-lpddr-dmem-qb {
+ filename = "lpddr5_dmem_qb_v202311.bin";
+ type = "blob-ext";
+ };
+ };
+ };
+
+ imx-boot {
+ filename = "flash.bin";
+ pad-byte = <0x00>;
+
+ spl {
+ align = <0x400>;
+ align-size = <0x400>;
+ type = "mkimage";
+ args = "-n spl/u-boot-spl.cfgout -T imx8image";
+ };
+
+ u-boot {
+ type = "mkimage";
+ args = "-n u-boot-container.cfgout -T imx8image";
+ };
+ };
+ };
+};
+
+&aips1 {
+ bootph-all;
+};
+
+&aips2 {
+ bootph-all;
+};
+
+&aips3 {
+ bootph-pre-ram;
+};
+
+&clk_ext1 {
+ bootph-all;
+};
+
+&elemu1 {
+ bootph-all;
+ status = "okay";
+};
+
+&elemu3 {
+ bootph-all;
+ status = "okay";
+};
+
+&{/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;
+};
+
+&mu2 {
+ bootph-all;
+};
+
+&osc_24m {
+ bootph-all;
+};
+
+&{/soc} {
+ bootph-all;
+};
+
+&sram0 {
+ bootph-all;
+};
+
+&scmi_buf0 {
+ bootph-all;
+};
+
+&scmi_buf1 {
+ bootph-all;
+};
diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig
index ef364ca1a2f..19b6e7c981a 100644
--- a/arch/arm/mach-imx/imx9/Kconfig
+++ b/arch/arm/mach-imx/imx9/Kconfig
@@ -74,6 +74,13 @@ config TARGET_PHYCORE_IMX93
select OF_BOARD_FIXUP
select OF_BOARD_SETUP
+config TARGET_IMX95_19X19_EVK
+ bool "imx95_19x19_evk"
+ select IMX95
+ imply BOOTSTD_BOOTCOMMAND
+ imply BOOTSTD_FULL
+ imply OF_UPSTREAM
+
endchoice
source "board/freescale/imx91_evk/Kconfig"
@@ -81,6 +88,7 @@ source "board/freescale/imx93_evk/Kconfig"
source "board/freescale/imx93_qsb/Kconfig"
source "board/phytec/phycore_imx93/Kconfig"
source "board/variscite/imx93_var_som/Kconfig"
+source "board/freescale/imx95_evk/Kconfig"
endif
diff --git a/arch/arm/mach-imx/imx9/scmi/container.cfg b/arch/arm/mach-imx/imx9/scmi/container.cfg
new file mode 100644
index 00000000000..441d9beedd1
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/container.cfg
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2025 NXP
+ */
+
+BOOT_FROM SD
+SOC_TYPE IMX9
+CONTAINER
+IMAGE A55 bl31.bin 0x8a200000
+IMAGE A55 u-boot.bin CONFIG_TEXT_BASE
diff --git a/arch/arm/mach-imx/imx9/scmi/imximage.cfg b/arch/arm/mach-imx/imx9/scmi/imximage.cfg
new file mode 100644
index 00000000000..6af1c4ba628
--- /dev/null
+++ b/arch/arm/mach-imx/imx9/scmi/imximage.cfg
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2025 NXP
+ */
+
+BOOT_FROM SD
+SOC_TYPE IMX9
+APPEND mx95a0-ahab-container.img
+CONTAINER
+IMAGE OEI m33-oei-ddrfw.bin 0x1ffc0000
+HOLD 0x10000
+IMAGE OEI oei-m33-tcm.bin 0x1ffc0000
+IMAGE M33 m33_image.bin 0x1ffc0000
+IMAGE A55 spl/u-boot-spl.bin 0x20480000
+DUMMY_V2X 0x8b000000
diff --git a/board/freescale/imx95_evk/Kconfig b/board/freescale/imx95_evk/Kconfig
new file mode 100644
index 00000000000..f9a67353e5d
--- /dev/null
+++ b/board/freescale/imx95_evk/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_IMX95_19X19_EVK
+
+config SYS_BOARD
+ default "imx95_evk"
+
+config SYS_VENDOR
+ default "freescale"
+
+config SYS_CONFIG_NAME
+ default "imx95_evk"
+
+endif
diff --git a/board/freescale/imx95_evk/MAINTAINERS b/board/freescale/imx95_evk/MAINTAINERS
new file mode 100644
index 00000000000..5caf763e0cc
--- /dev/null
+++ b/board/freescale/imx95_evk/MAINTAINERS
@@ -0,0 +1,6 @@
+i.MX95 EVK BOARD
+M: Alice Guo <alice.guo@nxp.com>
+S: Maintained
+F: board/freescale/imx95_evk/
+F: include/configs/imx95_evk.h
+F: configs/imx95_19x19_evk_defconfig
diff --git a/board/freescale/imx95_evk/Makefile b/board/freescale/imx95_evk/Makefile
new file mode 100644
index 00000000000..0f5cec385c3
--- /dev/null
+++ b/board/freescale/imx95_evk/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright 2025 NXP
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += imx95_evk.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+endif
diff --git a/board/freescale/imx95_evk/imx95_19x19_evk.env b/board/freescale/imx95_evk/imx95_19x19_evk.env
new file mode 100644
index 00000000000..a002767e874
--- /dev/null
+++ b/board/freescale/imx95_evk/imx95_19x19_evk.env
@@ -0,0 +1,91 @@
+sec_boot=no
+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 console=${console} root=${mmcroot}
+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=auth_cntr ${cntr_addr}
+boot_os=booti ${loadaddr} - ${fdt_addr_r};
+mmcboot=echo Booting from mmc ...;
+ run mmcargs;
+ if test ${sec_boot} = yes; then
+ if run auth_os; then
+ run boot_os;
+ else
+ echo ERR: failed to authenticate;
+ fi;
+ 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 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};
+ if run auth_os; then
+ run boot_os;
+ else
+ echo ERR: failed to authenticate;
+ fi;
+ 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/imx95_evk/imx95_evk.c b/board/freescale/imx95_evk/imx95_evk.c
new file mode 100644
index 00000000000..d5f5e310b6b
--- /dev/null
+++ b/board/freescale/imx95_evk/imx95_evk.c
@@ -0,0 +1,36 @@
+// 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>
+
+int board_early_init_f(void)
+{
+ /* UART1: A55, UART2: M33, UART3: M7 */
+ 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();
+
+ 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/imx95_evk/spl.c b/board/freescale/imx95_evk/spl.c
new file mode 100644
index 00000000000..08f4da0bb73
--- /dev/null
+++ b/board/freescale/imx95_evk/spl.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/mu.h>
+#include <asm/mach-imx/boot_mode.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;
+ default:
+ return BOOT_DEVICE_NONE;
+ }
+}
+
+void spl_board_init(void)
+{
+ puts("Normal Boot\n");
+}
+
+void board_init_f(ulong dummy)
+{
+ int ret;
+
+ /* Clear the BSS. */
+ memset(__bss_start, 0, __bss_end - __bss_start);
+
+#ifdef CONFIG_SPL_RECOVER_DATA_SECTION
+ if (IS_ENABLED(CONFIG_SPL_BUILD))
+ spl_save_restore_data();
+#endif
+
+ timer_init();
+
+ /* Need dm_init() to run before any SCMI calls can be made. */
+ 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);
+
+ board_init_r(NULL, 0);
+}
diff --git a/configs/imx95_19x19_evk_defconfig b/configs/imx95_19x19_evk_defconfig
new file mode 100644
index 00000000000..fe968d5a239
--- /dev/null
+++ b/configs/imx95_19x19_evk_defconfig
@@ -0,0 +1,152 @@
+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=3
+CONFIG_ENV_SOURCE_FILE="imx95_19x19_evk"
+CONFIG_SF_DEFAULT_SPEED=40000000
+CONFIG_ENV_SIZE=0x4000
+CONFIG_ENV_OFFSET=0x700000
+CONFIG_IMX_CONFIG="arch/arm/mach-imx/imx9/scmi/imximage.cfg"
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="freescale/imx95-19x19-evk"
+CONFIG_TARGET_IMX95_19X19_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_STACK=0x204d6000
+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_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="imx95-19x19-evk.dtb"
+CONFIG_SYS_CBSIZE=2048
+CONFIG_SYS_PBSIZE=2074
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_LOAD_IMX_CONTAINER=y
+CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/scmi/container.cfg"
+# 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_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_POWER=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_I2C=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_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SYS_MMC_ENV_DEV=1
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_ETHPRIME=y
+CONFIG_ETHPRIME="eth0"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
+CONFIG_SPL_DM=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_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_SPL_FIRMWARE=y
+# CONFIG_SCMI_AGENT_SMCCC is not set
+CONFIG_IMX_RGPIO2P=y
+CONFIG_DM_PCA953X=y
+CONFIG_ADP5585_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_IMX_MU_MBOX=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_ES_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_FSL_USDHC=y
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_AQUANTIA=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DM_MDIO=y
+CONFIG_MII=y
+CONFIG_FSL_ENETC=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_PHY=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_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_NXP_FSPI=y
+CONFIG_ULP_WATCHDOG=y
+CONFIG_LZO=y
+CONFIG_BZIP2=y
diff --git a/doc/board/nxp/imx95_evk.rst b/doc/board/nxp/imx95_evk.rst
new file mode 100644
index 00000000000..9121f7561ab
--- /dev/null
+++ b/doc/board/nxp/imx95_evk.rst
@@ -0,0 +1,114 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+imx95_evk
+=======================
+
+U-Boot for the NXP i.MX95 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-1.3.0-17945fc.bin
+ $ sh firmware-ele-imx-1.3.0-17945fc.bin --auto-accept
+ $ cp firmware-ele-imx-1.3.0-17945fc/mx95a0-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.26-d4c33ab.bin
+ $ sh firmware-imx-8.26-d4c33ab.bin --auto-accept
+ $ cp firmware-imx-8.26-d4c33ab/firmware/ddr/synopsys/lpddr5*v202311.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=mx95lp5 oei=ddr DEBUG=1
+ $ cp build/mx95lp5/ddr/oei-m33-ddr.bin $(srctree)
+
+ $ make board=mx95lp5 oei=tcm DEBUG=1
+ $ cp build/mx95lp5/tcm/oei-m33-tcm.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=mx95evk all
+ $ cp build/mx95evk/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.10
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=aarch64-poky-linux-
+ $ unset LDFLAGS
+ $ git clone -b lf_v2.10 https://github.com/nxp-imx/imx-atf.git
+ $ cd imx-atf
+ $ make PLAT=imx95 bl31
+ $ cp build/imx95/release/bl31.bin $(srctree)
+
+Build the Bootloader Image
+--------------------------
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=aarch64-poky-linux-
+ $ make imx95_19x19_evk_defconfig
+ $ make
+
+Copy imx-boot-imx95.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.MX95 boot device to MicroSD card
diff --git a/doc/board/nxp/index.rst b/doc/board/nxp/index.rst
index 8ca4b561986..e7ec725cc04 100644
--- a/doc/board/nxp/index.rst
+++ b/doc/board/nxp/index.rst
@@ -15,6 +15,7 @@ NXP Semiconductors
imx91_11x11_evk
imx93_9x9_qsb
imx93_11x11_evk
+ imx95_evk
imxrt1020-evk
imxrt1050-evk
imxrt1170-evk
diff --git a/include/configs/imx95_evk.h b/include/configs/imx95_evk.h
new file mode 100644
index 00000000000..2eebdadc51d
--- /dev/null
+++ b/include/configs/imx95_evk.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2025 NXP
+ */
+
+#ifndef __IMX95_EVK_H
+#define __IMX95_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
+/* Totally 16GB */
+#define PHYS_SDRAM_SIZE 0x70000000 /* 2GB - 256MB DDR */
+#define PHYS_SDRAM_2_SIZE 0x380000000 /* 14GB */
+
+#define WDOG_BASE_ADDR WDG3_BASE_ADDR
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v8 19/19] Makefile: add some files to CLEAN_FILES
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (17 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 18/19] imx95_evk: add i.MX95 19x19 EVK board basic support Alice Guo (OSS)
@ 2025-03-21 7:15 ` Alice Guo (OSS)
2025-03-22 2:20 ` [PATCH v8 00/19] imx: add i.MX95 support Marek Vasut
19 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-21 7:15 UTC (permalink / raw)
To: Tom Rini, Lukasz Majewski, Sean Anderson, Simon Glass,
Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Marek Vasut, Lothar Waßmann
Cc: u-boot
From: Alice Guo <alice.guo@nxp.com>
When building the flash.bin of i.MX95 with binman,
mkimage.imx-boot.spl, mkimage.imx-boot.u-boot,
mkimage-out.imx-boot.spl and mkimage-out.imx-boot.u-boot are created.
Add these files to CLEAN_FILES so that they can be removed when running
"make clean".
Signed-off-by: Alice Guo <alice.guo@nxp.com>
---
Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index ea6ca427496..cc02c8dd59f 100644
--- a/Makefile
+++ b/Makefile
@@ -2229,7 +2229,8 @@ CLEAN_FILES += include/autoconf.mk* include/bmp_logo.h include/bmp_logo_data.h \
itb.fit.fit itb.fit.itb itb.map spl.map mkimage-out.rom.mkimage \
mkimage.rom.mkimage mkimage-in-simple-bin* rom.map simple-bin* \
idbloader-spi.img lib/efi_loader/helloworld_efi.S *.itb \
- Test* capsule*.*.efi-capsule capsule*.map
+ Test* capsule*.*.efi-capsule capsule*.map mkimage.imx-boot.spl \
+ mkimage.imx-boot.u-boot mkimage-out.imx-boot.spl mkimage-out.imx-boot.u-boot
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include/generated spl tpl vpl \
--
2.43.0
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable
2025-03-21 7:15 ` [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable Alice Guo (OSS)
@ 2025-03-22 0:38 ` Marek Vasut
2025-04-01 8:02 ` 回复: " Alice Guo (OSS)
0 siblings, 1 reply; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 0:38 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Viorel Suman, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
Hi,
> @@ -48,6 +58,9 @@ int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt)
> if (!smt->buf)
> return -ENOMEM;
>
> + if (IS_ENABLED(CONFIG_SCMI_TRANSPORT_SMT_INTR))
> + scmi_smt_enable_intr(smt, true);
Can we somehow figure out whether this interrupt needs to be enabled
purely from U-Boot control DT ? For example, check DT /firmware/scmi
node for compatible == "arm,scmi" (or != "arm,scmi-smc") and presence of
"mboxes" property ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-21 7:15 ` [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol Alice Guo (OSS)
@ 2025-03-22 0:46 ` Marek Vasut
2025-03-25 8:06 ` Peng Fan
2025-04-01 8:17 ` Alice Guo (OSS)
0 siblings, 2 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 0:46 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Ranjani Vaidyanathan, Peng Fan, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]
> +static int imx_scmi_pinctrl_probe(struct udevice *dev)
> +{
> + struct imx_scmi_pinctrl_priv *priv = dev_get_priv(dev);
> +
> + priv->daisy_offset = is_imx93() ? DAISY_OFFSET_IMX93 : DAISY_OFFSET_IMX95;
> +
> + return devm_scmi_of_get_channel(dev);
> +}
> +
> +static int imx_scmi_pinctrl_bind(struct udevice *dev)
> +{
> + if (IS_ENABLED(CONFIG_IMX95))
> + return 0;
Why does this driver support iMX93 , but it is explicitly not going to
bind on iMX93 ?
In case the MX93 support is going to be added, you probably need
something like:
if (IS_ENABLED(CONFIG_IMX95) && is_imx95())
return 0;
Because IS_ENABLED(CONFIG_IMX95) does not automatically imply that this
code is started on MX95 , that is when is_imx95() comes into play and
does runtime check for MX95 .
> + return -ENODEV;
> +}
> +
> +U_BOOT_DRIVER(scmi_pinctrl_imx) = {
> + .name = "scmi_pinctrl_imx",
> + .id = UCLASS_PINCTRL,
> + .bind = imx_scmi_pinctrl_bind,
> + .probe = imx_scmi_pinctrl_probe,
> + .priv_auto = sizeof(struct imx_scmi_pinctrl_priv),
> + .ops = &imx_scmi_pinctrl_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
> index 7abb2a6f36b..279ebbad440 100644
> --- a/include/scmi_protocols.h
> +++ b/include/scmi_protocols.h
> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
> SCMI_PROTOCOL_ID_SENSOR = 0x15,
> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
If this is the IMX specific pinctrl protocol, please make sure to name
it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or something .
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support
2025-03-21 7:15 ` [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support Alice Guo (OSS)
@ 2025-03-22 1:55 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 1:55 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]
> @@ -352,6 +358,22 @@ static int scmi_fill_base_info(struct udevice *agent, struct udevice *dev)
> return 0;
> }
>
> +static struct driver *scmi_proto_driver_get(unsigned int proto_id)
> +{
> + struct scmi_proto_driver *start, *entry;
> + int n_ents;
> +
> + start = ll_entry_start(struct scmi_proto_driver, scmi_proto_driver);
> + n_ents = ll_entry_count(struct scmi_proto_driver, scmi_proto_driver);
> +
> + for (entry = start; entry != start + n_ents; entry++) {
> + if (entry->match->proto_id == proto_id)
> + return entry->driver;
> + }
> +
> + return NULL;
> +}
Ideally, the addition of core code like scmi_proto_driver_get() should
be a separate preparatory patch.
Please also make sure to convert the four SCMI protocol drivers to
U_BOOT_SCMI_PROTO_DRIVER() , otherwise the code become inconsistent.
That should be easy, since there are literally four SCMI protocol drivers.
> /*
> * SCMI agent devices binds devices of various uclasses depending on
> * the FDT description. scmi_bind_protocol() is a generic bind sequence
> @@ -436,6 +458,9 @@ static int scmi_bind_protocols(struct udevice *dev)
> drv = DM_DRIVER_GET(scmi_voltage_domain);
> }
> break;
> + case SCMI_PROTOCOL_ID_PINCTRL:
> + drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL);
Please have a look at patch I just sent and give it a try:
[PATCH] power: regulator: scmi: Move regulator subnode hack to
scmi_regulator
With that and the conversion above in place, you should be able to
entirely eliminate this switch-case code and make use of the full
potential of your newly added scmi_proto_driver_get(), this way:
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c
b/drivers/firmware/scmi/scmi_agent-uclass.c
index 09a25d0067c..98e0c4d7c93 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -431,34 +431,10 @@ static int scmi_bind_protocols(struct udevice *dev)
drv = NULL;
name = ofnode_get_name(node);
- switch (protocol_id) {
- case SCMI_PROTOCOL_ID_POWER_DOMAIN:
- if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN) &&
- scmi_protocol_is_supported(dev, protocol_id))
- drv = DM_DRIVER_GET(scmi_power_domain);
- break;
- case SCMI_PROTOCOL_ID_CLOCK:
- if (CONFIG_IS_ENABLED(CLK_SCMI) &&
- scmi_protocol_is_supported(dev, protocol_id))
- drv = DM_DRIVER_GET(scmi_clock);
- break;
- case SCMI_PROTOCOL_ID_RESET_DOMAIN:
- if (IS_ENABLED(CONFIG_RESET_SCMI) &&
- scmi_protocol_is_supported(dev, protocol_id))
- drv = DM_DRIVER_GET(scmi_reset_domain);
- break;
- case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
- if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI) &&
- scmi_protocol_is_supported(dev, protocol_id))
- drv = DM_DRIVER_GET(scmi_voltage_domain);
- break;
- case SCMI_PROTOCOL_ID_PINCTRL:
- drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL);
- break;
- default:
- break;
- }
+ if (!scmi_protocol_is_supported(dev, protocol_id))
+ continue;
+ drv = scmi_proto_driver_get(protocol_id);
if (!drv) {
dev_dbg(dev, "Ignore unsupported SCMI protocol %#x\n",
protocol_id);
> + break;
> default:
> break;
> }
> diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
> index 0ed971369a3..dbd6ff437e5 100644
> --- a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
> +++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
> @@ -9,6 +9,7 @@
> #include <dm/device_compat.h>
> #include <dm/pinctrl.h>
> #include <scmi_agent.h>
> +#include <scmi_agent-uclass.h>
> #include <scmi_protocols.h>
>
> #include "pinctrl-imx.h"
> @@ -150,3 +151,9 @@ U_BOOT_DRIVER(scmi_pinctrl_imx) = {
> .ops = &imx_scmi_pinctrl_ops,
> .flags = DM_FLAG_PRE_RELOC,
> };
> +
> +static struct scmi_proto_match match = {
> + .proto_id = SCMI_PROTOCOL_ID_PINCTRL,
> +};
This should be a zero terminated array I think ?
static struct scmi_proto_match match[] = {
{ SCMI_PROTOCOL_ID_PINCTRL },
{ /* Sentinel */ }
};
[...]
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data
2025-03-21 7:15 ` [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data Alice Guo (OSS)
@ 2025-03-22 1:55 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 1:55 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> SCMI misc protocol is intended for miscellaneous functions which are
> device specific and are usually defined to access bit fields. It is i.MX
> specific. This patch adds SCMI misc protocol protocol_id and message_id
> for getting the ROM passover data.
Reviewed-by: Marek Vasut <marex@denx.de>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs
2025-03-21 7:15 ` [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs Alice Guo (OSS)
@ 2025-03-22 1:55 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 1:55 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> SCMI Performance domain management protocol is intended for performance
> management of groups of devices or APs that run in the same performance
> domain. The functionality provided by the callee-side can be used by
> passing the corresponding message_id.
Reviewed-by: Marek Vasut <marex@denx.de>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET
2025-03-21 7:15 ` [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET Alice Guo (OSS)
@ 2025-03-22 1:57 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 1:57 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Peng Fan, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
> From: Peng Fan <peng.fan@nxp.com>
>
> This patch adds the command CLOCK_PARENT_SET that can be used to set the
> parent of a clock. ARM SCMI Version 3.2 supports to change the parent of
> a clock device.
Reviewed-by: Marek Vasut <marex@denx.de>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions
2025-03-21 7:15 ` [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions Alice Guo (OSS)
@ 2025-03-22 2:02 ` Marek Vasut
2025-03-28 10:26 ` 回复: " Alice Guo (OSS)
0 siblings, 1 reply; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 2:02 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]
> +static int scmi_clk_get_permissions(struct udevice *dev, int clkid, u32 *perm)
> +{
> + u32 version;
> + int ret;
> +
> + struct scmi_clk_get_permissions_in in = {
> + .clock_id = clkid,
> + };
> + struct scmi_clk_get_permissions_out out;
> + struct scmi_msg msg = {
> + .protocol_id = SCMI_PROTOCOL_ID_CLOCK,
> + .message_id = SCMI_CLOCK_GET_PERMISSIONS,
> + .in_msg = (u8 *)&in,
> + .in_msg_sz = sizeof(in),
> + .out_msg = (u8 *)&out,
> + .out_msg_sz = sizeof(out),
> + };
> +
> + ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK, &version);
Would it be possible to query the version in .probe() once and cache the
value in private data ?
> + if (ret) {
> + log_debug("%s: get SCMI clock management protocol version failed\n", __func__);
> + return ret;
> + }
> +
> + if (version < CLOCK_PROTOCOL_VERSION_3_0) {
> + log_debug("%s: SCMI clock management protocol version is less than 3.0.\n", __func__);
> + return -EINVAL;
> + }
> +
> + ret = devm_scmi_process_msg(dev, &msg);
> + if (ret) {
> + log_debug("%s: get SCMI clock management protocol permissions failed\n", __func__);
> + return ret;
> + }
> +
> + ret = scmi_to_linux_errno(out.status);
> + if (ret < 0) {
> + log_debug("%s: the status code of getting permissions: %d\n", __func__, ret);
> + return ret;
> + }
> +
> + *perm = out.permissions;
> + return 0;
> +}
[...]
> @@ -156,29 +267,44 @@ static int scmi_clk_probe(struct udevice *dev)
>
> for (i = 0; i < num_clocks; i++) {
> char *clock_name;
> + u32 attributes;
>
> - if (!scmi_clk_get_attibute(dev, i, &clock_name)) {
> - clk = kzalloc(sizeof(*clk), GFP_KERNEL);
> - if (!clk || !clock_name)
> + if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
> + clk_scmi = kzalloc(sizeof(*clk_scmi), GFP_KERNEL);
> + if (!clk_scmi || !clock_name)
> ret = -ENOMEM;
> else
> - ret = clk_register(clk, dev->driver->name,
> + ret = clk_register(&clk_scmi->clk, dev->driver->name,
> clock_name, dev->name);
>
> if (ret) {
> - free(clk);
> + free(clk_scmi);
> free(clock_name);
> + free(&attributes);
Do you really need to free() an u32 attributes here ?
> return ret;
> }
>
> - clk_dm(i, clk);
> + clk_dm(i, &clk_scmi->clk);
> +
> + if (CLK_HAS_RESTRICTIONS(attributes)) {
> + u32 perm;
> +
> + ret = scmi_clk_get_permissions(dev, i, &perm);
> + if (ret < 0)
> + clk_scmi->ctrl_flags = 0;
> + else
> + clk_scmi->ctrl_flags = perm;
> + } else {
> + clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL | SUPPORT_CLK_PARENT_CONTROL |
> + SUPPORT_CLK_RATE_CONTROL;
> + }
> }
> }
>
> return 0;
> }
[...]
> enum scmi_clock_message_id {
> SCMI_CLOCK_ATTRIBUTES = 0x3,
> @@ -738,6 +739,7 @@ enum scmi_clock_message_id {
> SCMI_CLOCK_RATE_GET = 0x6,
> SCMI_CLOCK_CONFIG_SET = 0x7,
> SCMI_CLOCK_PARENT_SET = 0xD,
> + SCMI_CLOCK_GET_PERMISSIONS = 0xF,
Better call it SCMI_CLOCK_PERMISSIONS_GET to be consistent with the rest
of these fields , unless this is some SCMI specification name ?
[...]
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out
2025-03-21 7:15 ` [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out Alice Guo (OSS)
@ 2025-03-22 2:10 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 2:10 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Ye Li
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]
> @@ -276,22 +276,31 @@ static int scmi_base_discover_list_protocols_int(struct udevice *dev,
> if (ret)
> return ret;
>
This math here could really use a code comment to explain what is going
on here.
I assume there is 1 byte per protocol in the struct
scmi_base_discover_list_protocols_out { .protocols[] } member, right ?
If so, why not simply change u32 protocols[] to u8 protocols[] and use some:
out_size = sizeof(*out) + roundup(num_protocols, sizeof(u32))
?
That might make the whole parsing using for (i = 0; i <
out->num_protocols; i++, cur++) simpler too ?
> + out_size = sizeof(*out) + sizeof(u32) * (1 + (num_protocols - 1) / 4);
> + out = calloc(1, out_size);
> + if (!out)
> + return -ENOMEM;
> + msg.out_msg = (u8 *)out;
> + msg.out_msg_sz = out_size;
> +
> buf = calloc(sizeof(u8), num_protocols);
> - if (!buf)
> + if (!buf) {
> + free(out);
> return -ENOMEM;
> + }
>
> cur = 0;
> do {
> ret = devm_scmi_process_msg(dev, &msg);
> if (ret)
> goto err;
> - if (out.status) {
> - ret = scmi_to_linux_errno(out.status);
> + if (out->status) {
> + ret = scmi_to_linux_errno(out->status);
> goto err;
> }
>
> - for (i = 0; i < out.num_protocols; i++, cur++)
> - buf[cur] = out.protocols[i / 4] >> ((i % 4) * 8);
> + for (i = 0; i < out->num_protocols; i++, cur++)
> + buf[cur] = out->protocols[i / 4] >> ((i % 4) * 8);
> } while (cur < num_protocols);
>
> *protocols = buf;
> @@ -299,6 +308,7 @@ static int scmi_base_discover_list_protocols_int(struct udevice *dev,
> return num_protocols;
> err:
> free(buf);
> + free(out);
>
> return ret;
> }
> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
> index 519b906b4ce..9046de7e3e7 100644
> --- a/include/scmi_protocols.h
> +++ b/include/scmi_protocols.h
> @@ -145,7 +145,7 @@ struct scmi_base_discover_impl_version_out {
> struct scmi_base_discover_list_protocols_out {
> s32 status;
> u32 num_protocols;
> - u32 protocols[3];
> + u32 protocols[];
> };
[...]
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region
2025-03-21 7:15 ` [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region Alice Guo (OSS)
@ 2025-03-22 2:14 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 2:14 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Ye Li, Peng Fan
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]
> @@ -42,12 +53,30 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
>
> debug("%s: container: %p offset: %lu size: %lu\n", __func__,
> container, offset, size);
> - if (info->read(info, offset, size,
> - map_sysmem(images[image_index].dst - overhead,
> - images[image_index].size)) <
> - images[image_index].size) {
> - printf("%s wrong\n", __func__);
> - return NULL;
> +
> + buf = map_sysmem(images[image_index].dst - overhead, images[image_index].size);
> + if (IS_ENABLED(CONFIG_SPL_IMX_CONTAINER_USE_TRAMPOLINE) &&
> + arch_check_dst_in_secure(buf, size)) {
> + trampoline = arch_get_container_trampoline();
> + if (!trampoline) {
> + printf("%s: trampoline size is zero\n", __func__);
> + return NULL;
> + }
> +
> + if (info->read(info, offset, size, trampoline) < images[image_index].size) {
> + printf("%s wrong\n", __func__);
> + return NULL;
> + }
> +
> + memcpy(buf, trampoline, images[image_index].size);
> + } else {
> + if (info->read(info, offset, size,
> + map_sysmem(images[image_index].dst - overhead,
> + images[image_index].size)) <
> + images[image_index].size) {
> + printf("%s wrong\n", __func__);
Can you please make those debug prints a bit more informative about the
failure that occurred ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95
2025-03-21 7:15 ` [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95 Alice Guo (OSS)
@ 2025-03-22 2:15 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 2:15 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
> From: Alice Guo <alice.guo@nxp.com>
>
> i.MX95 only supports low power boot, which means A55 is kicked by M33.
> There is no ROM runs on A55 in such case so that deselect IMX8_ROMAPI
> for i.MX95.
>
> Signed-off-by: Alice Guo <alice.guo@nxp.com>
> ---
> arch/arm/mach-imx/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 134e42028c3..f38f3b2d338 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -180,7 +180,7 @@ config DDRMC_VF610_CALIBRATION
>
> config IMX8_ROMAPI
> def_bool y
> - depends on IMX8MN || IMX8MP || IMX8ULP || IMX9
> + depends on IMX8MN || IMX8MP || IMX8ULP || IMX93 || IMX91
Keep the list sorted, MX91 goes before MX93
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 00/19] imx: add i.MX95 support
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
` (18 preceding siblings ...)
2025-03-21 7:15 ` [PATCH v8 19/19] Makefile: add some files to CLEAN_FILES Alice Guo (OSS)
@ 2025-03-22 2:20 ` Marek Vasut
19 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-22 2:20 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot, Viorel Suman, Ye Li, Ranjani Vaidyanathan, Peng Fan,
Frank Li, Ji Luo, Jindong Yue
On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
> Changes for v7:
> - separate i.MX Messaging Unit driver patch from this patch set
> - add U_BOOT_SCMI_PROTO_DRIVER() to avoid putting i.MX related code in scmi_agent-uclass.c.
> - update drivers/clk/clk_scmi.c according to comment
> - dynamically allocate the size of struct scmi_base_discover_list_protocols_out
>
> Changes for v8:
> - add a comma to enum scmi_clock_message_id
> - use readl_poll_timeout instead of while to avoid to silent hang in
> disable_wdog()
> - use the format "%pM" to print a MAC address
> - use "%u" to match the data type u32
> - add a comma enum imx8image_cmd, enum imx8image_core_type and so on
> - add a line at end of container.cfg, imximage.cfg and imx95_19x19_evk.env
> - update arch/arm/mach-imx/imx9/scmi/soc.c
I added a couple of comments , I'm sorry this took so long.
I think the SCMI part is starting to be pretty good.
It might make sense to split off the SCMI parts and get that in first,
this way:
Separate patch:
[PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable
Separate patch:
[PATCH v8 09/19] scmi_protocols: update struct
scmi_base_discover_list_protocols_out
Separate patchset:
[PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support
...
[PATCH v8 08/19] sandbox: add SCMI clock control permissions to sandbox
And then the rest as a follow up series.
This will allow you to reduce the size of the series and get the pieces
which are good in quickly, without having to resend them repeatedly as a
part of larger series. (and yes, it also makes reviewing easier)
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-22 0:46 ` Marek Vasut
@ 2025-03-25 8:06 ` Peng Fan
2025-03-26 1:24 ` Marek Vasut
2025-04-01 8:17 ` Alice Guo (OSS)
1 sibling, 1 reply; 45+ messages in thread
From: Peng Fan @ 2025-03-25 8:06 UTC (permalink / raw)
To: Marek Vasut
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann, u-boot,
Ranjani Vaidyanathan, Peng Fan, Ye Li
On Sat, Mar 22, 2025 at 01:46:02AM +0100, Marek Vasut wrote:
>On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
>
>[...]
>
>> +static int imx_scmi_pinctrl_probe(struct udevice *dev)
>> +{
>> + struct imx_scmi_pinctrl_priv *priv = dev_get_priv(dev);
>> +
>> + priv->daisy_offset = is_imx93() ? DAISY_OFFSET_IMX93 : DAISY_OFFSET_IMX95;
>> +
>> + return devm_scmi_of_get_channel(dev);
>> +}
>> +
>> +static int imx_scmi_pinctrl_bind(struct udevice *dev)
>> +{
>> + if (IS_ENABLED(CONFIG_IMX95))
>> + return 0;
>
>Why does this driver support iMX93 , but it is explicitly not going to bind
>on iMX93 ?
>
>In case the MX93 support is going to be added, you probably need something
>like:
>
>if (IS_ENABLED(CONFIG_IMX95) && is_imx95())
> return 0;
>
>Because IS_ENABLED(CONFIG_IMX95) does not automatically imply that this code
>is started on MX95 , that is when is_imx95() comes into play and does runtime
>check for MX95 .
>
>> + return -ENODEV;
>> +}
>> +
>> +U_BOOT_DRIVER(scmi_pinctrl_imx) = {
>> + .name = "scmi_pinctrl_imx",
>> + .id = UCLASS_PINCTRL,
>> + .bind = imx_scmi_pinctrl_bind,
>> + .probe = imx_scmi_pinctrl_probe,
>> + .priv_auto = sizeof(struct imx_scmi_pinctrl_priv),
>> + .ops = &imx_scmi_pinctrl_ops,
>> + .flags = DM_FLAG_PRE_RELOC,
>> +};
>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
>> index 7abb2a6f36b..279ebbad440 100644
>> --- a/include/scmi_protocols.h
>> +++ b/include/scmi_protocols.h
>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
>If this is the IMX specific pinctrl protocol, please make sure to name it
>accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or something .
This ID is generic ID, not i.MX specific.
i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
are different compared with ARM SCMI generic pinconf bindings, so we
need a separate driver for i.MX.
Regards,
Peng
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-25 8:06 ` Peng Fan
@ 2025-03-26 1:24 ` Marek Vasut
2025-03-26 1:52 ` Peng Fan
0 siblings, 1 reply; 45+ messages in thread
From: Marek Vasut @ 2025-03-26 1:24 UTC (permalink / raw)
To: Peng Fan
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, NXP i.MX U-Boot Team,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann, u-boot,
Ranjani Vaidyanathan, Peng Fan, Ye Li
On 3/25/25 9:06 AM, Peng Fan wrote:
[...]
>>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
>>> index 7abb2a6f36b..279ebbad440 100644
>>> --- a/include/scmi_protocols.h
>>> +++ b/include/scmi_protocols.h
>>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
>>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
>>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
>>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
>>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
>> If this is the IMX specific pinctrl protocol, please make sure to name it
>> accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or something .
>
> This ID is generic ID, not i.MX specific.
>
> i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
> are different compared with ARM SCMI generic pinconf bindings, so we
> need a separate driver for i.MX.
But then, why is it using the same protocol ID ?
And I feel I asked this question multiple times now, please do include
this information in the commit message .
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-26 1:24 ` Marek Vasut
@ 2025-03-26 1:52 ` Peng Fan
2025-03-26 3:00 ` Marek Vasut
0 siblings, 1 reply; 45+ messages in thread
From: Peng Fan @ 2025-03-26 1:52 UTC (permalink / raw)
To: Marek Vasut, Peng Fan (OSS)
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li
> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver
> based on SCMI pin control protocol
>
> On 3/25/25 9:06 AM, Peng Fan wrote:
>
> [...]
>
> >>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
> >>> index 7abb2a6f36b..279ebbad440 100644
> >>> --- a/include/scmi_protocols.h
> >>> +++ b/include/scmi_protocols.h
> >>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
> >>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
> >>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
> >>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
> >>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
> >> If this is the IMX specific pinctrl protocol, please make sure to
> >> name it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or
> something .
> >
> > This ID is generic ID, not i.MX specific.
> >
> > i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
> are
> > different compared with ARM SCMI generic pinconf bindings, so we
> need
> > a separate driver for i.MX.
> But then, why is it using the same protocol ID ?
i.MX System Manager FW pinctrl follows ARM SCMI spec,
the ID value is 0x19.
If you look at linux kernel driver
drivers/pinctrl/pinctrl-scmi.c
drivers/pinctrl/freescale/pinctrl-scmi-imx.c
Both use same ID 0x19.
It is fine to use below, if it is fine to you.
SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
Regards,
Peng.
>
> And I feel I asked this question multiple times now, please do include
> this information in the commit message .
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-26 1:52 ` Peng Fan
@ 2025-03-26 3:00 ` Marek Vasut
2025-03-26 6:42 ` Peng Fan
0 siblings, 1 reply; 45+ messages in thread
From: Marek Vasut @ 2025-03-26 3:00 UTC (permalink / raw)
To: Peng Fan, Peng Fan (OSS)
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li
On 3/26/25 2:52 AM, Peng Fan wrote:
>> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver
>> based on SCMI pin control protocol
>>
>> On 3/25/25 9:06 AM, Peng Fan wrote:
>>
>> [...]
>>
>>>>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
>>>>> index 7abb2a6f36b..279ebbad440 100644
>>>>> --- a/include/scmi_protocols.h
>>>>> +++ b/include/scmi_protocols.h
>>>>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
>>>>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
>>>>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
>>>>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
>>>>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
>>>> If this is the IMX specific pinctrl protocol, please make sure to
>>>> name it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or
>> something .
>>>
>>> This ID is generic ID, not i.MX specific.
>>>
>>> i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
>> are
>>> different compared with ARM SCMI generic pinconf bindings, so we
>> need
>>> a separate driver for i.MX.
>> But then, why is it using the same protocol ID ?
>
> i.MX System Manager FW pinctrl follows ARM SCMI spec,
> the ID value is 0x19.
>
>
> If you look at linux kernel driver
>
> drivers/pinctrl/pinctrl-scmi.c
> drivers/pinctrl/freescale/pinctrl-scmi-imx.c
Is the second driver upstream at all ? I don't see it in linux-next ?
> Both use same ID 0x19.
>
> It is fine to use below, if it is fine to you.
> SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
How does the kernel discern which driver it should use to communicate
with the SCMI provider if both drivers are compiled into the kernel ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-26 3:00 ` Marek Vasut
@ 2025-03-26 6:42 ` Peng Fan
2025-03-27 13:18 ` Marek Vasut
0 siblings, 1 reply; 45+ messages in thread
From: Peng Fan @ 2025-03-26 6:42 UTC (permalink / raw)
To: Marek Vasut, Peng Fan (OSS)
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li
> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver
> based on SCMI pin control protocol
>
> On 3/26/25 2:52 AM, Peng Fan wrote:
> >> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller
> >> driver based on SCMI pin control protocol
> >>
> >> On 3/25/25 9:06 AM, Peng Fan wrote:
> >>
> >> [...]
> >>
> >>>>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
> >>>>> index 7abb2a6f36b..279ebbad440 100644
> >>>>> --- a/include/scmi_protocols.h
> >>>>> +++ b/include/scmi_protocols.h
> >>>>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
> >>>>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
> >>>>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
> >>>>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
> >>>>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
> >>>> If this is the IMX specific pinctrl protocol, please make sure to
> >>>> name it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or
> >> something .
> >>>
> >>> This ID is generic ID, not i.MX specific.
> >>>
> >>> i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
> >> are
> >>> different compared with ARM SCMI generic pinconf bindings, so we
> >> need
> >>> a separate driver for i.MX.
> >> But then, why is it using the same protocol ID ?
> >
> > i.MX System Manager FW pinctrl follows ARM SCMI spec, the ID
> value is
> > 0x19.
> >
> >
> > If you look at linux kernel driver
> >
> > drivers/pinctrl/pinctrl-scmi.c
> > drivers/pinctrl/freescale/pinctrl-scmi-imx.c
>
> Is the second driver upstream at all ? I don't see it in linux-next ?
Typo: drivers/pinctrl/freescale/pinctrl-imx-scmi.c
>
> > Both use same ID 0x19.
> >
> > It is fine to use below, if it is fine to you.
> > SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
> How does the kernel discern which driver it should use to
> communicate with the SCMI provider if both drivers are compiled into
> the kernel ?
There is a check in drivers probe. Only one will succeed.
But there is a common issue regarding scmi devlink that I am trying
to resolve.
Regards,
Peng.
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-26 6:42 ` Peng Fan
@ 2025-03-27 13:18 ` Marek Vasut
2025-04-01 10:57 ` 回复: " Alice Guo (OSS)
0 siblings, 1 reply; 45+ messages in thread
From: Marek Vasut @ 2025-03-27 13:18 UTC (permalink / raw)
To: Peng Fan, Peng Fan (OSS)
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li
On 3/26/25 7:42 AM, Peng Fan wrote:
>> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver
>> based on SCMI pin control protocol
>>
>> On 3/26/25 2:52 AM, Peng Fan wrote:
>>>> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller
>>>> driver based on SCMI pin control protocol
>>>>
>>>> On 3/25/25 9:06 AM, Peng Fan wrote:
>>>>
>>>> [...]
>>>>
>>>>>>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
>>>>>>> index 7abb2a6f36b..279ebbad440 100644
>>>>>>> --- a/include/scmi_protocols.h
>>>>>>> +++ b/include/scmi_protocols.h
>>>>>>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
>>>>>>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
>>>>>>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
>>>>>>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
>>>>>>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
>>>>>> If this is the IMX specific pinctrl protocol, please make sure to
>>>>>> name it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or
>>>> something .
>>>>>
>>>>> This ID is generic ID, not i.MX specific.
>>>>>
>>>>> i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
>>>> are
>>>>> different compared with ARM SCMI generic pinconf bindings, so we
>>>> need
>>>>> a separate driver for i.MX.
>>>> But then, why is it using the same protocol ID ?
>>>
>>> i.MX System Manager FW pinctrl follows ARM SCMI spec, the ID
>> value is
>>> 0x19.
>>>
>>>
>>> If you look at linux kernel driver
>>>
>>> drivers/pinctrl/pinctrl-scmi.c
>>> drivers/pinctrl/freescale/pinctrl-scmi-imx.c
>>
>> Is the second driver upstream at all ? I don't see it in linux-next ?
>
> Typo: drivers/pinctrl/freescale/pinctrl-imx-scmi.c
Ah, thank you for clarifying.
>>> Both use same ID 0x19.
>>>
>>> It is fine to use below, if it is fine to you.
>>> SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
>> How does the kernel discern which driver it should use to
>> communicate with the SCMI provider if both drivers are compiled into
>> the kernel ?
>
> There is a check in drivers probe. Only one will succeed.
I have to admit, this is just ... uhhh :(
But I think now, we should also have a driver-side check and two
separate drivers, similar to this patch:
[PATCH] power: regulator: scmi: Move regulator subnode hack to
scmi_regulator
right ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* 回复: [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions
2025-03-22 2:02 ` Marek Vasut
@ 2025-03-28 10:26 ` Alice Guo (OSS)
2025-03-30 21:05 ` Marek Vasut
0 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-03-28 10:26 UTC (permalink / raw)
To: Marek Vasut, Alice Guo (OSS), Tom Rini, Lukasz Majewski,
Sean Anderson, Simon Glass, Stefano Babic, Fabio Estevam,
dl-uboot-imx, Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot@lists.denx.de, Ye Li, Peng Fan
> -----邮件原件-----
> 发件人: Marek Vasut <marex@denx.de>
> 发送时间: 2025年3月22日 10:02
> 收件人: Alice Guo (OSS) <alice.guo@oss.nxp.com>; Tom Rini
> <trini@konsulko.com>; Lukasz Majewski <lukma@denx.de>; Sean Anderson
> <seanga2@gmail.com>; Simon Glass <sjg@chromium.org>; Stefano Babic
> <sbabic@denx.de>; Fabio Estevam <festevam@gmail.com>; dl-uboot-imx
> <uboot-imx@nxp.com>; Alper Nebi Yasak <alpernebiyasak@gmail.com>; Alice
> Guo <alice.guo@nxp.com>; Lothar Waßmann <LW@KARO-electronics.de>
> 抄送: u-boot@lists.denx.de; Ye Li <ye.li@nxp.com>; Peng Fan
> <peng.fan@nxp.com>
> 主题: Re: [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control
> permissions
>
> On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
>
> [...]
>
> > +static int scmi_clk_get_permissions(struct udevice *dev, int clkid,
> > +u32 *perm) {
> > + u32 version;
> > + int ret;
> > +
> > + struct scmi_clk_get_permissions_in in = {
> > + .clock_id = clkid,
> > + };
> > + struct scmi_clk_get_permissions_out out;
> > + struct scmi_msg msg = {
> > + .protocol_id = SCMI_PROTOCOL_ID_CLOCK,
> > + .message_id = SCMI_CLOCK_GET_PERMISSIONS,
> > + .in_msg = (u8 *)&in,
> > + .in_msg_sz = sizeof(in),
> > + .out_msg = (u8 *)&out,
> > + .out_msg_sz = sizeof(out),
> > + };
> > +
> > + ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK,
> > +&version);
>
> Would it be possible to query the version in .probe() once and cache the value in
> private data ?
>
> > + if (ret) {
> > + log_debug("%s: get SCMI clock management protocol version
> failed\n", __func__);
> > + return ret;
> > + }
> > +
> > + if (version < CLOCK_PROTOCOL_VERSION_3_0) {
> > + log_debug("%s: SCMI clock management protocol version is less than
> 3.0.\n", __func__);
> > + return -EINVAL;
> > + }
> > +
> > + ret = devm_scmi_process_msg(dev, &msg);
> > + if (ret) {
> > + log_debug("%s: get SCMI clock management protocol permissions
> failed\n", __func__);
> > + return ret;
> > + }
> > +
> > + ret = scmi_to_linux_errno(out.status);
> > + if (ret < 0) {
> > + log_debug("%s: the status code of getting permissions: %d\n",
> __func__, ret);
> > + return ret;
> > + }
> > +
> > + *perm = out.permissions;
> > + return 0;
> > +}
>
> [...]
>
> > @@ -156,29 +267,44 @@ static int scmi_clk_probe(struct udevice *dev)
> >
> > for (i = 0; i < num_clocks; i++) {
> > char *clock_name;
> > + u32 attributes;
> >
> > - if (!scmi_clk_get_attibute(dev, i, &clock_name)) {
> > - clk = kzalloc(sizeof(*clk), GFP_KERNEL);
> > - if (!clk || !clock_name)
> > + if (!scmi_clk_get_attibute(dev, i, &clock_name, &attributes)) {
> > + clk_scmi = kzalloc(sizeof(*clk_scmi), GFP_KERNEL);
> > + if (!clk_scmi || !clock_name)
> > ret = -ENOMEM;
> > else
> > - ret = clk_register(clk, dev->driver->name,
> > + ret = clk_register(&clk_scmi->clk, dev->driver->name,
> > clock_name, dev->name);
> >
> > if (ret) {
> > - free(clk);
> > + free(clk_scmi);
> > free(clock_name);
> > + free(&attributes);
>
> Do you really need to free() an u32 attributes here ?
>
> > return ret;
> > }
> >
> > - clk_dm(i, clk);
> > + clk_dm(i, &clk_scmi->clk);
> > +
> > + if (CLK_HAS_RESTRICTIONS(attributes)) {
> > + u32 perm;
> > +
> > + ret = scmi_clk_get_permissions(dev, i, &perm);
> > + if (ret < 0)
> > + clk_scmi->ctrl_flags = 0;
> > + else
> > + clk_scmi->ctrl_flags = perm;
> > + } else {
> > + clk_scmi->ctrl_flags = SUPPORT_CLK_STAT_CONTROL |
> SUPPORT_CLK_PARENT_CONTROL |
> > + SUPPORT_CLK_RATE_CONTROL;
> > + }
> > }
> > }
> >
> > return 0;
> > }
>
> [...]
>
> > enum scmi_clock_message_id {
> > SCMI_CLOCK_ATTRIBUTES = 0x3,
> > @@ -738,6 +739,7 @@ enum scmi_clock_message_id {
> > SCMI_CLOCK_RATE_GET = 0x6,
> > SCMI_CLOCK_CONFIG_SET = 0x7,
> > SCMI_CLOCK_PARENT_SET = 0xD,
> > + SCMI_CLOCK_GET_PERMISSIONS = 0xF,
>
> Better call it SCMI_CLOCK_PERMISSIONS_GET to be consistent with the rest of
> these fields , unless this is some SCMI specification name ?
CLOCK_GET_PERMISSIONS is from Arm System Control and Management Interface Platform Design Document 3.2.
Best Regards,
Alice Guo
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: 回复: [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions
2025-03-28 10:26 ` 回复: " Alice Guo (OSS)
@ 2025-03-30 21:05 ` Marek Vasut
0 siblings, 0 replies; 45+ messages in thread
From: Marek Vasut @ 2025-03-30 21:05 UTC (permalink / raw)
To: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot@lists.denx.de, Ye Li, Peng Fan
On 3/28/25 11:26 AM, Alice Guo (OSS) wrote:
Hello Alice,
>>> enum scmi_clock_message_id {
>>> SCMI_CLOCK_ATTRIBUTES = 0x3,
>>> @@ -738,6 +739,7 @@ enum scmi_clock_message_id {
>>> SCMI_CLOCK_RATE_GET = 0x6,
>>> SCMI_CLOCK_CONFIG_SET = 0x7,
>>> SCMI_CLOCK_PARENT_SET = 0xD,
>>> + SCMI_CLOCK_GET_PERMISSIONS = 0xF,
>>
>> Better call it SCMI_CLOCK_PERMISSIONS_GET to be consistent with the rest of
>> these fields , unless this is some SCMI specification name ?
>
> CLOCK_GET_PERMISSIONS is from Arm System Control and Management Interface Platform Design Document 3.2.
Understood, please note it in the commit message .
Thank you.
^ permalink raw reply [flat|nested] 45+ messages in thread
* 回复: [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable
2025-03-22 0:38 ` Marek Vasut
@ 2025-04-01 8:02 ` Alice Guo (OSS)
0 siblings, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-04-01 8:02 UTC (permalink / raw)
To: Marek Vasut, Alice Guo (OSS), Tom Rini, Lukasz Majewski,
Sean Anderson, Simon Glass, Stefano Babic, Fabio Estevam,
dl-uboot-imx, Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot@lists.denx.de, Viorel Suman, Ye Li
> -----邮件原件-----
> 发件人: Marek Vasut <marex@denx.de>
> 发送时间: 2025年3月22日 8:38
> 收件人: Alice Guo (OSS) <alice.guo@oss.nxp.com>; Tom Rini
> <trini@konsulko.com>; Lukasz Majewski <lukma@denx.de>; Sean Anderson
> <seanga2@gmail.com>; Simon Glass <sjg@chromium.org>; Stefano Babic
> <sbabic@denx.de>; Fabio Estevam <festevam@gmail.com>; dl-uboot-imx
> <uboot-imx@nxp.com>; Alper Nebi Yasak <alpernebiyasak@gmail.com>; Alice
> Guo <alice.guo@nxp.com>; Lothar Waßmann <LW@KARO-electronics.de>
> 抄送: u-boot@lists.denx.de; Viorel Suman <viorel.suman@nxp.com>; Ye Li
> <ye.li@nxp.com>
> 主题: Re: [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication
> enable
>
> On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
>
> Hi,
>
> > @@ -48,6 +58,9 @@ int scmi_dt_get_smt_buffer(struct udevice *dev, struct
> scmi_smt *smt)
> > if (!smt->buf)
> > return -ENOMEM;
> >
> > + if (IS_ENABLED(CONFIG_SCMI_TRANSPORT_SMT_INTR))
> > + scmi_smt_enable_intr(smt, true);
> Can we somehow figure out whether this interrupt needs to be enabled purely
> from U-Boot control DT ? For example, check DT /firmware/scmi node for
> compatible == "arm,scmi" (or != "arm,scmi-smc") and presence of "mboxes"
> property ?
Hi Marek,
I have changed to check DT and sent this patch separately. Please review! https://patchwork.ozlabs.org/project/uboot/patch/20250401075635.3802640-1-alice.guo@oss.nxp.com/
Best regards,
Alice Guo
^ permalink raw reply [flat|nested] 45+ messages in thread
* 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-22 0:46 ` Marek Vasut
2025-03-25 8:06 ` Peng Fan
@ 2025-04-01 8:17 ` Alice Guo (OSS)
1 sibling, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-04-01 8:17 UTC (permalink / raw)
To: Marek Vasut, Alice Guo (OSS), Tom Rini, Lukasz Majewski,
Sean Anderson, Simon Glass, Stefano Babic, Fabio Estevam,
dl-uboot-imx, Alper Nebi Yasak, Alice Guo, Lothar Waßmann
Cc: u-boot@lists.denx.de, Ranjani Vaidyanathan, Peng Fan, Ye Li
> -----邮件原件-----
> 发件人: Marek Vasut <marex@denx.de>
> 发送时间: 2025年3月22日 8:46
> 收件人: Alice Guo (OSS) <alice.guo@oss.nxp.com>; Tom Rini
> <trini@konsulko.com>; Lukasz Majewski <lukma@denx.de>; Sean Anderson
> <seanga2@gmail.com>; Simon Glass <sjg@chromium.org>; Stefano Babic
> <sbabic@denx.de>; Fabio Estevam <festevam@gmail.com>; dl-uboot-imx
> <uboot-imx@nxp.com>; Alper Nebi Yasak <alpernebiyasak@gmail.com>; Alice
> Guo <alice.guo@nxp.com>; Lothar Waßmann <LW@KARO-electronics.de>
> 抄送: u-boot@lists.denx.de; Ranjani Vaidyanathan
> <ranjani.vaidyanathan@nxp.com>; Peng Fan <peng.fan@nxp.com>; Ye Li
> <ye.li@nxp.com>
> 主题: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on
> SCMI pin control protocol
>
> On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
>
> [...]
>
> > +static int imx_scmi_pinctrl_probe(struct udevice *dev) {
> > + struct imx_scmi_pinctrl_priv *priv = dev_get_priv(dev);
> > +
> > + priv->daisy_offset = is_imx93() ? DAISY_OFFSET_IMX93 :
> > +DAISY_OFFSET_IMX95;
> > +
> > + return devm_scmi_of_get_channel(dev); }
> > +
> > +static int imx_scmi_pinctrl_bind(struct udevice *dev) {
> > + if (IS_ENABLED(CONFIG_IMX95))
> > + return 0;
>
> Why does this driver support iMX93 , but it is explicitly not going to bind on
> iMX93 ?
This is my mistake. Will clean up the relevant code.
>
> In case the MX93 support is going to be added, you probably need something
> like:
>
> if (IS_ENABLED(CONFIG_IMX95) && is_imx95())
> return 0;
>
> Because IS_ENABLED(CONFIG_IMX95) does not automatically imply that this
> code is started on MX95 , that is when is_imx95() comes into play and does
> runtime check for MX95 .
>
> > + return -ENODEV;
> > +}
> > +
> > +U_BOOT_DRIVER(scmi_pinctrl_imx) = {
> > + .name = "scmi_pinctrl_imx",
> > + .id = UCLASS_PINCTRL,
> > + .bind = imx_scmi_pinctrl_bind,
> > + .probe = imx_scmi_pinctrl_probe,
> > + .priv_auto = sizeof(struct imx_scmi_pinctrl_priv),
> > + .ops = &imx_scmi_pinctrl_ops,
> > + .flags = DM_FLAG_PRE_RELOC,
> > +};
> > diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h index
> > 7abb2a6f36b..279ebbad440 100644
> > --- a/include/scmi_protocols.h
> > +++ b/include/scmi_protocols.h
> > @@ -24,6 +24,7 @@ enum scmi_std_protocol {
> > SCMI_PROTOCOL_ID_SENSOR = 0x15,
> > SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
> > SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
> > + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
> If this is the IMX specific pinctrl protocol, please make sure to name it
> accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or something .
^ permalink raw reply [flat|nested] 45+ messages in thread
* 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-03-27 13:18 ` Marek Vasut
@ 2025-04-01 10:57 ` Alice Guo (OSS)
2025-04-01 12:53 ` Marek Vasut
0 siblings, 1 reply; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-04-01 10:57 UTC (permalink / raw)
To: Marek Vasut, Peng Fan, Peng Fan (OSS)
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Stefano Babic, Fabio Estevam, dl-uboot-imx,
Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li
> -----邮件原件-----
> 发件人: Marek Vasut <marex@denx.de>
> 发送时间: 2025年3月27日 21:19
> 收件人: Peng Fan <peng.fan@nxp.com>; Peng Fan (OSS)
> <peng.fan@oss.nxp.com>
> 抄送: Alice Guo (OSS) <alice.guo@oss.nxp.com>; Tom Rini
> <trini@konsulko.com>; Lukasz Majewski <lukma@denx.de>; Sean Anderson
> <seanga2@gmail.com>; Simon Glass <sjg@chromium.org>; Stefano Babic
> <sbabic@denx.de>; Fabio Estevam <festevam@gmail.com>; dl-uboot-imx
> <uboot-imx@nxp.com>; Alper Nebi Yasak <alpernebiyasak@gmail.com>; Alice
> Guo <alice.guo@nxp.com>; Lothar Waßmann <LW@karo-electronics.de>;
> u-boot@lists.denx.de; Ranjani Vaidyanathan <ranjani.vaidyanathan@nxp.com>;
> Ye Li <ye.li@nxp.com>
> 主题: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on
> SCMI pin control protocol
>
> On 3/26/25 7:42 AM, Peng Fan wrote:
> >> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller
> >> driver based on SCMI pin control protocol
> >>
> >> On 3/26/25 2:52 AM, Peng Fan wrote:
> >>>> Subject: Re: [PATCH v8 02/19] pinctrl: nxp: add a pin controller
> >>>> driver based on SCMI pin control protocol
> >>>>
> >>>> On 3/25/25 9:06 AM, Peng Fan wrote:
> >>>>
> >>>> [...]
> >>>>
> >>>>>>> diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
> >>>>>>> index 7abb2a6f36b..279ebbad440 100644
> >>>>>>> --- a/include/scmi_protocols.h
> >>>>>>> +++ b/include/scmi_protocols.h
> >>>>>>> @@ -24,6 +24,7 @@ enum scmi_std_protocol {
> >>>>>>> SCMI_PROTOCOL_ID_SENSOR = 0x15,
> >>>>>>> SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
> >>>>>>> SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
> >>>>>>> + SCMI_PROTOCOL_ID_PINCTRL = 0x19,
> >>>>>> If this is the IMX specific pinctrl protocol, please make sure to
> >>>>>> name it accordingly , SCMI_PROTOCOL_ID_PINCTRL_IMX or
> >>>> something .
> >>>>>
> >>>>> This ID is generic ID, not i.MX specific.
> >>>>>
> >>>>> i.MX SCMI pinctrl follows ARM SCMI spec, but i.MX pinctrl bindings
> >>>> are
> >>>>> different compared with ARM SCMI generic pinconf bindings, so we
> >>>> need
> >>>>> a separate driver for i.MX.
> >>>> But then, why is it using the same protocol ID ?
> >>>
> >>> i.MX System Manager FW pinctrl follows ARM SCMI spec, the ID
> >> value is
> >>> 0x19.
> >>>
> >>>
> >>> If you look at linux kernel driver
> >>>
> >>> drivers/pinctrl/pinctrl-scmi.c
> >>> drivers/pinctrl/freescale/pinctrl-scmi-imx.c
> >>
> >> Is the second driver upstream at all ? I don't see it in linux-next ?
> >
> > Typo: drivers/pinctrl/freescale/pinctrl-imx-scmi.c
>
> Ah, thank you for clarifying.
>
> >>> Both use same ID 0x19.
> >>>
> >>> It is fine to use below, if it is fine to you.
> >>> SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
> >> How does the kernel discern which driver it should use to communicate
> >> with the SCMI provider if both drivers are compiled into the kernel ?
> >
> > There is a check in drivers probe. Only one will succeed.
>
> I have to admit, this is just ... uhhh :(
>
> But I think now, we should also have a driver-side check and two separate
> drivers, similar to this patch:
>
> [PATCH] power: regulator: scmi: Move regulator subnode hack to
> scmi_regulator
Hi Marek,
When will this patch "[PATCH] power: regulator: scmi: Move regulator subnode hack to scmi_regulator" be applied to the uboot next branch? I have already made the next version patch set based on this patch.
Best Regards,
Alice Guo
> right ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-04-01 10:57 ` 回复: " Alice Guo (OSS)
@ 2025-04-01 12:53 ` Marek Vasut
2025-04-01 13:22 ` 回复: " Alice Guo (OSS)
2025-04-01 13:27 ` Fabio Estevam
0 siblings, 2 replies; 45+ messages in thread
From: Marek Vasut @ 2025-04-01 12:53 UTC (permalink / raw)
To: Alice Guo (OSS), Fabio Estevam, Tom Rini
Cc: Lukasz Majewski, Sean Anderson, Simon Glass, Peng Fan,
dl-uboot-imx, Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li, Peng Fan (OSS)
On 4/1/25 12:57 PM, Alice Guo (OSS) wrote:
Hello Alice,
>>>>> Both use same ID 0x19.
>>>>>
>>>>> It is fine to use below, if it is fine to you.
>>>>> SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
>>>> How does the kernel discern which driver it should use to communicate
>>>> with the SCMI provider if both drivers are compiled into the kernel ?
>>>
>>> There is a check in drivers probe. Only one will succeed.
>>
>> I have to admit, this is just ... uhhh :(
>>
>> But I think now, we should also have a driver-side check and two separate
>> drivers, similar to this patch:
>>
>> [PATCH] power: regulator: scmi: Move regulator subnode hack to
>> scmi_regulator
>
> Hi Marek,
>
> When will this patch "[PATCH] power: regulator: scmi: Move regulator subnode hack to scmi_regulator" be applied to the uboot next branch? I have already made the next version patch set based on this patch.
Fabio/Tom ?
^ permalink raw reply [flat|nested] 45+ messages in thread
* 回复: 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-04-01 12:53 ` Marek Vasut
@ 2025-04-01 13:22 ` Alice Guo (OSS)
2025-04-01 13:27 ` Fabio Estevam
1 sibling, 0 replies; 45+ messages in thread
From: Alice Guo (OSS) @ 2025-04-01 13:22 UTC (permalink / raw)
To: Marek Vasut, Alice Guo (OSS), Fabio Estevam, Tom Rini
Cc: Lukasz Majewski, Sean Anderson, Simon Glass, Peng Fan,
dl-uboot-imx, Alper Nebi Yasak, Alice Guo, Lothar Waßmann,
u-boot@lists.denx.de, Ranjani Vaidyanathan, Ye Li, Peng Fan (OSS)
> -----邮件原件-----
> 发件人: Marek Vasut <marex@denx.de>
> 发送时间: 2025年4月1日 20:53
> 收件人: Alice Guo (OSS) <alice.guo@oss.nxp.com>; Fabio Estevam
> <festevam@gmail.com>; Tom Rini <trini@konsulko.com>
> 抄送: Lukasz Majewski <lukma@denx.de>; Sean Anderson
> <seanga2@gmail.com>; Simon Glass <sjg@chromium.org>; Peng Fan
> <peng.fan@nxp.com>; dl-uboot-imx <uboot-imx@nxp.com>; Alper Nebi Yasak
> <alpernebiyasak@gmail.com>; Alice Guo <alice.guo@nxp.com>; Lothar
> Waßmann <LW@karo-electronics.de>; u-boot@lists.denx.de; Ranjani
> Vaidyanathan <ranjani.vaidyanathan@nxp.com>; Ye Li <ye.li@nxp.com>; Peng
> Fan (OSS) <peng.fan@oss.nxp.com>
> 主题: Re: 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver
> based on SCMI pin control protocol
>
> On 4/1/25 12:57 PM, Alice Guo (OSS) wrote:
>
> Hello Alice,
>
> >>>>> Both use same ID 0x19.
> >>>>>
> >>>>> It is fine to use below, if it is fine to you.
> >>>>> SCMI_PROTOCOL_ID_PINCTRL_IMX = 0x19.
> >>>> How does the kernel discern which driver it should use to
> >>>> communicate with the SCMI provider if both drivers are compiled into
> the kernel ?
> >>>
> >>> There is a check in drivers probe. Only one will succeed.
> >>
> >> I have to admit, this is just ... uhhh :(
> >>
> >> But I think now, we should also have a driver-side check and two
> >> separate drivers, similar to this patch:
> >>
> >> [PATCH] power: regulator: scmi: Move regulator subnode hack to
> >> scmi_regulator
> >
> > Hi Marek,
> >
> > When will this patch "[PATCH] power: regulator: scmi: Move regulator
> subnode hack to scmi_regulator" be applied to the uboot next branch? I have
> already made the next version patch set based on this patch.
> Fabio/Tom ?
U-Boot source code I used is cloned by git clone https://source.denx.de/u-boot/u-boot.git
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: 回复: [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol
2025-04-01 12:53 ` Marek Vasut
2025-04-01 13:22 ` 回复: " Alice Guo (OSS)
@ 2025-04-01 13:27 ` Fabio Estevam
1 sibling, 0 replies; 45+ messages in thread
From: Fabio Estevam @ 2025-04-01 13:27 UTC (permalink / raw)
To: Marek Vasut, Jaehoon Chung
Cc: Alice Guo (OSS), Tom Rini, Lukasz Majewski, Sean Anderson,
Simon Glass, Peng Fan, dl-uboot-imx, Alper Nebi Yasak, Alice Guo,
Lothar Waßmann, u-boot@lists.denx.de, Ranjani Vaidyanathan,
Ye Li, Peng Fan (OSS)
On Tue, Apr 1, 2025 at 9:53 AM Marek Vasut <marex@denx.de> wrote:
> > When will this patch "[PATCH] power: regulator: scmi: Move regulator subnode hack to scmi_regulator" be applied to the uboot next branch? I have already made the next version patch set based on this patch.
> Fabio/Tom ?
This is assigned to Jaehoon in patchwork:
https://patchwork.ozlabs.org/project/uboot/patch/20250322014444.174796-1-marex@denx.de/
^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2025-04-01 13:27 UTC | newest]
Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-21 7:15 [PATCH v8 00/19] imx: add i.MX95 support Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 01/19] firmware: scmi: smt: Interrupt communication enable Alice Guo (OSS)
2025-03-22 0:38 ` Marek Vasut
2025-04-01 8:02 ` 回复: " Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 02/19] pinctrl: nxp: add a pin controller driver based on SCMI pin control protocol Alice Guo (OSS)
2025-03-22 0:46 ` Marek Vasut
2025-03-25 8:06 ` Peng Fan
2025-03-26 1:24 ` Marek Vasut
2025-03-26 1:52 ` Peng Fan
2025-03-26 3:00 ` Marek Vasut
2025-03-26 6:42 ` Peng Fan
2025-03-27 13:18 ` Marek Vasut
2025-04-01 10:57 ` 回复: " Alice Guo (OSS)
2025-04-01 12:53 ` Marek Vasut
2025-04-01 13:22 ` 回复: " Alice Guo (OSS)
2025-04-01 13:27 ` Fabio Estevam
2025-04-01 8:17 ` Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 03/19] firmware: scmi_agent: add SCMI pin control protocol support Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 04/19] scmi_protocols: add SCMI misc protocol protocol_id and message_id for getting the ROM passover data Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 05/19] scmi_protocols: add SCMI Performance domain management protocol message IDs Alice Guo (OSS)
2025-03-22 1:55 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 06/19] clk: scmi: add the command CLOCK_PARENT_SET Alice Guo (OSS)
2025-03-22 1:57 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 07/19] clk: scmi: check the clock state/parent/rate control permissions Alice Guo (OSS)
2025-03-22 2:02 ` Marek Vasut
2025-03-28 10:26 ` 回复: " Alice Guo (OSS)
2025-03-30 21:05 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 08/19] sandbox: add SCMI clock control permissions to sandbox Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 09/19] scmi_protocols: update struct scmi_base_discover_list_protocols_out Alice Guo (OSS)
2025-03-22 2:10 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 10/19] imx9: scmi: add i.MX95 SoC and clock related code Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 11/19] spl: imx: use trampoline buffer to load images to secure region Alice Guo (OSS)
2025-03-22 2:14 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 12/19] imx9: add i.MX95 Kconfig and Makefile Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 13/19] imx: Kconfig: IMX8_ROMAPI is not configured for i.MX95 Alice Guo (OSS)
2025-03-22 2:15 ` Marek Vasut
2025-03-21 7:15 ` [PATCH v8 14/19] binman: add a new entry type for packing DDR PHY firmware images Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 15/19] tools: imx8image: add i.MX95 support Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 16/19] imx: container: add V2X container support for i.MX95 Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 17/19] doc: imx: add document for i.MX95 Image Container Format Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 18/19] imx95_evk: add i.MX95 19x19 EVK board basic support Alice Guo (OSS)
2025-03-21 7:15 ` [PATCH v8 19/19] Makefile: add some files to CLEAN_FILES Alice Guo (OSS)
2025-03-22 2:20 ` [PATCH v8 00/19] imx: add i.MX95 support Marek Vasut
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox