diff options
| author | Tom Rini <[email protected]> | 2025-11-04 13:06:26 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-11-04 13:06:26 -0600 |
| commit | 1c250e444ad3b15315ee8b0fcb3fc3acc26449e2 (patch) | |
| tree | 47cd432ccfc396c9fabd4631566289f120c01605 | |
| parent | ef34776f21969a71594dc6224d0e54cf5a2a980c (diff) | |
| parent | 2b7892255bd617dfc523cfe8455dbf386a3dfaf5 (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.
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 = <ðphy5>; + 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 = <ðphy6>; + 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 = <®_gpy_en>; + status = "okay"; + + ethphy5: ethernet-phy@6 { + reg = <0x6>; + realtek,clkout-disable; + }; + + ethphy6: ethernet-phy@7 { + reg = <0x7>; + realtek,clkout-disable; + }; +}; + ®_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 = <®_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; +}; + +®_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, |
