summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2025-11-04 13:06:26 -0600
committerTom Rini <[email protected]>2025-11-04 13:06:26 -0600
commit1c250e444ad3b15315ee8b0fcb3fc3acc26449e2 (patch)
tree47cd432ccfc396c9fabd4631566289f120c01605
parentef34776f21969a71594dc6224d0e54cf5a2a980c (diff)
parent2b7892255bd617dfc523cfe8455dbf386a3dfaf5 (diff)
Merge tag 'u-boot-imx-master-20251104' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/28144 - Extend USB support for the i.MX9 family. - Update memory controller for imx6ulz_smm_m2. - Add remoteproc support for several i.MX boards. - Add support for iMX95 15x15 EVK.
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/dts/imx8mm-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx8mn-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx8mp-dhcom-pdk2-u-boot.dtsi20
-rw-r--r--arch/arm/dts/imx8mp-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx8mq-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx943-evk-u-boot.dtsi182
-rw-r--r--arch/arm/dts/imx943-u-boot.dtsi234
-rw-r--r--arch/arm/dts/imx95-15x15-evk-u-boot.dtsi85
-rw-r--r--arch/arm/include/asm/arch-imx9/imx-regs.h5
-rw-r--r--arch/arm/mach-imx/imx8m/Kconfig20
-rw-r--r--arch/arm/mach-imx/imx8ulp/soc.c17
-rw-r--r--arch/arm/mach-imx/imx9/Kconfig19
-rw-r--r--arch/arm/mach-imx/imx9/scmi/clock_scmi.c2
-rw-r--r--arch/arm/mach-imx/spl.c12
-rw-r--r--board/bsh/imx6ulz_smm_m2/Makefile2
-rw-r--r--board/bsh/imx6ulz_smm_m2/README67
-rw-r--r--board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m_m2b.c127
-rw-r--r--board/bsh/imx6ulz_smm_m2/spl.c2
-rw-r--r--board/freescale/imx95_evk/Kconfig2
-rw-r--r--board/freescale/imx95_evk/MAINTAINERS1
-rw-r--r--board/freescale/imx95_evk/imx95_evk.env (renamed from board/freescale/imx95_evk/imx95_19x19_evk.env)0
-rw-r--r--board/kontron/common/Kconfig14
-rw-r--r--board/kontron/common/Makefile1
-rw-r--r--board/kontron/common/hw-uid.c75
-rw-r--r--board/kontron/common/hw-uid.h26
-rw-r--r--board/kontron/sl-mx6ul/Kconfig2
-rw-r--r--board/kontron/sl-mx6ul/sl-mx6ul.c32
-rw-r--r--board/kontron/sl-mx8mm/Kconfig2
-rw-r--r--board/kontron/sl-mx8mm/sl-mx8mm.c32
-rw-r--r--board/kontron/sl-mx8mm/spl.c47
-rw-r--r--configs/dh_imx6.config1
-rw-r--r--configs/imx943_evk_defconfig30
-rw-r--r--configs/imx95_15x15_evk_defconfig148
-rw-r--r--configs/imx95_evk.config2
-rw-r--r--configs/kontron-sl-mx6ul_defconfig2
-rw-r--r--configs/kontron-sl-mx8mm_defconfig1
-rw-r--r--configs/toradex-smarc-imx95_defconfig1
-rw-r--r--doc/board/bsh/imx6ulz_bsh_smm_m2.rst85
-rw-r--r--doc/board/bsh/index.rst1
-rw-r--r--doc/board/nxp/imx95_evk.rst24
-rw-r--r--doc/board/nxp/index.rst1
-rw-r--r--doc/board/nxp/rproc.rst69
-rw-r--r--doc/usage/cmd/rproc.rst78
-rw-r--r--drivers/net/Kconfig5
-rw-r--r--drivers/net/fsl_enetc_mdio.c25
-rw-r--r--drivers/net/fsl_enetc_netc_blk_ctrl.c329
-rw-r--r--drivers/phy/Kconfig14
-rw-r--r--drivers/phy/Makefile2
-rw-r--r--drivers/remoteproc/Kconfig7
-rw-r--r--drivers/remoteproc/Makefile1
-rw-r--r--drivers/remoteproc/imx_rproc.c370
-rw-r--r--drivers/remoteproc/imx_rproc.h56
-rw-r--r--drivers/remoteproc/renesas_apmu.c3
-rw-r--r--drivers/remoteproc/rproc-elf-loader.c95
-rw-r--r--drivers/remoteproc/sandbox_testproc.c3
-rw-r--r--drivers/remoteproc/stm32_copro.c3
-rw-r--r--drivers/remoteproc/ti_k3_dsp_rproc.c2
-rw-r--r--drivers/remoteproc/ti_k3_m4_rproc.c2
-rw-r--r--drivers/remoteproc/ti_k3_r5f_rproc.c2
-rw-r--r--drivers/usb/gadget/f_sdp.c2
-rw-r--r--drivers/usb/host/Kconfig6
-rw-r--r--include/configs/dh_imx6.h1
-rw-r--r--include/configs/imx95_evk.h8
-rw-r--r--include/remoteproc.h3
65 files changed, 2292 insertions, 136 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 8c7d0e0ab2f..60772a494a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -317,8 +317,10 @@ F: arch/arm/include/asm/mach-imx/
F: board/freescale/*mx*/
F: board/freescale/common/
F: common/spl/spl_imx_container.c
+F: doc/board/nxp/
F: doc/imx/
F: drivers/mailbox/imx-mailbox.c
+F: drivers/remoteproc/imx*
F: drivers/serial/serial_mxc.c
F: include/imx_container.h
diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi
index eb5b95a1fda..d891e8062fe 100644
--- a/arch/arm/dts/imx8mm-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-u-boot.dtsi
@@ -15,6 +15,10 @@
};
};
#endif
+ imx8mm-cm4 {
+ compatible = "fsl,imx8mm-cm4";
+ syscon = <&src>;
+ };
};
#ifdef CONFIG_FSL_CAAM
diff --git a/arch/arm/dts/imx8mn-u-boot.dtsi b/arch/arm/dts/imx8mn-u-boot.dtsi
index 4a4498b36b0..29eecd6d70d 100644
--- a/arch/arm/dts/imx8mn-u-boot.dtsi
+++ b/arch/arm/dts/imx8mn-u-boot.dtsi
@@ -16,6 +16,10 @@
};
#endif
+ imx8mn-cm7 {
+ compatible = "fsl,imx8mn-cm7";
+ };
+
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
diff --git a/arch/arm/dts/imx8mp-dhcom-pdk2-u-boot.dtsi b/arch/arm/dts/imx8mp-dhcom-pdk2-u-boot.dtsi
index be2d4fb184a..b8b3abd0f03 100644
--- a/arch/arm/dts/imx8mp-dhcom-pdk2-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-dhcom-pdk2-u-boot.dtsi
@@ -4,3 +4,23 @@
*/
#include "imx8mp-dhcom-u-boot.dtsi"
+
+/ {
+ led {
+ led-0 {
+ function-enumerator = <0>;
+ };
+
+ led-1 {
+ function-enumerator = <1>;
+ };
+
+ led-2 {
+ function-enumerator = <2>;
+ };
+
+ led-3 {
+ function-enumerator = <3>;
+ };
+ };
+};
diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi
index 9ede98a11e4..d9d220c70db 100644
--- a/arch/arm/dts/imx8mp-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-u-boot.dtsi
@@ -16,6 +16,10 @@
};
};
#endif
+
+ imx8mp-cm7 {
+ compatible = "fsl,imx8mp-cm7";
+ };
};
#ifdef CONFIG_FSL_CAAM
diff --git a/arch/arm/dts/imx8mq-u-boot.dtsi b/arch/arm/dts/imx8mq-u-boot.dtsi
index 93e2ef27f7c..0687fcdbd68 100644
--- a/arch/arm/dts/imx8mq-u-boot.dtsi
+++ b/arch/arm/dts/imx8mq-u-boot.dtsi
@@ -7,6 +7,10 @@
binman: binman {
};
+ imx8mq-cm4 {
+ compatible = "fsl,imx8mq-cm4";
+ syscon = <&src>;
+ };
};
&soc {
diff --git a/arch/arm/dts/imx943-evk-u-boot.dtsi b/arch/arm/dts/imx943-evk-u-boot.dtsi
index 5496385dc4d..528b3b02a3f 100644
--- a/arch/arm/dts/imx943-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx943-evk-u-boot.dtsi
@@ -5,14 +5,146 @@
#include "imx943-u-boot.dtsi"
+&enetc1 {
+ clocks = <&scmi_clk IMX94_CLK_MAC4>;
+ clock-names = "enet_ref_clk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eth3>;
+ phy-handle = <&ethphy5>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&enetc2 {
+ clocks = <&scmi_clk IMX94_CLK_MAC5>;
+ clock-names = "enet_ref_clk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eth4>;
+ phy-handle = <&ethphy6>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&lpi2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c3>;
+ status = "okay";
+
+ pca9548_i2c3: i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x77>;
+
+ i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ pcal6416_i2c3_u171: gpio@21 {
+ compatible = "nxp,pcal6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ethphy2-on-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
+ ethphy3-on-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
+ ethphy4-on-hog {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
+ lvds-en-hog {
+ gpio-hog;
+ gpios = <9 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+ };
+ };
+ };
+};
+
&lpuart1 {
bootph-pre-ram;
};
+&netc_blk_ctrl {
+ assigned-clocks = <&scmi_clk IMX94_CLK_MAC2>,
+ <&scmi_clk IMX94_CLK_MAC4>,
+ <&scmi_clk IMX94_CLK_MAC5>;
+ assigned-clock-parents = <&scmi_clk IMX94_CLK_SYSPLL1_PFD0>,
+ <&scmi_clk IMX94_CLK_SYSPLL1_PFD0>,
+ <&scmi_clk IMX94_CLK_SYSPLL1_PFD0>;
+ assigned-clock-rates = <250000000>, <250000000>, <250000000>;
+ status = "okay";
+};
+
+&netc_emdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_emdio>;
+ phy-supply = <&reg_gpy_en>;
+ status = "okay";
+
+ ethphy5: ethernet-phy@6 {
+ reg = <0x6>;
+ realtek,clkout-disable;
+ };
+
+ ethphy6: ethernet-phy@7 {
+ reg = <0x7>;
+ realtek,clkout-disable;
+ };
+};
+
&reg_usdhc2_vmmc {
bootph-pre-ram;
};
+&usb2 {
+ dr_mode = "host";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ disable-over-current;
+ status = "okay";
+};
+
+&usb3 {
+ bootph-pre-ram;
+ status = "okay";
+};
+
+&usb3_dwc3 {
+ bootph-pre-ram;
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ role-switch-default-mode = "peripheral";
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ status = "okay";
+};
+
+&usb3_phy {
+ bootph-pre-ram;
+ orientation-switch;
+ status = "okay";
+};
+
&usdhc1 {
bootph-pre-ram;
};
@@ -25,6 +157,56 @@
status = "disabled";
};
+&scmi_iomuxc {
+ pinctrl_emdio: emdiogrp {
+ fsl,pins = <
+ IMX94_PAD_ETH4_MDC_GPIO1__NETC_EMDC 0x57e
+ IMX94_PAD_ETH4_MDIO_GPIO2__NETC_EMDIO 0x97e
+ >;
+ };
+
+ pinctrl_eth3: eth3grp {
+ fsl,pins = <
+ IMX94_PAD_ETH3_TXD3__NETC_PINMUX_ETH3_TXD3 0x57e
+ IMX94_PAD_ETH3_TXD2__NETC_PINMUX_ETH3_TXD2 0x57e
+ IMX94_PAD_ETH3_TXD1__NETC_PINMUX_ETH3_TXD1 0x57e
+ IMX94_PAD_ETH3_TXD0__NETC_PINMUX_ETH3_TXD0 0x57e
+ IMX94_PAD_ETH3_TX_CTL__NETC_PINMUX_ETH3_TX_CTL 0x57e
+ IMX94_PAD_ETH3_TX_CLK__NETC_PINMUX_ETH3_TX_CLK 0x5fe
+ IMX94_PAD_ETH3_RX_CTL__NETC_PINMUX_ETH3_RX_CTL 0x57e
+ IMX94_PAD_ETH3_RX_CLK__NETC_PINMUX_ETH3_RX_CLK 0x5fe
+ IMX94_PAD_ETH3_RXD0__NETC_PINMUX_ETH3_RXD0 0x57e
+ IMX94_PAD_ETH3_RXD1__NETC_PINMUX_ETH3_RXD1 0x57e
+ IMX94_PAD_ETH3_RXD2__NETC_PINMUX_ETH3_RXD2 0x57e
+ IMX94_PAD_ETH3_RXD3__NETC_PINMUX_ETH3_RXD3 0x57e
+ >;
+ };
+
+ pinctrl_eth4: eth4grp {
+ fsl,pins = <
+ IMX94_PAD_ETH4_TXD3__NETC_PINMUX_ETH4_TXD3 0x57e
+ IMX94_PAD_ETH4_TXD2__NETC_PINMUX_ETH4_TXD2 0x57e
+ IMX94_PAD_ETH4_TXD1__NETC_PINMUX_ETH4_TXD1 0x57e
+ IMX94_PAD_ETH4_TXD0__NETC_PINMUX_ETH4_TXD0 0x57e
+ IMX94_PAD_ETH4_TX_CTL__NETC_PINMUX_ETH4_TX_CTL 0x57e
+ IMX94_PAD_ETH4_TX_CLK__NETC_PINMUX_ETH4_TX_CLK 0x5fe
+ IMX94_PAD_ETH4_RX_CTL__NETC_PINMUX_ETH4_RX_CTL 0x57e
+ IMX94_PAD_ETH4_RX_CLK__NETC_PINMUX_ETH4_RX_CLK 0x5fe
+ IMX94_PAD_ETH4_RXD0__NETC_PINMUX_ETH4_RXD0 0x57e
+ IMX94_PAD_ETH4_RXD1__NETC_PINMUX_ETH4_RXD1 0x57e
+ IMX94_PAD_ETH4_RXD2__NETC_PINMUX_ETH4_RXD2 0x57e
+ IMX94_PAD_ETH4_RXD3__NETC_PINMUX_ETH4_RXD3 0x57e
+ >;
+ };
+
+ pinctrl_lpi2c3: lpi2c3grp {
+ fsl,pins = <
+ IMX94_PAD_GPIO_IO16__LPI2C3_SDA 0x40000b9e
+ IMX94_PAD_GPIO_IO17__LPI2C3_SCL 0x40000b9e
+ >;
+ };
+};
+
&pinctrl_reg_usdhc2_vmmc {
bootph-pre-ram;
};
diff --git a/arch/arm/dts/imx943-u-boot.dtsi b/arch/arm/dts/imx943-u-boot.dtsi
index 9c4882f7d79..2b93ba9a38b 100644
--- a/arch/arm/dts/imx943-u-boot.dtsi
+++ b/arch/arm/dts/imx943-u-boot.dtsi
@@ -83,6 +83,32 @@
};
};
};
+
+ reg_gpy_stby: regulator-gpy-stby {
+ compatible = "regulator-fixed";
+ regulator-name = "gpy-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pcal6416_i2c3_u171 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_gpy_en: regulator-gpy-en {
+ compatible = "regulator-fixed";
+ regulator-name = "gpy-en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&reg_gpy_stby>;
+ gpio = <&pcal6416_i2c3_u171 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ usbphynop: usbphynop {
+ compatible = "usb-nop-xceiv";
+ clocks = <&scmi_clk IMX94_CLK_HSIO>;
+ clock-names = "main_clk";
+ #phy-cells = <0>;
+ };
};
&cpu0 {
@@ -192,6 +218,214 @@
&{/soc} {
bootph-all;
+ usb3: usb@4c010010 {
+ compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
+ reg = <0x0 0x4c010010 0x0 0x04>,
+ <0x0 0x4c1f0000 0x0 0x20>;
+ ranges;
+ interrupts = <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ clocks = <&scmi_clk IMX94_CLK_HSIO>,
+ <&scmi_clk IMX94_CLK_32K>;
+ clock-names = "hsio", "suspend";
+ power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
+ status = "disabled";
+
+ usb3_dwc3: usb@4c100000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x4c100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX94_CLK_HSIO>,
+ <&scmi_clk IMX94_CLK_24M>,
+ <&scmi_clk IMX94_CLK_32K>;
+ clock-names = "bus_early", "ref", "suspend";
+ phys = <&usb3_phy>, <&usb3_phy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ snps,gfladj-refclk-lpm-sel-quirk;
+ snps,parkmode-disable-ss-quirk;
+ };
+ };
+
+ usb3_phy: phy@4c1f0040 {
+ compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
+ reg = <0x0 0x4c1f0040 0x0 0x40>,
+ <0x0 0x4c1fc000 0x0 0x100>;
+ clocks = <&scmi_clk IMX94_CLK_HSIO>;
+ clock-names = "phy";
+ #phy-cells = <0>;
+ power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
+ status = "disabled";
+ };
+
+ usb2: usb@4c200000 {
+ compatible = "fsl,imx95-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x0 0x4c200000 0x0 0x200>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scmi_clk IMX94_CLK_HSIO>,
+ <&scmi_clk IMX94_CLK_32K>;
+ clock-names = "usb_ctrl_root", "usb_wakeup";
+ power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
+ phys = <&usbphynop>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc@4c200200 {
+ compatible = "fsl,imx95-usbmisc", "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x0 0x4c200200 0x0 0x200>,
+ <0x0 0x4c010014 0x0 0x04>;
+ #index-cells = <1>;
+ };
+
+ netc_blk_ctrl: system-controller@4ceb0000 {
+ compatible = "nxp,imx94-netc-blk-ctrl";
+ reg = <0x0 0x4ceb0000 0x0 0x10000>,
+ <0x0 0x4cec0000 0x0 0x10000>,
+ <0x0 0x4c810000 0x0 0x7C>;
+ reg-names = "ierb", "prb", "netcmix";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ power-domains = <&scmi_devpd IMX94_PD_NETC>;
+ status = "disabled";
+
+ netc_bus0: pcie@4ca00000 {
+ compatible = "pci-host-ecam-generic";
+ reg = <0x0 0x4ca00000 0x0 0x100000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ bus-range = <0x0 0x0>;
+ /* Switch BAR0 - non-prefetchable memory */
+ ranges = <0x02000000 0x0 0x4cc00000 0x0 0x4cc00000 0x0 0x80000
+ /* ENETC 3 and Timer 0 BAR0 - non-prefetchable memory */
+ 0x02000000 0x0 0x4cd40000 0x0 0x4cd40000 0x0 0x60000
+ /* Switch and Timer 0 BAR2 - prefetchable memory */
+ 0x42000000 0x0 0x4ce00000 0x0 0x4ce00000 0x0 0x20000
+ /* ENETC 3 VF0-2 BAR0 - non-prefetchable memory */
+ 0x02000000 0x0 0x4ce50000 0x0 0x4ce50000 0x0 0x30000
+ /* ENETC 3 VF0-2 BAR2 - prefetchable memory */
+ 0x42000000 0x0 0x4ce80000 0x0 0x4ce80000 0x0 0x30000>;
+
+ enetc3: ethernet@0,0 {
+ compatible = "pci1131,e110";
+ reg = <0x0 0 0 0 0>;
+ phy-mode = "internal";
+ status = "disabled";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ netc_timer0: ethernet@0,1 {
+ compatible = "pci1131,ee02";
+ reg = <0x100 0 0 0 0>;
+ status = "disabled";
+ };
+
+ netc_switch: ethernet-switch@0,2 {
+ compatible = "pci1131,eef2", "nxp,imx943-netc-switch";
+ reg = <0x200 0 0 0 0>;
+ status = "disabled";
+
+ netc_switch_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* External ports */
+ netc_switch_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ netc_switch_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ netc_switch_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ /* Internal port, a.k.a management port */
+ netc_switch_port3: port@3 {
+ reg = <3>;
+ phy-mode = "internal";
+ ethernet = <&enetc3>;
+ status = "disabled";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+ };
+ };
+
+ netc_bus1: pcie@4cb00000 {
+ compatible = "pci-host-ecam-generic";
+ reg = <0x0 0x4cb00000 0x0 0x100000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ linux,pci-domain = <1>;
+ bus-range = <0x1 0x1>;
+ /* ENETC 0-2 BAR0 - non-prefetchable memory */
+ ranges = <0x02000000 0x0 0x4cC80000 0x0 0x4cc80000 0x0 0xc0000
+ /* Timer 1-2 and EMDIO BAR0 - non-prefetchable memory */
+ 0x02000000 0x0 0x4cda0000 0x0 0x4cda0000 0x0 0x60000
+ /* Timer 1-2 and EMDIO BAR2 - prefetchable memory */
+ 0x42000000 0x0 0x4ce20000 0x0 0x4ce20000 0x0 0x30000>;
+
+ enetc0: ethernet@0,0 {
+ compatible = "pci1131,e101";
+ reg = <0x10000 0 0 0 0>;
+ status = "disabled";
+ };
+
+ netc_timer1: ethernet@0,1 {
+ compatible = "pci1131,ee02";
+ reg = <0x10100 0 0 0 0>;
+ status = "disabled";
+ };
+
+ enetc1: ethernet@8,0 {
+ compatible = "pci1131,e101";
+ reg = <0x14000 0 0 0 0>;
+ status = "disabled";
+ };
+
+ enetc2: ethernet@10,0 {
+ compatible = "pci1131,e101";
+ reg = <0x18000 0 0 0 0>;
+ status = "disabled";
+ };
+
+ netc_timer2: ethernet@10,1 {
+ compatible = "pci1131,ee02";
+ reg = <0x18100 0 0 0 0>;
+ status = "disabled";
+ };
+
+ netc_emdio: mdio@18,0 {
+ compatible = "pci1131,ee00";
+ reg = <0x1c000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+ };
+
elemu1: mailbox@47530000 {
compatible = "fsl,imx93-mu-s4";
reg = <0x0 0x47530000 0x0 0x10000>;
diff --git a/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi b/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi
new file mode 100644
index 00000000000..514dd729be9
--- /dev/null
+++ b/arch/arm/dts/imx95-15x15-evk-u-boot.dtsi
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 NXP
+ */
+
+#include "imx95-u-boot.dtsi"
+
+/ {
+ aliases {
+ pci0 = &netc_bus0;
+ pci1 = &netc_bus1;
+ };
+};
+
+&{/binman/m33-oei-ddrfw/imx-lpddr/imx-lpddr-imem} {
+ filename = "lpddr4x_imem_v202409.bin";
+};
+
+&{/binman/m33-oei-ddrfw/imx-lpddr/imx-lpddr-dmem} {
+ filename = "lpddr4x_dmem_v202409.bin";
+};
+
+&{/binman/m33-oei-ddrfw/imx-lpddr-qb/imx-lpddr-imem-qb} {
+ filename = "lpddr4x_imem_qb_v202409.bin";
+};
+
+&{/binman/m33-oei-ddrfw/imx-lpddr-qb/imx-lpddr-dmem-qb} {
+ filename = "lpddr4x_dmem_qb_v202409.bin";
+};
+
+&lpuart1 {
+ bootph-pre-ram;
+};
+
+&reg_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/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h
index e641ed299c0..2d084e5227a 100644
--- a/arch/arm/include/asm/arch-imx9/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx9/imx-regs.h
@@ -39,6 +39,11 @@
#define ANATOP_BASE_ADDR 0x44480000UL
+#define USB1_BASE_ADDR 0x4c100000
+#define USB2_BASE_ADDR 0x4c200000
+
+#define USB_BASE_ADDR USB2_BASE_ADDR
+
#define BLK_CTRL_WAKEUPMIX_BASE_ADDR 0x42420000
#define BLK_CTRL_NS_ANOMIX_BASE_ADDR 0x44210000
#define BLK_CTRL_S_ANOMIX_BASE_ADDR 0x444f0000
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index f7b80f3178a..030ed2f0633 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -67,6 +67,10 @@ config TARGET_IMX8MQ_EVK
select FSL_CAAM
select ARCH_MISC_INIT
select SPL_CRYPTO if SPL
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
@@ -95,6 +99,10 @@ config TARGET_IMX8MM_EVK
select FSL_CAAM
select ARCH_MISC_INIT
select SPL_CRYPTO if SPL
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
imply OF_UPSTREAM
@@ -171,6 +179,10 @@ config TARGET_IMX8MN_EVK
select IMX8M_LPDDR4
select FSL_CAAM
select SPL_CRYPTO if SPL
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
@@ -182,6 +194,10 @@ config TARGET_IMX8MN_DDR4_EVK
select IMX8M_DDR4
select FSL_CAAM
select SPL_CRYPTO if SPL
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
@@ -248,6 +264,10 @@ config TARGET_IMX8MP_EVK
select FSL_CAAM
select ARCH_MISC_INIT
select SPL_CRYPTO if SPL
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c
index 04c6f064130..1ee483065e8 100644
--- a/arch/arm/mach-imx/imx8ulp/soc.c
+++ b/arch/arm/mach-imx/imx8ulp/soc.c
@@ -384,7 +384,22 @@ static struct mm_region imx8ulp_arm64_mem_map[] = {
/* SRAM0 (align with 2M) */
.virt = 0x22000000UL,
.phys = 0x22000000UL,
- .size = 0x200000UL,
+ .size = 0x1f000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* SCMI shared memory buffer must be mapped as non-cacheable. */
+ .virt = 0x2201f000UL,
+ .phys = 0x2201f000UL,
+ .size = 0x1000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ .virt = 0x22020000UL,
+ .phys = 0x22020000UL,
+ .size = 0x1e0000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig
index 6ad02b9d581..d9725a96043 100644
--- a/arch/arm/mach-imx/imx9/Kconfig
+++ b/arch/arm/mach-imx/imx9/Kconfig
@@ -69,6 +69,10 @@ config TARGET_IMX93_9X9_QSB
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
config TARGET_IMX93_11X11_EVK
bool "imx93_11x11_evk"
@@ -77,6 +81,10 @@ config TARGET_IMX93_11X11_EVK
imply OF_UPSTREAM
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
config TARGET_IMX93_FRDM
bool "imx93_frdm"
@@ -85,6 +93,10 @@ config TARGET_IMX93_FRDM
select IMX9_LPDDR4X
imply BOOTSTD_FULL
imply BOOTSTD_BOOTCOMMAND
+ select CMD_REMOTEPROC
+ select REMOTEPROC_IMX
+ select REGMAP
+ select SYSCON
config TARGET_IMX93_VAR_SOM
bool "imx93_var_som"
@@ -106,6 +118,13 @@ config TARGET_IMX95_19X19_EVK
imply BOOTSTD_FULL
imply OF_UPSTREAM
+config TARGET_IMX95_15X15_EVK
+ bool "imx95_15x15_evk"
+ select IMX95
+ imply BOOTSTD_BOOTCOMMAND
+ imply BOOTSTD_FULL
+ imply OF_UPSTREAM
+
config TARGET_IMX943_EVK
bool "imx943_evk"
select IMX94
diff --git a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c
index fa15b5f8df9..b6be20ec674 100644
--- a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c
+++ b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c
@@ -12,7 +12,7 @@ int imx_clk_scmi_enable(u32 clock_id, bool enable)
{
struct scmi_clk_state_in in = {
.clock_id = clock_id,
- .attributes = (enable) ? 1 : 0,
+ .attributes = !!enable,
};
struct scmi_clk_state_out out;
struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 518d9cb1262..57ae81c7834 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -21,6 +21,8 @@
#include <g_dnl.h>
#include <linux/libfdt.h>
#include <memalign.h>
+#include <asm/setup.h>
+#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -184,6 +186,16 @@ u32 spl_boot_device(void)
#ifdef CONFIG_SPL_USB_GADGET
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#ifdef CONFIG_IMX94
+ struct tag_serialnr serialnr;
+ char serial_string[0x21] = {0};
+
+ get_board_serial(&serialnr);
+ snprintf(serial_string, sizeof(serial_string), "%08x%08x", serialnr.high, serialnr.low);
+ g_dnl_set_serialnumber(serial_string);
+#endif
+#endif
put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM + 0xfff, &dev->idProduct);
return 0;
diff --git a/board/bsh/imx6ulz_smm_m2/Makefile b/board/bsh/imx6ulz_smm_m2/Makefile
index 233bbff4c16..5ab00a5ea75 100644
--- a/board/bsh/imx6ulz_smm_m2/Makefile
+++ b/board/bsh/imx6ulz_smm_m2/Makefile
@@ -4,4 +4,4 @@
obj-y := imx6ulz_smm_m2.o
obj-$(CONFIG_XPL_BUILD) += spl.o
obj-$(CONFIG_BSH_M2_MEMORY) += ddr3l_timing_512m.o ddr3l_timing_256m.o ddr3l_timing_128m.o
-obj-$(CONFIG_BSH_M2B_MEMORY) += ddr3l_timing_256m_m2b.o ddr3l_timing_128m_m2b.o
+obj-$(CONFIG_BSH_M2B_MEMORY) += ddr3l_timing_512m_m2b.o ddr3l_timing_256m_m2b.o ddr3l_timing_128m_m2b.o
diff --git a/board/bsh/imx6ulz_smm_m2/README b/board/bsh/imx6ulz_smm_m2/README
deleted file mode 100644
index 03d01325a97..00000000000
--- a/board/bsh/imx6ulz_smm_m2/README
+++ /dev/null
@@ -1,67 +0,0 @@
-How to Update U-Boot on imx6ulz_smm_m2 board
---------------------------------------------
-
-Required software on the host PC:
-
-- UUU: https://github.com/NXPmicro/mfgtools
-
-Build U-Boot for m2:
-
-$ make mrproper
-$ make imx6ulz_smm_m2_defconfig
-$ make
-
-This generates the SPL and u-boot-dtb.img binaries.
-
-1. Loading U-Boot via USB Serial Download Protocol
-
-Copy SPL and u-boot-dtb.img to the uuu folder.
-
-Load the U-Boot via USB:
-
-$ sudo uuu -v -b nand_script.lst u-boot-with-spl.imx
-
-where nand_script.lst contains the following:
-
-uuu_version 1.2.39
-
-# @_flash.bin | bootloader
-# @_image [_flash.bin] | image burn to nand, default is the same as bootloader
-
-# This command will be run when i.MX6/7 i.MX8MM, i.MX8MQ
-SDP: boot -f _flash.bin
-
-# This command will be run when ROM support stream mode
-# i.MX8QXP, i.MX8QM
-SDPS: boot -f _flash.bin
-
-# These commands will be run when use SPL and will be skipped if no spl
-# SDPU will be deprecated. please use SDPV instead of SDPU
-# {
-SDPU: delay 1000
-SDPU: write -f _flash.bin -offset 0x57c00
-SDPU: jump
-# }
-
-# These commands will be run when use SPL and will be skipped if no spl
-# if (SPL support SDPV)
-# {
-SDPV: delay 1000
-SDPV: write -f _flash.bin -offset 0x11000
-SDPV: jump
-# }
-
-FB: ucmd setenv fastboot_buffer ${loadaddr}
-FB: download -f _image
-FB: ucmd if test ! -n "$fastboot_bytes"; then setenv fastboot_bytes $filesize; else true; fi
-# Burn image to nandfit partition if needed
-FB: ucmd if env exists nandfit_part; then nand erase.part nandfit; nand write ${fastboot_buffer} nandfit ${fastboot_bytes}; else true; fi;
-FB: ucmd nandbcb init ${fastboot_buffer} nandboot ${fastboot_bytes}
-FB: Done
-
-Then U-Boot starts and its messages appear in the console program.
-
-Use the default environment variables:
-
-=> env default -f -a
-=> saveenv
diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m_m2b.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m_m2b.c
new file mode 100644
index 00000000000..04d39a9bdd6
--- /dev/null
+++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m_m2b.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "spl_mtypes.h"
+
+static const struct dram_cfg_param ddr_ddrc_cfg_512mb[] = {
+ /* ============================================================================= */
+ /* IOMUX */
+ /* ============================================================================= */
+ /* DDR IO TYPE: */
+ {0x020E04B4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */
+ {0x020E04AC, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */
+
+ /* CLOCK: */
+ {0x020E027C, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P */
+
+ /* Control: */
+ {0x020E0250, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */
+ {0x020E024C, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */
+ {0x020E0490, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */
+ {0x020E0288, 0x000C0030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */
+ {0x020E0270, 0x00000000}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 */
+ /* DSE can be configured using Group Control Register: */
+ /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */
+ {0x020E0260, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT0 */
+ {0x020E0264, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT1 */
+ {0x020E04A0, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */
+
+ /* Data Strobes: */
+ {0x020E0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */
+ {0x020E0280, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P */
+ {0x020E0284, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P */
+
+ /* Data: */
+ {0x020E04B0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */
+ {0x020E0498, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */
+ {0x020E04A4, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */
+ {0x020E0244, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */
+ {0x020E0248, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */
+
+ /* ============================================================================= */
+ /* DDR Controller Registers */
+ /* ============================================================================= */
+ /* Manufacturer 1:NANYA */
+ /* Device Part Number 1:NT5CC256M16ER-EKI */
+ /* Manufacturer 2:MICRON */
+ /* Device Part Number 2:MT41K256M16TW-107 */
+ /* Clock Freq.: 400MHz */
+ /* Density per CS in Gb: 4 */
+ /* Chip Selects used:1 */
+ /* Total DRAM density (Gb)4 */
+ /* Number of Banks:8 */
+ /* Row address: 15 */
+ /* Column address: 10 */
+ /* Data bus width16 */
+ /* ============================================================================= */
+ {0x021B001C, 0x00008000}, /* [MMDC_MDSCR] MMDC Core Special Command Register */
+
+ /* ====================================================== */
+ /* Calibrations: */
+ /* ====================================================== */
+ {0x021B0800, 0xA1390003}, /* DDR_PHY_P0_MPZQHWCTRL, */
+ /* enable both one-time & periodic HW ZQ calibration. */
+
+ {0x021B080C, 0x00060002},
+ /* [MMDC_MPWLDECTRL0] MMDC PHY Write Leveling Delay Control Register 0 */
+ {0x021B083C, 0x41500158},
+ /* [MMDC_MPDGCTRL0] MMDC PHY Read DQS Gating Control Register 0 */
+ {0x021B0848, 0x40403A3E},
+ /* [MMDC_MPRDDLCTL] MMDC PHY Read delay-lines Configuration Register */
+ {0x021B0850, 0x40402E28},
+ /* [MMDC_MPWRDLCTL] MMDC PHY Write delay-lines Configuration Register */
+
+ {0x021B081C, 0x33333333}, /* [MMDC_MPRDDQBY0DL] MMDC PHY Read DQ Byte0 Delay Register */
+ {0x021B0820, 0x33333333}, /* [MMDC_MPRDDQBY1DL] MMDC PHY Read DQ Byte1 Delay Register */
+
+ {0x021B082C, 0xf3333333}, /* [MMDC_MPWRDQBY0DL] MMDC PHY Write DQ Byte0 Delay Register */
+ {0x021B0830, 0xf3333333}, /* [MMDC_MPWRDQBY1DL] MMDC PHY Write DQ Byte1 Delay Register */
+
+ {0x021B08C0, 0x00944009}, /* [MMDC_MPDCCR] MMDC Duty Cycle Control Register */
+
+ /* Complete calibration by forced measurement: */
+ {0x021B08B8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */
+
+ /* ====================================================== */
+ /* MMDC init: */
+ /* ====================================================== */
+ {0x021B0004, 0x0002002D}, /* MMDC0_MDPDC */
+ {0x021B0008, 0x1B333030}, /* MMDC0_MDOTC */
+ {0x021B000C, 0x616552F3}, /* MMDC0_MDCFG0 */
+ {0x021B0010, 0xB62C0A63}, /* MMDC0_MDCFG1 */
+ {0x021B0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */
+ {0x021B0018, 0x00201740}, /* MMDC0_MDMISC */
+ {0x021B002C, 0x000026D2}, /* MMDC0_MDRWD; recommend to maintain the default values */
+ {0x021B0030, 0x00651023}, /* MMDC0_MDOR */
+ {0x021B0040, 0x0000004F}, /* CS0_END */
+ {0x021B0000, 0x84180000}, /* MMDC0_MDCTL */
+
+ /* Mode register writes for CS0 */
+ {0x021B001C, 0x02008032}, /* MMDC0_MDSCR, MR2 write, CS0 */
+ {0x021B001C, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */
+ {0x021B001C, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */
+ {0x021B001C, 0x15208030}, /* MMDC0_MDSCR, MR0 write, CS0 */
+ {0x021B001C, 0x04008040},
+ /* MMDC0_MDSCR, ZQ calibration command sent to device on CS0 */
+
+ /* Mode register writes for CS, commented out automatically if only */
+ /* one chip select used */
+ /* {0x021B001C,0x0200803A}, */
+ /* {0x021B001C,0x0000803B}, */
+ /* {0x021B001C,0x00048039}, */
+ /* {0x021B001C,0x15208038}, */
+ /* {0x021B001C,0x04008048}, */
+
+ /* final DDR setup, before operation start: */
+ {0x021B0020, 0x00000800}, /* MMDC0_MDREF */
+ {0x021B0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */
+ {0x021B0004, 0x0002556D}, /* MMDC0_MDPDC now SDCTL power down enabled */
+ {0x021B0404, 0x00011006}, /* MMDC0_MAPSR ADOPT power down enabled */
+ {0x021B001C, 0x00000000}, /* MMDC0_MDSCR, clear this register */
+ /* (especially the configuration bit as initialization is complete) */
+};
+
+struct dram_timing_info bsh_dram_timing_512mb = {
+ .ddrc_cfg = ddr_ddrc_cfg_512mb,
+ .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_512mb),
+ .dram_size = SZ_512M,
+};
diff --git a/board/bsh/imx6ulz_smm_m2/spl.c b/board/bsh/imx6ulz_smm_m2/spl.c
index 7aea73f0f5d..580f5ab9dff 100644
--- a/board/bsh/imx6ulz_smm_m2/spl.c
+++ b/board/bsh/imx6ulz_smm_m2/spl.c
@@ -53,9 +53,7 @@ static void ddr_cfg_write(const struct dram_timing_info *dram_timing_info)
}
static const struct dram_timing_info *board_dram_timing[] = {
-#if defined(CONFIG_M2_MEMORY)
&bsh_dram_timing_512mb,
-#endif
&bsh_dram_timing_256mb,
&bsh_dram_timing_128mb,
};
diff --git a/board/freescale/imx95_evk/Kconfig b/board/freescale/imx95_evk/Kconfig
index f9a67353e5d..bf746e091de 100644
--- a/board/freescale/imx95_evk/Kconfig
+++ b/board/freescale/imx95_evk/Kconfig
@@ -1,4 +1,4 @@
-if TARGET_IMX95_19X19_EVK
+if TARGET_IMX95_19X19_EVK || TARGET_IMX95_15X15_EVK
config SYS_BOARD
default "imx95_evk"
diff --git a/board/freescale/imx95_evk/MAINTAINERS b/board/freescale/imx95_evk/MAINTAINERS
index 9d5c4e41b65..bc27786f70d 100644
--- a/board/freescale/imx95_evk/MAINTAINERS
+++ b/board/freescale/imx95_evk/MAINTAINERS
@@ -5,3 +5,4 @@ F: board/freescale/imx95_evk/
F: include/configs/imx95_evk.h
F: configs/imx95_a0_19x19_evk_defconfig
F: configs/imx95_19x19_evk_defconfig
+F: configs/imx95_15x15_evk_defconfig
diff --git a/board/freescale/imx95_evk/imx95_19x19_evk.env b/board/freescale/imx95_evk/imx95_evk.env
index a7309d734b0..a7309d734b0 100644
--- a/board/freescale/imx95_evk/imx95_19x19_evk.env
+++ b/board/freescale/imx95_evk/imx95_evk.env
diff --git a/board/kontron/common/Kconfig b/board/kontron/common/Kconfig
new file mode 100644
index 00000000000..d581006c203
--- /dev/null
+++ b/board/kontron/common/Kconfig
@@ -0,0 +1,14 @@
+menuconfig KONTRON_HW_UID
+ bool "Enable reading Kontron HW UID from OTP fuses"
+ help
+ Enable support for reading Kontron hardware UIDs from OTP fuse registers.
+ The UIDs are factory-programmed for SoMs and boards and are printed to the
+ console and used as serial numbers if this option is enabled.
+
+menuconfig KONTRON_HW_UID_USE_SOC_FALLBACK
+ bool "Use the unique ID of the SoC as fallback serial number"
+ depends on KONTRON_HW_UID
+ default n
+ help
+ Enable the fallback to the UID of the SoC programmed by the SoC
+ manufacturer if no Kontron UID is found in the OTP fuses.
diff --git a/board/kontron/common/Makefile b/board/kontron/common/Makefile
new file mode 100644
index 00000000000..634744dc542
--- /dev/null
+++ b/board/kontron/common/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_KONTRON_HW_UID) += hw-uid.o
diff --git a/board/kontron/common/hw-uid.c b/board/kontron/common/hw-uid.c
new file mode 100644
index 00000000000..5358b1dfcf1
--- /dev/null
+++ b/board/kontron/common/hw-uid.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Kontron Electronics GmbH
+ */
+
+#include <linux/errno.h>
+#include <compiler.h>
+#include <asm/io.h>
+#include <env.h>
+#include <string.h>
+#include <vsprintf.h>
+
+#include "hw-uid.h"
+
+int get_serial_str_from_otp(struct uid_otp_loc loc, char *str, size_t str_len)
+{
+ u64 uid;
+ int ret;
+
+ if (loc.len < 1 || loc.len > 2) {
+ printf("Invalid number of UID OTP registers set!\n");
+ return -EINVAL;
+ }
+
+ uid = readl(loc.addr);
+
+ if (loc.len == 2)
+ uid |= (u64)readl(loc.addr + 0x4) << 32;
+
+ if (!uid)
+ return -ENOENT;
+
+ if (uid) {
+ switch (loc.format) {
+ case UID_OTP_FORMAT_DEC:
+ ret = snprintf(str, str_len, "%010llu", uid);
+ break;
+ case UID_OTP_FORMAT_HEX:
+ ret = snprintf(str, str_len, "%016llX", uid);
+ break;
+ }
+ if (ret < 0 || ret >= str_len) {
+ printf("Failed to convert UID!\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+void get_serial_number(struct uid_otp_loc *locs, unsigned int num)
+{
+ char serial_string[17];
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < num; i++) {
+ ret = get_serial_str_from_otp(locs[i], serial_string, sizeof(serial_string));
+ if (ret == 0)
+ break;
+ }
+
+ /* No valid UID in the OTP fuses, skip. */
+ if (ret) {
+ printf("Serial Number: None\n");
+ return;
+ }
+
+ printf("Serial Number: %s (%s)\n", serial_string, locs[i].desc);
+
+ if (!env_get("serial#"))
+ env_set("serial#", serial_string);
+ else if (strcmp(env_get("serial#"), serial_string))
+ printf("Warning: mismatch of UIDs in env and OTPs!\n");
+}
diff --git a/board/kontron/common/hw-uid.h b/board/kontron/common/hw-uid.h
new file mode 100644
index 00000000000..7eaf2cc9b6c
--- /dev/null
+++ b/board/kontron/common/hw-uid.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024 Kontron Electronics GmbH
+ */
+
+#ifndef _KONTRON_HW_UID_H
+#define _KONTRON_HW_UID_H
+
+#include <compiler.h>
+#include <stddef.h>
+
+enum {
+ UID_OTP_FORMAT_DEC = 0,
+ UID_OTP_FORMAT_HEX,
+};
+
+struct uid_otp_loc {
+ u32 *addr;
+ size_t len;
+ unsigned int format;
+ char *desc;
+};
+
+void get_serial_number(struct uid_otp_loc *locs, unsigned int num);
+
+#endif /* _KONTRON_HW_UID_H */
diff --git a/board/kontron/sl-mx6ul/Kconfig b/board/kontron/sl-mx6ul/Kconfig
index 7a4ffbed289..a6d3fa49778 100644
--- a/board/kontron/sl-mx6ul/Kconfig
+++ b/board/kontron/sl-mx6ul/Kconfig
@@ -9,4 +9,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "kontron-sl-mx6ul"
+source "board/kontron/common/Kconfig"
+
endif
diff --git a/board/kontron/sl-mx6ul/sl-mx6ul.c b/board/kontron/sl-mx6ul/sl-mx6ul.c
index 65f9b75c1a0..9dda8822ef9 100644
--- a/board/kontron/sl-mx6ul/sl-mx6ul.c
+++ b/board/kontron/sl-mx6ul/sl-mx6ul.c
@@ -14,8 +14,37 @@
#include "sl-mx6ul-common.h"
+#include "../common/hw-uid.h"
+
DECLARE_GLOBAL_DATA_PTR;
+#if IS_ENABLED(CONFIG_KONTRON_HW_UID)
+
+struct uid_otp_loc uid_otp_locations[] = {
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x670),
+ .len = 1,
+ .format = UID_OTP_FORMAT_DEC,
+ .desc = "BOARD"
+ },
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x660),
+ .len = 1,
+ .format = UID_OTP_FORMAT_DEC,
+ .desc = "SOM"
+ },
+#if IS_ENABLED(CONFIG_KONTRON_HW_UID_USE_SOC_FALLBACK)
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x410),
+ .len = 2,
+ .format = UID_OTP_FORMAT_HEX,
+ .desc = "SOC"
+ }
+#endif
+};
+
+#endif /* CONFIG_KONTRON_HW_UID */
+
int dram_init(void)
{
gd->ram_size = imx_ddr_size();
@@ -91,6 +120,9 @@ int board_init(void)
int board_late_init(void)
{
+ if (IS_ENABLED(CONFIG_KONTRON_HW_UID))
+ get_serial_number(uid_otp_locations, ARRAY_SIZE(uid_otp_locations));
+
if (is_boot_from_usb()) {
env_set("bootdelay", "0");
env_set("bootcmd", "fastboot 0");
diff --git a/board/kontron/sl-mx8mm/Kconfig b/board/kontron/sl-mx8mm/Kconfig
index 1597bcf894d..0a5123d2979 100644
--- a/board/kontron/sl-mx8mm/Kconfig
+++ b/board/kontron/sl-mx8mm/Kconfig
@@ -9,4 +9,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "kontron-sl-mx8mm"
+source "board/kontron/common/Kconfig"
+
endif
diff --git a/board/kontron/sl-mx8mm/sl-mx8mm.c b/board/kontron/sl-mx8mm/sl-mx8mm.c
index df92765cb2d..d24d5286e45 100644
--- a/board/kontron/sl-mx8mm/sl-mx8mm.c
+++ b/board/kontron/sl-mx8mm/sl-mx8mm.c
@@ -18,8 +18,37 @@
#include <mmc.h>
#include <net.h>
+#include "../common/hw-uid.h"
+
DECLARE_GLOBAL_DATA_PTR;
+#if IS_ENABLED(CONFIG_KONTRON_HW_UID)
+
+struct uid_otp_loc uid_otp_locations[] = {
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x7A0),
+ .len = 2,
+ .format = UID_OTP_FORMAT_DEC,
+ .desc = "BOARD"
+ },
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x780),
+ .len = 2,
+ .format = UID_OTP_FORMAT_DEC,
+ .desc = "SOM"
+ },
+#if IS_ENABLED(CONFIG_KONTRON_HW_UID_USE_SOC_FALLBACK)
+ {
+ .addr = (u32 *)(OCOTP_BASE_ADDR + 0x410),
+ .len = 2,
+ .format = UID_OTP_FORMAT_HEX,
+ .desc = "SOC"
+ }
+#endif
+};
+
+#endif /* CONFIG_KONTRON_HW_UID */
+
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
struct efi_fw_image fw_images[] = {
{
@@ -167,6 +196,9 @@ int board_late_init(void)
env_set("touch_rst_gpio", "87");
}
+ if (IS_ENABLED(CONFIG_KONTRON_HW_UID))
+ get_serial_number(uid_otp_locations, ARRAY_SIZE(uid_otp_locations));
+
if (is_usb_boot()) {
env_set("bootcmd", "fastboot 0");
env_set("bootdelay", "0");
diff --git a/board/kontron/sl-mx8mm/spl.c b/board/kontron/sl-mx8mm/spl.c
index e3b029752b8..a5cdd2ab6d1 100644
--- a/board/kontron/sl-mx8mm/spl.c
+++ b/board/kontron/sl-mx8mm/spl.c
@@ -186,6 +186,53 @@ static int power_init_board(void)
return 0;
}
+unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
+{
+ /*
+ * The image offset on SD/MMC devices is 33 KiB, except for eMMC boot if
+ * fastboot is enabled. In this case it is 1 KiB. In order to make the
+ * bootloader universal, check the fastboot OTP boot fuse and adjust
+ * the offset.
+ */
+ if (!IS_SD(mmc) && (readl(OCOTP_BASE_ADDR + 0x470) & 0x80)) {
+ switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
+ case EMMC_BOOT_PART_BOOT1:
+ case EMMC_BOOT_PART_BOOT2:
+ raw_sect -= 32 * 2;
+ break;
+ }
+ }
+
+ return raw_sect;
+}
+
+const char *spl_board_loader_name(u32 boot_device)
+{
+ static char name[16];
+ struct mmc *mmc;
+
+ switch (boot_device) {
+ case BOOT_DEVICE_SPI:
+ sprintf(name, "SPI NOR");
+ return name;
+ case BOOT_DEVICE_MMC1:
+ mmc_init_device(0);
+ mmc = find_mmc_device(0);
+ mmc_init(mmc);
+ snprintf(name, sizeof(name), "eMMC %s",
+ emmc_hwpart_names[EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)]);
+ return name;
+ case BOOT_DEVICE_MMC2:
+ sprintf(name, "SD card");
+ return name;
+ case BOOT_DEVICE_BOARD:
+ sprintf(name, "USB OTG");
+ return name;
+ }
+
+ return NULL;
+}
+
void board_init_f(ulong dummy)
{
int ret;
diff --git a/configs/dh_imx6.config b/configs/dh_imx6.config
index 01db41be2a0..b1eeb8901f4 100644
--- a/configs/dh_imx6.config
+++ b/configs/dh_imx6.config
@@ -60,6 +60,7 @@ CONFIG_MISC=y
CONFIG_PINCTRL_IMX6=y
+CONFIG_DFU_SF=y
CONFIG_SDP_LOADADDR=0x17ffffc0
CONFIG_SPL_FIT=y
CONFIG_SPL_SPI=y
diff --git a/configs/imx943_evk_defconfig b/configs/imx943_evk_defconfig
index 27230ed3207..39b616e266e 100644
--- a/configs/imx943_evk_defconfig
+++ b/configs/imx943_evk_defconfig
@@ -39,6 +39,7 @@ CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2074
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_LATE_INIT=y
+CONFIG_PCI_INIT_R=y
CONFIG_SPL_MAX_SIZE=0x30000
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_LOAD_IMX_CONTAINER=y
@@ -66,6 +67,7 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_USB=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
@@ -82,6 +84,8 @@ CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_REGMAP=y
@@ -96,9 +100,21 @@ CONFIG_SPL_CLK_SCMI=y
CONFIG_SPL_FIRMWARE=y
# CONFIG_SCMI_AGENT_SMCCC is not set
CONFIG_IMX_RGPIO2P=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
CONFIG_IMX_MU_MBOX=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_FSL_USDHC=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DM_MDIO=y
+CONFIG_FSL_ENETC=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SPL_PHY=y
+CONFIG_SPL_PHY_IMX8MQ_USB=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_IMX_SCMI=y
@@ -112,4 +128,18 @@ CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_DM_SERIAL=y
CONFIG_FSL_LPUART=y
+CONFIG_USB=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_SPL_USB_DWC3_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="FSL"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0525
+CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
+CONFIG_SDP_LOADADDR=0x90400000
+CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_ULP_WATCHDOG=y
diff --git a/configs/imx95_15x15_evk_defconfig b/configs/imx95_15x15_evk_defconfig
new file mode 100644
index 00000000000..96b1d2a64af
--- /dev/null
+++ b/configs/imx95_15x15_evk_defconfig
@@ -0,0 +1,148 @@
+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_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-15x15-evk"
+CONFIG_TARGET_IMX95_15X15_EVK=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SYS_MONITOR_LEN=524288
+CONFIG_SPL_MMC=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_TEXT_BASE=0x20480000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x204d6000
+CONFIG_SPL_BSS_MAX_SIZE=0x2000
+CONFIG_SYS_LOAD_ADDR=0x90400000
+CONFIG_SPL=y
+CONFIG_SPL_RECOVER_DATA_SECTION=y
+CONFIG_PCI=y
+CONFIG_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-15x15-evk.dtb"
+CONFIG_SYS_CBSIZE=2048
+CONFIG_SYS_PBSIZE=2074
+CONFIG_BOARD_EARLY_INIT_F=y
+# CONFIG_BOARD_INIT is not set
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_PCI_INIT_R=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_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_MMC_DEVICE_INDEX=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_SPL_OF_TRANSLATE=y
+CONFIG_SPL_CLK=y
+CONFIG_SPL_CLK_CCF=y
+CONFIG_CLK_SCMI=y
+CONFIG_SPL_CLK_SCMI=y
+CONFIG_CLK_IMX95_BLKCTRL=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_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_PCIE_DW_IMX=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_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/configs/imx95_evk.config b/configs/imx95_evk.config
index 231b42cb377..631ec23c335 100644
--- a/configs/imx95_evk.config
+++ b/configs/imx95_evk.config
@@ -7,7 +7,7 @@ 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_ENV_SOURCE_FILE="imx95_evk"
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x700000
diff --git a/configs/kontron-sl-mx6ul_defconfig b/configs/kontron-sl-mx6ul_defconfig
index 8e35d894dae..c6d450419cc 100644
--- a/configs/kontron-sl-mx6ul_defconfig
+++ b/configs/kontron-sl-mx6ul_defconfig
@@ -13,6 +13,7 @@ CONFIG_ENV_SECT_SIZE=0x4000
CONFIG_MX6UL=y
CONFIG_TARGET_KONTRON_MX6UL=y
CONFIG_DM_GPIO=y
+CONFIG_KONTRON_HW_UID=y
CONFIG_DEFAULT_DEVICE_TREE="nxp/imx/imx6ul-kontron-bl"
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
@@ -34,6 +35,7 @@ CONFIG_SYS_PBSIZE=532
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
CONFIG_BOARD_TYPES=y
CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_RAW_IMAGE_SUPPORT=y
CONFIG_SPL_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK=y
diff --git a/configs/kontron-sl-mx8mm_defconfig b/configs/kontron-sl-mx8mm_defconfig
index 42346a305f9..ed60d3b9ce4 100644
--- a/configs/kontron-sl-mx8mm_defconfig
+++ b/configs/kontron-sl-mx8mm_defconfig
@@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x1E0000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_IMX_CONFIG="board/kontron/sl-mx8mm/imximage.cfg"
CONFIG_DM_GPIO=y
+CONFIG_KONTRON_HW_UID=y
CONFIG_SPL_DM_SPI=y
CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mm-kontron-bl"
CONFIG_TARGET_KONTRON_MX8MM=y
diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig
index 6f7b406e817..c5cea6e4e5f 100644
--- a/configs/toradex-smarc-imx95_defconfig
+++ b/configs/toradex-smarc-imx95_defconfig
@@ -164,6 +164,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Toradex"
CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
+CONFIG_USB_GADGET_OS_DESCRIPTORS=y
CONFIG_CI_UDC=y
CONFIG_SDP_LOADADDR=0x90400000
CONFIG_ULP_WATCHDOG=y
diff --git a/doc/board/bsh/imx6ulz_bsh_smm_m2.rst b/doc/board/bsh/imx6ulz_bsh_smm_m2.rst
new file mode 100644
index 00000000000..0f391a17ade
--- /dev/null
+++ b/doc/board/bsh/imx6ulz_bsh_smm_m2.rst
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+How to Update U-Boot on imx6ulz_smm_m2 and imx6ulz_smm_m2b boards
+=================================================================
+
+Required software on the host PC:
+
+- UUU: https://github.com/NXPmicro/mfgtools
+
+Build U-Boot for m2:
+
+.. code-block:: bash
+
+ $ make mrproper
+ $ make imx6ulz_smm_m2_defconfig
+ $ make
+
+Build U-Boot for m2b:
+
+.. code-block:: bash
+
+ $ make mrproper
+ $ make imx6ulz_smm_m2b_defconfig
+ $ make
+
+This generates the SPL and u-boot-dtb.img binaries.
+
+Loading U-Boot via USB Serial Download Protocol
+-----------------------------------------------
+
+Copy SPL and u-boot-dtb.img to the uuu folder.
+
+Load the U-Boot via USB:
+
+.. code-block:: bash
+
+ $ sudo uuu -v -b nand_script.lst u-boot-with-spl.imx
+
+where nand_script.lst contains the following:
+
+.. code-block::
+
+ uuu_version 1.2.39
+
+ # @_flash.bin | bootloader
+ # @_image [_flash.bin] | image burn to nand, default is the same as bootloader
+
+ # This command will be run when i.MX6/7 i.MX8MM, i.MX8MQ
+ SDP: boot -f _flash.bin
+
+ # This command will be run when ROM support stream mode
+ # i.MX8QXP, i.MX8QM
+ SDPS: boot -f _flash.bin
+
+ # These commands will be run when use SPL and will be skipped if no spl
+ # SDPU will be deprecated. please use SDPV instead of SDPU
+ # {
+ SDPU: delay 1000
+ SDPU: write -f _flash.bin -offset 0x57c00
+ SDPU: jump
+ # }
+
+ # These commands will be run when use SPL and will be skipped if no spl
+ # if (SPL support SDPV)
+ # {
+ SDPV: delay 1000
+ SDPV: write -f _flash.bin -offset 0x11000
+ SDPV: jump
+ # }
+
+ FB: ucmd setenv fastboot_buffer ${loadaddr}
+ FB: download -f _image
+ FB: ucmd if test ! -n "$fastboot_bytes"; then setenv fastboot_bytes $filesize; else true; fi
+ # Burn image to nandfit partition if needed
+ FB: ucmd if env exists nandfit_part; then nand erase.part nandfit; nand write ${fastboot_buffer} nandfit ${fastboot_bytes}; else true; fi;
+ FB: ucmd nandbcb init ${fastboot_buffer} nandboot ${fastboot_bytes}
+ FB: Done
+
+Then U-Boot starts and its messages appear in the console program.
+
+Use the default environment variables:
+
+=> env default -f -a
+
+=> saveenv
diff --git a/doc/board/bsh/index.rst b/doc/board/bsh/index.rst
index 570ee4d72ed..e4f8b1f0b1c 100644
--- a/doc/board/bsh/index.rst
+++ b/doc/board/bsh/index.rst
@@ -7,3 +7,4 @@ BSH Hausgeraete GmbH
:maxdepth: 2
imx8mn_bsh_smm_s2
+ imx6ulz_bsh_smm_m2
diff --git a/doc/board/nxp/imx95_evk.rst b/doc/board/nxp/imx95_evk.rst
index 709992e016d..b8c3f4bed50 100644
--- a/doc/board/nxp/imx95_evk.rst
+++ b/doc/board/nxp/imx95_evk.rst
@@ -48,6 +48,7 @@ Note: srctree is U-Boot source directory
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.28-994fa14.bin
$ sh firmware-imx-8.28-994fa14.bin --auto-accept
$ cp firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr5*v202409.bin $(srctree)
+ $ cp firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr4x*v202409.bin $(srctree)
Get and Build OEI Images
--------------------------------------
@@ -65,7 +66,7 @@ branch: master
$ git clone -b master https://github.com/nxp-imx/imx-oei.git
$ cd imx-oei
-i.MX95 A0 silicon version
+i.MX95 A0 silicon version on 19x19 LPDDR5 EVK
.. code-block:: bash
@@ -75,13 +76,20 @@ i.MX95 A0 silicon version
$ make board=mx95lp5 oei=tcm DEBUG=1 r=A0 all
$ cp build/mx95lp5/tcm/oei-m33-tcm.bin $(srctree)
-i.MX95 B0 silicon version
+i.MX95 B0 silicon version on 19x19 LPDDR5 EVK
.. code-block:: bash
$ make board=mx95lp5 oei=ddr DEBUG=1 r=B0 all
$ cp build/mx95lp5/ddr/oei-m33-ddr.bin $(srctree)
+i.MX95 B0 silicon version on 15x15 LPDDR4X EVK
+
+.. code-block:: bash
+
+ $ make board=mx95lp4x-15 oei=ddr DEBUG=1 r=B0 all
+ $ cp build/mx95lp4x-15/ddr/oei-m33-ddr.bin $(srctree)
+
Get and Build System Manager Image
--------------------------------------
@@ -120,7 +128,7 @@ branch: lf_v2.12
Build the Bootloader Image
--------------------------
-i.MX95 A0 silicon version
+i.MX95 A0 silicon version on 19x19 LPDDR5 EVK
.. code-block:: bash
@@ -128,7 +136,7 @@ i.MX95 A0 silicon version
$ make imx95_a0_19x19_evk_defconfig
$ make
-i.MX95 B0 silicon version
+i.MX95 B0 silicon version on 19x19 LPDDR5 EVK
.. code-block:: bash
@@ -136,6 +144,14 @@ i.MX95 B0 silicon version
$ make imx95_19x19_evk_defconfig
$ make
+i.MX95 B0 silicon version on 15x15 LPDDR4X EVK
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=aarch64-poky-linux-
+ $ make imx95_15x15_evk_defconfig
+ $ make
+
Copy imx-boot-imx95.bin to the MicroSD card:
.. code-block:: bash
diff --git a/doc/board/nxp/index.rst b/doc/board/nxp/index.rst
index 670501164b5..7b881961b65 100644
--- a/doc/board/nxp/index.rst
+++ b/doc/board/nxp/index.rst
@@ -26,4 +26,5 @@ NXP Semiconductors
mx6sabresd
mx6ul_14x14_evk
mx6ullevk
+ rproc
psb
diff --git a/doc/board/nxp/rproc.rst b/doc/board/nxp/rproc.rst
new file mode 100644
index 00000000000..b023c1fadf6
--- /dev/null
+++ b/doc/board/nxp/rproc.rst
@@ -0,0 +1,69 @@
+.. SPDX-License-Identifier: GPL-2.0+
+ Copyright 2025 NXP
+ Written by Peng Fan <[email protected]>
+
+i.MX remoteproc usage guide
+===========================
+
+Introduction
+------------
+
+This guide is for giving user how to use the Remote Processors found on
+various i.MX Chips. The term remote processor is indicating the Cortex-M
+[4,7,33] cores inside i.MX family.
+
+i.MX8MM-EVK
+-----------
+
+Steps to start the Cortex-M4 core
+
+ load mmc 2:2 0x90000000 /lib/firmware/imx8mm_m4_TCM_rpmsg_lite_str_echo_rtos.elf
+
+ rproc load 0 0x90000000 ${filesize}
+
+ rproc start 0
+
+i.MX8MN-EVK
+-----------
+
+Steps to start the Cortex-M7 core
+
+ load mmc 2:2 0x90000000 /lib/firmware/imx8mn_m7_TCM_rpmsg_lite_str_echo_rtos.elf
+
+ rproc load 0 0x90000000 ${filesize}
+
+ rproc start 0
+
+i.MX8MQ-EVK
+-----------
+
+Steps to start the Cortex-M4 core
+
+ load mmc 0:2 0x90000000 /lib/firmware/imx8mq_m4_TCM_rpmsg_lite_str_echo_rtos.elf
+
+ rproc load 0 0x90000000 ${filesize}
+
+ rproc start 0
+
+i.MX8MP-EVK
+-----------
+
+Steps to start the Cortex-M7 core
+
+ load mmc 2:2 0x90000000 /lib/firmware/imx8mp_m7_TCM_rpmsg_lite_str_echo_rtos.elf
+
+ rproc load 0 0x90000000 ${filesize}
+
+ rproc start 0
+
+i.MX93-FRDM/QSB/EVK
+-------------------
+
+Steps to start the Cortex-M33 core, need to choose the correct file for
+corresponding board.
+
+ load mmc 0:2 0x90000000 /lib/firmware/imx93-11x11-evk_m33_TCM_rpmsg_lite_str_echo_rtos.elf
+
+ rproc load 0 0x90000000 ${filesize}
+
+ rproc start 0
diff --git a/doc/usage/cmd/rproc.rst b/doc/usage/cmd/rproc.rst
new file mode 100644
index 00000000000..663c1e3d490
--- /dev/null
+++ b/doc/usage/cmd/rproc.rst
@@ -0,0 +1,78 @@
+.. SPDX-License-Identifier: GPL-2.0+
+ Copyright 2025 NXP
+ Written by Peng Fan <[email protected]>
+
+remoteproc command
+==================
+
+Synopsis
+--------
+
+::
+
+ rproc init <id>
+ rproc list
+ rproc load <id> [addr] [size]
+ rproc start <id>
+ rproc stop <id>
+ rproc reset <id>
+ rproc is_running <id>
+ rproc ping <id>
+
+Description
+-----------
+
+The rproc command provides a generic U-Boot mechanism to manage the Remote
+Processors inside a SoC .
+
+The 'rproc init' command enumerate and initialize the remote processor.
+
+ id
+ remote processor id. if id is not passed, initialize all the
+ remote prcessors
+
+The 'rproc list' list available remote processors.
+
+The 'rproc load' load the remote processor with binary.
+
+ id
+ remote processor id.
+ addr
+ address that image is loaded at.
+ size
+ image size
+
+The 'rproc start' start the remote processor(must be loaded).
+
+ id
+ remote processor id.
+
+The 'rproc stop' stop the remote processor.
+
+ id
+ remote processor id.
+
+The 'rproc reset' reset the remote processor.
+
+ id
+ remote processor id.
+
+The 'rproc is_running' reports if the remote processor is running.
+
+ id
+ remote processor id.
+
+The 'rproc ping' ping the remote processor for communication.
+
+ id
+ remote processor id.
+
+Configuration
+-------------
+
+The rproc command is only available if CONFIG_CMD_REMOTEPROC=y.
+
+.. toctree::
+ :maxdepth: 2
+
+ ../../board/nxp/rproc.rst
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c9b35b5a2ff..913670ce412 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1006,8 +1006,9 @@ config FSL_ENETC
config FSL_ENETC_NETC_BLK_CTRL
bool "NXP ENETC NETC blocks control driver"
- depends on FSL_ENETC && IMX95
- default y if IMX95
+ depends on FSL_ENETC
+ depends on IMX95 || IMX94
+ default y if IMX95 || IMX94
help
This driver configures Integrated Endpoint Register Block (IERB) and
Privileged Register Block (PRB) of NETC. For i.MX platforms, it also
diff --git a/drivers/net/fsl_enetc_mdio.c b/drivers/net/fsl_enetc_mdio.c
index c1d491f2c5a..3d76d92a62a 100644
--- a/drivers/net/fsl_enetc_mdio.c
+++ b/drivers/net/fsl_enetc_mdio.c
@@ -11,6 +11,8 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <miiphy.h>
+#include <linux/delay.h>
+#include <power/regulator.h>
#include "fsl_enetc.h"
@@ -135,6 +137,8 @@ static int enetc_mdio_probe(struct udevice *dev)
struct pci_child_plat *pplat = dev_get_parent_plat(dev);
struct enetc_mdio_priv *priv = dev_get_priv(dev);
u16 cmd = PCI_COMMAND_MEMORY;
+ int ret;
+ struct udevice *supply = NULL;
priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, 0);
if (!priv->regs_base) {
@@ -144,6 +148,27 @@ static int enetc_mdio_probe(struct udevice *dev)
priv->regs_base += ENETC_MDIO_BASE;
+ if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
+ ret = device_get_supply_regulator(dev, "phy-supply",
+ &supply);
+ if (ret && ret != -ENOENT) {
+ printf("%s: device_get_supply_regulator failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (supply) {
+ regulator_set_enable(supply, false);
+ mdelay(100);
+
+ ret = regulator_set_enable_if_allowed(supply, true);
+ if (ret) {
+ printf("%s: Error enabling phy supply\n", dev->name);
+ return ret;
+ }
+ }
+ }
+
if (pplat->vendor == PCI_VENDOR_ID_PHILIPS) /* i.MX95 */
cmd |= PCI_COMMAND_MASTER;
diff --git a/drivers/net/fsl_enetc_netc_blk_ctrl.c b/drivers/net/fsl_enetc_netc_blk_ctrl.c
index fecd66eb15a..8577bb75632 100644
--- a/drivers/net/fsl_enetc_netc_blk_ctrl.c
+++ b/drivers/net/fsl_enetc_netc_blk_ctrl.c
@@ -43,6 +43,18 @@
#define PCS_PROT_SFI BIT(4)
#define PCS_PROT_10G_SXGMII BIT(6)
+#define IMX94_MISC_SOC_CONTROL 0x0
+#define SEL_XPCS_1 BIT(1)
+#define IMX94_XPCS_PORT_0 0x0
+#define IMX94_XPCS_PORT_1 0x1
+
+#define IMX94_EXT_PIN_CONTROL 0x10
+#define MAC2_MAC3_SEL BIT(1)
+
+#define IMX94_NETC_LINK_CFG(a) (0x4c + (a) * 4)
+#define NETC_LINK_CFG_MII_PROT GENMASK(3, 0)
+#define NETC_LINK_CFG_IO_VAR GENMASK(19, 16)
+
/* NETC privileged register block register */
#define PRB_NETCRR 0x100
#define NETCRR_SR BIT(0)
@@ -55,6 +67,7 @@
/* NETC integrated endpoint register block register */
#define IERB_EMDIOFAUXR 0x344
#define IERB_T0FAUXR 0x444
+#define IERB_ETBCR(a) (0x300c + 0x100 * (a))
#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a))
#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a))
#define FAUXR_LDID GENMASK(3, 0)
@@ -64,6 +77,26 @@
#define IMX95_ENETC1_BUS_DEVFN 0x40
#define IMX95_ENETC2_BUS_DEVFN 0x80
+#define IMX94_ENETC3_BUS_DEVFN 0x0
+#define IMX94_TIMER0_BUS_DEVFN 0x1
+#define IMX94_SWITCH_BUS_DEVFN 0x2
+#define IMX94_ENETC0_BUS_DEVFN 0x100
+#define IMX94_TIMER1_BUS_DEVFN 0x101
+#define IMX94_ENETC1_BUS_DEVFN 0x140
+#define IMX94_ENETC2_BUS_DEVFN 0x180
+#define IMX94_TIMER2_BUS_DEVFN 0x181
+#define IMX94_ENETC0_LINK 3
+#define IMX94_ENETC1_LINK 4
+#define IMX94_ENETC2_LINK 5
+#define IMX94_ENETC0_OFFSET 0
+#define IMX94_ENETC1_OFFSET 1
+#define IMX94_ENETC2_OFFSET 2
+#define IMX94_SWITCH_PORT2 2
+#define IMX94_SWITCH_CPU_PORT 3
+#define IMX94_TIMER0_ID 0
+#define IMX94_TIMER1_ID 1
+#define IMX94_TIMER2_ID 2
+
/* Flags for different platforms */
#define NETC_HAS_NETCMIX BIT(0)
@@ -73,6 +106,15 @@ struct netc_blk_ctrl {
void __iomem *netcmix;
};
+struct netc_devinfo {
+ int (*netcmix_init)(struct udevice *dev);
+ int (*ierb_init)(struct udevice *dev);
+ void (*xpcs_port_init)(struct netc_blk_ctrl *priv, int port);
+};
+
+static struct netc_blk_ctrl *netc_bc;
+static struct netc_devinfo *netc_di;
+
static void netc_reg_write(void __iomem *base, u32 offset, u32 val)
{
writel(val, base + offset);
@@ -183,6 +225,142 @@ static int imx95_netcmix_init(struct udevice *dev)
return 0;
}
+static int imx94_enetc_get_link_num(ofnode np)
+{
+ int bus_devfn;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(np);
+ if (bus_devfn < 0)
+ return -EINVAL;
+
+ /* Parse ENETC link number */
+ switch (bus_devfn) {
+ case IMX94_ENETC0_BUS_DEVFN:
+ return IMX94_ENETC0_LINK;
+ case IMX94_ENETC1_BUS_DEVFN:
+ return IMX94_ENETC1_LINK;
+ case IMX94_ENETC2_BUS_DEVFN:
+ return IMX94_ENETC2_LINK;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int imx94_link_config(struct netc_blk_ctrl *priv,
+ ofnode np, int link_id)
+{
+ phy_interface_t interface;
+ int mii_proto;
+ u32 val;
+
+ interface = ofnode_read_phy_mode(np);
+ if (interface == -1)
+ return -EINVAL;
+
+ mii_proto = netc_get_link_mii_protocol(interface);
+ if (mii_proto < 0)
+ return -EINVAL;
+
+ val = mii_proto & NETC_LINK_CFG_MII_PROT;
+ if (mii_proto == MII_PROT_SERIAL)
+ val = u32_replace_bits(val, IO_VAR_16FF_16G_SERDES,
+ NETC_LINK_CFG_IO_VAR);
+
+ netc_reg_write(priv->netcmix, IMX94_NETC_LINK_CFG(link_id), val);
+
+ if (link_id == IMX94_ENETC0_LINK) {
+ val = netc_reg_read(priv->netcmix, IMX94_EXT_PIN_CONTROL);
+ val |= MAC2_MAC3_SEL;
+ netc_reg_write(priv->netcmix, IMX94_EXT_PIN_CONTROL, val);
+ }
+
+ return 0;
+}
+
+static int imx94_enetc_link_config(struct netc_blk_ctrl *priv,
+ ofnode np, bool *enetc0_en)
+{
+ int link_id;
+
+ link_id = imx94_enetc_get_link_num(np);
+ if (link_id < 0)
+ return -EINVAL;
+
+ if (link_id == IMX94_ENETC0_LINK)
+ *enetc0_en = true;
+
+ return imx94_link_config(priv, np, link_id);
+}
+
+static int imx94_switch_link_config(struct netc_blk_ctrl *priv,
+ ofnode np, bool *swp2_en)
+{
+ ofnode ports, child;
+ int port_id, err = 0;
+
+ ports = ofnode_find_subnode(np, "ports");
+ if (!ofnode_valid(ports))
+ ports = ofnode_find_subnode(np, "ethernet-ports");
+ if (!ofnode_valid(ports))
+ return -ENODEV;
+
+ ofnode_for_each_subnode(child, ports) {
+ if (ofnode_read_u32(child, "reg", &port_id) < 0) {
+ err = -ENODEV;
+ goto end;
+ }
+
+ if (port_id == IMX94_SWITCH_CPU_PORT)
+ continue;
+
+ if (port_id == IMX94_SWITCH_PORT2)
+ *swp2_en = true;
+
+ err = imx94_link_config(priv, child, port_id);
+ if (err)
+ goto end;
+ }
+
+end:
+ return err;
+}
+
+static int imx94_netcmix_init(struct udevice *dev)
+{
+ struct netc_blk_ctrl *priv = dev_get_priv(dev);
+ ofnode child, gchild;
+ bool enetc0_en = false, swp2_en = false;
+ int err;
+
+ dev_for_each_subnode(child, dev) {
+ if (!ofnode_is_enabled(child))
+ continue;
+
+ ofnode_for_each_subnode(gchild, child) {
+ if (!ofnode_is_enabled(gchild))
+ continue;
+
+ if (ofnode_device_is_compatible(gchild, "pci1131,e101")) {
+ err = imx94_enetc_link_config(priv, gchild, &enetc0_en);
+ if (err)
+ return err;
+ } else if (ofnode_device_is_compatible(gchild, "pci1131,eef2")) {
+ err = imx94_switch_link_config(priv, gchild, &swp2_en);
+ if (err)
+ return err;
+ }
+ }
+ }
+
+ if (enetc0_en && swp2_en) {
+ dev_err(dev, "Cannot enable swp2 and enetc0 at the same time\n");
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static bool netc_ierb_is_locked(struct netc_blk_ctrl *priv)
{
return !!(netc_reg_read(priv->prb, PRB_NETCRR) & NETCRR_LOCK);
@@ -238,9 +416,99 @@ static int imx95_ierb_init(struct udevice *dev)
return 0;
}
+static int imx94_enetc_get_enetc_offset(ofnode np)
+{
+ int bus_devfn;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(np);
+ if (bus_devfn < 0)
+ return -EINVAL;
+
+ /* Parse ENETC offset */
+ switch (bus_devfn) {
+ case IMX94_ENETC0_BUS_DEVFN:
+ return IMX94_ENETC0_OFFSET;
+ case IMX94_ENETC1_BUS_DEVFN:
+ return IMX94_ENETC1_OFFSET;
+ case IMX94_ENETC2_BUS_DEVFN:
+ return IMX94_ENETC2_OFFSET;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int imx94_enetc_get_timer_id(ofnode np)
+{
+ int bus_devfn;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(np);
+ if (bus_devfn < 0)
+ return -EINVAL;
+
+ /* Parse ENETC PTP timer ID */
+ switch (bus_devfn) {
+ case IMX94_TIMER0_BUS_DEVFN:
+ return IMX94_TIMER0_ID;
+ case IMX94_TIMER1_BUS_DEVFN:
+ return IMX94_TIMER1_ID;
+ case IMX94_TIMER2_BUS_DEVFN:
+ return IMX94_TIMER2_ID;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int imx94_enetc_update_tid(struct netc_blk_ctrl *priv, ofnode pf_np)
+{
+ ofnode timer_np;
+ int offset, tid;
+
+ offset = imx94_enetc_get_enetc_offset(pf_np);
+ if (offset < 0) {
+ printf("Find unknown PF node.\n");
+ return offset;
+ }
+
+ timer_np = ofnode_parse_phandle(pf_np, "nxp,ptp-timer", 0);
+ if (!ofnode_valid(timer_np)) {
+ /*
+ * If nxp,ptp-timer is not set, the first timer of the bus
+ * where enetc is located will be used as the default timer.
+ */
+ tid = IMX94_TIMER1_ID;
+ goto update_reg;
+ }
+
+ tid = imx94_enetc_get_timer_id(timer_np);
+ if (tid < 0) {
+ printf("Incorrect bus/devfn of ptp-timer.\n");
+ return tid;
+ }
+
+update_reg:
+ netc_reg_write(priv->ierb, IERB_ETBCR(offset), tid);
+
+ return 0;
+}
+
+static int imx94_ierb_init(struct udevice *dev)
+{
+ struct netc_blk_ctrl *priv = dev_get_priv(dev);
+ ofnode bus_np, pf_np;
+ int ret = 0;
+
+ dev_for_each_subnode(bus_np, dev)
+ ofnode_for_each_subnode(pf_np, bus_np)
+ if (ofnode_device_is_compatible(pf_np, "pci1131,e101"))
+ ret = imx94_enetc_update_tid(priv, pf_np);
+
+ return ret;
+}
+
static int netc_ierb_init(struct udevice *dev)
{
struct netc_blk_ctrl *priv = dev_get_priv(dev);
+ struct netc_devinfo *devinfo = (struct netc_devinfo *)dev_get_driver_data(dev);
int err;
if (netc_ierb_is_locked(priv)) {
@@ -251,9 +519,11 @@ static int netc_ierb_init(struct udevice *dev)
}
}
- err = imx95_ierb_init(dev);
- if (err)
- return err;
+ if (devinfo->ierb_init) {
+ err = devinfo->ierb_init(dev);
+ if (err)
+ return err;
+ }
err = netc_lock_ierb(priv);
if (err) {
@@ -264,6 +534,31 @@ static int netc_ierb_init(struct udevice *dev)
return 0;
}
+static void imx94_netc_xpcs_port_init(struct netc_blk_ctrl *priv, int port)
+{
+ u32 val;
+
+ val = netc_reg_read(priv->netcmix, IMX94_MISC_SOC_CONTROL);
+ if (port == IMX94_XPCS_PORT_1)
+ val |= SEL_XPCS_1;
+ else
+ val &= ~SEL_XPCS_1;
+ netc_reg_write(priv->netcmix, IMX94_MISC_SOC_CONTROL, val);
+}
+
+void netc_xpcs_port_init(int port)
+{
+ struct netc_blk_ctrl *priv = netc_bc;
+ struct netc_devinfo *devinfo;
+
+ if (!priv)
+ return;
+
+ devinfo = netc_di;
+ if (devinfo->xpcs_port_init)
+ devinfo->xpcs_port_init(priv, port);
+}
+
static int netc_prb_check_error(struct netc_blk_ctrl *priv)
{
if (netc_reg_read(priv->prb, PRB_NETCSR) & NETCSR_ERROR)
@@ -272,14 +567,27 @@ static int netc_prb_check_error(struct netc_blk_ctrl *priv)
return 0;
}
+static const struct netc_devinfo imx95_devinfo = {
+ .netcmix_init = imx95_netcmix_init,
+ .ierb_init = imx95_ierb_init,
+};
+
+static const struct netc_devinfo imx94_devinfo = {
+ .netcmix_init = imx94_netcmix_init,
+ .ierb_init = imx94_ierb_init,
+ .xpcs_port_init = imx94_netc_xpcs_port_init,
+};
+
static const struct udevice_id netc_blk_ctrl_match[] = {
- { .compatible = "nxp,imx95-netc-blk-ctrl" },
+ { .compatible = "nxp,imx95-netc-blk-ctrl", .data = (ulong)&imx95_devinfo },
+ { .compatible = "nxp,imx94-netc-blk-ctrl", .data = (ulong)&imx94_devinfo },
{},
};
static int netc_blk_ctrl_probe(struct udevice *dev)
{
struct netc_blk_ctrl *priv = dev_get_priv(dev);
+ struct netc_devinfo *devinfo = (struct netc_devinfo *)dev_get_driver_data(dev);
struct clk *ipg_clk;
fdt_addr_t regs;
int err;
@@ -318,10 +626,12 @@ static int netc_blk_ctrl_probe(struct udevice *dev)
priv->netcmix = (void __iomem *)regs;
- err = imx95_netcmix_init(dev);
- if (err) {
- dev_err(dev, "Initializing NETCMIX failed\n");
- return err;
+ if (devinfo->netcmix_init) {
+ err = devinfo->netcmix_init(dev);
+ if (err) {
+ dev_err(dev, "Initializing NETCMIX failed\n");
+ return err;
+ }
}
err = netc_ierb_init(dev);
@@ -333,6 +643,9 @@ static int netc_blk_ctrl_probe(struct udevice *dev)
if (netc_prb_check_error(priv) < 0)
dev_warn(dev, "The current IERB configuration is invalid\n");
+ netc_bc = priv;
+ netc_di = devinfo;
+
return 0;
}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index d36a5f00ef8..420d7c7a44d 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -289,11 +289,19 @@ config PHY_NPCM_USB
Support the USB PHY in NPCM SoCs
config PHY_IMX8MQ_USB
- bool "NXP i.MX8MQ/i.MX8MP/i.MX95 USB PHY Driver"
+ bool "NXP i.MX8MQ/i.MX8MP/i.MX95/i.MX94 USB PHY Driver"
depends on PHY
- depends on IMX8MQ || IMX8MP || IMX95
+ depends on IMX8MQ || IMX8MP || IMX95 || IMX94
help
- Support the USB3.0 PHY in NXP i.MX8MQ, i.MX8MP, and i.MX95 SoC
+ Support the USB3.0 PHY in NXP i.MX8MQ, i.MX8MP, i.MX95, and i.MX94 SoCs.
+
+config SPL_PHY_IMX8MQ_USB
+ bool "Enable NXP i.MX8MQ/i.MX8MP/i.MX95/i.MX94 USB3.0 PHY Driver in SPL"
+ depends on SPL_PHY
+ depends on IMX8MQ || IMX8MP || IMX95 || IMX94
+ help
+ Enable support for the USB3.0 PHY in NXP i.MX8MQ, i.MX8MP, i.MX95, and
+ i.MX94 SoCs in SPL.
config PHY_IMX8M_PCIE
bool "NXP i.MX8MM/i.MX8MP PCIe PHY Driver"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 98c1ef8683b..5a6df0ecfeb 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -38,7 +38,7 @@ obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
obj-$(CONFIG_PHY_EXYNOS_USBDRD) += phy-exynos-usbdrd.o
obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o
-obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
+obj-$(CONFIG_$(PHASE_)PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o
obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o
obj-y += cadence/
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index e9f19a69433..8056f210abc 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -33,6 +33,13 @@ config REMOTEPROC_ADI_SC5XX
Say 'y' here to add support for loading code onto SHARC cores in
an ADSP-SC5xx SoC from Analog Devices
+config REMOTEPROC_IMX
+ bool "Support for NXP i.MX remoteproc"
+ select REMOTEPROC
+ depends on DM && MACH_IMX && OF_CONTROL
+ help
+ Say 'y' here to add support for i.MX remoteproc.
+
config REMOTEPROC_RENESAS_APMU
bool "Support for Renesas R-Car Gen4 APMU start of CR52 processor"
select REMOTEPROC
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 47bd57c7890..7ea8023c50b 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_$(PHASE_)REMOTEPROC) += rproc-uclass.o rproc-elf-loader.o
# Remote proc drivers - Please keep this list alphabetically sorted.
obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
obj-$(CONFIG_REMOTEPROC_ADI_SC5XX) += adi_sc5xx_rproc.o
+obj-$(CONFIG_REMOTEPROC_IMX) += imx_rproc.o
obj-$(CONFIG_REMOTEPROC_RENESAS_APMU) += renesas_apmu.o
obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
new file mode 100644
index 00000000000..9bb55327998
--- /dev/null
+++ b/drivers/remoteproc/imx_rproc.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/device_compat.h>
+#include <linux/arm-smccc.h>
+#include <linux/types.h>
+#include <regmap.h>
+#include <remoteproc.h>
+#include <syscon.h>
+
+#include "imx_rproc.h"
+
+#define IMX7D_SRC_SCR 0x0C
+#define IMX7D_ENABLE_M4 BIT(3)
+#define IMX7D_SW_M4P_RST BIT(2)
+#define IMX7D_SW_M4C_RST BIT(1)
+#define IMX7D_SW_M4C_NON_SCLR_RST BIT(0)
+
+#define IMX7D_M4_RST_MASK (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
+ | IMX7D_SW_M4C_RST \
+ | IMX7D_SW_M4C_NON_SCLR_RST)
+
+#define IMX7D_M4_START (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
+ | IMX7D_SW_M4C_RST)
+#define IMX7D_M4_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
+ IMX7D_SW_M4C_NON_SCLR_RST)
+
+#define IMX_RPROC_MEM_MAX 32
+
+#define IMX_SIP_RPROC 0xC2000005
+#define IMX_SIP_RPROC_START 0x00
+#define IMX_SIP_RPROC_STARTED 0x01
+#define IMX_SIP_RPROC_STOP 0x02
+
+struct imx_rproc {
+ const struct imx_rproc_dcfg *dcfg;
+ struct regmap *regmap;
+};
+
+/* att flags: lower 16 bits specifying core, higher 16 bits for flags */
+/* M4 own area. Can be mapped at probe */
+#define ATT_OWN BIT(31)
+#define ATT_IOMEM BIT(30)
+
+static int imx_rproc_arm_smc_start(struct udevice *dev)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
+
+ return res.a0;
+}
+
+static int imx_rproc_mmio_start(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+ return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_start);
+}
+
+static int imx_rproc_start(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+ int ret;
+
+ if (!dcfg->ops || !dcfg->ops->start)
+ return -EOPNOTSUPP;
+
+ ret = dcfg->ops->start(dev);
+ if (ret)
+ dev_err(dev, "Failed to enable remote core!\n");
+
+ return ret;
+}
+
+static int imx_rproc_arm_smc_stop(struct udevice *dev)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a1)
+ dev_info(dev, "Not in wfi, force stopped\n");
+
+ return res.a0;
+}
+
+static int imx_rproc_mmio_stop(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+ return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_stop);
+}
+
+static int imx_rproc_stop(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+ int ret;
+
+ if (!dcfg->ops || !dcfg->ops->stop)
+ return -EOPNOTSUPP;
+
+ ret = dcfg->ops->stop(dev);
+ if (ret)
+ dev_err(dev, "Failed to stop remote core\n");
+
+ return ret;
+}
+
+static int imx_rproc_arm_smc_is_running(struct udevice *dev)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0)
+ return 0;
+
+ return 1;
+}
+
+static int imx_rproc_mmio_is_running(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+ int ret;
+ u32 val;
+
+ ret = regmap_read(priv->regmap, dcfg->src_reg, &val);
+ if (ret) {
+ dev_err(dev, "Failed to read src\n");
+ return ret;
+ }
+
+ if ((val & dcfg->src_mask) != dcfg->src_stop)
+ return 0;
+
+ return 1;
+}
+
+static int imx_rproc_is_running(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+
+ if (!dcfg->ops || !dcfg->ops->is_running)
+ return 0;
+
+ return dcfg->ops->is_running(dev);
+}
+
+static int imx_rproc_init(struct udevice *dev)
+{
+ return 0;
+}
+
+static int imx_rproc_da_to_sys(struct udevice *dev, u64 da, size_t len, u64 *sys, bool *is_iomem)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+ int i;
+
+ /* parse address translation table */
+ for (i = 0; i < dcfg->att_size; i++) {
+ const struct imx_rproc_att *att = &dcfg->att[i];
+
+ if (da >= att->da && da + len < att->da + att->size) {
+ unsigned int offset = da - att->da;
+
+ *sys = att->sa + offset;
+
+ if (is_iomem)
+ *is_iomem = att->flags & ATT_IOMEM;
+
+ return 0;
+ }
+ }
+
+ dev_err(dev, "Translation failed: da = 0x%llx len = 0x%zx\n", da, len);
+
+ return -ENOENT;
+}
+
+static void *imx_rproc_device_to_virt(struct udevice *dev, ulong da, ulong size, bool *is_iomem)
+{
+ u64 sys;
+
+ if (imx_rproc_da_to_sys(dev, da, size, &sys, is_iomem))
+ return NULL;
+
+ dev_dbg(dev, "da = 0x%lx len = 0x%lx sys = 0x%llx\n", da, size, sys);
+
+ return phys_to_virt(sys);
+}
+
+static int imx_rproc_load(struct udevice *dev, ulong addr, ulong size)
+{
+ return rproc_elf_load_image(dev, addr, size);
+}
+
+static const struct dm_rproc_ops imx_rproc_ops = {
+ .init = imx_rproc_init,
+ .start = imx_rproc_start,
+ .stop = imx_rproc_stop,
+ .load = imx_rproc_load,
+ .device_to_virt = imx_rproc_device_to_virt,
+ .is_running = imx_rproc_is_running,
+};
+
+static int imx_rproc_probe(struct udevice *dev)
+{
+ struct imx_rproc *priv = dev_get_priv(dev);
+ struct imx_rproc_dcfg *dcfg = (struct imx_rproc_dcfg *)dev_get_driver_data(dev);
+ ofnode node;
+
+ node = dev_ofnode(dev);
+
+ priv->dcfg = dcfg;
+
+ if (dcfg->method != IMX_RPROC_MMIO)
+ return 0;
+
+ priv->regmap = syscon_regmap_lookup_by_phandle(dev, "syscon");
+ if (IS_ERR(priv->regmap)) {
+ dev_err(dev, "No syscon: %ld\n", PTR_ERR(priv->regmap));
+ return PTR_ERR(priv->regmap);
+ }
+
+ return 0;
+}
+
+static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
+ /* dev addr , sys addr , size , flags */
+ /* ITCM */
+ { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
+ /* OCRAM_S */
+ { 0x00180000, 0x00180000, 0x00009000, 0 },
+ /* OCRAM */
+ { 0x00900000, 0x00900000, 0x00020000, 0 },
+ /* OCRAM */
+ { 0x00920000, 0x00920000, 0x00020000, 0 },
+ /* OCRAM */
+ { 0x00940000, 0x00940000, 0x00050000, 0 },
+ /* QSPI Code - alias */
+ { 0x08000000, 0x08000000, 0x08000000, 0 },
+ /* DDR (Code) - alias */
+ { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
+ /* DTCM */
+ { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
+ /* OCRAM_S - alias */
+ { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
+ /* OCRAM */
+ { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
+ /* OCRAM */
+ { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
+ /* OCRAM */
+ { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
+ /* DDR (Data) */
+ { 0x40000000, 0x40000000, 0x80000000, 0 },
+};
+
+static const struct imx_rproc_plat_ops imx_rproc_ops_arm_smc = {
+ .start = imx_rproc_arm_smc_start,
+ .stop = imx_rproc_arm_smc_stop,
+ .is_running = imx_rproc_arm_smc_is_running,
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
+ .att = imx_rproc_att_imx8mn,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
+ .method = IMX_RPROC_SMC,
+ .ops = &imx_rproc_ops_arm_smc,
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
+ /* dev addr , sys addr , size , flags */
+ /* TCML - alias */
+ { 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
+ /* OCRAM_S */
+ { 0x00180000, 0x00180000, 0x00008000, 0 },
+ /* OCRAM */
+ { 0x00900000, 0x00900000, 0x00020000, 0 },
+ /* OCRAM */
+ { 0x00920000, 0x00920000, 0x00020000, 0 },
+ /* QSPI Code - alias */
+ { 0x08000000, 0x08000000, 0x08000000, 0 },
+ /* DDR (Code) - alias */
+ { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
+ /* TCML/U */
+ { 0x1FFE0000, 0x007E0000, 0x00040000, ATT_OWN | ATT_IOMEM},
+ /* OCRAM_S */
+ { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
+ /* OCRAM */
+ { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
+ /* OCRAM */
+ { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
+ /* DDR (Data) */
+ { 0x40000000, 0x40000000, 0x80000000, 0 },
+};
+
+static const struct imx_rproc_plat_ops imx_rproc_ops_mmio = {
+ .start = imx_rproc_mmio_start,
+ .stop = imx_rproc_mmio_stop,
+ .is_running = imx_rproc_mmio_is_running,
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
+ .src_reg = IMX7D_SRC_SCR,
+ .src_mask = IMX7D_M4_RST_MASK,
+ .src_start = IMX7D_M4_START,
+ .src_stop = IMX7D_M4_STOP,
+ .att = imx_rproc_att_imx8mq,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq),
+ .method = IMX_RPROC_MMIO,
+ .ops = &imx_rproc_ops_mmio,
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx93[] = {
+ /* dev addr , sys addr , size , flags */
+ /* TCM CODE NON-SECURE */
+ { 0x0FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+ /* TCM CODE SECURE */
+ { 0x1FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+ /* TCM SYS NON-SECURE*/
+ { 0x20000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+ /* TCM SYS SECURE*/
+ { 0x30000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
+
+ /* DDR */
+ { 0x80000000, 0x80000000, 0x10000000, 0 },
+ { 0x90000000, 0x80000000, 0x10000000, 0 },
+
+ { 0xC0000000, 0xC0000000, 0x10000000, 0 },
+ { 0xD0000000, 0xC0000000, 0x10000000, 0 },
+};
+
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
+ .att = imx_rproc_att_imx93,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx93),
+ .method = IMX_RPROC_SMC,
+ .ops = &imx_rproc_ops_arm_smc,
+};
+
+static const struct udevice_id imx_rproc_ids[] = {
+ { .compatible = "fsl,imx8mm-cm4", .data = (ulong)&imx_rproc_cfg_imx8mq },
+ { .compatible = "fsl,imx8mn-cm7", .data = (ulong)&imx_rproc_cfg_imx8mn, },
+ { .compatible = "fsl,imx8mp-cm7", .data = (ulong)&imx_rproc_cfg_imx8mn, },
+ { .compatible = "fsl,imx8mq-cm4", .data = (ulong)&imx_rproc_cfg_imx8mq },
+ { .compatible = "fsl,imx93-cm33", .data = (ulong)&imx_rproc_cfg_imx93 },
+ {}
+};
+
+U_BOOT_DRIVER(imx_rproc) = {
+ .name = "imx_rproc",
+ .of_match = imx_rproc_ids,
+ .id = UCLASS_REMOTEPROC,
+ .ops = &imx_rproc_ops,
+ .probe = imx_rproc_probe,
+ .priv_auto = sizeof(struct imx_rproc),
+};
diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
new file mode 100644
index 00000000000..7a82dc4a195
--- /dev/null
+++ b/drivers/remoteproc/imx_rproc.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017 Pengutronix, Oleksij Rempel <[email protected]>
+ * Copyright 2021 NXP
+ */
+
+#ifndef _IMX_RPROC_H
+#define _IMX_RPROC_H
+
+/* address translation table */
+struct imx_rproc_att {
+ u32 da; /* device address (From Cortex M4 view)*/
+ u32 sa; /* system bus address */
+ u32 size; /* size of reg range */
+ int flags;
+};
+
+/* Remote core start/stop method */
+enum imx_rproc_method {
+ IMX_RPROC_NONE,
+ /* Through syscon regmap */
+ IMX_RPROC_MMIO,
+ /* Through ARM SMCCC */
+ IMX_RPROC_SMC,
+ /* Through System Control Unit API */
+ IMX_RPROC_SCU_API,
+ /* Through Reset Controller API */
+ IMX_RPROC_RESET_CONTROLLER,
+ /* Through System Manager */
+ IMX_RPROC_SM,
+};
+
+/* dcfg flags */
+#define IMX_RPROC_NEED_SYSTEM_OFF BIT(0)
+
+struct imx_rproc_plat_ops {
+ int (*start)(struct udevice *dev);
+ int (*stop)(struct udevice *dev);
+ int (*is_running)(struct udevice *dev);
+};
+
+struct imx_rproc_dcfg {
+ u32 src_reg;
+ u32 src_mask;
+ u32 src_start;
+ u32 src_stop;
+ u32 gpr_reg;
+ u32 gpr_wait;
+ const struct imx_rproc_att *att;
+ size_t att_size;
+ enum imx_rproc_method method;
+ u32 flags;
+ const struct imx_rproc_plat_ops *ops;
+};
+
+#endif /* _IMX_RPROC_H */
diff --git a/drivers/remoteproc/renesas_apmu.c b/drivers/remoteproc/renesas_apmu.c
index 1a50cd3289b..91586a99e0d 100644
--- a/drivers/remoteproc/renesas_apmu.c
+++ b/drivers/remoteproc/renesas_apmu.c
@@ -170,11 +170,12 @@ static int renesas_apmu_rproc_init(struct udevice *dev)
* @dev: corresponding remote processor device
* @da: device address
* @size: Size of the memory region @da is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
*
* Return: converted virtual address
*/
static void *renesas_apmu_rproc_device_to_virt(struct udevice *dev, ulong da,
- ulong size)
+ ulong size, bool *is_iomem)
{
/*
* The Cortex R52 and A76 share the same address space,
diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c
index 0b3941b7798..83d70c2fb54 100644
--- a/drivers/remoteproc/rproc-elf-loader.c
+++ b/drivers/remoteproc/rproc-elf-loader.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright 2025 NXP
*/
#include <cpu_func.h>
#include <dm.h>
@@ -9,6 +10,7 @@
#include <mapmem.h>
#include <remoteproc.h>
#include <asm/cache.h>
+#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/compat.h>
#include <linux/printk.h>
@@ -181,27 +183,38 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
void *dst = (void *)(uintptr_t)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
+ bool is_iomem = false;
ulong dst_addr;
- if (phdr->p_type != PT_LOAD)
+ if (phdr->p_type != PT_LOAD || !phdr->p_memsz)
continue;
if (ops->device_to_virt)
dst = ops->device_to_virt(dev, (ulong)dst,
- phdr->p_memsz);
+ phdr->p_memsz, &is_iomem);
dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
i, dst, phdr->p_filesz);
- if (phdr->p_filesz)
- memcpy(dst, src, phdr->p_filesz);
- if (phdr->p_filesz != phdr->p_memsz)
- memset(dst + phdr->p_filesz, 0x00,
- phdr->p_memsz - phdr->p_filesz);
+ if (phdr->p_filesz) {
+ if (is_iomem)
+ memcpy_toio(dst, src, phdr->p_filesz);
+ else
+ memcpy(dst, src, phdr->p_filesz);
+ }
+ if (phdr->p_filesz != phdr->p_memsz) {
+ if (is_iomem)
+ memset_io(dst + phdr->p_filesz, 0x00,
+ phdr->p_memsz - phdr->p_filesz);
+ else
+ memset(dst + phdr->p_filesz, 0x00,
+ phdr->p_memsz - phdr->p_filesz);
+ }
dst_addr = map_to_sysmem(dst);
- flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
- roundup(dst_addr + phdr->p_filesz,
- ARCH_DMA_MINALIGN) -
- rounddown(dst_addr, ARCH_DMA_MINALIGN));
+ if (!is_iomem) {
+ flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
+ roundup(dst_addr + phdr->p_filesz, ARCH_DMA_MINALIGN) -
+ rounddown(dst_addr, ARCH_DMA_MINALIGN));
+ }
}
return 0;
@@ -230,6 +243,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
memsz = phdr->p_memsz;
filesz = phdr->p_filesz;
offset = phdr->p_offset;
+ bool is_iomem = false;
if (phdr->p_type != PT_LOAD)
continue;
@@ -239,7 +253,7 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
ptr = (void *)(uintptr_t)da;
if (ops->device_to_virt) {
- ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
+ ptr = ops->device_to_virt(dev, da, phdr->p_memsz, &is_iomem);
if (!ptr) {
dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
memsz);
@@ -248,14 +262,24 @@ int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
}
}
- if (filesz)
- memcpy(ptr, (void *)addr + offset, filesz);
- if (filesz != memsz)
- memset(ptr + filesz, 0x00, memsz - filesz);
+ if (filesz) {
+ if (is_iomem)
+ memcpy_toio(ptr, (void *)addr + offset, filesz);
+ else
+ memcpy(ptr, (void *)addr + offset, filesz);
+ }
+ if (filesz != memsz) {
+ if (is_iomem)
+ memset_io(ptr + filesz, 0x00, memsz - filesz);
+ else
+ memset(ptr + filesz, 0x00, memsz - filesz);
+ }
- flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
- roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
- rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
+ if (!is_iomem) {
+ flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
+ roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
+ rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
+ }
}
return ret;
@@ -381,6 +405,7 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
Elf32_Shdr *shdr;
void *src, *dst;
ulong dst_addr;
+ bool is_iomem = false;
shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
if (!shdr)
@@ -394,18 +419,22 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
src = (void *)fw_addr + shdr->sh_offset;
if (ops->device_to_virt)
- dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
+ dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size, &is_iomem);
else
dst = (void *)rsc_addr;
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
(ulong)dst, *rsc_size);
- memcpy(dst, src, *rsc_size);
- dst_addr = map_to_sysmem(dst);
- flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
- roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) -
- rounddown(dst_addr, ARCH_DMA_MINALIGN));
+ if (is_iomem) {
+ memcpy_toio(dst, src, *rsc_size);
+ } else {
+ memcpy(dst, src, *rsc_size);
+ dst_addr = map_to_sysmem(dst);
+ flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
+ roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) -
+ rounddown(dst_addr, ARCH_DMA_MINALIGN));
+ }
return 0;
}
@@ -490,6 +519,7 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
const struct dm_rproc_ops *ops;
Elf64_Shdr *shdr;
void *src, *dst;
+ bool is_iomem = false;
shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
if (!shdr)
@@ -503,18 +533,21 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
src = (void *)fw_addr + shdr->sh_offset;
if (ops->device_to_virt)
- dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
+ dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size, &is_iomem);
else
dst = (void *)rsc_addr;
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
(ulong)dst, *rsc_size);
- memcpy(dst, src, *rsc_size);
- flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
- roundup((unsigned long)dst + *rsc_size,
- ARCH_DMA_MINALIGN) -
- rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
+ if (is_iomem) {
+ memcpy_toio(dst, src, *rsc_size);
+ } else {
+ memcpy(dst, src, *rsc_size);
+ flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+ roundup((unsigned long)dst + *rsc_size, ARCH_DMA_MINALIGN) -
+ rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
+ }
return 0;
}
diff --git a/drivers/remoteproc/sandbox_testproc.c b/drivers/remoteproc/sandbox_testproc.c
index ad575a7c10f..7ed38e8656c 100644
--- a/drivers/remoteproc/sandbox_testproc.c
+++ b/drivers/remoteproc/sandbox_testproc.c
@@ -308,10 +308,11 @@ static int sandbox_testproc_ping(struct udevice *dev)
* @dev: device to operate upon
* @da: device address
* @size: Size of the memory region @da is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
* Return: converted virtual address
*/
static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da,
- ulong size)
+ ulong size, bool *is_iomem)
{
u64 paddr;
diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c
index f45da9a68ac..bf721e78bb3 100644
--- a/drivers/remoteproc/stm32_copro.c
+++ b/drivers/remoteproc/stm32_copro.c
@@ -61,10 +61,11 @@ static int stm32_copro_probe(struct udevice *dev)
* @dev: corresponding STM32 remote processor device
* @da: device address
* @size: Size of the memory region @da is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
* Return: converted virtual address
*/
static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da,
- ulong size)
+ ulong size, bool *is_iomem)
{
fdt32_t in_addr = cpu_to_be32(da), end_addr;
u64 paddr;
diff --git a/drivers/remoteproc/ti_k3_dsp_rproc.c b/drivers/remoteproc/ti_k3_dsp_rproc.c
index 5a7d6377283..9275e1b241d 100644
--- a/drivers/remoteproc/ti_k3_dsp_rproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_rproc.c
@@ -261,7 +261,7 @@ static int k3_dsp_reset(struct udevice *dev)
return 0;
}
-static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len)
+static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len, bool *is_iomem)
{
struct k3_dsp_privdata *dsp = dev_get_priv(dev);
phys_addr_t bus_addr, dev_addr;
diff --git a/drivers/remoteproc/ti_k3_m4_rproc.c b/drivers/remoteproc/ti_k3_m4_rproc.c
index 31b9de71579..f358788f07f 100644
--- a/drivers/remoteproc/ti_k3_m4_rproc.c
+++ b/drivers/remoteproc/ti_k3_m4_rproc.c
@@ -181,7 +181,7 @@ static int k3_m4_stop(struct udevice *dev)
return 0;
}
-static void *k3_m4_da_to_va(struct udevice *dev, ulong da, ulong len)
+static void *k3_m4_da_to_va(struct udevice *dev, ulong da, ulong len, bool *is_iomem)
{
struct k3_m4_privdata *m4 = dev_get_priv(dev);
phys_addr_t bus_addr, dev_addr;
diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c
index 48401bc6eb6..c738607c109 100644
--- a/drivers/remoteproc/ti_k3_r5f_rproc.c
+++ b/drivers/remoteproc/ti_k3_r5f_rproc.c
@@ -534,7 +534,7 @@ proc_release:
return ret;
}
-static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size)
+static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size, bool *is_iomem)
{
struct k3_r5f_core *core = dev_get_priv(dev);
void __iomem *va = NULL;
diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
index 647001d8dd0..f72e27028b7 100644
--- a/drivers/usb/gadget/f_sdp.c
+++ b/drivers/usb/gadget/f_sdp.c
@@ -765,7 +765,7 @@ static ulong search_container_header(ulong p, int size)
for (i = 0; i < size; i += 4) {
hdr = (u8 *)(p + i);
- if (*(hdr + 3) == 0x87 && *hdr == 0)
+ if (*(hdr + 3) == 0x87 && (*hdr == 0 || *hdr == 2))
if (*(hdr + 1) != 0 || *(hdr + 2) != 0)
return p + i;
}
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2cf687fc4f3..427b62e934b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -210,10 +210,10 @@ config USB_EHCI_MX6
config USB_EHCI_MX7
bool "Support for i.MX7/i.MX8M/i.MX9 on-chip EHCI USB controller"
- depends on ARCH_MX7 || IMX8M || IMX93 || IMX95
+ depends on ARCH_MX7 || IMX8M || IMX9
select EHCI_HCD_INIT_AFTER_RESET if ARCH_MX7
- select PHY if IMX8M || IMX93 || IMX95
- select NOP_PHY if IMX8M || IMX93 || IMX95
+ select PHY if IMX8M || IMX9
+ select NOP_PHY if IMX8M || IMX9
default y
---help---
Enables support for the on-chip EHCI controller on i.MX7/i.MX8M/i.MX9 SoCs.
diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h
index 09354936d73..d849cb544be 100644
--- a/include/configs/dh_imx6.h
+++ b/include/configs/dh_imx6.h
@@ -38,6 +38,7 @@
#define CFG_EXTRA_ENV_SETTINGS \
"bootm_size=0x10000000\0" \
"console=ttymxc0,115200\0" \
+ "dfu_alt_info=sf 0:0=flash-bin raw 0 0x200000\0" \
"fdt_addr=0x18000000\0" \
"kernel_addr_r=0x10008000\0" \
"fdt_addr_r=0x13000000\0" \
diff --git a/include/configs/imx95_evk.h b/include/configs/imx95_evk.h
index 2eebdadc51d..3d22740b3f4 100644
--- a/include/configs/imx95_evk.h
+++ b/include/configs/imx95_evk.h
@@ -15,9 +15,13 @@
#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 */
+#ifdef CONFIG_TARGET_IMX95_15X15_EVK
+#define PHYS_SDRAM_2_SIZE 0x180000000 /* 6GB (Totally 8GB) */
+#else
+#define PHYS_SDRAM_2_SIZE 0x380000000 /* 14GB (Totally 16GB) */
+#endif
#define WDOG_BASE_ADDR WDG3_BASE_ADDR
diff --git a/include/remoteproc.h b/include/remoteproc.h
index 6f8068e1496..9adc3d17d8f 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -495,9 +495,10 @@ struct dm_rproc_ops {
* @dev: Remote proc device
* @da: Device address
* @size: Size of the memory region @da is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
* @return virtual address.
*/
- void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size);
+ void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size, bool *is_iomem);
int (*add_res)(struct udevice *dev,
struct rproc_mem_entry *mapping);
void * (*alloc_mem)(struct udevice *dev, unsigned long len,