Merge tag 'u-boot-stm32-20220510' of https://source.denx.de/u-boot/custodians/u-boot-stm
Add new STM32 MCU boards and Documentation
STM32 programmer improvements
video: support several LTDC HW versions and fix data enable polarity
board: fix stboard error message, consider USB cable connected when boot device is USB
configs: stm32mp1: set console variable for extlinux.conf
configs: stm32mp1: add support for baudrate higher than 115200 for ST-Link
ARM: stm32mp: Fix Silicon version handling and ft_system_setup()
phy: stm32-usbphyc: Add DT phy tuning support
arm: dts: stm32mp15: alignment with v5.18
ram: Conditionally enable ASR
mach-stm32mp: psci: retain MCUDIVR, PLL3CR, PLL4CR, MSSCKSELR across suspend
configs: Use TFTP_TSIZE on DHSOM and STMicroelectronics boards
ARM: stm32: Use default CONFIG_TFTP_BLOCKSIZE on DHSOM
pinctrl: stm32: rework GPIO holes management
diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi
index 6161f59..f0d66d8 100644
--- a/arch/arm/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi
@@ -338,6 +338,47 @@
};
};
+ ethernet0_rmii_pins_b: rmii-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 5, AF0)>, /* ETH1_CLK */
+ <STM32_PINMUX('C', 1, AF11)>, /* ETH1_MDC */
+ <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH1_MDIO */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('A', 7, AF11)>, /* ETH1_CRS_DV */
+ <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>; /* ETH1_RXD1 */
+ bias-disable;
+ };
+ pins4 {
+ pinmux = <STM32_PINMUX('B', 11, AF11)>; /* ETH1_TX_EN */
+ };
+ };
+
+ ethernet0_rmii_sleep_pins_b: rmii-sleep-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */
+ <STM32_PINMUX('A', 7, ANALOG)>, /* ETH1_CRS_DV */
+ <STM32_PINMUX('B', 5, ANALOG)>, /* ETH1_CLK */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_TX_EN */
+ <STM32_PINMUX('C', 1, ANALOG)>, /* ETH1_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH1_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH1_RXD1 */
+ <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>; /* ETH1_TXD1 */
+ };
+ };
+
fmc_pins_a: fmc-0 {
pins1 {
pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
@@ -927,6 +968,21 @@
};
};
+ pwm1_pins_b: pwm1-1 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 9, AF1)>; /* TIM1_CH1 */
+ bias-pull-down;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ };
+
+ pwm1_sleep_pins_b: pwm1-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 9, ANALOG)>; /* TIM1_CH1 */
+ };
+ };
+
pwm2_pins_a: pwm2-0 {
pins {
pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
@@ -2042,6 +2098,42 @@
};
};
+ usart3_pins_d: usart3-3 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 9, AF7)>, /* USART3_RX */
+ <STM32_PINMUX('D', 11, AF7)>; /* USART3_CTS_NSS */
+ bias-disable;
+ };
+ };
+
+ usart3_idle_pins_d: usart3-idle-3 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+ <STM32_PINMUX('D', 11, ANALOG)>; /* USART3_CTS_NSS */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 9, AF7)>; /* USART3_RX */
+ bias-disable;
+ };
+ };
+
+ usart3_sleep_pins_d: usart3-sleep-3 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+ <STM32_PINMUX('D', 11, ANALOG)>, /* USART3_CTS_NSS */
+ <STM32_PINMUX('D', 9, ANALOG)>; /* USART3_RX */
+ };
+ };
+
usbotg_hs_pins_a: usbotg-hs-0 {
pins {
pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi
index e23d6c7..d9d0474 100644
--- a/arch/arm/dts/stm32mp15-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15-u-boot.dtsi
@@ -188,18 +188,6 @@
#size-cells = <0>;
};
-&sdmmc1 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-};
-
-&sdmmc2 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-};
-
-&sdmmc3 {
- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-};
-
&usart1 {
resets = <&rcc USART1_R>;
};
diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi
index 5a2be00..e74a5fa 100644
--- a/arch/arm/dts/stm32mp151.dtsi
+++ b/arch/arm/dts/stm32mp151.dtsi
@@ -63,10 +63,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&intc>;
};
@@ -473,6 +473,9 @@
interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART2_K>;
wakeup-source;
+ dmas = <&dmamux1 43 0x400 0x15>,
+ <&dmamux1 44 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -482,6 +485,9 @@
interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART3_K>;
wakeup-source;
+ dmas = <&dmamux1 45 0x400 0x15>,
+ <&dmamux1 46 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -491,6 +497,9 @@
interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART4_K>;
wakeup-source;
+ dmas = <&dmamux1 63 0x400 0x15>,
+ <&dmamux1 64 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -500,6 +509,9 @@
interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART5_K>;
wakeup-source;
+ dmas = <&dmamux1 65 0x400 0x15>,
+ <&dmamux1 66 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -606,6 +618,9 @@
interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART7_K>;
wakeup-source;
+ dmas = <&dmamux1 79 0x400 0x15>,
+ <&dmamux1 80 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -615,6 +630,9 @@
interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART8_K>;
wakeup-source;
+ dmas = <&dmamux1 81 0x400 0x15>,
+ <&dmamux1 82 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -696,6 +714,9 @@
interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART6_K>;
wakeup-source;
+ dmas = <&dmamux1 71 0x400 0x15>,
+ <&dmamux1 72 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -1077,7 +1098,7 @@
};
sdmmc3: mmc@48004000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x48004000 0x400>;
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
@@ -1411,7 +1432,7 @@
};
sdmmc1: mmc@58005000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x58005000 0x1000>;
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
@@ -1426,7 +1447,7 @@
};
sdmmc2: mmc@58007000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x58007000 0x1000>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
@@ -1590,7 +1611,7 @@
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
- interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
diff --git a/arch/arm/dts/stm32mp153.dtsi b/arch/arm/dts/stm32mp153.dtsi
index 1c1889b..486084e 100644
--- a/arch/arm/dts/stm32mp153.dtsi
+++ b/arch/arm/dts/stm32mp153.dtsi
@@ -22,6 +22,13 @@
interrupt-affinity = <&cpu0>, <&cpu1>;
};
+ timer {
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
soc {
m_can1: can@4400e000 {
compatible = "bosch,m_can";
diff --git a/arch/arm/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts b/arch/arm/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
index d3058a0..1f75f1d 100644
--- a/arch/arm/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
+++ b/arch/arm/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
@@ -43,5 +43,7 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts b/arch/arm/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
index ec9f1d1..3a1295c 100644
--- a/arch/arm/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
+++ b/arch/arm/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
@@ -43,5 +43,7 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
index 5670b23..fae656e 100644
--- a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
+++ b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
@@ -143,6 +143,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -150,5 +152,7 @@
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
index 7a75868..b9d0d3d 100644
--- a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
+++ b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
@@ -44,6 +44,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -51,5 +53,7 @@
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index f62b46b..fe5c8f2 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -392,6 +392,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts
index 0e72549..17bcf56 100644
--- a/arch/arm/dts/stm32mp157c-odyssey.dts
+++ b/arch/arm/dts/stm32mp157c-odyssey.dts
@@ -132,6 +132,8 @@
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-drc02.dtsi
index 4b10b01..35b1034 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-drc02.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-drc02.dtsi
@@ -131,6 +131,8 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -144,6 +146,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
rts-gpios = <&gpioe 6 GPIO_ACTIVE_HIGH>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dtsi
index fbf3826..5f586f0 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -287,6 +287,8 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -294,6 +296,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>;
uart-has-rtscts;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-picoitx.dtsi
index ba816ef..abc5953 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-picoitx.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-picoitx.dtsi
@@ -105,12 +105,16 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-som.dtsi
index 8c41f81..83e2c87 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-som.dtsi
@@ -196,7 +196,6 @@
"", "", "DHCOM-E", "",
"", "", "", "",
"", "", "", "";
- status = "okay";
};
&gpiod {
@@ -521,5 +520,7 @@
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtsi
index 6885948..61e17f4 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtsi
@@ -376,6 +376,8 @@
label = "LS-UART1";
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_b>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -385,6 +387,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart7_pins_a>;
uart-has-rtscts;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -394,6 +398,8 @@
pinctrl-0 = <&usart2_pins_a>;
pinctrl-1 = <&usart2_sleep_pins_a>;
st,hw-flow-ctrl;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
bluetooth {
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
index 7517231..9937b28 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi
@@ -18,6 +18,11 @@
};
};
+&vdd {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+};
+
&pwr_regulators {
vdd-supply = <&vdd_io>;
};
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-som.dtsi
index 44ecc47..98033b5 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-som.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-som.dtsi
@@ -77,8 +77,8 @@
vdd: buck3 {
regulator-name = "vdd";
- regulator-min-microvolt = <2900000>;
- regulator-max-microvolt = <2900000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-initial-mode = <0>;
regulator-over-current-protection;
diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi
index f8130bf..3d36cac 100644
--- a/arch/arm/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi
@@ -658,6 +658,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -666,6 +668,8 @@
pinctrl-0 = <&uart7_pins_c>;
pinctrl-1 = <&uart7_sleep_pins_c>;
pinctrl-2 = <&uart7_idle_pins_c>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "disabled";
};
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index a439dbd..a44ebf2 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -25,26 +25,6 @@
select PINCTRL
select PINCTRL_STM32
select RAM
- select SPL
- select SPL_BOARD_INIT
- select SPL_CLK
- select SPL_DM
- select SPL_DM_RESET
- select SPL_DM_SEQ_ALIAS
- select SPL_DRIVERS_MISC
- select SPL_GPIO
- select SPL_LIBCOMMON_SUPPORT
- select SPL_LIBGENERIC_SUPPORT
- select SPL_MTD_SUPPORT
- select SPL_OF_CONTROL
- select SPL_OF_LIBFDT
- select SPL_OF_TRANSLATE
- select SPL_PINCTRL
- select SPL_RAM
- select SPL_SERIAL
- select SPL_SYS_MALLOC_SIMPLE
- select SPL_TIMER
- select SPL_XIP_SUPPORT
select STM32_RCC
select STM32_RESET
select STM32_SDRAM
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
index dd166a1..8f91db4 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig
@@ -31,3 +31,10 @@
activate the command "stm32prog serial" for STM32MP soc family
with the tools STM32CubeProgrammer using U-Boot serial device
and UART protocol.
+
+config CMD_STM32PROG_OTP
+ bool "support stm32prog for OTP update"
+ depends on CMD_STM32PROG
+ default y if ARM_SMCCC || OPTEE
+ help
+ Support the OTP update with the command "stm32prog" for STM32MP
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
index 41452b5..f59414e 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
@@ -73,16 +73,9 @@
/* check STM32IMAGE presence */
if (size == 0) {
- stm32prog_header_check((struct raw_header_s *)addr, &header);
+ stm32prog_header_check(addr, &header);
if (header.type == HEADER_STM32IMAGE) {
- size = header.image_length + BL_HEADER_SIZE;
-
-#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
- /* uImage detected in STM32IMAGE, execute the script */
- if (IMAGE_FORMAT_LEGACY ==
- genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
- return image_source_script(addr + BL_HEADER_SIZE, "script@1");
-#endif
+ size = header.image_length + header.length;
}
}
@@ -160,6 +153,8 @@
else if (CONFIG_IS_ENABLED(CMD_BOOTZ))
do_bootz(cmdtp, 0, 4, bootm_argv);
}
+ if (data->script)
+ image_source_script(data->script, "script@stm32prog");
if (reset) {
puts("Reset...\n");
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index 61cba15..b711112 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -6,12 +6,15 @@
#include <command.h>
#include <console.h>
#include <dfu.h>
+#include <image.h>
#include <malloc.h>
#include <misc.h>
#include <mmc.h>
#include <part.h>
+#include <tee.h>
#include <asm/arch/stm32mp1_smc.h>
#include <asm/global_data.h>
+#include <dm/device_compat.h>
#include <dm/uclass.h>
#include <jffs2/load_kernel.h>
#include <linux/list.h>
@@ -46,7 +49,7 @@
EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \
0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18)
-/* RAW parttion (binary / bootloader) used Linux - reserved UUID */
+/* RAW partition (binary / bootloader) used Linux - reserved UUID */
#define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908"
/*
@@ -60,6 +63,28 @@
ROOTFS_MMC2_UUID
};
+/* FIP type partition UUID used by TF-A*/
+#define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5"
+
+/* unique partition guid (uuid) for FIP partitions A/B */
+#define FIP_A_UUID \
+ EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \
+ 0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87)
+
+#define FIP_B_UUID \
+ EFI_GUID(0x09C54952, 0xD5BF, 0x45AF, \
+ 0xAC, 0xEE, 0x33, 0x53, 0x03, 0x76, 0x6F, 0xB3)
+
+static const char * const fip_part_name[] = {
+ "fip-a",
+ "fip-b"
+};
+
+static const efi_guid_t fip_part_uuid[] = {
+ FIP_A_UUID,
+ FIP_B_UUID
+};
+
/* order of column in flash layout file */
enum stm32prog_col_t {
COL_OPTION,
@@ -79,8 +104,110 @@
u64 flags;
};
+#define TA_NVMEM_UUID { 0x1a8342cc, 0x81a5, 0x4512, \
+ { 0x99, 0xfe, 0x9e, 0x2b, 0x3e, 0x37, 0xd6, 0x26 } }
+
+/*
+ * Read NVMEM memory for STM32CubeProgrammer
+ *
+ * [in] value[0].a: Type (0 for OTP access)
+ * [out] memref[1].buffer Output buffer to return all read values
+ * [out] memref[1].size Size of buffer to be read
+ *
+ * Return codes:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ */
+#define TA_NVMEM_READ 0x0
+
+/*
+ * Write NVMEM memory for STM32CubeProgrammer
+ *
+ * [in] value[0].a Type (0 for OTP access)
+ * [in] memref[1].buffer Input buffer with the values to write
+ * [in] memref[1].size Size of buffer to be written
+ *
+ * Return codes:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ */
+#define TA_NVMEM_WRITE 0x1
+
+/* value of TA_NVMEM type = value[in] a */
+#define NVMEM_OTP 0
+
DECLARE_GLOBAL_DATA_PTR;
+/* OPTEE TA NVMEM open helper */
+static int optee_ta_open(struct stm32prog_data *data)
+{
+ const struct tee_optee_ta_uuid uuid = TA_NVMEM_UUID;
+ struct tee_open_session_arg arg;
+ struct udevice *tee = NULL;
+ int rc;
+
+ if (data->tee)
+ return 0;
+
+ tee = tee_find_device(NULL, NULL, NULL, NULL);
+ if (!tee)
+ return -ENODEV;
+
+ memset(&arg, 0, sizeof(arg));
+ tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
+ rc = tee_open_session(tee, &arg, 0, NULL);
+ if (rc < 0)
+ return -ENODEV;
+
+ data->tee = tee;
+ data->tee_session = arg.session;
+
+ return 0;
+}
+
+/* OPTEE TA NVMEM invoke helper */
+static int optee_ta_invoke(struct stm32prog_data *data, int cmd, int type,
+ void *buff, ulong size)
+{
+ struct tee_invoke_arg arg;
+ struct tee_param param[2];
+ struct tee_shm *buff_shm;
+ int rc;
+
+ rc = tee_shm_register(data->tee, buff, size, 0, &buff_shm);
+ if (rc)
+ return rc;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.func = cmd;
+ arg.session = data->tee_session;
+
+ memset(param, 0, sizeof(param));
+ param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
+ param[0].u.value.a = type;
+
+ if (cmd == TA_NVMEM_WRITE)
+ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
+ else
+ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
+
+ param[1].u.memref.shm = buff_shm;
+ param[1].u.memref.size = size;
+
+ rc = tee_invoke_func(data->tee, &arg, 2, param);
+ if (rc < 0 || arg.ret != 0) {
+ dev_err(data->tee,
+ "TA_NVMEM invoke failed TEE err: %x, err:%x\n",
+ arg.ret, rc);
+ if (!rc)
+ rc = -EIO;
+ }
+
+ tee_shm_free(buff_shm);
+
+ return rc;
+}
+
/* partition handling routines : CONFIG_CMD_MTDPARTS */
int mtdparts_init(void);
int find_dev_and_part(const char *id, struct mtd_device **dev,
@@ -101,52 +228,98 @@
return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number;
}
-void stm32prog_header_check(struct raw_header_s *raw_header,
- struct image_header_s *header)
+static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header)
{
unsigned int i;
+ if (header->magic_number !=
+ (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
+ log_debug("%s:invalid magic number : 0x%x\n",
+ __func__, header->magic_number);
+ return false;
+ }
+ if (header->header_version != 0x00010000) {
+ log_debug("%s:invalid header version : 0x%x\n",
+ __func__, header->header_version);
+ return false;
+ }
+
+ if (header->reserved1 || header->reserved2) {
+ log_debug("%s:invalid reserved field\n", __func__);
+ return false;
+ }
+ for (i = 0; i < sizeof(header->padding); i++) {
+ if (header->padding[i] != 0) {
+ log_debug("%s:invalid padding field\n", __func__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header)
+{
+ unsigned int i;
+
+ if (header->magic_number !=
+ (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
+ log_debug("%s:invalid magic number : 0x%x\n",
+ __func__, header->magic_number);
+ return false;
+ }
+ if (header->header_version != 0x00020000) {
+ log_debug("%s:invalid header version : 0x%x\n",
+ __func__, header->header_version);
+ return false;
+ }
+ if (header->reserved1 || header->reserved2)
+ return false;
+
+ for (i = 0; i < sizeof(header->padding); i++) {
+ if (header->padding[i] != 0) {
+ log_debug("%s:invalid padding field\n", __func__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header)
+{
+ struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header;
+ struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header;
+
if (!raw_header || !header) {
log_debug("%s:no header data\n", __func__);
return;
}
+ if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
+ header->type = HEADER_FIP;
+ header->length = 0;
+ return;
+ }
+ if (stm32prog_is_stm32_header_v1(v1_header)) {
+ header->type = HEADER_STM32IMAGE;
+ header->image_checksum = le32_to_cpu(v1_header->image_checksum);
+ header->image_length = le32_to_cpu(v1_header->image_length);
+ header->length = sizeof(struct stm32_header_v1);
+ return;
+ }
+ if (stm32prog_is_stm32_header_v2(v2_header)) {
+ header->type = HEADER_STM32IMAGE_V2;
+ header->image_checksum = le32_to_cpu(v2_header->image_checksum);
+ header->image_length = le32_to_cpu(v2_header->image_length);
+ header->length = sizeof(struct stm32_header_v1) +
+ v2_header->extension_headers_length;
+ return;
+ }
+
header->type = HEADER_NONE;
header->image_checksum = 0x0;
header->image_length = 0x0;
-
- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
- header->type = HEADER_FIP;
- return;
- }
-
- if (raw_header->magic_number !=
- (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) {
- log_debug("%s:invalid magic number : 0x%x\n",
- __func__, raw_header->magic_number);
- return;
- }
- /* only header v1.0 supported */
- if (raw_header->header_version != 0x00010000) {
- log_debug("%s:invalid header version : 0x%x\n",
- __func__, raw_header->header_version);
- return;
- }
- if (raw_header->reserved1 != 0x0 || raw_header->reserved2) {
- log_debug("%s:invalid reserved field\n", __func__);
- return;
- }
- for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) {
- if (raw_header->padding[i] != 0) {
- log_debug("%s:invalid padding field\n", __func__);
- return;
- }
- }
- header->type = HEADER_STM32IMAGE;
- header->image_checksum = le32_to_cpu(raw_header->image_checksum);
- header->image_length = le32_to_cpu(raw_header->image_length);
-
- return;
}
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header)
@@ -255,6 +428,8 @@
part->bin_nb =
dectoul(&p[7], NULL);
}
+ } else if (!strcmp(p, "FIP")) {
+ part->part_type = PART_FIP;
} else if (!strcmp(p, "System")) {
part->part_type = PART_SYSTEM;
} else if (!strcmp(p, "FileSystem")) {
@@ -376,11 +551,11 @@
data->part_nb = 0;
/* check if STM32image is detected */
- stm32prog_header_check((struct raw_header_s *)addr, &header);
+ stm32prog_header_check(addr, &header);
if (header.type == HEADER_STM32IMAGE) {
u32 checksum;
- addr = addr + BL_HEADER_SIZE;
+ addr = addr + header.length;
size = header.image_length;
checksum = stm32prog_header_checksum(addr, &header);
@@ -906,9 +1081,10 @@
char uuid[UUID_STR_LEN + 1];
unsigned char *uuid_bin;
unsigned int mmc_id;
- int i;
+ int i, j;
bool rootfs_found;
struct stm32prog_part_t *part;
+ const char *type_str;
buf = malloc(buflen);
if (!buf)
@@ -950,33 +1126,46 @@
part->addr,
part->size);
- if (part->part_type == PART_BINARY)
- offset += snprintf(buf + offset,
- buflen - offset,
- ",type="
- LINUX_RESERVED_UUID);
- else
- offset += snprintf(buf + offset,
- buflen - offset,
- ",type=linux");
+ switch (part->part_type) {
+ case PART_BINARY:
+ type_str = LINUX_RESERVED_UUID;
+ break;
+ case PART_FIP:
+ type_str = FIP_TYPE_UUID;
+ break;
+ default:
+ type_str = "linux";
+ break;
+ }
+ offset += snprintf(buf + offset,
+ buflen - offset,
+ ",type=%s", type_str);
if (part->part_type == PART_SYSTEM)
offset += snprintf(buf + offset,
buflen - offset,
",bootable");
+ /* partition UUID */
+ uuid_bin = NULL;
if (!rootfs_found && !strcmp(part->name, "rootfs")) {
mmc_id = part->dev_id;
rootfs_found = true;
- if (mmc_id < ARRAY_SIZE(uuid_mmc)) {
- uuid_bin =
- (unsigned char *)uuid_mmc[mmc_id].b;
- uuid_bin_to_str(uuid_bin, uuid,
- UUID_STR_FORMAT_GUID);
- offset += snprintf(buf + offset,
- buflen - offset,
- ",uuid=%s", uuid);
- }
+ if (mmc_id < ARRAY_SIZE(uuid_mmc))
+ uuid_bin = (unsigned char *)uuid_mmc[mmc_id].b;
+ }
+ if (part->part_type == PART_FIP) {
+ for (j = 0; j < ARRAY_SIZE(fip_part_name); j++)
+ if (!strcmp(part->name, fip_part_name[j])) {
+ uuid_bin = (unsigned char *)fip_part_uuid[j].b;
+ break;
+ }
+ }
+ if (uuid_bin) {
+ uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
+ offset += snprintf(buf + offset,
+ buflen - offset,
+ ",uuid=%s", uuid);
}
offset += snprintf(buf + offset, buflen - offset, ";");
@@ -1154,7 +1343,9 @@
struct dfu_entity *dfu;
int alt_nb;
- alt_nb = 2; /* number of virtual = CMD, OTP*/
+ alt_nb = 1; /* number of virtual = CMD*/
+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP))
+ alt_nb++; /* OTP*/
if (CONFIG_IS_ENABLED(DM_PMIC))
alt_nb++; /* PMIC NVMEM*/
@@ -1205,8 +1396,12 @@
if (!ret)
ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
- if (!ret)
- ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
+ if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
+ ret = optee_ta_open(data);
+ log_debug("optee_ta result %d\n", ret);
+ ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP,
+ data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC);
+ }
if (!ret && CONFIG_IS_ENABLED(DM_PMIC))
ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE);
@@ -1224,19 +1419,26 @@
int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer,
long *size)
{
+ u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC;
log_debug("%s: %x %lx\n", __func__, offset, *size);
+ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
+ stm32prog_err("OTP update not supported");
+
+ return -EOPNOTSUPP;
+ }
+
if (!data->otp_part) {
- data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
+ data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part)
return -ENOMEM;
}
if (!offset)
- memset(data->otp_part, 0, OTP_SIZE);
+ memset(data->otp_part, 0, otp_size);
- if (offset + *size > OTP_SIZE)
- *size = OTP_SIZE - offset;
+ if (offset + *size > otp_size)
+ *size = otp_size - offset;
memcpy((void *)((u32)data->otp_part + offset), buffer, *size);
@@ -1246,12 +1448,13 @@
int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer,
long *size)
{
+ u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC;
int result = 0;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
+ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
stm32prog_err("OTP update not supported");
- return -1;
+ return -EOPNOTSUPP;
}
log_debug("%s: %x %lx\n", __func__, offset, *size);
@@ -1259,7 +1462,7 @@
if (!offset) {
if (!data->otp_part)
data->otp_part =
- memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE);
+ memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size);
if (!data->otp_part) {
result = -ENOMEM;
@@ -1267,11 +1470,16 @@
}
/* init struct with 0 */
- memset(data->otp_part, 0, OTP_SIZE);
+ memset(data->otp_part, 0, otp_size);
/* call the service */
- result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
- (u32)data->otp_part, 0);
+ result = -EOPNOTSUPP;
+ if (data->tee && CONFIG_IS_ENABLED(OPTEE))
+ result = optee_ta_invoke(data, TA_NVMEM_READ, NVMEM_OTP,
+ data->otp_part, OTP_SIZE_TA);
+ else if (IS_ENABLED(CONFIG_ARM_SMCCC))
+ result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL,
+ (u32)data->otp_part, 0);
if (result)
goto end_otp_read;
}
@@ -1281,8 +1489,8 @@
goto end_otp_read;
}
- if (offset + *size > OTP_SIZE)
- *size = OTP_SIZE - offset;
+ if (offset + *size > otp_size)
+ *size = otp_size - offset;
memcpy(buffer, (void *)((u32)data->otp_part + offset), *size);
end_otp_read:
@@ -1296,10 +1504,10 @@
int result = 0;
struct arm_smccc_res res;
- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) {
+ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) {
stm32prog_err("OTP update not supported");
- return -1;
+ return -EOPNOTSUPP;
}
if (!data->otp_part) {
@@ -1307,28 +1515,34 @@
return -1;
}
- arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
- (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
+ result = -EOPNOTSUPP;
+ if (data->tee && CONFIG_IS_ENABLED(OPTEE)) {
+ result = optee_ta_invoke(data, TA_NVMEM_WRITE, NVMEM_OTP,
+ data->otp_part, OTP_SIZE_TA);
+ } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) {
+ arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL,
+ (u32)data->otp_part, 0, 0, 0, 0, 0, &res);
- if (!res.a0) {
- switch (res.a1) {
- case 0:
- result = 0;
- break;
- case 1:
- stm32prog_err("Provisioning");
- result = 0;
- break;
- default:
- log_err("%s: OTP incorrect value (err = %ld)\n",
- __func__, res.a1);
+ if (!res.a0) {
+ switch (res.a1) {
+ case 0:
+ result = 0;
+ break;
+ case 1:
+ stm32prog_err("Provisioning");
+ result = 0;
+ break;
+ default:
+ log_err("%s: OTP incorrect value (err = %ld)\n",
+ __func__, res.a1);
+ result = -EINVAL;
+ break;
+ }
+ } else {
+ log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
+ __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0);
result = -EINVAL;
- break;
}
- } else {
- log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
- __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0);
- result = -EINVAL;
}
free(data->otp_part);
@@ -1431,7 +1645,7 @@
int ret, i;
void *fsbl;
struct image_header_s header;
- struct raw_header_s raw_header;
+ struct stm32_header_v2 raw_header; /* V2 size > v1 size */
struct dfu_entity *dfu;
long size, offset;
@@ -1443,17 +1657,18 @@
/* read header */
dfu_transaction_cleanup(dfu);
- size = BL_HEADER_SIZE;
+ size = sizeof(raw_header);
ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size);
if (ret)
return ret;
- stm32prog_header_check(&raw_header, &header);
- if (header.type != HEADER_STM32IMAGE)
+ stm32prog_header_check((ulong)&raw_header, &header);
+ if (header.type != HEADER_STM32IMAGE &&
+ header.type != HEADER_STM32IMAGE_V2)
return -ENOENT;
/* read header + payload */
- size = header.image_length + BL_HEADER_SIZE;
+ size = header.image_length + header.length;
size = round_up(size, part->dev->mtd->erasesize);
fsbl = calloc(1, size);
if (!fsbl)
@@ -1483,7 +1698,16 @@
static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset)
{
if (data->phase == PHASE_FLASHLAYOUT) {
- if (parse_flash_layout(data, STM32_DDR_BASE, 0))
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
+ if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) {
+ data->script = STM32_DDR_BASE;
+ data->phase = PHASE_END;
+ log_notice("U-Boot script received\n");
+ return;
+ }
+#endif
+ log_notice("\nFlashLayout received, size = %lld\n", offset);
+ if (parse_flash_layout(data, STM32_DDR_BASE, offset))
stm32prog_err("Layout: invalid FlashLayout");
return;
}
@@ -1739,6 +1963,12 @@
free(data->part_array);
free(data->otp_part);
free(data->buffer);
+
+ if (CONFIG_IS_ENABLED(OPTEE) && data->tee) {
+ tee_close_session(data->tee, data->tee_session);
+ data->tee = NULL;
+ data->tee_session = 0x0;
+ }
}
/* DFU callback: used after serial and direct DFU USB access */
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
index 240c5c4..ac30076 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
@@ -20,7 +20,8 @@
#define DEFAULT_ADDRESS 0xFFFFFFFF
#define CMD_SIZE 512
-#define OTP_SIZE 1024
+#define OTP_SIZE_SMC 1024
+#define OTP_SIZE_TA 776
#define PMIC_SIZE 8
enum stm32prog_target {
@@ -41,6 +42,7 @@
enum stm32prog_header_t {
HEADER_NONE,
HEADER_STM32IMAGE,
+ HEADER_STM32IMAGE_V2,
HEADER_FIP,
};
@@ -48,11 +50,12 @@
enum stm32prog_header_t type;
u32 image_checksum;
u32 image_length;
+ u32 length;
};
-struct raw_header_s {
+struct stm32_header_v1 {
u32 magic_number;
- u32 image_signature[64 / 4];
+ u8 image_signature[64];
u32 image_checksum;
u32 header_version;
u32 image_length;
@@ -63,19 +66,38 @@
u32 version_number;
u32 option_flags;
u32 ecdsa_algorithm;
- u32 ecdsa_public_key[64 / 4];
- u32 padding[83 / 4];
- u32 binary_type;
+ u8 ecdsa_public_key[64];
+ u8 padding[83];
+ u8 binary_type;
};
-#define BL_HEADER_SIZE sizeof(struct raw_header_s)
+struct stm32_header_v2 {
+ u32 magic_number;
+ u8 image_signature[64];
+ u32 image_checksum;
+ u32 header_version;
+ u32 image_length;
+ u32 image_entry_point;
+ u32 reserved1;
+ u32 load_address;
+ u32 reserved2;
+ u32 version_number;
+ u32 extension_flags;
+ u32 extension_headers_length;
+ u32 binary_type;
+ u8 padding[16];
+ u32 extension_header_type;
+ u32 extension_header_length;
+ u8 extension_padding[376];
+};
/* partition type in flashlayout file */
enum stm32prog_part_type {
PART_BINARY,
+ PART_FIP,
PART_SYSTEM,
PART_FILESYSTEM,
- RAW_IMAGE
+ RAW_IMAGE,
};
/* device information */
@@ -147,6 +169,12 @@
u32 dtb;
u32 initrd;
u32 initrd_size;
+
+ u32 script;
+
+ /* OPTEE PTA NVMEM */
+ struct udevice *tee;
+ u32 tee_session;
};
extern struct stm32prog_data *stm32prog_data;
@@ -166,8 +194,7 @@
int stm32prog_pmic_start(struct stm32prog_data *data);
/* generic part*/
-void stm32prog_header_check(struct raw_header_s *raw_header,
- struct image_header_s *header);
+void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header);
int stm32prog_dfu_init(struct stm32prog_data *data);
void stm32prog_next_phase(struct stm32prog_data *data);
void stm32prog_do_reset(struct stm32prog_data *data);
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
index e8acc30..a8b57c4 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
@@ -181,7 +181,7 @@
*size = CMD_SIZE;
break;
case PHASE_OTP:
- *size = OTP_SIZE;
+ *size = stm32prog_data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC;
break;
case PHASE_PMIC:
*size = PMIC_SIZE;
@@ -206,9 +206,12 @@
g_dnl_set_product(product);
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
+ /* forget any previous Control C */
+ clear_ctrlc();
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
- if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT)
- return ret;
+ /* DFU reset received, no error or CtrlC */
+ if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT || had_ctrlc())
+ return ret; /* true = reset on DFU error */
/* prepare the second enumeration with the FlashLayout */
stm32prog_dfu_init(data);
}
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 325d710..0ad5f30 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -432,13 +432,13 @@
/* Revision */
switch (get_cpu_rev()) {
- case CPU_REVA:
+ case CPU_REV1:
*rev = 1;
break;
- case CPU_REVB:
+ case CPU_REV2:
*rev = 2;
break;
- case CPU_REVZ:
+ case CPU_REV2_1:
*rev = 3;
break;
default:
diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c
index 91330a6..b1a4b76 100644
--- a/arch/arm/mach-stm32mp/fdt.c
+++ b/arch/arm/mach-stm32mp/fdt.c
@@ -260,6 +260,9 @@
char name[SOC_NAME_SIZE];
soc = fdt_path_offset(blob, "/soc");
+ /* when absent, nothing to do */
+ if (soc == -FDT_ERR_NOTFOUND)
+ return 0;
if (soc < 0)
return soc;
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index 4149d3a..b91f98e 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -25,11 +25,12 @@
/* return CPU_DEV constants */
u32 get_cpu_dev(void);
-#define CPU_REVA 0x1000
-#define CPU_REVB 0x2000
-#define CPU_REVZ 0x2001
+#define CPU_REV1 0x1000
+#define CPU_REV1_1 0x1001
+#define CPU_REV2 0x2000
+#define CPU_REV2_1 0x2001
-/* return CPU_REV constants */
+/* return Silicon revision = REV_ID[15:0] of Device Version */
u32 get_cpu_rev(void);
/* Get Package options from OTP */
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index 86c1609..1e69673 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -26,6 +26,7 @@
#define PWR_MPUCR_CSSF BIT(9)
/* RCC */
+#define RCC_MSSCKSELR 0x48
#define RCC_DDRITFCR 0xd8
#define RCC_DDRITFCR_DDRC1EN BIT(0)
@@ -49,6 +50,10 @@
#define RCC_MP_CIFR 0x418
#define RCC_MP_CIFR_WKUPF BIT(20)
+#define RCC_MCUDIVR 0x830
+#define RCC_PLL3CR 0x880
+#define RCC_PLL4CR 0x894
+
/* SYSCFG */
#define SYSCFG_CMPCR 0x20
#define SYSCFG_CMPCR_SW_CTRL BIT(2)
@@ -690,6 +695,7 @@
void __secure psci_system_suspend(u32 __always_unused function_id,
u32 ep, u32 context_id)
{
+ u32 saved_mcudivr, saved_pll3cr, saved_pll4cr, saved_mssckselr;
u32 saved_pwrctl, reg;
/* Disable IO compensation */
@@ -708,6 +714,11 @@
setbits_le32(STM32_PWR_BASE + PWR_MPUCR,
PWR_MPUCR_CSSF | PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_PDDS);
+ saved_mcudivr = readl(STM32_RCC_BASE + RCC_MCUDIVR);
+ saved_pll3cr = readl(STM32_RCC_BASE + RCC_PLL3CR);
+ saved_pll4cr = readl(STM32_RCC_BASE + RCC_PLL4CR);
+ saved_mssckselr = readl(STM32_RCC_BASE + RCC_MSSCKSELR);
+
psci_v7_flush_dcache_all();
ddr_sr_mode_ssr(&saved_pwrctl);
ddr_sw_self_refresh_in();
@@ -724,6 +735,11 @@
ddr_sw_self_refresh_exit();
ddr_sr_mode_restore(saved_pwrctl);
+ writel(saved_mcudivr, STM32_RCC_BASE + RCC_MCUDIVR);
+ writel(saved_pll3cr, STM32_RCC_BASE + RCC_PLL3CR);
+ writel(saved_pll4cr, STM32_RCC_BASE + RCC_PLL4CR);
+ writel(saved_mssckselr, STM32_RCC_BASE + RCC_MSSCKSELR);
+
writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR);
clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
}
diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c
index c1ecd64..e12669b 100644
--- a/board/st/common/cmd_stboard.c
+++ b/board/st/common/cmd_stboard.c
@@ -92,14 +92,14 @@
&otp, sizeof(otp));
if (ret != sizeof(otp)) {
- puts("OTP read error");
+ puts("OTP read error\n");
return CMD_RET_FAILURE;
}
ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD),
&lock, sizeof(lock));
if (ret != sizeof(lock)) {
- puts("LOCK read error");
+ puts("LOCK read error\n");
return CMD_RET_FAILURE;
}
diff --git a/board/st/stm32f429-discovery/MAINTAINERS b/board/st/stm32f429-discovery/MAINTAINERS
index fdb62e9..7661a15 100644
--- a/board/st/stm32f429-discovery/MAINTAINERS
+++ b/board/st/stm32f429-discovery/MAINTAINERS
@@ -1,6 +1,7 @@
STM32F429-DISCOVERY BOARD
M: Kamil Lulko <kamil.lulko@gmail.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32f429-discovery/
F: include/configs/stm32f429-discovery.h
F: configs/stm32f429-discovery_defconfig
diff --git a/board/st/stm32f429-evaluation/MAINTAINERS b/board/st/stm32f429-evaluation/MAINTAINERS
index 29d00ef..b272893 100644
--- a/board/st/stm32f429-evaluation/MAINTAINERS
+++ b/board/st/stm32f429-evaluation/MAINTAINERS
@@ -1,6 +1,7 @@
STM32F429-EVALUATION BOARD
M: Patrice Chotard <patrice.chotard@foss.st.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32f429-evaluation/
F: include/configs/stm32f429-evaluation.h
F: configs/stm32f429-evaluation_defconfig
diff --git a/board/st/stm32f469-discovery/MAINTAINERS b/board/st/stm32f469-discovery/MAINTAINERS
index 5a6a78b..a95f93f 100644
--- a/board/st/stm32f469-discovery/MAINTAINERS
+++ b/board/st/stm32f469-discovery/MAINTAINERS
@@ -1,6 +1,7 @@
STM32F469-DISCOVERY BOARD
M: Patrice Chotard <patrice.chotard@foss.st.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32f469-discovery/
F: include/configs/stm32f469-discovery.h
F: configs/stm32f469-discovery_defconfig
diff --git a/board/st/stm32f746-disco/MAINTAINERS b/board/st/stm32f746-disco/MAINTAINERS
index 3bbb513..18e4c99 100644
--- a/board/st/stm32f746-disco/MAINTAINERS
+++ b/board/st/stm32f746-disco/MAINTAINERS
@@ -1,7 +1,12 @@
STM32F746 DISCOVERY BOARD
M: Vikas Manocha <vikas.manocha@st.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32f746-disco
F: include/configs/stm32f746-disco.h
F: configs/stm32f746-disco_defconfig
+F: configs/stm32f746-disco_spl_defconfig
+F: configs/stm32746g-eval_defconfig
+F: configs/stm32746g-eval_spl_defconfig
F: configs/stm32f769-disco_defconfig
+F: configs/stm32f769-disco_spl_defconfig
diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c
index 69f657c..2ab23f2 100644
--- a/board/st/stm32f746-disco/stm32f746-disco.c
+++ b/board/st/stm32f746-disco/stm32f746-disco.c
@@ -29,7 +29,7 @@
int dram_init(void)
{
-#ifndef CONFIG_SUPPORT_SPL
+#ifndef CONFIG_SPL_BUILD
int rv;
struct udevice *dev;
rv = uclass_get_device(UCLASS_RAM, 0, &dev);
diff --git a/board/st/stm32h743-disco/MAINTAINERS b/board/st/stm32h743-disco/MAINTAINERS
index 60fbe34..f4ecef3 100644
--- a/board/st/stm32h743-disco/MAINTAINERS
+++ b/board/st/stm32h743-disco/MAINTAINERS
@@ -1,6 +1,7 @@
STM32H743 DISCOVERY BOARD
M: Patrice Chotard <patrice.chotard@foss.st.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32h743-disco
F: include/configs/stm32h743-disco.h
F: configs/stm32h743-disco_defconfig
diff --git a/board/st/stm32h743-eval/MAINTAINERS b/board/st/stm32h743-eval/MAINTAINERS
index fda93db..b69e0d4 100644
--- a/board/st/stm32h743-eval/MAINTAINERS
+++ b/board/st/stm32h743-eval/MAINTAINERS
@@ -1,6 +1,7 @@
STM32H743 EVALUATION BOARD
M: Patrice Chotard <patrice.chotard@foss.st.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32h743-eval
F: include/configs/stm32h743-eval.h
F: configs/stm32h743-eval_defconfig
diff --git a/board/st/stm32h750-art-pi/MAINTAINERS b/board/st/stm32h750-art-pi/MAINTAINERS
index 9578833..2fd69e6 100644
--- a/board/st/stm32h750-art-pi/MAINTAINERS
+++ b/board/st/stm32h750-art-pi/MAINTAINERS
@@ -1,6 +1,7 @@
STM32H750 ART PI BOARD
M: Dillon Min <dillon.minfei@gmail.com>
S: Maintained
+F: doc/board/st/
F: board/st/stm32h750-art-pi
F: include/configs/stm32h750-art-pi.h
F: configs/stm32h750-art-pi_defconfig
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 7466e1c..07b1a63 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -199,6 +199,13 @@
if (!IS_ENABLED(CONFIG_USB_GADGET_DWC2_OTG))
return -ENODEV;
+ /*
+ * In case of USB boot device is detected, consider USB cable is
+ * connected
+ */
+ if ((get_bootmode() & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_USB)
+ return true;
+
/* if typec stusb160x is present, means DK1 or DK2 board */
ret = stusb160x_cable_connected();
if (ret >= 0)
diff --git a/configs/stm32746g-eval_defconfig b/configs/stm32746g-eval_defconfig
new file mode 100644
index 0000000..9f79b5a
--- /dev/null
+++ b/configs/stm32746g-eval_defconfig
@@ -0,0 +1,64 @@
+CONFIG_ARM=y
+CONFIG_ARCH_STM32=y
+CONFIG_SYS_TEXT_BASE=0x08000000
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SYS_MALLOC_F_LEN=0xE00
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="stm32746g-eval"
+CONFIG_STM32F7=y
+CONFIG_TARGET_STM32F746_DISCO=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x8008000
+CONFIG_BOOTDELAY=3
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+# CONFIG_ISO_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_ARM_PL180_MMCI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_STM32_FLASH=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_STM32_QSPI=y
+CONFIG_DM_VIDEO=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_VIDEO_STM32=y
+CONFIG_VIDEO_STM32_MAX_XRES=480
+CONFIG_VIDEO_STM32_MAX_YRES=640
+CONFIG_SPLASH_SCREEN=y
+CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32746g-eval_spl_defconfig b/configs/stm32746g-eval_spl_defconfig
new file mode 100644
index 0000000..169a9c5
--- /dev/null
+++ b/configs/stm32746g-eval_spl_defconfig
@@ -0,0 +1,86 @@
+CONFIG_ARM=y
+CONFIG_ARCH_STM32=y
+CONFIG_SYS_TEXT_BASE=0x08008000
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SYS_MALLOC_F_LEN=0xE00
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="stm32746g-eval"
+CONFIG_SPL_TEXT_BASE=0x8000000
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_STM32F7=y
+CONFIG_TARGET_STM32F746_DISCO=y
+CONFIG_SPL=y
+CONFIG_BUILD_TARGET="u-boot-with-spl.bin"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x8008000
+CONFIG_BOOTDELAY=3
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_XIP_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+# CONFIG_ISO_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_SPL_CLK=y
+CONFIG_ARM_PL180_MMCI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_STM32_FLASH=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_SPL_PINCTRL=y
+CONFIG_SPL_RAM=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_STM32_QSPI=y
+CONFIG_SPL_TIMER=y
+CONFIG_DM_VIDEO=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_VIDEO_STM32=y
+CONFIG_VIDEO_STM32_MAX_XRES=480
+CONFIG_VIDEO_STM32_MAX_YRES=640
+CONFIG_SPLASH_SCREEN=y
+CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig
index 130b90f..2c70bac 100644
--- a/configs/stm32f746-disco_defconfig
+++ b/configs/stm32f746-disco_defconfig
@@ -1,16 +1,15 @@
CONFIG_ARM=y
CONFIG_ARCH_STM32=y
-CONFIG_SYS_TEXT_BASE=0x08008000
+CONFIG_SYS_TEXT_BASE=0x08000000
CONFIG_SYS_MALLOC_LEN=0x100000
CONFIG_SYS_MALLOC_F_LEN=0xE00
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x2000
CONFIG_DEFAULT_DEVICE_TREE="stm32f746-disco"
-CONFIG_SPL_TEXT_BASE=0x8000000
CONFIG_STM32F7=y
CONFIG_TARGET_STM32F746_DISCO=y
-CONFIG_SYS_LOAD_ADDR=0x8008000
CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x8008000
CONFIG_BOOTDELAY=3
CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
@@ -30,15 +29,11 @@
CONFIG_CMD_BMP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
-# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set
-# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_NETCONSOLE=y
-# CONFIG_SPL_BLK is not set
-# CONFIG_SPL_DM_MMC is not set
CONFIG_ARM_PL180_MMCI=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
diff --git a/configs/stm32f746-disco_spl_defconfig b/configs/stm32f746-disco_spl_defconfig
new file mode 100644
index 0000000..9fef65f
--- /dev/null
+++ b/configs/stm32f746-disco_spl_defconfig
@@ -0,0 +1,86 @@
+CONFIG_ARM=y
+CONFIG_ARCH_STM32=y
+CONFIG_SYS_TEXT_BASE=0x08008000
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SYS_MALLOC_F_LEN=0xE00
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="stm32f746-disco"
+CONFIG_SPL_TEXT_BASE=0x8000000
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_STM32F7=y
+CONFIG_TARGET_STM32F746_DISCO=y
+CONFIG_SPL=y
+CONFIG_BUILD_TARGET="u-boot-with-spl.bin"
+CONFIG_SYS_LOAD_ADDR=0x8008000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTDELAY=3
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_XIP_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+# CONFIG_ISO_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_SPL_CLK=y
+CONFIG_ARM_PL180_MMCI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_STM32_FLASH=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_SPL_PINCTRL=y
+CONFIG_SPL_RAM=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_STM32_QSPI=y
+CONFIG_SPL_TIMER=y
+CONFIG_DM_VIDEO=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_VIDEO_STM32=y
+CONFIG_VIDEO_STM32_MAX_XRES=480
+CONFIG_VIDEO_STM32_MAX_YRES=640
+CONFIG_SPLASH_SCREEN=y
+CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig
index f151dab..3c11288 100644
--- a/configs/stm32f769-disco_defconfig
+++ b/configs/stm32f769-disco_defconfig
@@ -1,16 +1,15 @@
CONFIG_ARM=y
CONFIG_ARCH_STM32=y
-CONFIG_SYS_TEXT_BASE=0x08008000
+CONFIG_SYS_TEXT_BASE=0x08000000
CONFIG_SYS_MALLOC_LEN=0x100000
CONFIG_SYS_MALLOC_F_LEN=0xE00
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x2000
CONFIG_DEFAULT_DEVICE_TREE="stm32f769-disco"
-CONFIG_SPL_TEXT_BASE=0x8000000
CONFIG_STM32F7=y
CONFIG_TARGET_STM32F746_DISCO=y
-CONFIG_SYS_LOAD_ADDR=0x8008000
CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x8008000
CONFIG_BOOTDELAY=3
CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
@@ -29,15 +28,11 @@
CONFIG_CMD_BMP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
-# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set
-# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_NETCONSOLE=y
-# CONFIG_SPL_BLK is not set
-# CONFIG_SPL_DM_MMC is not set
CONFIG_ARM_PL180_MMCI=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
diff --git a/configs/stm32f769-disco_spl_defconfig b/configs/stm32f769-disco_spl_defconfig
new file mode 100644
index 0000000..672c1ec
--- /dev/null
+++ b/configs/stm32f769-disco_spl_defconfig
@@ -0,0 +1,87 @@
+CONFIG_ARM=y
+CONFIG_ARCH_STM32=y
+CONFIG_SYS_TEXT_BASE=0x08008000
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SYS_MALLOC_F_LEN=0xE00
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="stm32f769-disco"
+CONFIG_SPL_TEXT_BASE=0x8000000
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_STM32F7=y
+CONFIG_TARGET_STM32F746_DISCO=y
+CONFIG_SPL=y
+CONFIG_BUILD_TARGET="u-boot-with-spl.bin"
+CONFIG_SYS_LOAD_ADDR=0x8008000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTDELAY=3
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_XIP_SUPPORT=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_CMD_GPT=y
+# CONFIG_RANDOM_UUID is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+# CONFIG_ISO_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_SPL_CLK=y
+CONFIG_ARM_PL180_MMCI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_STM32_FLASH=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_SPL_PINCTRL=y
+CONFIG_SPL_RAM=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_STM32_QSPI=y
+CONFIG_SPL_TIMER=y
+CONFIG_DM_VIDEO=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y
+CONFIG_VIDEO_STM32=y
+CONFIG_VIDEO_STM32_DSI=y
+CONFIG_VIDEO_STM32_MAX_XRES=480
+CONFIG_VIDEO_STM32_MAX_YRES=800
+CONFIG_SPLASH_SCREEN=y
+CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_VIDEO_BMP_RLE8=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 5d1b2e0..1b1c255 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -80,6 +80,7 @@
CONFIG_SYS_MMC_ENV_DEV=-1
# CONFIG_SPL_ENV_IS_NOWHERE is not set
# CONFIG_SPL_ENV_IS_IN_SPI_FLASH is not set
+CONFIG_TFTP_TSIZE=y
CONFIG_STM32_ADC=y
CONFIG_SET_DFU_ALT_INFO=y
CONFIG_USB_FUNCTION_FASTBOOT=y
diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig
index f6e7fc8..02b37e1 100644
--- a/configs/stm32mp15_defconfig
+++ b/configs/stm32mp15_defconfig
@@ -61,6 +61,7 @@
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_DEV=-1
+CONFIG_TFTP_TSIZE=y
CONFIG_STM32_ADC=y
CONFIG_CLK_SCMI=y
CONFIG_SET_DFU_ALT_INFO=y
diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig
index ec955ea..7f7aecf 100644
--- a/configs/stm32mp15_dhcom_basic_defconfig
+++ b/configs/stm32mp15_dhcom_basic_defconfig
@@ -80,7 +80,7 @@
CONFIG_SPL_ENV_IS_NOWHERE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_IP_DEFRAG=y
-CONFIG_TFTP_BLOCKSIZE=1536
+CONFIG_TFTP_TSIZE=y
CONFIG_STM32_ADC=y
CONFIG_SPL_BLOCK_CACHE=y
CONFIG_DFU_MMC=y
diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig
index 387e068..35e43a9 100644
--- a/configs/stm32mp15_dhcor_basic_defconfig
+++ b/configs/stm32mp15_dhcor_basic_defconfig
@@ -77,7 +77,7 @@
CONFIG_SPL_ENV_IS_NOWHERE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_IP_DEFRAG=y
-CONFIG_TFTP_BLOCKSIZE=1536
+CONFIG_TFTP_TSIZE=y
CONFIG_STM32_ADC=y
CONFIG_SPL_BLOCK_CACHE=y
CONFIG_DFU_MMC=y
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 855a394..df31c0f 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -62,6 +62,7 @@
CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_DEV=-1
+CONFIG_TFTP_TSIZE=y
CONFIG_STM32_ADC=y
CONFIG_CLK_SCMI=y
CONFIG_SET_DFU_ALT_INFO=y
diff --git a/doc/board/st/index.rst b/doc/board/st/index.rst
index 9bba42f..2a8a4ef 100644
--- a/doc/board/st/index.rst
+++ b/doc/board/st/index.rst
@@ -8,3 +8,4 @@
st-dt
stm32mp1
+ stm32_MCU
diff --git a/doc/board/st/stm32_MCU.rst b/doc/board/st/stm32_MCU.rst
new file mode 100644
index 0000000..7ff7c73
--- /dev/null
+++ b/doc/board/st/stm32_MCU.rst
@@ -0,0 +1,186 @@
+.. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+.. sectionauthor:: Patrice Chotard <patrice.chotardy@foss.st.com>
+
+STM32 MCU boards
+=================
+
+This is a quick instruction for setup STM32 MCU boards.
+
+Supported devices
+-----------------
+
+U-Boot supports the following STMP32 MCU SoCs:
+
+ - STM32F429
+ - STM32F469
+ - STM32F746
+ - STM32F769
+ - STM32H743
+ - STM32H750
+
+SoCs information:
+-----------------
+STM32F4 series are Cortex-M4 MCU.
+STM32F7 and STM32H7 series are Cortex-M7 MCU.
+
+ + STM32F4 series: https://www.st.com/en/microcontrollers-microprocessors/stm32f4-series.html
+ + STM32F7 series: https://www.st.com/en/microcontrollers-microprocessors/stm32f7-series.html
+ + STM32H7 series: https://www.st.com/en/microcontrollers-microprocessors/stm32h7-series.html
+
+Currently the following boards are supported:
+
+ + stm32f429-discovery
+ + stm32f469-discovery
+ + stm32746g-evaluation
+ + stm32f746-discovery
+ + stm32f769-discovery
+ + stm32h743i-discovery
+ + stm32h743i-evaluation
+ + stm32h750i-art-pi
+
+Boot Sequences
+--------------
+
+For STM32F7 series, 2 boot configurations are supported with and without SPL
+
++------------------------+-------------------------+--------------+
+| **FSBL** | **SSBL** | **OS** |
++------------------------+-------------------------+--------------+
+| First Stage Bootloader | Second Stage Bootloader | Linux Kernel |
++------------------------+-------------------------+--------------+
+| embedded Flash | DDR |
++------------------------+-------------------------+--------------+
+
+The boot chain with SPL
+```````````````````````
+
+defconfig_file :
+ + **stm32746g-eval_spl_defconfig**
+ + **stm32f746-disco_spl_defconfig**
+ + **stm32f769-disco_spl_defconfig**
+
++------------+------------+-------+
+| FSBL | SSBL | OS |
++------------+------------+-------+
+|U-Boot SPL | U-Boot | Linux |
++------------+------------+-------+
+
+The boot chain without SPL
+``````````````````````````
+
+defconfig_file :
+ + **stm32f429-discovery_defconfig**
+ + **stm32f429-evaluation_defconfig**
+ + **stm32f469-discovery_defconfig**
+ + **stm32746g-eval_defconfig**
+ + **stm32f746-disco_defconfig**
+ + **stm32f769-disco_defconfig**
+ + **stm32h743-disco_defconfig**
+ + **stm32h743-eval_defconfig**
+ + **stm32h750-art-pi_defconfig**
+
++-----------+-------+
+| FSBL | OS |
++-----------+-------+
+|U-Boot | Linux |
++-----------+-------+
+
+Build Procedure
+---------------
+
+1. Install the required tools for U-Boot
+
+ * install package needed in U-Boot makefile
+ (libssl-dev, swig, libpython-dev...)
+
+ * install ARMv7 toolchain for 32bit Cortex-A (from Linaro,
+ from SDK for STM32MP15x, or any crosstoolchains from your distribution)
+ (you can use any gcc cross compiler compatible with U-Boot)
+
+2. Set the cross compiler::
+
+ # export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi-
+
+3. Select the output directory (optional)::
+
+ # export KBUILD_OUTPUT=/path/to/output
+
+ for example: use one output directory for each configuration::
+
+ # export KBUILD_OUTPUT=stm32f4
+ # export KBUILD_OUTPUT=stm32f7
+ # export KBUILD_OUTPUT=stm32h7
+
+ you can build outside of code directory::
+
+ # export KBUILD_OUTPUT=../build/stm32f4
+
+4. Configure U-Boot::
+
+ # make <defconfig_file>
+
+ For example with <defconfig_file>:
+
+ - For **stm32f429 discovery** board : **stm32f429-discovery_defconfig**
+ - For **stm32f769 discovery** board with SPL: **stm32f769-disco_spl_defconfig**
+ - For **stm32f769 discovery** board without SPL: **stm32f769-disco_defconfig**
+
+5. Configure the device-tree and build the U-Boot image::
+
+ # make DEVICE_TREE=<name> all
+
+ Examples:
+
+ a) boot with SPL on stm32f746 discovery board::
+
+ # export KBUILD_OUTPUT=stm32f746-disco
+ # make stm32f746-disco_spl_defconfig
+ # make all
+
+ b) boot without SPL on stm32f746 discovery board::
+
+ # export KBUILD_OUTPUT=stm32f746-disco
+ # make stm32f746-disco_defconfig
+ # make all
+
+ c) boot on stm32h743 discovery board::
+
+ # export KBUILD_OUTPUT=stm32h743-disco
+ # make stm32h743-disco_defconfig
+ # make all
+
+ d) boot on stm32h743 evaluation board::
+
+ # export KBUILD_OUTPUT=stm32h743-disco
+ # make stm32h743-eval_defconfig
+ # make all
+
+6. U-Boot Output files
+
+ So in the output directory (selected by KBUILD_OUTPUT),
+ you can found the needed U-Boot files, for example::
+
+ - stm32f746-disco_defconfig = **u-boot-dtb.bin** and **u-boot.dtb**
+
+ - FSBL = u-boot-dtb.bin
+
+ - stm32f746-disco_spl_defconfig = **u-boot-dtb.bin**, **u-boot.dtb** and **u-boot-with-spl.bin**
+
+ - FSBL + SSBL = u-boot-with-spl.bin
+ - SSBL = u-boot-dtb.bin
+
+7. Flash U-Boot files
+
+Plug STM32 MCUs board using the USB ST-Link connector, hence it will expose
+the flash area as a mass-storage. In this mass-storage you will find the
+following files:
+
+- DETAILS.TXT: give the bootrom version and build
+- MBED.HTM: shortcul to the hardware board description web page from st.com.
+
+Copy/paste the u-boot.bin or u-boot-with-spl.bin (in case of bootchain with SPL)
+to this mass-storage. The "COM" LED will blink alternatively red and green during
+the flash process. When done the board will reboot automatically.
+
+In case of boot with SPL, by default SPL will try to load either a Linux
+kernel (falcon mode) or, if the key "c" is maintained pressed, the main U-Boot.
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 83ab6b7..4525500 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -2205,7 +2205,7 @@
for (i = 0; i < NB_OSC; i++) {
if (clk_get_by_name(dev, name[i], &priv->osc_clk[i]))
- dev_dbg(dev, "No source clock \"%s\"", name[i]);
+ dev_dbg(dev, "No source clock \"%s\"\n", name[i]);
else
dev_dbg(dev, "%s clock rate: %luHz\n",
name[i], clk_get_rate(&priv->osc_clk[i]));
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index 8667ed3..7a2ca91 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -83,38 +83,22 @@
return (readl(®s->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK;
}
-/*
- * convert gpio offset to gpio index taking into account gpio holes
- * into gpio bank
- */
-int stm32_offset_to_index(struct udevice *dev, unsigned int offset)
+static bool stm32_gpio_is_mapped(struct udevice *dev, int offset)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
- unsigned int idx = 0;
- int i;
- for (i = 0; i < STM32_GPIOS_PER_BANK; i++) {
- if (priv->gpio_range & BIT(i)) {
- if (idx == offset)
- return idx;
- idx++;
- }
- }
- /* shouldn't happen */
- return -EINVAL;
+ return !!(priv->gpio_range & BIT(offset));
}
static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
+ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_IN);
return 0;
}
@@ -124,15 +108,13 @@
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
+ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_OUT);
- writel(BSRR_BIT(idx, value), ®s->bsrr);
+ writel(BSRR_BIT(offset, value), ®s->bsrr);
return 0;
}
@@ -141,26 +123,22 @@
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
- return readl(®s->idr) & BIT(idx) ? 1 : 0;
+ return readl(®s->idr) & BIT(offset) ? 1 : 0;
}
static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
- writel(BSRR_BIT(idx, value), ®s->bsrr);
+ writel(BSRR_BIT(offset, value), ®s->bsrr);
return 0;
}
@@ -171,14 +149,12 @@
struct stm32_gpio_regs *regs = priv->regs;
int bits_index;
int mask;
- int idx;
u32 mode;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return GPIOF_UNKNOWN;
- bits_index = MODE_BITS(idx);
+ bits_index = MODE_BITS(offset);
mask = MODE_BITS_MASK << bits_index;
mode = (readl(®s->moder) & mask) >> bits_index;
@@ -197,30 +173,28 @@
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
if (flags & GPIOD_IS_OUT) {
bool value = flags & GPIOD_IS_OUT_ACTIVE;
if (flags & GPIOD_OPEN_DRAIN)
- stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
+ stm32_gpio_set_otype(regs, offset, STM32_GPIO_OTYPE_OD);
else
- stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
+ stm32_gpio_set_otype(regs, offset, STM32_GPIO_OTYPE_PP);
- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
- writel(BSRR_BIT(idx, value), ®s->bsrr);
+ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_OUT);
+ writel(BSRR_BIT(offset, value), ®s->bsrr);
} else if (flags & GPIOD_IS_IN) {
- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
+ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_IN);
}
if (flags & GPIOD_PULL_UP)
- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP);
+ stm32_gpio_set_pupd(regs, offset, STM32_GPIO_PUPD_UP);
else if (flags & GPIOD_PULL_DOWN)
- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN);
+ stm32_gpio_set_pupd(regs, offset, STM32_GPIO_PUPD_DOWN);
return 0;
}
@@ -230,19 +204,17 @@
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
- int idx;
ulong dir_flags = 0;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
- return idx;
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
- switch (stm32_gpio_get_moder(regs, idx)) {
+ switch (stm32_gpio_get_moder(regs, offset)) {
case STM32_GPIO_MODE_OUT:
dir_flags |= GPIOD_IS_OUT;
- if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD)
+ if (stm32_gpio_get_otype(regs, offset) == STM32_GPIO_OTYPE_OD)
dir_flags |= GPIOD_OPEN_DRAIN;
- if (readl(®s->idr) & BIT(idx))
+ if (readl(®s->idr) & BIT(offset))
dir_flags |= GPIOD_IS_OUT_ACTIVE;
break;
case STM32_GPIO_MODE_IN:
@@ -251,7 +223,7 @@
default:
break;
}
- switch (stm32_gpio_get_pupd(regs, idx)) {
+ switch (stm32_gpio_get_pupd(regs, offset)) {
case STM32_GPIO_PUPD_UP:
dir_flags |= GPIOD_PULL_UP;
break;
@@ -304,17 +276,14 @@
if (!ret && args.args_count < 3)
return -EINVAL;
- if (ret == -ENOENT) {
- uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
+ uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
+ if (ret == -ENOENT)
priv->gpio_range = GENMASK(STM32_GPIOS_PER_BANK - 1, 0);
- }
while (ret != -ENOENT) {
priv->gpio_range |= GENMASK(args.args[2] + args.args[0] - 1,
args.args[0]);
- uc_priv->gpio_count += args.args[2];
-
ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
++i, &args);
if (!ret && args.args_count < 3)
diff --git a/drivers/gpio/stm32_gpio_priv.h b/drivers/gpio/stm32_gpio_priv.h
index d3d8f2e..662a000 100644
--- a/drivers/gpio/stm32_gpio_priv.h
+++ b/drivers/gpio/stm32_gpio_priv.h
@@ -81,6 +81,4 @@
unsigned int gpio_range;
};
-int stm32_offset_to_index(struct udevice *dev, unsigned int offset);
-
#endif /* _STM32_GPIO_PRIV_H_ */
diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index 9c1dcfa..d7f7c37 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -17,6 +17,8 @@
#include <usb.h>
#include <asm/io.h>
#include <dm/device_compat.h>
+#include <dm/of_access.h>
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <power/regulator.h>
@@ -24,6 +26,7 @@
/* USBPHYC registers */
#define STM32_USBPHYC_PLL 0x0
#define STM32_USBPHYC_MISC 0x8
+#define STM32_USBPHYC_TUNE(X) (0x10C + ((X) * 0x100))
/* STM32_USBPHYC_PLL bit fields */
#define PLLNDIV GENMASK(6, 0)
@@ -40,6 +43,26 @@
/* STM32_USBPHYC_MISC bit fields */
#define SWITHOST BIT(0)
+/* STM32_USBPHYC_TUNE bit fields */
+#define INCURREN BIT(0)
+#define INCURRINT BIT(1)
+#define LFSCAPEN BIT(2)
+#define HSDRVSLEW BIT(3)
+#define HSDRVDCCUR BIT(4)
+#define HSDRVDCLEV BIT(5)
+#define HSDRVCURINCR BIT(6)
+#define FSDRVRFADJ BIT(7)
+#define HSDRVRFRED BIT(8)
+#define HSDRVCHKITRM GENMASK(12, 9)
+#define HSDRVCHKZTRM GENMASK(14, 13)
+#define OTPCOMP GENMASK(19, 15)
+#define SQLCHCTL GENMASK(21, 20)
+#define HDRXGNEQEN BIT(22)
+#define HSRXOFF GENMASK(24, 23)
+#define HSFALLPREEM BIT(25)
+#define SHTCCTCTLPROT BIT(26)
+#define STAGSEL BIT(27)
+
#define MAX_PHYS 2
/* max 100 us for PLL lock and 100 us for PHY init */
@@ -49,6 +72,62 @@
#define PLL_INFF_MIN_RATE 19200000 /* in Hz */
#define PLL_INFF_MAX_RATE 38400000 /* in Hz */
+enum boosting_vals {
+ BOOST_1000_UA = 1000,
+ BOOST_2000_UA = 2000,
+};
+
+enum dc_level_vals {
+ DC_MINUS_5_TO_7_MV,
+ DC_PLUS_5_TO_7_MV,
+ DC_PLUS_10_TO_14_MV,
+ DC_MAX,
+};
+
+enum current_trim {
+ CUR_NOMINAL,
+ CUR_PLUS_1_56_PCT,
+ CUR_PLUS_3_12_PCT,
+ CUR_PLUS_4_68_PCT,
+ CUR_PLUS_6_24_PCT,
+ CUR_PLUS_7_8_PCT,
+ CUR_PLUS_9_36_PCT,
+ CUR_PLUS_10_92_PCT,
+ CUR_PLUS_12_48_PCT,
+ CUR_PLUS_14_04_PCT,
+ CUR_PLUS_15_6_PCT,
+ CUR_PLUS_17_16_PCT,
+ CUR_PLUS_19_01_PCT,
+ CUR_PLUS_20_58_PCT,
+ CUR_PLUS_22_16_PCT,
+ CUR_PLUS_23_73_PCT,
+ CUR_MAX,
+};
+
+enum impedance_trim {
+ IMP_NOMINAL,
+ IMP_MINUS_2_OHMS,
+ IMP_MINUS_4_OMHS,
+ IMP_MINUS_6_OHMS,
+ IMP_MAX,
+};
+
+enum squelch_level {
+ SQLCH_NOMINAL,
+ SQLCH_PLUS_7_MV,
+ SQLCH_MINUS_5_MV,
+ SQLCH_PLUS_14_MV,
+ SQLCH_MAX,
+};
+
+enum rx_offset {
+ NO_RX_OFFSET,
+ RX_OFFSET_PLUS_5_MV,
+ RX_OFFSET_PLUS_10_MV,
+ RX_OFFSET_MINUS_5_MV,
+ RX_OFFSET_MAX,
+};
+
struct pll_params {
u8 ndiv;
u16 frac;
@@ -327,6 +406,90 @@
return 0;
}
+static void stm32_usbphyc_tuning(struct udevice *dev, ofnode node, u32 index)
+{
+ struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
+ u32 reg = STM32_USBPHYC_TUNE(index);
+ u32 otpcomp, val, tune = 0;
+ int ret;
+
+ /* Backup OTP compensation code */
+ otpcomp = FIELD_GET(OTPCOMP, readl(usbphyc->base + reg));
+
+ ret = ofnode_read_u32(node, "st,current-boost-microamp", &val);
+ if (!ret && (val == BOOST_1000_UA || val == BOOST_2000_UA)) {
+ val = (val == BOOST_2000_UA) ? 1 : 0;
+ tune |= INCURREN | FIELD_PREP(INCURRINT, val);
+ } else if (ret != -EINVAL) {
+ dev_warn(dev, "phy%d: invalid st,current-boost-microamp value\n", index);
+ }
+
+ if (!ofnode_read_bool(node, "st,no-lsfs-fb-cap"))
+ tune |= LFSCAPEN;
+
+ if (ofnode_read_bool(node, "st,decrease-hs-slew-rate"))
+ tune |= HSDRVSLEW;
+
+ ret = ofnode_read_u32(node, "st,tune-hs-dc-level", &val);
+ if (!ret && val < DC_MAX) {
+ if (val == DC_MINUS_5_TO_7_MV) {
+ tune |= HSDRVDCCUR;
+ } else {
+ val = (val == DC_PLUS_10_TO_14_MV) ? 1 : 0;
+ tune |= HSDRVCURINCR | FIELD_PREP(HSDRVDCLEV, val);
+ }
+ } else if (ret != -EINVAL) {
+ dev_warn(dev, "phy%d: invalid st,tune-hs-dc-level value\n", index);
+ }
+
+ if (ofnode_read_bool(node, "st,enable-fs-rftime-tuning"))
+ tune |= FSDRVRFADJ;
+
+ if (ofnode_read_bool(node, "st,enable-hs-rftime-reduction"))
+ tune |= HSDRVRFRED;
+
+ ret = ofnode_read_u32(node, "st,trim-hs-current", &val);
+ if (!ret && val < CUR_MAX)
+ tune |= FIELD_PREP(HSDRVCHKITRM, val);
+ else if (ret != -EINVAL)
+ dev_warn(dev, "phy%d: invalid st,trim-hs-current value\n", index);
+
+ ret = ofnode_read_u32(node, "st,trim-hs-impedance", &val);
+ if (!ret && val < IMP_MAX)
+ tune |= FIELD_PREP(HSDRVCHKZTRM, val);
+ else if (ret != -EINVAL)
+ dev_warn(dev, "phy%d: invalid trim-hs-impedance value\n", index);
+
+ ret = ofnode_read_u32(node, "st,tune-squelch-level", &val);
+ if (!ret && val < SQLCH_MAX)
+ tune |= FIELD_PREP(SQLCHCTL, val);
+ else if (ret != -EINVAL)
+ dev_warn(dev, "phy%d: invalid st,tune-squelch-level value\n", index);
+
+ if (ofnode_read_bool(node, "st,enable-hs-rx-gain-eq"))
+ tune |= HDRXGNEQEN;
+
+ ret = ofnode_read_u32(node, "st,tune-hs-rx-offset", &val);
+ if (!ret && val < RX_OFFSET_MAX)
+ tune |= FIELD_PREP(HSRXOFF, val);
+ else if (ret != -EINVAL)
+ dev_warn(dev, "phy%d: invalid st,tune-hs-rx-offset value\n", index);
+
+ if (ofnode_read_bool(node, "st,no-hs-ftime-ctrl"))
+ tune |= HSFALLPREEM;
+
+ if (!ofnode_read_bool(node, "st,no-lsfs-sc"))
+ tune |= SHTCCTCTLPROT;
+
+ if (ofnode_read_bool(node, "st,enable-hs-tx-staggering"))
+ tune |= STAGSEL;
+
+ /* Restore OTP compensation code */
+ tune |= FIELD_PREP(OTPCOMP, otpcomp);
+
+ writel(tune, usbphyc->base + reg);
+}
+
static const struct phy_ops stm32_usbphyc_phy_ops = {
.init = stm32_usbphyc_phy_init,
.exit = stm32_usbphyc_phy_exit,
@@ -389,6 +552,10 @@
phy_id, ofnode_get_name(node));
return -ENOENT;
}
+
+ /* Configure phy tuning */
+ stm32_usbphyc_tuning(dev, node, phy_id);
+
usbphyc_phy = usbphyc->phys + phy_id;
usbphyc_phy->init = false;
usbphyc_phy->powered = false;
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index 5729799..56a20e8 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -42,13 +42,12 @@
#ifndef CONFIG_SPL_BUILD
static char pin_name[PINNAME_SIZE];
-#define PINMUX_MODE_COUNT 5
-static const char * const pinmux_mode[PINMUX_MODE_COUNT] = {
- "gpio input",
- "gpio output",
- "analog",
- "unknown",
- "alt function",
+static const char * const pinmux_mode[GPIOF_COUNT] = {
+ [GPIOF_INPUT] = "gpio input",
+ [GPIOF_OUTPUT] = "gpio output",
+ [GPIOF_UNUSED] = "analog",
+ [GPIOF_UNKNOWN] = "unknown",
+ [GPIOF_FUNC] = "alt function",
};
static const char * const pinmux_bias[] = {
@@ -158,10 +157,7 @@
* we found the bank, convert pin selector to
* gpio bank index
*/
- *idx = stm32_offset_to_index(gpio_bank->gpio_dev,
- selector - pin_count);
- if (IS_ERR_VALUE(*idx))
- return NULL;
+ *idx = selector - pin_count;
return gpio_bank->gpio_dev;
}
@@ -221,8 +217,6 @@
switch (mode) {
case GPIOF_UNKNOWN:
- /* should never happen */
- return -EINVAL;
case GPIOF_UNUSED:
snprintf(buf, size, "%s", pinmux_mode[mode]);
break;
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index 528a171..ab913a6 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -653,10 +653,14 @@
wait_sw_done_ack(ctl);
}
-static void stm32mp1_asr_enable(struct ddr_info *priv)
+static void stm32mp1_asr_enable(struct ddr_info *priv, const u32 pwrctl)
{
struct stm32mp1_ddrctl *ctl = priv->ctl;
+ /* SSR is the best we can do. */
+ if (!(pwrctl & DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE))
+ return;
+
clrsetbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCKMOD_MASK,
RCC_DDRITFCR_DDRCKMOD_ASR);
@@ -666,8 +670,12 @@
writel(DDRCTRL_PWRTMG_POWERDOWN_TO_X32(0x10) |
DDRCTRL_PWRTMG_SELFREF_TO_X32(0x01),
&ctl->pwrtmg);
+
+ /* HSR we can do. */
setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
- setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
+
+ if (pwrctl & DDRCTRL_PWRCTL_SELFREF_EN) /* ASR we can do. */
+ setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
wait_sw_done_ack(ctl);
@@ -845,7 +853,7 @@
config->c_reg.pwrctl);
/* Enable auto-self-refresh, which saves a bit of power at runtime. */
- stm32mp1_asr_enable(priv);
+ stm32mp1_asr_enable(priv, config->c_reg.pwrctl);
/* enable uMCTL2 AXI port 0 and 1 */
setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c
index e741e74..58b6434 100644
--- a/drivers/video/stm32/stm32_ltdc.c
+++ b/drivers/video/stm32/stm32_ltdc.c
@@ -25,8 +25,114 @@
void __iomem *regs;
enum video_log2_bpp l2bpp;
u32 bg_col_argb;
+ const u32 *layer_regs;
+ const u32 *pix_fmt_hw;
u32 crop_x, crop_y, crop_w, crop_h;
u32 alpha;
+ u32 hw_version;
+};
+
+/* Layer register offsets */
+static const u32 layer_regs_a0[] = {
+ 0x80, /* L1 configuration 0 */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x84, /* L1 control register */
+ 0x88, /* L1 window horizontal position configuration */
+ 0x8c, /* L1 window vertical position configuration */
+ 0x90, /* L1 color keying configuration */
+ 0x94, /* L1 pixel format configuration */
+ 0x98, /* L1 constant alpha configuration */
+ 0x9c, /* L1 default color configuration */
+ 0xa0, /* L1 blending factors configuration */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0xac, /* L1 color frame buffer address */
+ 0xb0, /* L1 color frame buffer length */
+ 0xb4, /* L1 color frame buffer line number */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0xc4, /* L1 CLUT write */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00 /* not available */
+};
+
+static const u32 layer_regs_a1[] = {
+ 0x80, /* L1 configuration 0 */
+ 0x84, /* L1 configuration 1 */
+ 0x00, /* L1 reload control */
+ 0x88, /* L1 control register */
+ 0x8c, /* L1 window horizontal position configuration */
+ 0x90, /* L1 window vertical position configuration */
+ 0x94, /* L1 color keying configuration */
+ 0x98, /* L1 pixel format configuration */
+ 0x9c, /* L1 constant alpha configuration */
+ 0xa0, /* L1 default color configuration */
+ 0xa4, /* L1 blending factors configuration */
+ 0xa8, /* L1 burst length configuration */
+ 0x00, /* not available */
+ 0xac, /* L1 color frame buffer address */
+ 0xb0, /* L1 color frame buffer length */
+ 0xb4, /* L1 color frame buffer line number */
+ 0xb8, /* L1 auxiliary frame buffer address 0 */
+ 0xbc, /* L1 auxiliary frame buffer address 1 */
+ 0xc0, /* L1 auxiliary frame buffer length */
+ 0xc4, /* L1 auxiliary frame buffer line number */
+ 0xc8, /* L1 CLUT write */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00, /* not available */
+ 0x00 /* not available */
+};
+
+static const u32 layer_regs_a2[] = {
+ 0x100, /* L1 configuration 0 */
+ 0x104, /* L1 configuration 1 */
+ 0x108, /* L1 reload control */
+ 0x10c, /* L1 control register */
+ 0x110, /* L1 window horizontal position configuration */
+ 0x114, /* L1 window vertical position configuration */
+ 0x118, /* L1 color keying configuration */
+ 0x11c, /* L1 pixel format configuration */
+ 0x120, /* L1 constant alpha configuration */
+ 0x124, /* L1 default color configuration */
+ 0x128, /* L1 blending factors configuration */
+ 0x12c, /* L1 burst length configuration */
+ 0x130, /* L1 planar configuration */
+ 0x134, /* L1 color frame buffer address */
+ 0x138, /* L1 color frame buffer length */
+ 0x13c, /* L1 color frame buffer line number */
+ 0x140, /* L1 auxiliary frame buffer address 0 */
+ 0x144, /* L1 auxiliary frame buffer address 1 */
+ 0x148, /* L1 auxiliary frame buffer length */
+ 0x14c, /* L1 auxiliary frame buffer line number */
+ 0x150, /* L1 CLUT write */
+ 0x154, /* not available */
+ 0x158, /* not available */
+ 0x15c, /* not available */
+ 0x160, /* not available */
+ 0x164, /* not available */
+ 0x168, /* not available */
+ 0x16c, /* L1 Conversion YCbCr RGB 0 */
+ 0x170, /* L1 Conversion YCbCr RGB 1 */
+ 0x174, /* L1 Flexible Pixel Format 0 */
+ 0x178 /* L1 Flexible Pixel Format 1 */
};
/* LTDC main registers */
@@ -49,26 +155,32 @@
#define LTDC_CPSR 0x44 /* Current Position Status */
#define LTDC_CDSR 0x48 /* Current Display Status */
-/* LTDC layer 1 registers */
-#define LTDC_L1LC1R 0x80 /* L1 Layer Configuration 1 */
-#define LTDC_L1LC2R 0x84 /* L1 Layer Configuration 2 */
-#define LTDC_L1CR 0x84 /* L1 Control */
-#define LTDC_L1WHPCR 0x88 /* L1 Window Hor Position Config */
-#define LTDC_L1WVPCR 0x8C /* L1 Window Vert Position Config */
-#define LTDC_L1CKCR 0x90 /* L1 Color Keying Configuration */
-#define LTDC_L1PFCR 0x94 /* L1 Pixel Format Configuration */
-#define LTDC_L1CACR 0x98 /* L1 Constant Alpha Config */
-#define LTDC_L1DCCR 0x9C /* L1 Default Color Configuration */
-#define LTDC_L1BFCR 0xA0 /* L1 Blend Factors Configuration */
-#define LTDC_L1FBBCR 0xA4 /* L1 FrameBuffer Bus Control */
-#define LTDC_L1AFBCR 0xA8 /* L1 AuxFB Control */
-#define LTDC_L1CFBAR 0xAC /* L1 Color FrameBuffer Address */
-#define LTDC_L1CFBLR 0xB0 /* L1 Color FrameBuffer Length */
-#define LTDC_L1CFBLNR 0xB4 /* L1 Color FrameBuffer Line Nb */
-#define LTDC_L1AFBAR 0xB8 /* L1 AuxFB Address */
-#define LTDC_L1AFBLR 0xBC /* L1 AuxFB Length */
-#define LTDC_L1AFBLNR 0xC0 /* L1 AuxFB Line Number */
-#define LTDC_L1CLUTWR 0xC4 /* L1 CLUT Write */
+/* Layer register offsets */
+#define LTDC_L1C0R (priv->layer_regs[0]) /* L1 configuration 0 */
+#define LTDC_L1C1R (priv->layer_regs[1]) /* L1 configuration 1 */
+#define LTDC_L1RCR (priv->layer_regs[2]) /* L1 reload control */
+#define LTDC_L1CR (priv->layer_regs[3]) /* L1 control register */
+#define LTDC_L1WHPCR (priv->layer_regs[4]) /* L1 window horizontal position configuration */
+#define LTDC_L1WVPCR (priv->layer_regs[5]) /* L1 window vertical position configuration */
+#define LTDC_L1CKCR (priv->layer_regs[6]) /* L1 color keying configuration */
+#define LTDC_L1PFCR (priv->layer_regs[7]) /* L1 pixel format configuration */
+#define LTDC_L1CACR (priv->layer_regs[8]) /* L1 constant alpha configuration */
+#define LTDC_L1DCCR (priv->layer_regs[9]) /* L1 default color configuration */
+#define LTDC_L1BFCR (priv->layer_regs[10]) /* L1 blending factors configuration */
+#define LTDC_L1BLCR (priv->layer_regs[11]) /* L1 burst length configuration */
+#define LTDC_L1PCR (priv->layer_regs[12]) /* L1 planar configuration */
+#define LTDC_L1CFBAR (priv->layer_regs[13]) /* L1 color frame buffer address */
+#define LTDC_L1CFBLR (priv->layer_regs[14]) /* L1 color frame buffer length */
+#define LTDC_L1CFBLNR (priv->layer_regs[15]) /* L1 color frame buffer line number */
+#define LTDC_L1AFBA0R (priv->layer_regs[16]) /* L1 auxiliary frame buffer address 0 */
+#define LTDC_L1AFBA1R (priv->layer_regs[17]) /* L1 auxiliary frame buffer address 1 */
+#define LTDC_L1AFBLR (priv->layer_regs[18]) /* L1 auxiliary frame buffer length */
+#define LTDC_L1AFBLNR (priv->layer_regs[19]) /* L1 auxiliary frame buffer line number */
+#define LTDC_L1CLUTWR (priv->layer_regs[20]) /* L1 CLUT write */
+#define LTDC_L1CYR0R (priv->layer_regs[27]) /* L1 Conversion YCbCr RGB 0 */
+#define LTDC_L1CYR1R (priv->layer_regs[28]) /* L1 Conversion YCbCr RGB 1 */
+#define LTDC_L1FPF0R (priv->layer_regs[29]) /* L1 Flexible Pixel Format 0 */
+#define LTDC_L1FPF1R (priv->layer_regs[30]) /* L1 Flexible Pixel Format 1 */
/* Bit definitions */
#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
@@ -144,15 +256,60 @@
#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
#define BF2_1CA 0x005 /* 1 - Constant Alpha */
+#define NB_PF 8 /* Max nb of HW pixel format */
+
+#define HWVER_10200 0x010200
+#define HWVER_10300 0x010300
+#define HWVER_20101 0x020101
+#define HWVER_40100 0x040100
+
enum stm32_ltdc_pix_fmt {
- PF_ARGB8888 = 0,
- PF_RGB888,
- PF_RGB565,
- PF_ARGB1555,
- PF_ARGB4444,
- PF_L8,
- PF_AL44,
- PF_AL88
+ PF_ARGB8888 = 0, /* ARGB [32 bits] */
+ PF_ABGR8888, /* ABGR [32 bits] */
+ PF_BGRA8888, /* BGRA [32 bits] */
+ PF_RGBA8888, /* RGBA [32 bits] */
+ PF_RGB888, /* RGB [24 bits] */
+ PF_BGR565, /* RGB [16 bits] */
+ PF_RGB565, /* RGB [16 bits] */
+ PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
+ PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
+ PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
+ PF_AL88, /* Alpha:8 bits + indexed 8 bits [16 bits] */
+ PF_L8, /* Indexed 8 bits [8 bits] */
+ PF_NONE
+};
+
+static const enum stm32_ltdc_pix_fmt pix_fmt_a0[NB_PF] = {
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_ARGB1555, /* 0x03 */
+ PF_ARGB4444, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_AL44, /* 0x06 */
+ PF_AL88 /* 0x07 */
+};
+
+static const enum stm32_ltdc_pix_fmt pix_fmt_a1[NB_PF] = {
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_RGBA8888, /* 0x03 */
+ PF_AL44, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_ARGB1555, /* 0x06 */
+ PF_ARGB4444 /* 0x07 */
+};
+
+static const enum stm32_ltdc_pix_fmt pix_fmt_a2[NB_PF] = {
+ PF_ARGB8888, /* 0x00 */
+ PF_ABGR8888, /* 0x01 */
+ PF_RGBA8888, /* 0x02 */
+ PF_BGRA8888, /* 0x03 */
+ PF_RGB565, /* 0x04 */
+ PF_BGR565, /* 0x05 */
+ PF_RGB888, /* 0x06 */
+ PF_NONE /* 0x07 (flexible pixel format) */
};
/* TODO add more color format support */
@@ -255,7 +412,7 @@
val |= GCR_HSPOL;
if (timings->flags & DISPLAY_FLAGS_VSYNC_HIGH)
val |= GCR_VSPOL;
- if (timings->flags & DISPLAY_FLAGS_DE_HIGH)
+ if (timings->flags & DISPLAY_FLAGS_DE_LOW)
val |= GCR_DEPOL;
if (timings->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
val |= GCR_PCPOL;
@@ -306,7 +463,16 @@
/* Pixel format */
format = stm32_ltdc_get_pixel_format(priv->l2bpp);
- clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, format);
+ for (val = 0; val < NB_PF; val++)
+ if (priv->pix_fmt_hw[val] == format)
+ break;
+
+ if (val >= NB_PF) {
+ log_err("invalid pixel format\n");
+ return;
+ }
+
+ clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, val);
/* Constant alpha value */
clrsetbits_le32(regs + LTDC_L1CACR, LXCACR_CONSTA, priv->alpha);
@@ -359,6 +525,27 @@
return ret;
}
+ priv->hw_version = readl(priv->regs + LTDC_IDR);
+ debug("%s: LTDC hardware 0x%x\n", __func__, priv->hw_version);
+
+ switch (priv->hw_version) {
+ case HWVER_10200:
+ case HWVER_10300:
+ priv->layer_regs = layer_regs_a0;
+ priv->pix_fmt_hw = pix_fmt_a0;
+ break;
+ case HWVER_20101:
+ priv->layer_regs = layer_regs_a1;
+ priv->pix_fmt_hw = pix_fmt_a1;
+ break;
+ case HWVER_40100:
+ priv->layer_regs = layer_regs_a2;
+ priv->pix_fmt_hw = pix_fmt_a2;
+ break;
+ default:
+ return -ENODEV;
+ }
+
ret = uclass_first_device_err(UCLASS_PANEL, &panel);
if (ret) {
if (ret != -ENODEV)
diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h
index 8ad4bb9..cc3d4b4 100644
--- a/include/configs/stm32f746-disco.h
+++ b/include/configs/stm32f746-disco.h
@@ -34,7 +34,7 @@
#include <config_distro_bootcmd.h>
#define CONFIG_EXTRA_ENV_SETTINGS \
"kernel_addr_r=0xC0008000\0" \
- "fdtfile=stm32f746-disco.dtb\0" \
+ "fdtfile="CONFIG_DEFAULT_DEVICE_TREE".dtb\0" \
"fdt_addr_r=0xC0408000\0" \
"scriptaddr=0xC0418000\0" \
"pxefile_addr_r=0xC0428000\0" \
@@ -49,6 +49,7 @@
#define CONFIG_SYS_UBOOT_START 0x080083FD
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + \
CONFIG_SYS_SPL_LEN)
+#define CONFIG_SPL_PAD_TO 0x8000
/* DT blob (fdt) address */
#define CONFIG_SYS_FDT_BASE (CONFIG_SYS_FLASH_BASE + \
diff --git a/include/configs/stm32mp15_st_common.h b/include/configs/stm32mp15_st_common.h
index 10248bf..3c0ffb8 100644
--- a/include/configs/stm32mp15_st_common.h
+++ b/include/configs/stm32mp15_st_common.h
@@ -8,8 +8,16 @@
#ifndef __CONFIG_STM32MP15_ST_COMMON_H__
#define __CONFIG_STM32MP15_ST_COMMON_H__
+#define STM32MP_BOARD_EXTRA_ENV \
+ "console=ttySTM0\0"
+
#include <configs/stm32mp15_common.h>
+/* uart with on-board st-link */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
+ 230400, 460800, 921600, \
+ 1000000, 2000000 }
+
#ifdef CONFIG_EXTRA_ENV_SETTINGS
/*
* default bootcmd for stm32mp1 STMicroelectronics boards: