diff options
author | Tom Rini <trini@konsulko.com> | 2022-05-10 15:28:02 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-05-10 15:28:02 -0400 |
commit | 21e25992c86306b41caafcf85efc47d66f5efa6e (patch) | |
tree | 3c9f1ccb01f1a83f077064b4e4f4e028760f2e39 /arch | |
parent | b4eb57766314062e3dd1ee8e439d2cb2d5dc33d8 (diff) | |
parent | e198d4fe7c34cbb97d7d3cbf31d3a78a5ecc43f7 (diff) | |
download | u-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')
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); } |