aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-05-10 15:28:02 -0400
committerTom Rini <trini@konsulko.com>2022-05-10 15:28:02 -0400
commit21e25992c86306b41caafcf85efc47d66f5efa6e (patch)
tree3c9f1ccb01f1a83f077064b4e4f4e028760f2e39 /arch
parentb4eb57766314062e3dd1ee8e439d2cb2d5dc33d8 (diff)
parente198d4fe7c34cbb97d7d3cbf31d3a78a5ecc43f7 (diff)
downloadu-boot-WIP/10May2022.zip
u-boot-WIP/10May2022.tar.gz
u-boot-WIP/10May2022.tar.bz2
Merge tag 'u-boot-stm32-20220510' of https://source.denx.de/u-boot/custodians/u-boot-stmWIP/10May2022
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
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/dts/stm32mp15-pinctrl.dtsi92
-rw-r--r--arch/arm/dts/stm32mp15-u-boot.dtsi12
-rw-r--r--arch/arm/dts/stm32mp151.dtsi37
-rw-r--r--arch/arm/dts/stm32mp153.dtsi7
-rw-r--r--arch/arm/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts2
-rw-r--r--arch/arm/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts2
-rw-r--r--arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts4
-rw-r--r--arch/arm/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts4
-rw-r--r--arch/arm/dts/stm32mp157c-ed1.dts2
-rw-r--r--arch/arm/dts/stm32mp157c-odyssey.dts2
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcom-drc02.dtsi4
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcom-pdk2.dtsi4
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcom-picoitx.dtsi4
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcom-som.dtsi3
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtsi6
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcor-io1v8.dtsi5
-rw-r--r--arch/arm/dts/stm32mp15xx-dhcor-som.dtsi4
-rw-r--r--arch/arm/dts/stm32mp15xx-dkx.dtsi4
-rw-r--r--arch/arm/mach-stm32/Kconfig20
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig7
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c13
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c418
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h47
-rw-r--r--arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c9
-rw-r--r--arch/arm/mach-stm32mp/cpu.c6
-rw-r--r--arch/arm/mach-stm32mp/fdt.c3
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h9
-rw-r--r--arch/arm/mach-stm32mp/psci.c16
28 files changed, 580 insertions, 166 deletions
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 @@ config STM32F7
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 @@ config CMD_STM32PROG_SERIAL
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 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
/* 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 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
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 @@ static const efi_guid_t uuid_mmc[3] = {
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 @@ struct fip_toc_header {
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 @@ static bool stm32prog_is_fip_header(struct fip_toc_header *header)
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 (!raw_header || !header) {
- log_debug("%s:no header data\n", __func__);
- return;
+ 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;
}
- 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 (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;
+ }
}
- if (raw_header->magic_number !=
+ 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__, raw_header->magic_number);
- return;
+ __func__, header->magic_number);
+ return false;
}
- /* only header v1.0 supported */
- if (raw_header->header_version != 0x00010000) {
+ if (header->header_version != 0x00020000) {
log_debug("%s:invalid header version : 0x%x\n",
- __func__, raw_header->header_version);
+ __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 (raw_header->reserved1 != 0x0 || raw_header->reserved2) {
- log_debug("%s:invalid reserved field\n", __func__);
+
+ if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) {
+ header->type = HEADER_FIP;
+ header->length = 0;
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;
- }
+ 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_STM32IMAGE;
- header->image_checksum = le32_to_cpu(raw_header->image_checksum);
- header->image_length = le32_to_cpu(raw_header->image_length);
- return;
+ header->type = HEADER_NONE;
+ header->image_checksum = 0x0;
+ header->image_length = 0x0;
}
static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header)
@@ -255,6 +428,8 @@ static int parse_type(struct stm32prog_data *data,
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 @@ static int parse_flash_layout(struct stm32prog_data *data,
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 @@ static int create_gpt_partitions(struct stm32prog_data *data)
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 @@ static int create_gpt_partitions(struct stm32prog_data *data)
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 @@ static int dfu_init_entities(struct stm32prog_data *data)
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 @@ static int dfu_init_entities(struct stm32prog_data *data)
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 @@ static int dfu_init_entities(struct stm32prog_data *data)
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_write(struct stm32prog_data *data, u32 offset, u8 *buffer,
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 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer,
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 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer,
}
/* 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 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer,
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 stm32prog_otp_start(struct stm32prog_data *data)
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 @@ int stm32prog_otp_start(struct stm32prog_data *data)
return -1;
}
- 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);
+ 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);
+ 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 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
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 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part)
/* 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 @@ error:
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 @@ void stm32prog_clean(struct stm32prog_data *data)
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_link_t {
enum stm32prog_header_t {
HEADER_NONE,
HEADER_STM32IMAGE,
+ HEADER_STM32IMAGE_V2,
HEADER_FIP,
};
@@ -48,11 +50,12 @@ struct image_header_s {
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 @@ struct raw_header_s {
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 @@ struct stm32prog_data {
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_read(struct stm32prog_data *data, u32 offset,
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 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
*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 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
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 @@ static void get_cpu_string_offsets(unsigned int *type, unsigned int *pkg,
/* 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 @@ int ft_system_setup(void *blob, struct bd_info *bd)
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 @@ u32 get_cpu_type(void);
/* 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 @@ static void __secure ddr_sw_self_refresh_exit(void)
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 @@ void __secure psci_system_suspend(u32 __always_unused function_id,
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 @@ void __secure psci_system_suspend(u32 __always_unused function_id,
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);
}