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.
This commit is contained in:
Tom Rini
2025-11-04 13:06:26 -06:00
65 changed files with 2292 additions and 136 deletions
+2
View File
@@ -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
+4
View File
@@ -15,6 +15,10 @@
};
};
#endif
imx8mm-cm4 {
compatible = "fsl,imx8mm-cm4";
syscon = <&src>;
};
};
#ifdef CONFIG_FSL_CAAM
+4
View File
@@ -16,6 +16,10 @@
};
#endif
imx8mn-cm7 {
compatible = "fsl,imx8mn-cm7";
};
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
@@ -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>;
};
};
};
+4
View File
@@ -16,6 +16,10 @@
};
};
#endif
imx8mp-cm7 {
compatible = "fsl,imx8mp-cm7";
};
};
#ifdef CONFIG_FSL_CAAM
+4
View File
@@ -7,6 +7,10 @@
binman: binman {
};
imx8mq-cm4 {
compatible = "fsl,imx8mq-cm4";
syscon = <&src>;
};
};
&soc {
+182
View File
@@ -5,14 +5,146 @@
#include "imx943-u-boot.dtsi"
&enetc1 {
clocks = <&scmi_clk IMX94_CLK_MAC4>;
clock-names = "enet_ref_clk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eth3>;
phy-handle = <&ethphy5>;
phy-mode = "rgmii-id";
status = "okay";
};
&enetc2 {
clocks = <&scmi_clk IMX94_CLK_MAC5>;
clock-names = "enet_ref_clk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eth4>;
phy-handle = <&ethphy6>;
phy-mode = "rgmii-id";
status = "okay";
};
&lpi2c3 {
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpi2c3>;
status = "okay";
pca9548_i2c3: i2c-mux@77 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x77>;
i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
pcal6416_i2c3_u171: gpio@21 {
compatible = "nxp,pcal6416";
reg = <0x21>;
gpio-controller;
#gpio-cells = <2>;
ethphy2-on-hog {
gpio-hog;
gpios = <2 GPIO_ACTIVE_HIGH>;
output-high;
};
ethphy3-on-hog {
gpio-hog;
gpios = <3 GPIO_ACTIVE_HIGH>;
output-high;
};
ethphy4-on-hog {
gpio-hog;
gpios = <4 GPIO_ACTIVE_HIGH>;
output-high;
};
lvds-en-hog {
gpio-hog;
gpios = <9 GPIO_ACTIVE_HIGH>;
output-high;
};
};
};
};
};
&lpuart1 {
bootph-pre-ram;
};
&netc_blk_ctrl {
assigned-clocks = <&scmi_clk IMX94_CLK_MAC2>,
<&scmi_clk IMX94_CLK_MAC4>,
<&scmi_clk IMX94_CLK_MAC5>;
assigned-clock-parents = <&scmi_clk IMX94_CLK_SYSPLL1_PFD0>,
<&scmi_clk IMX94_CLK_SYSPLL1_PFD0>,
<&scmi_clk IMX94_CLK_SYSPLL1_PFD0>;
assigned-clock-rates = <250000000>, <250000000>, <250000000>;
status = "okay";
};
&netc_emdio {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_emdio>;
phy-supply = <&reg_gpy_en>;
status = "okay";
ethphy5: ethernet-phy@6 {
reg = <0x6>;
realtek,clkout-disable;
};
ethphy6: ethernet-phy@7 {
reg = <0x7>;
realtek,clkout-disable;
};
};
&reg_usdhc2_vmmc {
bootph-pre-ram;
};
&usb2 {
dr_mode = "host";
hnp-disable;
srp-disable;
adp-disable;
disable-over-current;
status = "okay";
};
&usb3 {
bootph-pre-ram;
status = "okay";
};
&usb3_dwc3 {
bootph-pre-ram;
dr_mode = "otg";
hnp-disable;
srp-disable;
adp-disable;
usb-role-switch;
role-switch-default-mode = "peripheral";
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
status = "okay";
};
&usb3_phy {
bootph-pre-ram;
orientation-switch;
status = "okay";
};
&usdhc1 {
bootph-pre-ram;
};
@@ -25,6 +157,56 @@
status = "disabled";
};
&scmi_iomuxc {
pinctrl_emdio: emdiogrp {
fsl,pins = <
IMX94_PAD_ETH4_MDC_GPIO1__NETC_EMDC 0x57e
IMX94_PAD_ETH4_MDIO_GPIO2__NETC_EMDIO 0x97e
>;
};
pinctrl_eth3: eth3grp {
fsl,pins = <
IMX94_PAD_ETH3_TXD3__NETC_PINMUX_ETH3_TXD3 0x57e
IMX94_PAD_ETH3_TXD2__NETC_PINMUX_ETH3_TXD2 0x57e
IMX94_PAD_ETH3_TXD1__NETC_PINMUX_ETH3_TXD1 0x57e
IMX94_PAD_ETH3_TXD0__NETC_PINMUX_ETH3_TXD0 0x57e
IMX94_PAD_ETH3_TX_CTL__NETC_PINMUX_ETH3_TX_CTL 0x57e
IMX94_PAD_ETH3_TX_CLK__NETC_PINMUX_ETH3_TX_CLK 0x5fe
IMX94_PAD_ETH3_RX_CTL__NETC_PINMUX_ETH3_RX_CTL 0x57e
IMX94_PAD_ETH3_RX_CLK__NETC_PINMUX_ETH3_RX_CLK 0x5fe
IMX94_PAD_ETH3_RXD0__NETC_PINMUX_ETH3_RXD0 0x57e
IMX94_PAD_ETH3_RXD1__NETC_PINMUX_ETH3_RXD1 0x57e
IMX94_PAD_ETH3_RXD2__NETC_PINMUX_ETH3_RXD2 0x57e
IMX94_PAD_ETH3_RXD3__NETC_PINMUX_ETH3_RXD3 0x57e
>;
};
pinctrl_eth4: eth4grp {
fsl,pins = <
IMX94_PAD_ETH4_TXD3__NETC_PINMUX_ETH4_TXD3 0x57e
IMX94_PAD_ETH4_TXD2__NETC_PINMUX_ETH4_TXD2 0x57e
IMX94_PAD_ETH4_TXD1__NETC_PINMUX_ETH4_TXD1 0x57e
IMX94_PAD_ETH4_TXD0__NETC_PINMUX_ETH4_TXD0 0x57e
IMX94_PAD_ETH4_TX_CTL__NETC_PINMUX_ETH4_TX_CTL 0x57e
IMX94_PAD_ETH4_TX_CLK__NETC_PINMUX_ETH4_TX_CLK 0x5fe
IMX94_PAD_ETH4_RX_CTL__NETC_PINMUX_ETH4_RX_CTL 0x57e
IMX94_PAD_ETH4_RX_CLK__NETC_PINMUX_ETH4_RX_CLK 0x5fe
IMX94_PAD_ETH4_RXD0__NETC_PINMUX_ETH4_RXD0 0x57e
IMX94_PAD_ETH4_RXD1__NETC_PINMUX_ETH4_RXD1 0x57e
IMX94_PAD_ETH4_RXD2__NETC_PINMUX_ETH4_RXD2 0x57e
IMX94_PAD_ETH4_RXD3__NETC_PINMUX_ETH4_RXD3 0x57e
>;
};
pinctrl_lpi2c3: lpi2c3grp {
fsl,pins = <
IMX94_PAD_GPIO_IO16__LPI2C3_SDA 0x40000b9e
IMX94_PAD_GPIO_IO17__LPI2C3_SCL 0x40000b9e
>;
};
};
&pinctrl_reg_usdhc2_vmmc {
bootph-pre-ram;
};
+234
View File
@@ -83,6 +83,32 @@
};
};
};
reg_gpy_stby: regulator-gpy-stby {
compatible = "regulator-fixed";
regulator-name = "gpy-stby";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&pcal6416_i2c3_u171 5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
reg_gpy_en: regulator-gpy-en {
compatible = "regulator-fixed";
regulator-name = "gpy-en";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&reg_gpy_stby>;
gpio = <&pcal6416_i2c3_u171 6 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
usbphynop: usbphynop {
compatible = "usb-nop-xceiv";
clocks = <&scmi_clk IMX94_CLK_HSIO>;
clock-names = "main_clk";
#phy-cells = <0>;
};
};
&cpu0 {
@@ -192,6 +218,214 @@
&{/soc} {
bootph-all;
usb3: usb@4c010010 {
compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
reg = <0x0 0x4c010010 0x0 0x04>,
<0x0 0x4c1f0000 0x0 0x20>;
ranges;
interrupts = <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <2>;
#size-cells = <2>;
clocks = <&scmi_clk IMX94_CLK_HSIO>,
<&scmi_clk IMX94_CLK_32K>;
clock-names = "hsio", "suspend";
power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
status = "disabled";
usb3_dwc3: usb@4c100000 {
compatible = "snps,dwc3";
reg = <0x0 0x4c100000 0x0 0x10000>;
interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scmi_clk IMX94_CLK_HSIO>,
<&scmi_clk IMX94_CLK_24M>,
<&scmi_clk IMX94_CLK_32K>;
clock-names = "bus_early", "ref", "suspend";
phys = <&usb3_phy>, <&usb3_phy>;
phy-names = "usb2-phy", "usb3-phy";
snps,gfladj-refclk-lpm-sel-quirk;
snps,parkmode-disable-ss-quirk;
};
};
usb3_phy: phy@4c1f0040 {
compatible = "fsl,imx95-usb-phy", "fsl,imx8mp-usb-phy";
reg = <0x0 0x4c1f0040 0x0 0x40>,
<0x0 0x4c1fc000 0x0 0x100>;
clocks = <&scmi_clk IMX94_CLK_HSIO>;
clock-names = "phy";
#phy-cells = <0>;
power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
status = "disabled";
};
usb2: usb@4c200000 {
compatible = "fsl,imx95-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
reg = <0x0 0x4c200000 0x0 0x200>;
interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scmi_clk IMX94_CLK_HSIO>,
<&scmi_clk IMX94_CLK_32K>;
clock-names = "usb_ctrl_root", "usb_wakeup";
power-domains = <&scmi_devpd IMX94_PD_HSIO_TOP>;
phys = <&usbphynop>;
fsl,usbmisc = <&usbmisc 0>;
status = "disabled";
};
usbmisc: usbmisc@4c200200 {
compatible = "fsl,imx95-usbmisc", "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
reg = <0x0 0x4c200200 0x0 0x200>,
<0x0 0x4c010014 0x0 0x04>;
#index-cells = <1>;
};
netc_blk_ctrl: system-controller@4ceb0000 {
compatible = "nxp,imx94-netc-blk-ctrl";
reg = <0x0 0x4ceb0000 0x0 0x10000>,
<0x0 0x4cec0000 0x0 0x10000>,
<0x0 0x4c810000 0x0 0x7C>;
reg-names = "ierb", "prb", "netcmix";
#address-cells = <2>;
#size-cells = <2>;
ranges;
power-domains = <&scmi_devpd IMX94_PD_NETC>;
status = "disabled";
netc_bus0: pcie@4ca00000 {
compatible = "pci-host-ecam-generic";
reg = <0x0 0x4ca00000 0x0 0x100000>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
linux,pci-domain = <0>;
bus-range = <0x0 0x0>;
/* Switch BAR0 - non-prefetchable memory */
ranges = <0x02000000 0x0 0x4cc00000 0x0 0x4cc00000 0x0 0x80000
/* ENETC 3 and Timer 0 BAR0 - non-prefetchable memory */
0x02000000 0x0 0x4cd40000 0x0 0x4cd40000 0x0 0x60000
/* Switch and Timer 0 BAR2 - prefetchable memory */
0x42000000 0x0 0x4ce00000 0x0 0x4ce00000 0x0 0x20000
/* ENETC 3 VF0-2 BAR0 - non-prefetchable memory */
0x02000000 0x0 0x4ce50000 0x0 0x4ce50000 0x0 0x30000
/* ENETC 3 VF0-2 BAR2 - prefetchable memory */
0x42000000 0x0 0x4ce80000 0x0 0x4ce80000 0x0 0x30000>;
enetc3: ethernet@0,0 {
compatible = "pci1131,e110";
reg = <0x0 0 0 0 0>;
phy-mode = "internal";
status = "disabled";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
netc_timer0: ethernet@0,1 {
compatible = "pci1131,ee02";
reg = <0x100 0 0 0 0>;
status = "disabled";
};
netc_switch: ethernet-switch@0,2 {
compatible = "pci1131,eef2", "nxp,imx943-netc-switch";
reg = <0x200 0 0 0 0>;
status = "disabled";
netc_switch_ports: ports {
#address-cells = <1>;
#size-cells = <0>;
/* External ports */
netc_switch_port0: port@0 {
reg = <0>;
status = "disabled";
};
netc_switch_port1: port@1 {
reg = <1>;
status = "disabled";
};
netc_switch_port2: port@2 {
reg = <2>;
status = "disabled";
};
/* Internal port, a.k.a management port */
netc_switch_port3: port@3 {
reg = <3>;
phy-mode = "internal";
ethernet = <&enetc3>;
status = "disabled";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
};
};
};
netc_bus1: pcie@4cb00000 {
compatible = "pci-host-ecam-generic";
reg = <0x0 0x4cb00000 0x0 0x100000>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
linux,pci-domain = <1>;
bus-range = <0x1 0x1>;
/* ENETC 0-2 BAR0 - non-prefetchable memory */
ranges = <0x02000000 0x0 0x4cC80000 0x0 0x4cc80000 0x0 0xc0000
/* Timer 1-2 and EMDIO BAR0 - non-prefetchable memory */
0x02000000 0x0 0x4cda0000 0x0 0x4cda0000 0x0 0x60000
/* Timer 1-2 and EMDIO BAR2 - prefetchable memory */
0x42000000 0x0 0x4ce20000 0x0 0x4ce20000 0x0 0x30000>;
enetc0: ethernet@0,0 {
compatible = "pci1131,e101";
reg = <0x10000 0 0 0 0>;
status = "disabled";
};
netc_timer1: ethernet@0,1 {
compatible = "pci1131,ee02";
reg = <0x10100 0 0 0 0>;
status = "disabled";
};
enetc1: ethernet@8,0 {
compatible = "pci1131,e101";
reg = <0x14000 0 0 0 0>;
status = "disabled";
};
enetc2: ethernet@10,0 {
compatible = "pci1131,e101";
reg = <0x18000 0 0 0 0>;
status = "disabled";
};
netc_timer2: ethernet@10,1 {
compatible = "pci1131,ee02";
reg = <0x18100 0 0 0 0>;
status = "disabled";
};
netc_emdio: mdio@18,0 {
compatible = "pci1131,ee00";
reg = <0x1c000 0 0 0 0>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
};
};
elemu1: mailbox@47530000 {
compatible = "fsl,imx93-mu-s4";
reg = <0x0 0x47530000 0x0 0x10000>;
+85
View File
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2025 NXP
*/
#include "imx95-u-boot.dtsi"
/ {
aliases {
pci0 = &netc_bus0;
pci1 = &netc_bus1;
};
};
&{/binman/m33-oei-ddrfw/imx-lpddr/imx-lpddr-imem} {
filename = "lpddr4x_imem_v202409.bin";
};
&{/binman/m33-oei-ddrfw/imx-lpddr/imx-lpddr-dmem} {
filename = "lpddr4x_dmem_v202409.bin";
};
&{/binman/m33-oei-ddrfw/imx-lpddr-qb/imx-lpddr-imem-qb} {
filename = "lpddr4x_imem_qb_v202409.bin";
};
&{/binman/m33-oei-ddrfw/imx-lpddr-qb/imx-lpddr-dmem-qb} {
filename = "lpddr4x_dmem_qb_v202409.bin";
};
&lpuart1 {
bootph-pre-ram;
};
&reg_usdhc2_vmmc {
bootph-pre-ram;
};
&usdhc1 {
bootph-pre-ram;
};
&usdhc2 {
bootph-pre-ram;
};
&wdog3 {
status = "disabled";
};
&pinctrl_uart1 {
bootph-pre-ram;
};
&pinctrl_usdhc1 {
bootph-pre-ram;
};
&pinctrl_usdhc1_100mhz {
bootph-pre-ram;
};
&pinctrl_usdhc1_200mhz {
bootph-pre-ram;
};
&pinctrl_usdhc2 {
bootph-pre-ram;
};
&pinctrl_usdhc2_100mhz {
bootph-pre-ram;
};
&pinctrl_usdhc2_200mhz {
bootph-pre-ram;
};
&pinctrl_usdhc2_gpio {
bootph-pre-ram;
};
&pinctrl_reg_usdhc2_vmmc {
bootph-pre-ram;
};
@@ -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
+20
View File
@@ -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
+16 -1
View File
@@ -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
+19
View File
@@ -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
+1 -1
View File
@@ -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,
+12
View File
@@ -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;
+1 -1
View File
@@ -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
-67
View File
@@ -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
@@ -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,
};
-2
View File
@@ -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,
};
+1 -1
View File
@@ -1,4 +1,4 @@
if TARGET_IMX95_19X19_EVK
if TARGET_IMX95_19X19_EVK || TARGET_IMX95_15X15_EVK
config SYS_BOARD
default "imx95_evk"
+1
View File
@@ -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
+14
View File
@@ -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.
+1
View File
@@ -0,0 +1 @@
obj-$(CONFIG_KONTRON_HW_UID) += hw-uid.o
+75
View File
@@ -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");
}
+26
View File
@@ -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 */
+2
View File
@@ -9,4 +9,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "kontron-sl-mx6ul"
source "board/kontron/common/Kconfig"
endif
+32
View File
@@ -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");
+2
View File
@@ -9,4 +9,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "kontron-sl-mx8mm"
source "board/kontron/common/Kconfig"
endif
+32
View File
@@ -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");
+47
View File
@@ -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;
+1
View File
@@ -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
+30
View File
@@ -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
+148
View File
@@ -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
+1 -1
View File
@@ -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
+2
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
+85
View File
@@ -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
+1
View File
@@ -7,3 +7,4 @@ BSH Hausgeraete GmbH
:maxdepth: 2
imx8mn_bsh_smm_s2
imx6ulz_bsh_smm_m2
+20 -4
View File
@@ -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
+1
View File
@@ -26,4 +26,5 @@ NXP Semiconductors
mx6sabresd
mx6ul_14x14_evk
mx6ullevk
rproc
psb
+69
View File
@@ -0,0 +1,69 @@
.. SPDX-License-Identifier: GPL-2.0+
Copyright 2025 NXP
Written by Peng Fan <peng.fan@nxp.com>
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
+78
View File
@@ -0,0 +1,78 @@
.. SPDX-License-Identifier: GPL-2.0+
Copyright 2025 NXP
Written by Peng Fan <peng.fan@nxp.com>
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
+3 -2
View File
@@ -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
+25
View File
@@ -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;
+321 -8
View File
@@ -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;
}
+11 -3
View File
@@ -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"
+1 -1
View File
@@ -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/
+7
View File
@@ -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
+1
View File
@@ -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
+370
View File
@@ -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),
};
+56
View File
@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
* 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 */
+2 -1
View File
@@ -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,
+64 -31
View File
@@ -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;
}
+2 -1
View File
@@ -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;
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
}
+3 -3
View File
@@ -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.
+1
View File
@@ -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" \
+6 -2
View File
@@ -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
+2 -1
View File
@@ -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,