15946 lines
423 KiB
Diff
15946 lines
423 KiB
Diff
From 053c918ec81e85d5dd13087b056a294f69383661 Mon Sep 17 00:00:00 2001
|
||
From: Romuald JEANNE <romuald.jeanne@st.com>
|
||
Date: Fri, 5 Jun 2020 13:58:23 +0200
|
||
Subject: [PATCH] 3.9.0-stm32mp-r1
|
||
|
||
---
|
||
CONTRIBUTING.md | 30 +
|
||
core/arch/arm/dts/stm32mp15-pinctrl.dtsi | 914 +-------------
|
||
core/arch/arm/dts/stm32mp151.dtsi | 1327 +++-----------------
|
||
core/arch/arm/dts/stm32mp153.dtsi | 31 +-
|
||
core/arch/arm/dts/stm32mp157.dtsi | 24 -
|
||
core/arch/arm/dts/stm32mp157a-dk1.dts | 29 +-
|
||
core/arch/arm/dts/stm32mp157a-ed1.dts | 46 +
|
||
core/arch/arm/dts/stm32mp157a-ev1.dts | 23 +
|
||
core/arch/arm/dts/stm32mp157c-dk2.dts | 95 +-
|
||
core/arch/arm/dts/stm32mp157c-ed1.dts | 373 +-----
|
||
core/arch/arm/dts/stm32mp157c-ev1.dts | 350 +-----
|
||
core/arch/arm/dts/stm32mp157d-dk1.dts | 49 +
|
||
core/arch/arm/dts/stm32mp157d-ed1.dts | 46 +
|
||
core/arch/arm/dts/stm32mp157d-ev1.dts | 22 +
|
||
core/arch/arm/dts/stm32mp157f-dk2.dts | 55 +
|
||
core/arch/arm/dts/stm32mp157f-ed1.dts | 51 +
|
||
core/arch/arm/dts/stm32mp157f-ev1.dts | 22 +
|
||
core/arch/arm/dts/stm32mp15xa.dtsi | 13 +
|
||
core/arch/arm/dts/stm32mp15xc.dtsi | 3 +
|
||
core/arch/arm/dts/stm32mp15xd.dtsi | 19 +
|
||
core/arch/arm/dts/stm32mp15xf.dtsi | 21 +
|
||
core/arch/arm/dts/stm32mp15xx-dkx.dtsi | 692 ++++------
|
||
core/arch/arm/dts/stm32mp15xx-edx.dtsi | 478 +++++++
|
||
core/arch/arm/dts/stm32mp15xx-evx.dtsi | 71 ++
|
||
core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi | 3 +-
|
||
core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi | 2 +-
|
||
core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi | 3 +-
|
||
core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi | 2 +-
|
||
core/arch/arm/include/arm32.h | 11 +-
|
||
core/arch/arm/include/mm/core_mmu.h | 3 +
|
||
core/arch/arm/include/sm/pm.h | 4 +
|
||
core/arch/arm/mm/core_mmu.c | 18 +-
|
||
core/arch/arm/mm/mobj.c | 5 +-
|
||
core/arch/arm/plat-stm32mp1/boot_api.h | 2 +
|
||
core/arch/arm/plat-stm32mp1/conf.mk | 59 +-
|
||
.../arm/plat-stm32mp1/drivers/stm32mp1_calib.c | 501 ++++++++
|
||
core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c | 1268 ++++++++++++++++++-
|
||
.../arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c | 469 +++++++
|
||
.../arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h | 219 ++++
|
||
core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h | 31 +-
|
||
core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h | 35 +-
|
||
core/arch/arm/plat-stm32mp1/drivers/sub.mk | 2 +
|
||
core/arch/arm/plat-stm32mp1/main.c | 316 ++++-
|
||
.../arm/plat-stm32mp1/nsec-service/low_power_svc.c | 152 +++
|
||
.../arm/plat-stm32mp1/nsec-service/low_power_svc.h | 55 +
|
||
core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c | 89 ++
|
||
core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h | 22 +
|
||
core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c | 195 +++
|
||
core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h | 30 +
|
||
.../arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h | 196 ++-
|
||
.../nsec-service/stm32mp1_svc_setup.c | 79 +-
|
||
core/arch/arm/plat-stm32mp1/nsec-service/sub.mk | 3 +
|
||
core/arch/arm/plat-stm32mp1/platform_config.h | 131 +-
|
||
core/arch/arm/plat-stm32mp1/pm/context.c | 521 ++++++++
|
||
core/arch/arm/plat-stm32mp1/pm/context.h | 102 ++
|
||
.../arm/plat-stm32mp1/pm/context_asm_defines.c | 28 +
|
||
core/arch/arm/plat-stm32mp1/pm/low_power.c | 609 +++++++++
|
||
core/arch/arm/plat-stm32mp1/pm/pm_helpers.S | 740 +++++++++++
|
||
core/arch/arm/plat-stm32mp1/pm/power.h | 27 +
|
||
core/arch/arm/plat-stm32mp1/pm/power_config.c | 252 ++++
|
||
core/arch/arm/plat-stm32mp1/pm/psci.c | 224 +++-
|
||
core/arch/arm/plat-stm32mp1/pm/sub.mk | 6 +
|
||
core/arch/arm/plat-stm32mp1/reset.S | 30 +-
|
||
core/arch/arm/plat-stm32mp1/scmi_server.c | 81 +-
|
||
core/arch/arm/plat-stm32mp1/shared_resources.c | 31 +-
|
||
core/arch/arm/plat-stm32mp1/stm32_util.h | 54 +
|
||
core/arch/arm/plat-stm32mp1/stm32mp_pm.h | 21 +
|
||
core/arch/arm/sm/pm_a32.S | 83 +-
|
||
core/arch/arm/tee/entry_std.c | 2 +-
|
||
core/drivers/gic.c | 225 +++-
|
||
core/drivers/stm32_bsec.c | 130 +-
|
||
core/drivers/stm32_iwdg.c | 313 +++++
|
||
core/drivers/stm32_rtc.c | 445 +++++++
|
||
core/drivers/stm32_tim.c | 286 +++++
|
||
core/drivers/sub.mk | 3 +
|
||
core/include/drivers/gic.h | 24 +
|
||
core/include/drivers/stm32_bsec.h | 16 +
|
||
core/include/drivers/stm32_iwdg.h | 17 +
|
||
core/include/drivers/stm32_rtc.h | 60 +
|
||
core/include/drivers/stm32_tim.h | 25 +
|
||
core/include/dt-bindings/clock/stm32mp1-clksrc.h | 284 +++++
|
||
core/include/dt-bindings/power/stm32mp1-power.h | 19 +
|
||
core/include/dt-bindings/soc/st,stm32-etzpc.h | 107 ++
|
||
core/include/kernel/interrupt.h | 15 +
|
||
core/include/kernel/panic.h | 6 +
|
||
core/kernel/interrupt.c | 10 +
|
||
core/kernel/panic.c | 23 +-
|
||
mk/config.mk | 2 +-
|
||
88 files changed, 10040 insertions(+), 3470 deletions(-)
|
||
create mode 100644 CONTRIBUTING.md
|
||
create mode 100644 core/arch/arm/dts/stm32mp157a-ed1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157a-ev1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157d-dk1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157d-ed1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157d-ev1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157f-dk2.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157f-ed1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp157f-ev1.dts
|
||
create mode 100644 core/arch/arm/dts/stm32mp15xa.dtsi
|
||
create mode 100644 core/arch/arm/dts/stm32mp15xd.dtsi
|
||
create mode 100644 core/arch/arm/dts/stm32mp15xf.dtsi
|
||
create mode 100644 core/arch/arm/dts/stm32mp15xx-edx.dtsi
|
||
create mode 100644 core/arch/arm/dts/stm32mp15xx-evx.dtsi
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/context.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/context.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/low_power.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/pm_helpers.S
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/power.h
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/pm/power_config.c
|
||
create mode 100644 core/arch/arm/plat-stm32mp1/stm32mp_pm.h
|
||
create mode 100644 core/drivers/stm32_iwdg.c
|
||
create mode 100644 core/drivers/stm32_rtc.c
|
||
create mode 100644 core/drivers/stm32_tim.c
|
||
create mode 100644 core/include/drivers/stm32_iwdg.h
|
||
create mode 100644 core/include/drivers/stm32_rtc.h
|
||
create mode 100644 core/include/drivers/stm32_tim.h
|
||
create mode 100644 core/include/dt-bindings/clock/stm32mp1-clksrc.h
|
||
create mode 100644 core/include/dt-bindings/power/stm32mp1-power.h
|
||
create mode 100644 core/include/dt-bindings/soc/st,stm32-etzpc.h
|
||
|
||
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
|
||
new file mode 100644
|
||
index 0000000..3d1bacd
|
||
--- /dev/null
|
||
+++ b/CONTRIBUTING.md
|
||
@@ -0,0 +1,30 @@
|
||
+# Contributing guide
|
||
+
|
||
+This document serves as a checklist before contributing to this repository. It includes links to read up on if topics are unclear to you.
|
||
+
|
||
+This guide mainly focuses on the proper use of Git.
|
||
+
|
||
+## 1. Issues
|
||
+
|
||
+STM32MPU projects do not activate "Github issues" feature for the time being. If you need to report an issue or question about this project deliverables, you can report them using [ ST Support Center ](https://my.st.com/ols#/ols/newrequest) or [ ST Community MPU Forum ](https://community.st.com/s/topic/0TO0X0000003u2AWAQ/stm32-mpus).
|
||
+
|
||
+## 2. Pull Requests
|
||
+
|
||
+STMicrolectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure.
|
||
+
|
||
+* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual CLA (https://cla.st.com).
|
||
+* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate CLA (https://cla.st.com) mentioning your GitHub account name.
|
||
+* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account you can check here (https://cla.st.com).
|
||
+
|
||
+Please note that:
|
||
+* The Corporate CLA will always take precedence over the Individual CLA.
|
||
+* One CLA submission is sufficient, for any project proposed by STMicroelectronics.
|
||
+
|
||
+__How to proceed__
|
||
+
|
||
+* We recommend to fork the project in your GitHub account to further develop your contribution. Please use the latest commit version.
|
||
+* Please, submit one Pull Request for one new feature or proposal. This will ease the analysis and final merge if accepted.
|
||
+
|
||
+__Note__
|
||
+
|
||
+Merge will not be done directly in GitHub but it will need first to follow internal integration process before public deliver in a standard release. The Pull request will stay open until it is merged and delivered.
|
||
diff --git a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi
|
||
index 0237d4d..d3d1744 100644
|
||
--- a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi
|
||
@@ -6,162 +6,6 @@
|
||
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
|
||
|
||
&pinctrl {
|
||
- adc1_in6_pins_a: adc1-in6 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 12, ANALOG)>;
|
||
- };
|
||
- };
|
||
-
|
||
- adc12_ain_pins_a: adc12-ain-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('C', 3, ANALOG)>, /* ADC1 in13 */
|
||
- <STM32_PINMUX('F', 12, ANALOG)>, /* ADC1 in6 */
|
||
- <STM32_PINMUX('F', 13, ANALOG)>, /* ADC2 in2 */
|
||
- <STM32_PINMUX('F', 14, ANALOG)>; /* ADC2 in6 */
|
||
- };
|
||
- };
|
||
-
|
||
- adc12_usb_cc_pins_a: adc12-usb-cc-pins-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */
|
||
- <STM32_PINMUX('A', 5, ANALOG)>; /* ADC12 in19 */
|
||
- };
|
||
- };
|
||
-
|
||
- cec_pins_a: cec-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 15, AF4)>;
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- cec_pins_sleep_a: cec-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* HDMI_CEC */
|
||
- };
|
||
- };
|
||
-
|
||
- cec_pins_b: cec-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('B', 6, AF5)>;
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- cec_pins_sleep_b: cec-sleep-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* HDMI_CEC */
|
||
- };
|
||
- };
|
||
-
|
||
- dac_ch1_pins_a: dac-ch1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 4, ANALOG)>;
|
||
- };
|
||
- };
|
||
-
|
||
- dac_ch2_pins_a: dac-ch2 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 5, ANALOG)>;
|
||
- };
|
||
- };
|
||
-
|
||
- dcmi_pins_a: dcmi-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 8, AF13)>,/* DCMI_HSYNC */
|
||
- <STM32_PINMUX('B', 7, AF13)>,/* DCMI_VSYNC */
|
||
- <STM32_PINMUX('A', 6, AF13)>,/* DCMI_PIXCLK */
|
||
- <STM32_PINMUX('H', 9, AF13)>,/* DCMI_D0 */
|
||
- <STM32_PINMUX('H', 10, AF13)>,/* DCMI_D1 */
|
||
- <STM32_PINMUX('H', 11, AF13)>,/* DCMI_D2 */
|
||
- <STM32_PINMUX('H', 12, AF13)>,/* DCMI_D3 */
|
||
- <STM32_PINMUX('H', 14, AF13)>,/* DCMI_D4 */
|
||
- <STM32_PINMUX('I', 4, AF13)>,/* DCMI_D5 */
|
||
- <STM32_PINMUX('B', 8, AF13)>,/* DCMI_D6 */
|
||
- <STM32_PINMUX('E', 6, AF13)>,/* DCMI_D7 */
|
||
- <STM32_PINMUX('I', 1, AF13)>,/* DCMI_D8 */
|
||
- <STM32_PINMUX('H', 7, AF13)>,/* DCMI_D9 */
|
||
- <STM32_PINMUX('I', 3, AF13)>,/* DCMI_D10 */
|
||
- <STM32_PINMUX('H', 15, AF13)>;/* DCMI_D11 */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- dcmi_sleep_pins_a: dcmi-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 8, ANALOG)>,/* DCMI_HSYNC */
|
||
- <STM32_PINMUX('B', 7, ANALOG)>,/* DCMI_VSYNC */
|
||
- <STM32_PINMUX('A', 6, ANALOG)>,/* DCMI_PIXCLK */
|
||
- <STM32_PINMUX('H', 9, ANALOG)>,/* DCMI_D0 */
|
||
- <STM32_PINMUX('H', 10, ANALOG)>,/* DCMI_D1 */
|
||
- <STM32_PINMUX('H', 11, ANALOG)>,/* DCMI_D2 */
|
||
- <STM32_PINMUX('H', 12, ANALOG)>,/* DCMI_D3 */
|
||
- <STM32_PINMUX('H', 14, ANALOG)>,/* DCMI_D4 */
|
||
- <STM32_PINMUX('I', 4, ANALOG)>,/* DCMI_D5 */
|
||
- <STM32_PINMUX('B', 8, ANALOG)>,/* DCMI_D6 */
|
||
- <STM32_PINMUX('E', 6, ANALOG)>,/* DCMI_D7 */
|
||
- <STM32_PINMUX('I', 1, ANALOG)>,/* DCMI_D8 */
|
||
- <STM32_PINMUX('H', 7, ANALOG)>,/* DCMI_D9 */
|
||
- <STM32_PINMUX('I', 3, ANALOG)>,/* DCMI_D10 */
|
||
- <STM32_PINMUX('H', 15, ANALOG)>;/* DCMI_D11 */
|
||
- };
|
||
- };
|
||
-
|
||
- ethernet0_rgmii_pins_a: rgmii-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
|
||
- <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
|
||
- <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
|
||
- <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
|
||
- <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
|
||
- <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
|
||
- <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
|
||
- <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
|
||
- bias-disable;
|
||
- drive-push-pull;
|
||
- slew-rate = <2>;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH_MDIO */
|
||
- bias-disable;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- pins3 {
|
||
- pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
|
||
- <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
|
||
- <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
|
||
- <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
|
||
- <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
|
||
- <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
|
||
- <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
|
||
- <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
|
||
- <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
|
||
- <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
|
||
- <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
|
||
- <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
|
||
- <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
|
||
- <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
|
||
- <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
|
||
- <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
|
||
- <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
|
||
- <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
|
||
- <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
|
||
- <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
|
||
- };
|
||
- };
|
||
-
|
||
fmc_pins_a: fmc-0 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
|
||
@@ -187,412 +31,6 @@
|
||
};
|
||
};
|
||
|
||
- fmc_sleep_pins_a: fmc-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
|
||
- <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
|
||
- <STM32_PINMUX('D', 11, ANALOG)>, /* FMC_A16_FMC_CLE */
|
||
- <STM32_PINMUX('D', 12, ANALOG)>, /* FMC_A17_FMC_ALE */
|
||
- <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
|
||
- <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
|
||
- <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
|
||
- <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
|
||
- <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
|
||
- <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
|
||
- <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
|
||
- <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
|
||
- <STM32_PINMUX('D', 6, ANALOG)>, /* FMC_NWAIT */
|
||
- <STM32_PINMUX('G', 9, ANALOG)>; /* FMC_NE2_FMC_NCE */
|
||
- };
|
||
- };
|
||
-
|
||
- i2c1_pins_a: i2c1-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
|
||
- <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- i2c1_pins_sleep_a: i2c1-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
|
||
- <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
|
||
- };
|
||
- };
|
||
-
|
||
- i2c1_pins_b: i2c1-2 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 14, AF5)>, /* I2C1_SCL */
|
||
- <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- i2c1_pins_sleep_b: i2c1-3 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 14, ANALOG)>, /* I2C1_SCL */
|
||
- <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
|
||
- };
|
||
- };
|
||
-
|
||
- i2c2_pins_a: i2c2-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
|
||
- <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- i2c2_pins_sleep_a: i2c2-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
|
||
- <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
|
||
- };
|
||
- };
|
||
-
|
||
- i2c2_pins_b1: i2c2-2 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- i2c2_pins_sleep_b1: i2c2-3 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
|
||
- };
|
||
- };
|
||
-
|
||
- i2c5_pins_a: i2c5-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
|
||
- <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- i2c5_pins_sleep_a: i2c5-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */
|
||
- <STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */
|
||
-
|
||
- };
|
||
- };
|
||
-
|
||
- i2s2_pins_a: i2s2-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
|
||
- <STM32_PINMUX('B', 9, AF5)>, /* I2S2_WS */
|
||
- <STM32_PINMUX('A', 9, AF5)>; /* I2S2_CK */
|
||
- slew-rate = <1>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- i2s2_pins_sleep_a: i2s2-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
|
||
- <STM32_PINMUX('B', 9, ANALOG)>, /* I2S2_WS */
|
||
- <STM32_PINMUX('A', 9, ANALOG)>; /* I2S2_CK */
|
||
- };
|
||
- };
|
||
-
|
||
- ltdc_pins_a: ltdc-a-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('G', 7, AF14)>, /* LCD_CLK */
|
||
- <STM32_PINMUX('I', 10, AF14)>, /* LCD_HSYNC */
|
||
- <STM32_PINMUX('I', 9, AF14)>, /* LCD_VSYNC */
|
||
- <STM32_PINMUX('F', 10, AF14)>, /* LCD_DE */
|
||
- <STM32_PINMUX('H', 2, AF14)>, /* LCD_R0 */
|
||
- <STM32_PINMUX('H', 3, AF14)>, /* LCD_R1 */
|
||
- <STM32_PINMUX('H', 8, AF14)>, /* LCD_R2 */
|
||
- <STM32_PINMUX('H', 9, AF14)>, /* LCD_R3 */
|
||
- <STM32_PINMUX('H', 10, AF14)>, /* LCD_R4 */
|
||
- <STM32_PINMUX('C', 0, AF14)>, /* LCD_R5 */
|
||
- <STM32_PINMUX('H', 12, AF14)>, /* LCD_R6 */
|
||
- <STM32_PINMUX('E', 15, AF14)>, /* LCD_R7 */
|
||
- <STM32_PINMUX('E', 5, AF14)>, /* LCD_G0 */
|
||
- <STM32_PINMUX('E', 6, AF14)>, /* LCD_G1 */
|
||
- <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
|
||
- <STM32_PINMUX('H', 14, AF14)>, /* LCD_G3 */
|
||
- <STM32_PINMUX('H', 15, AF14)>, /* LCD_G4 */
|
||
- <STM32_PINMUX('I', 0, AF14)>, /* LCD_G5 */
|
||
- <STM32_PINMUX('I', 1, AF14)>, /* LCD_G6 */
|
||
- <STM32_PINMUX('I', 2, AF14)>, /* LCD_G7 */
|
||
- <STM32_PINMUX('D', 9, AF14)>, /* LCD_B0 */
|
||
- <STM32_PINMUX('G', 12, AF14)>, /* LCD_B1 */
|
||
- <STM32_PINMUX('G', 10, AF14)>, /* LCD_B2 */
|
||
- <STM32_PINMUX('D', 10, AF14)>, /* LCD_B3 */
|
||
- <STM32_PINMUX('I', 4, AF14)>, /* LCD_B4 */
|
||
- <STM32_PINMUX('A', 3, AF14)>, /* LCD_B5 */
|
||
- <STM32_PINMUX('B', 8, AF14)>, /* LCD_B6 */
|
||
- <STM32_PINMUX('D', 8, AF14)>; /* LCD_B7 */
|
||
- bias-disable;
|
||
- drive-push-pull;
|
||
- slew-rate = <1>;
|
||
- };
|
||
- };
|
||
-
|
||
- ltdc_pins_sleep_a: ltdc-a-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_CLK */
|
||
- <STM32_PINMUX('I', 10, ANALOG)>, /* LCD_HSYNC */
|
||
- <STM32_PINMUX('I', 9, ANALOG)>, /* LCD_VSYNC */
|
||
- <STM32_PINMUX('F', 10, ANALOG)>, /* LCD_DE */
|
||
- <STM32_PINMUX('H', 2, ANALOG)>, /* LCD_R0 */
|
||
- <STM32_PINMUX('H', 3, ANALOG)>, /* LCD_R1 */
|
||
- <STM32_PINMUX('H', 8, ANALOG)>, /* LCD_R2 */
|
||
- <STM32_PINMUX('H', 9, ANALOG)>, /* LCD_R3 */
|
||
- <STM32_PINMUX('H', 10, ANALOG)>, /* LCD_R4 */
|
||
- <STM32_PINMUX('C', 0, ANALOG)>, /* LCD_R5 */
|
||
- <STM32_PINMUX('H', 12, ANALOG)>, /* LCD_R6 */
|
||
- <STM32_PINMUX('E', 15, ANALOG)>, /* LCD_R7 */
|
||
- <STM32_PINMUX('E', 5, ANALOG)>, /* LCD_G0 */
|
||
- <STM32_PINMUX('E', 6, ANALOG)>, /* LCD_G1 */
|
||
- <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
|
||
- <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_G3 */
|
||
- <STM32_PINMUX('H', 15, ANALOG)>, /* LCD_G4 */
|
||
- <STM32_PINMUX('I', 0, ANALOG)>, /* LCD_G5 */
|
||
- <STM32_PINMUX('I', 1, ANALOG)>, /* LCD_G6 */
|
||
- <STM32_PINMUX('I', 2, ANALOG)>, /* LCD_G7 */
|
||
- <STM32_PINMUX('D', 9, ANALOG)>, /* LCD_B0 */
|
||
- <STM32_PINMUX('G', 12, ANALOG)>, /* LCD_B1 */
|
||
- <STM32_PINMUX('G', 10, ANALOG)>, /* LCD_B2 */
|
||
- <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B3 */
|
||
- <STM32_PINMUX('I', 4, ANALOG)>, /* LCD_B4 */
|
||
- <STM32_PINMUX('A', 3, ANALOG)>, /* LCD_B5 */
|
||
- <STM32_PINMUX('B', 8, ANALOG)>, /* LCD_B6 */
|
||
- <STM32_PINMUX('D', 8, ANALOG)>; /* LCD_B7 */
|
||
- };
|
||
- };
|
||
-
|
||
- ltdc_pins_b: ltdc-b-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */
|
||
- <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */
|
||
- <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */
|
||
- <STM32_PINMUX('K', 7, AF14)>, /* LCD_DE */
|
||
- <STM32_PINMUX('I', 15, AF14)>, /* LCD_R0 */
|
||
- <STM32_PINMUX('J', 0, AF14)>, /* LCD_R1 */
|
||
- <STM32_PINMUX('J', 1, AF14)>, /* LCD_R2 */
|
||
- <STM32_PINMUX('J', 2, AF14)>, /* LCD_R3 */
|
||
- <STM32_PINMUX('J', 3, AF14)>, /* LCD_R4 */
|
||
- <STM32_PINMUX('J', 4, AF14)>, /* LCD_R5 */
|
||
- <STM32_PINMUX('J', 5, AF14)>, /* LCD_R6 */
|
||
- <STM32_PINMUX('J', 6, AF14)>, /* LCD_R7 */
|
||
- <STM32_PINMUX('J', 7, AF14)>, /* LCD_G0 */
|
||
- <STM32_PINMUX('J', 8, AF14)>, /* LCD_G1 */
|
||
- <STM32_PINMUX('J', 9, AF14)>, /* LCD_G2 */
|
||
- <STM32_PINMUX('J', 10, AF14)>, /* LCD_G3 */
|
||
- <STM32_PINMUX('J', 11, AF14)>, /* LCD_G4 */
|
||
- <STM32_PINMUX('K', 0, AF14)>, /* LCD_G5 */
|
||
- <STM32_PINMUX('K', 1, AF14)>, /* LCD_G6 */
|
||
- <STM32_PINMUX('K', 2, AF14)>, /* LCD_G7 */
|
||
- <STM32_PINMUX('J', 12, AF14)>, /* LCD_B0 */
|
||
- <STM32_PINMUX('J', 13, AF14)>, /* LCD_B1 */
|
||
- <STM32_PINMUX('J', 14, AF14)>, /* LCD_B2 */
|
||
- <STM32_PINMUX('J', 15, AF14)>, /* LCD_B3 */
|
||
- <STM32_PINMUX('K', 3, AF14)>, /* LCD_B4 */
|
||
- <STM32_PINMUX('K', 4, AF14)>, /* LCD_B5 */
|
||
- <STM32_PINMUX('K', 5, AF14)>, /* LCD_B6 */
|
||
- <STM32_PINMUX('K', 6, AF14)>; /* LCD_B7 */
|
||
- bias-disable;
|
||
- drive-push-pull;
|
||
- slew-rate = <1>;
|
||
- };
|
||
- };
|
||
-
|
||
- ltdc_pins_sleep_b: ltdc-b-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */
|
||
- <STM32_PINMUX('I', 12, ANALOG)>, /* LCD_HSYNC */
|
||
- <STM32_PINMUX('I', 13, ANALOG)>, /* LCD_VSYNC */
|
||
- <STM32_PINMUX('K', 7, ANALOG)>, /* LCD_DE */
|
||
- <STM32_PINMUX('I', 15, ANALOG)>, /* LCD_R0 */
|
||
- <STM32_PINMUX('J', 0, ANALOG)>, /* LCD_R1 */
|
||
- <STM32_PINMUX('J', 1, ANALOG)>, /* LCD_R2 */
|
||
- <STM32_PINMUX('J', 2, ANALOG)>, /* LCD_R3 */
|
||
- <STM32_PINMUX('J', 3, ANALOG)>, /* LCD_R4 */
|
||
- <STM32_PINMUX('J', 4, ANALOG)>, /* LCD_R5 */
|
||
- <STM32_PINMUX('J', 5, ANALOG)>, /* LCD_R6 */
|
||
- <STM32_PINMUX('J', 6, ANALOG)>, /* LCD_R7 */
|
||
- <STM32_PINMUX('J', 7, ANALOG)>, /* LCD_G0 */
|
||
- <STM32_PINMUX('J', 8, ANALOG)>, /* LCD_G1 */
|
||
- <STM32_PINMUX('J', 9, ANALOG)>, /* LCD_G2 */
|
||
- <STM32_PINMUX('J', 10, ANALOG)>, /* LCD_G3 */
|
||
- <STM32_PINMUX('J', 11, ANALOG)>, /* LCD_G4 */
|
||
- <STM32_PINMUX('K', 0, ANALOG)>, /* LCD_G5 */
|
||
- <STM32_PINMUX('K', 1, ANALOG)>, /* LCD_G6 */
|
||
- <STM32_PINMUX('K', 2, ANALOG)>, /* LCD_G7 */
|
||
- <STM32_PINMUX('J', 12, ANALOG)>, /* LCD_B0 */
|
||
- <STM32_PINMUX('J', 13, ANALOG)>, /* LCD_B1 */
|
||
- <STM32_PINMUX('J', 14, ANALOG)>, /* LCD_B2 */
|
||
- <STM32_PINMUX('J', 15, ANALOG)>, /* LCD_B3 */
|
||
- <STM32_PINMUX('K', 3, ANALOG)>, /* LCD_B4 */
|
||
- <STM32_PINMUX('K', 4, ANALOG)>, /* LCD_B5 */
|
||
- <STM32_PINMUX('K', 5, ANALOG)>, /* LCD_B6 */
|
||
- <STM32_PINMUX('K', 6, ANALOG)>; /* LCD_B7 */
|
||
- };
|
||
- };
|
||
-
|
||
- m_can1_pins_a: m-can1-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
|
||
- slew-rate = <1>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- m_can1_sleep_pins_a: m_can1-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
|
||
- <STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm1_pins_a: pwm1-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('E', 9, AF1)>, /* TIM1_CH1 */
|
||
- <STM32_PINMUX('E', 11, AF1)>, /* TIM1_CH2 */
|
||
- <STM32_PINMUX('E', 14, AF1)>; /* TIM1_CH4 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm1_sleep_pins_a: pwm1-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('E', 9, ANALOG)>, /* TIM1_CH1 */
|
||
- <STM32_PINMUX('E', 11, ANALOG)>, /* TIM1_CH2 */
|
||
- <STM32_PINMUX('E', 14, ANALOG)>; /* TIM1_CH4 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm2_pins_a: pwm2-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm2_sleep_pins_a: pwm2-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 3, ANALOG)>; /* TIM2_CH4 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm3_pins_a: pwm3-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('C', 7, AF2)>; /* TIM3_CH2 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm3_sleep_pins_a: pwm3-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('C', 7, ANALOG)>; /* TIM3_CH2 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm4_pins_a: pwm4-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 14, AF2)>, /* TIM4_CH3 */
|
||
- <STM32_PINMUX('D', 15, AF2)>; /* TIM4_CH4 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm4_sleep_pins_a: pwm4-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 14, ANALOG)>, /* TIM4_CH3 */
|
||
- <STM32_PINMUX('D', 15, ANALOG)>; /* TIM4_CH4 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm4_pins_b: pwm4-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 13, AF2)>; /* TIM4_CH2 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm4_sleep_pins_b: pwm4-sleep-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('D', 13, ANALOG)>; /* TIM4_CH2 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm5_pins_a: pwm5-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 11, AF2)>; /* TIM5_CH2 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm5_sleep_pins_a: pwm5-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 11, ANALOG)>; /* TIM5_CH2 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm8_pins_a: pwm8-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 2, AF3)>; /* TIM8_CH4 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm8_sleep_pins_a: pwm8-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 2, ANALOG)>; /* TIM8_CH4 */
|
||
- };
|
||
- };
|
||
-
|
||
- pwm12_pins_a: pwm12-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 6, AF2)>; /* TIM12_CH1 */
|
||
- bias-pull-down;
|
||
- drive-push-pull;
|
||
- slew-rate = <0>;
|
||
- };
|
||
- };
|
||
-
|
||
- pwm12_sleep_pins_a: pwm12-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('H', 6, ANALOG)>; /* TIM12_CH1 */
|
||
- };
|
||
- };
|
||
-
|
||
qspi_clk_pins_a: qspi-clk-0 {
|
||
pins {
|
||
pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
|
||
@@ -602,12 +40,6 @@
|
||
};
|
||
};
|
||
|
||
- qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
|
||
- };
|
||
- };
|
||
-
|
||
qspi_bk1_pins_a: qspi-bk1-0 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
|
||
@@ -626,16 +58,6 @@
|
||
};
|
||
};
|
||
|
||
- qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
|
||
- <STM32_PINMUX('F', 9, ANALOG)>, /* QSPI_BK1_IO1 */
|
||
- <STM32_PINMUX('F', 7, ANALOG)>, /* QSPI_BK1_IO2 */
|
||
- <STM32_PINMUX('F', 6, ANALOG)>, /* QSPI_BK1_IO3 */
|
||
- <STM32_PINMUX('B', 6, ANALOG)>; /* QSPI_BK1_NCS */
|
||
- };
|
||
- };
|
||
-
|
||
qspi_bk2_pins_a: qspi-bk2-0 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
|
||
@@ -654,86 +76,9 @@
|
||
};
|
||
};
|
||
|
||
- qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 {
|
||
+ rtc_out2_rmp_pins_a: rtc-out2-rmp-pins-0 {
|
||
pins {
|
||
- pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* QSPI_BK2_IO0 */
|
||
- <STM32_PINMUX('H', 3, ANALOG)>, /* QSPI_BK2_IO1 */
|
||
- <STM32_PINMUX('G', 10, ANALOG)>, /* QSPI_BK2_IO2 */
|
||
- <STM32_PINMUX('G', 7, ANALOG)>, /* QSPI_BK2_IO3 */
|
||
- <STM32_PINMUX('C', 0, ANALOG)>; /* QSPI_BK2_NCS */
|
||
- };
|
||
- };
|
||
-
|
||
- sai2a_pins_a: sai2a-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */
|
||
- <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */
|
||
- <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */
|
||
- <STM32_PINMUX('E', 0, AF10)>; /* SAI2_MCLK_A */
|
||
- slew-rate = <0>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- sai2a_sleep_pins_a: sai2a-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */
|
||
- <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */
|
||
- <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */
|
||
- <STM32_PINMUX('E', 0, ANALOG)>; /* SAI2_MCLK_A */
|
||
- };
|
||
- };
|
||
-
|
||
- sai2b_pins_a: sai2b-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */
|
||
- <STM32_PINMUX('E', 13, AF10)>, /* SAI2_FS_B */
|
||
- <STM32_PINMUX('E', 14, AF10)>; /* SAI2_MCLK_B */
|
||
- slew-rate = <0>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- sai2b_sleep_pins_a: sai2b-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* SAI2_SD_B */
|
||
- <STM32_PINMUX('E', 12, ANALOG)>, /* SAI2_SCK_B */
|
||
- <STM32_PINMUX('E', 13, ANALOG)>, /* SAI2_FS_B */
|
||
- <STM32_PINMUX('E', 14, ANALOG)>; /* SAI2_MCLK_B */
|
||
- };
|
||
- };
|
||
-
|
||
- sai2b_pins_b: sai2b-2 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- sai2b_sleep_pins_b: sai2b-3 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
|
||
- };
|
||
- };
|
||
-
|
||
- sai4a_pins_a: sai4a-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('B', 5, AF10)>; /* SAI4_SD_A */
|
||
- slew-rate = <0>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- sai4a_sleep_pins_a: sai4a-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* SAI4_SD_A */
|
||
+ pinmux = <STM32_PINMUX('I', 8, ANALOG)>; /* RTC_OUT2_RMP */
|
||
};
|
||
};
|
||
|
||
@@ -756,41 +101,6 @@
|
||
};
|
||
};
|
||
|
||
- sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
|
||
- <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
|
||
- <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
|
||
- <STM32_PINMUX('C', 11, AF12)>; /* SDMMC1_D3 */
|
||
- slew-rate = <1>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
|
||
- slew-rate = <2>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins3 {
|
||
- pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
|
||
- slew-rate = <1>;
|
||
- drive-open-drain;
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
- sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
|
||
- <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
|
||
- <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
|
||
- <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
|
||
- <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
|
||
- <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
|
||
- };
|
||
- };
|
||
-
|
||
sdmmc1_dir_pins_a: sdmmc1-dir-0 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
|
||
@@ -806,15 +116,6 @@
|
||
};
|
||
};
|
||
|
||
- sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
|
||
- <STM32_PINMUX('C', 7, ANALOG)>, /* SDMMC1_D123DIR */
|
||
- <STM32_PINMUX('B', 9, ANALOG)>, /* SDMMC1_CDIR */
|
||
- <STM32_PINMUX('E', 4, ANALOG)>; /* SDMMC1_CKIN */
|
||
- };
|
||
- };
|
||
-
|
||
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
|
||
@@ -834,41 +135,6 @@
|
||
};
|
||
};
|
||
|
||
- sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
|
||
- <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
|
||
- <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
|
||
- <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
|
||
- slew-rate = <1>;
|
||
- drive-push-pull;
|
||
- bias-pull-up;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
|
||
- slew-rate = <2>;
|
||
- drive-push-pull;
|
||
- bias-pull-up;
|
||
- };
|
||
- pins3 {
|
||
- pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
|
||
- slew-rate = <1>;
|
||
- drive-open-drain;
|
||
- bias-pull-up;
|
||
- };
|
||
- };
|
||
-
|
||
- sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
|
||
- <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
|
||
- <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
|
||
- <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
|
||
- <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
|
||
- <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
|
||
- };
|
||
- };
|
||
-
|
||
sdmmc2_b4_pins_b: sdmmc2-b4-1 {
|
||
pins1 {
|
||
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
|
||
@@ -888,30 +154,6 @@
|
||
};
|
||
};
|
||
|
||
- sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
|
||
- <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
|
||
- <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
|
||
- <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
|
||
- slew-rate = <1>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
|
||
- slew-rate = <2>;
|
||
- drive-push-pull;
|
||
- bias-disable;
|
||
- };
|
||
- pins3 {
|
||
- pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
|
||
- slew-rate = <1>;
|
||
- drive-open-drain;
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
-
|
||
sdmmc2_d47_pins_a: sdmmc2-d47-0 {
|
||
pins {
|
||
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
|
||
@@ -924,140 +166,120 @@
|
||
};
|
||
};
|
||
|
||
- sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
|
||
- <STM32_PINMUX('A', 9, ANALOG)>, /* SDMMC2_D5 */
|
||
- <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC2_D6 */
|
||
- <STM32_PINMUX('D', 3, ANALOG)>; /* SDMMC2_D7 */
|
||
- };
|
||
- };
|
||
-
|
||
- sdmmc3_b4_pins_a: sdmmc3-b4-0 {
|
||
+ uart4_pins_a: uart4-0 {
|
||
pins1 {
|
||
- pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
|
||
- <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
|
||
- <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
|
||
- <STM32_PINMUX('D', 7, AF10)>, /* SDMMC3_D3 */
|
||
- <STM32_PINMUX('F', 1, AF9)>; /* SDMMC3_CMD */
|
||
- slew-rate = <1>;
|
||
+ pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
|
||
+ bias-disable;
|
||
drive-push-pull;
|
||
- bias-pull-up;
|
||
+ slew-rate = <0>;
|
||
};
|
||
pins2 {
|
||
- pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
|
||
- slew-rate = <2>;
|
||
- drive-push-pull;
|
||
- bias-pull-up;
|
||
+ pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
|
||
+ bias-disable;
|
||
};
|
||
};
|
||
|
||
- sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 {
|
||
+ uart4_pins_b: uart4-1 {
|
||
pins1 {
|
||
- pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
|
||
- <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
|
||
- <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
|
||
- <STM32_PINMUX('D', 7, AF10)>; /* SDMMC3_D3 */
|
||
- slew-rate = <1>;
|
||
+ pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
|
||
+ bias-disable;
|
||
drive-push-pull;
|
||
- bias-pull-up;
|
||
+ slew-rate = <0>;
|
||
};
|
||
pins2 {
|
||
- pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
|
||
- slew-rate = <2>;
|
||
- drive-push-pull;
|
||
- bias-pull-up;
|
||
- };
|
||
- pins3 {
|
||
- pinmux = <STM32_PINMUX('F', 1, AF9)>; /* SDMMC2_CMD */
|
||
- slew-rate = <1>;
|
||
- drive-open-drain;
|
||
- bias-pull-up;
|
||
+ pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
|
||
+ bias-disable;
|
||
};
|
||
};
|
||
|
||
- sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC3_D0 */
|
||
- <STM32_PINMUX('F', 4, ANALOG)>, /* SDMMC3_D1 */
|
||
- <STM32_PINMUX('F', 5, ANALOG)>, /* SDMMC3_D2 */
|
||
- <STM32_PINMUX('D', 7, ANALOG)>, /* SDMMC3_D3 */
|
||
- <STM32_PINMUX('G', 15, ANALOG)>, /* SDMMC3_CK */
|
||
- <STM32_PINMUX('F', 1, ANALOG)>; /* SDMMC3_CMD */
|
||
+ uart7_pins_a: uart7-0 {
|
||
+ pins1 {
|
||
+ pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
|
||
+ bias-disable;
|
||
+ drive-push-pull;
|
||
+ slew-rate = <0>;
|
||
};
|
||
- };
|
||
-
|
||
- spdifrx_pins_a: spdifrx-0 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('G', 12, AF8)>; /* SPDIF_IN1 */
|
||
+ pins2 {
|
||
+ pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART4_RX */
|
||
+ <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
|
||
+ <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
|
||
bias-disable;
|
||
};
|
||
};
|
||
|
||
- spdifrx_sleep_pins_a: spdifrx-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('G', 12, ANALOG)>; /* SPDIF_IN1 */
|
||
+ uart7_pins_b: uart7-1 {
|
||
+ pins1 {
|
||
+ pinmux = <STM32_PINMUX('E', 8, AF7)>; /* USART7_TX */
|
||
+ bias-disable;
|
||
+ drive-push-pull;
|
||
+ slew-rate = <0>;
|
||
+ };
|
||
+ pins2 {
|
||
+ pinmux = <STM32_PINMUX('E', 7, AF7)>; /* USART7_RX */
|
||
+ bias-disable;
|
||
};
|
||
};
|
||
|
||
- uart4_pins_a: uart4-0 {
|
||
+ usart2_pins_a: usart2-0 {
|
||
pins1 {
|
||
- pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
|
||
+ pinmux = <STM32_PINMUX('D', 5, AF7)>, /* USART2_TX */
|
||
+ <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
|
||
bias-disable;
|
||
drive-push-pull;
|
||
- slew-rate = <0>;
|
||
+ slew-rate = <3>;
|
||
};
|
||
pins2 {
|
||
- pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
|
||
+ pinmux = <STM32_PINMUX('D', 6, AF7)>, /* USART2_RX */
|
||
+ <STM32_PINMUX('D', 3, AF7)>; /* USART2_CTS_NSS */
|
||
bias-disable;
|
||
};
|
||
};
|
||
|
||
- uart4_pins_b: uart4-1 {
|
||
+ usart3_pins_a: usart3-0 {
|
||
pins1 {
|
||
- pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
|
||
+ 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('B', 2, AF8)>; /* UART4_RX */
|
||
+ pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
|
||
+ <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
|
||
bias-disable;
|
||
};
|
||
};
|
||
|
||
- uart7_pins_a: uart7-0 {
|
||
+ usart3_pins_b: usart3-1 {
|
||
pins1 {
|
||
- pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
|
||
+ 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('E', 7, AF7)>, /* UART4_RX */
|
||
- <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
|
||
- <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
|
||
+ pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
|
||
+ <STM32_PINMUX('B', 13, AF7)>; /* USART3_CTS_NSS */
|
||
bias-disable;
|
||
};
|
||
};
|
||
-};
|
||
|
||
-&pinctrl_z {
|
||
- i2c2_pins_b2: i2c2-0 {
|
||
+ usbotg_hs_pins_a: usbotg_hs-0 {
|
||
pins {
|
||
- pinmux = <STM32_PINMUX('Z', 0, AF3)>; /* I2C2_SCL */
|
||
- bias-disable;
|
||
- drive-open-drain;
|
||
- slew-rate = <0>;
|
||
+ pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
|
||
};
|
||
};
|
||
|
||
- i2c2_pins_sleep_b2: i2c2-1 {
|
||
+ usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 {
|
||
pins {
|
||
- pinmux = <STM32_PINMUX('Z', 0, ANALOG)>; /* I2C2_SCL */
|
||
+ pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* OTG_FS_DM */
|
||
+ <STM32_PINMUX('A', 12, ANALOG)>; /* OTG_FS_DP */
|
||
};
|
||
};
|
||
+};
|
||
|
||
+&pinctrl_z {
|
||
i2c4_pins_a: i2c4-0 {
|
||
pins {
|
||
pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
|
||
@@ -1067,26 +289,4 @@
|
||
slew-rate = <0>;
|
||
};
|
||
};
|
||
-
|
||
- i2c4_pins_sleep_a: i2c4-1 {
|
||
- pins {
|
||
- pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
|
||
- <STM32_PINMUX('Z', 5, ANALOG)>; /* I2C4_SDA */
|
||
- };
|
||
- };
|
||
-
|
||
- spi1_pins_a: spi1-0 {
|
||
- pins1 {
|
||
- pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
|
||
- <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
|
||
- bias-disable;
|
||
- drive-push-pull;
|
||
- slew-rate = <1>;
|
||
- };
|
||
-
|
||
- pins2 {
|
||
- pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
|
||
- bias-disable;
|
||
- };
|
||
- };
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp151.dtsi b/core/arch/arm/dts/stm32mp151.dtsi
|
||
index d8ac702..6e6dff4 100644
|
||
--- a/core/arch/arm/dts/stm32mp151.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp151.dtsi
|
||
@@ -19,9 +19,39 @@
|
||
compatible = "arm,cortex-a7";
|
||
device_type = "cpu";
|
||
reg = <0>;
|
||
+ clocks = <&rcc CK_MPU>;
|
||
+ clock-names = "cpu";
|
||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||
+ nvmem-cells = <&part_number_otp>;
|
||
+ nvmem-cell-names = "part_number";
|
||
};
|
||
};
|
||
|
||
+ cpu0_opp_table: cpu0-opp-table {
|
||
+ compatible = "operating-points-v2";
|
||
+ opp-shared;
|
||
+ };
|
||
+
|
||
+ nvmem_layout: nvmem_layout@0 {
|
||
+ compatible = "st,stm32-nvmem-layout";
|
||
+
|
||
+ nvmem-cells = <&cfg0_otp>,
|
||
+ <&part_number_otp>,
|
||
+ <&monotonic_otp>,
|
||
+ <&nand_otp>,
|
||
+ <&uid_otp>,
|
||
+ <&package_otp>,
|
||
+ <&hw2_otp>;
|
||
+
|
||
+ nvmem-cell-names = "cfg0_otp",
|
||
+ "part_number_otp",
|
||
+ "monotonic_otp",
|
||
+ "nand_otp",
|
||
+ "uid_otp",
|
||
+ "package_otp",
|
||
+ "hw2_otp";
|
||
+ };
|
||
+
|
||
psci {
|
||
compatible = "arm,psci-1.0";
|
||
method = "smc";
|
||
@@ -35,15 +65,6 @@
|
||
<0xa0022000 0x2000>;
|
||
};
|
||
|
||
- 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)>;
|
||
- interrupt-parent = <&intc>;
|
||
- };
|
||
-
|
||
clocks {
|
||
clk_hse: clk-hse {
|
||
#clock-cells = <0>;
|
||
@@ -76,37 +97,6 @@
|
||
};
|
||
};
|
||
|
||
- thermal-zones {
|
||
- cpu_thermal: cpu-thermal {
|
||
- polling-delay-passive = <0>;
|
||
- polling-delay = <0>;
|
||
- thermal-sensors = <&dts>;
|
||
-
|
||
- trips {
|
||
- cpu_alert1: cpu-alert1 {
|
||
- temperature = <85000>;
|
||
- hysteresis = <0>;
|
||
- type = "passive";
|
||
- };
|
||
-
|
||
- cpu-crit {
|
||
- temperature = <120000>;
|
||
- hysteresis = <0>;
|
||
- type = "critical";
|
||
- };
|
||
- };
|
||
-
|
||
- cooling-maps {
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- booster: regulator-booster {
|
||
- compatible = "st,stm32mp1-booster";
|
||
- st,syscfg = <&syscfg>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
soc {
|
||
compatible = "simple-bus";
|
||
#address-cells = <1>;
|
||
@@ -114,175 +104,6 @@
|
||
interrupt-parent = <&intc>;
|
||
ranges;
|
||
|
||
- timers2: timer@40000000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40000000 0x400>;
|
||
- clocks = <&rcc TIM2_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 18 0x400 0x1>,
|
||
- <&dmamux1 19 0x400 0x1>,
|
||
- <&dmamux1 20 0x400 0x1>,
|
||
- <&dmamux1 21 0x400 0x1>,
|
||
- <&dmamux1 22 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4", "up";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@1 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <1>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers3: timer@40001000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40001000 0x400>;
|
||
- clocks = <&rcc TIM3_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 23 0x400 0x1>,
|
||
- <&dmamux1 24 0x400 0x1>,
|
||
- <&dmamux1 25 0x400 0x1>,
|
||
- <&dmamux1 26 0x400 0x1>,
|
||
- <&dmamux1 27 0x400 0x1>,
|
||
- <&dmamux1 28 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@2 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <2>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers4: timer@40002000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40002000 0x400>;
|
||
- clocks = <&rcc TIM4_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 29 0x400 0x1>,
|
||
- <&dmamux1 30 0x400 0x1>,
|
||
- <&dmamux1 31 0x400 0x1>,
|
||
- <&dmamux1 32 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@3 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers5: timer@40003000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40003000 0x400>;
|
||
- clocks = <&rcc TIM5_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 55 0x400 0x1>,
|
||
- <&dmamux1 56 0x400 0x1>,
|
||
- <&dmamux1 57 0x400 0x1>,
|
||
- <&dmamux1 58 0x400 0x1>,
|
||
- <&dmamux1 59 0x400 0x1>,
|
||
- <&dmamux1 60 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@4 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <4>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers6: timer@40004000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40004000 0x400>;
|
||
- clocks = <&rcc TIM6_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 69 0x400 0x1>;
|
||
- dma-names = "up";
|
||
- status = "disabled";
|
||
-
|
||
- timer@5 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <5>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers7: timer@40005000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40005000 0x400>;
|
||
- clocks = <&rcc TIM7_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 70 0x400 0x1>;
|
||
- dma-names = "up";
|
||
- status = "disabled";
|
||
-
|
||
- timer@6 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <6>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
timers12: timer@40006000 {
|
||
#address-cells = <1>;
|
||
#size-cells = <0>;
|
||
@@ -291,152 +112,7 @@
|
||
clocks = <&rcc TIM12_K>;
|
||
clock-names = "int";
|
||
status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@11 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <11>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers13: timer@40007000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40007000 0x400>;
|
||
- clocks = <&rcc TIM13_K>;
|
||
- clock-names = "int";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@12 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <12>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers14: timer@40008000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x40008000 0x400>;
|
||
- clocks = <&rcc TIM14_K>;
|
||
- clock-names = "int";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@13 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <13>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- lptimer1: timer@40009000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-lptimer";
|
||
- reg = <0x40009000 0x400>;
|
||
- clocks = <&rcc LPTIM1_K>;
|
||
- clock-names = "mux";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm-lp";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- trigger@0 {
|
||
- compatible = "st,stm32-lptimer-trigger";
|
||
- reg = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-lptimer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- spi2: spi@4000b000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32h7-spi";
|
||
- reg = <0x4000b000 0x400>;
|
||
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc SPI2_K>;
|
||
- resets = <&rcc SPI2_R>;
|
||
- dmas = <&dmamux1 39 0x400 0x05>,
|
||
- <&dmamux1 40 0x400 0x05>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2s2: audio-controller@4000b000 {
|
||
- compatible = "st,stm32h7-i2s";
|
||
- #sound-dai-cells = <0>;
|
||
- reg = <0x4000b000 0x400>;
|
||
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 39 0x400 0x01>,
|
||
- <&dmamux1 40 0x400 0x01>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- spi3: spi@4000c000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32h7-spi";
|
||
- reg = <0x4000c000 0x400>;
|
||
- interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc SPI3_K>;
|
||
- resets = <&rcc SPI3_R>;
|
||
- dmas = <&dmamux1 61 0x400 0x05>,
|
||
- <&dmamux1 62 0x400 0x05>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2s3: audio-controller@4000c000 {
|
||
- compatible = "st,stm32h7-i2s";
|
||
- #sound-dai-cells = <0>;
|
||
- reg = <0x4000c000 0x400>;
|
||
- interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 61 0x400 0x01>,
|
||
- <&dmamux1 62 0x400 0x01>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- spdifrx: audio-controller@4000d000 {
|
||
- compatible = "st,stm32h7-spdifrx";
|
||
- #sound-dai-cells = <0>;
|
||
- reg = <0x4000d000 0x400>;
|
||
- clocks = <&rcc SPDIF_K>;
|
||
- clock-names = "kclk";
|
||
- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 93 0x400 0x01>,
|
||
- <&dmamux1 94 0x400 0x01>;
|
||
- dma-names = "rx", "rx-ctrl";
|
||
- status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
usart2: serial@4000e000 {
|
||
@@ -444,6 +120,7 @@
|
||
reg = <0x4000e000 0x400>;
|
||
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc USART2_K>;
|
||
+ resets = <&rcc USART2_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
@@ -452,14 +129,17 @@
|
||
reg = <0x4000f000 0x400>;
|
||
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc USART3_K>;
|
||
+ resets = <&rcc USART3_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
uart4: serial@40010000 {
|
||
compatible = "st,stm32h7-uart";
|
||
reg = <0x40010000 0x400>;
|
||
- interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc UART4_K>;
|
||
+ resets = <&rcc UART4_R>;
|
||
+ wakeup-source;
|
||
status = "disabled";
|
||
};
|
||
|
||
@@ -468,99 +148,16 @@
|
||
reg = <0x40011000 0x400>;
|
||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc UART5_K>;
|
||
+ resets = <&rcc UART5_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
- i2c1: i2c@40012000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
- reg = <0x40012000 0x400>;
|
||
- interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc I2C1_K>;
|
||
- resets = <&rcc I2C1_R>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2c2: i2c@40013000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
- reg = <0x40013000 0x400>;
|
||
- interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc I2C2_K>;
|
||
- resets = <&rcc I2C2_R>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2c3: i2c@40014000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
- reg = <0x40014000 0x400>;
|
||
- interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc I2C3_K>;
|
||
- resets = <&rcc I2C3_R>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2c5: i2c@40015000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
- reg = <0x40015000 0x400>;
|
||
- interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc I2C5_K>;
|
||
- resets = <&rcc I2C5_R>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- cec: cec@40016000 {
|
||
- compatible = "st,stm32-cec";
|
||
- reg = <0x40016000 0x400>;
|
||
- interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc CEC_K>, <&clk_lse>;
|
||
- clock-names = "cec", "hdmi-cec";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dac: dac@40017000 {
|
||
- compatible = "st,stm32h7-dac-core";
|
||
- reg = <0x40017000 0x400>;
|
||
- clocks = <&rcc DAC12>;
|
||
- clock-names = "pclk";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
-
|
||
- dac1: dac@1 {
|
||
- compatible = "st,stm32-dac";
|
||
- #io-channels-cells = <1>;
|
||
- reg = <1>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dac2: dac@2 {
|
||
- compatible = "st,stm32-dac";
|
||
- #io-channels-cells = <1>;
|
||
- reg = <2>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
uart7: serial@40018000 {
|
||
compatible = "st,stm32h7-uart";
|
||
reg = <0x40018000 0x400>;
|
||
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc UART7_K>;
|
||
+ resets = <&rcc UART7_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
@@ -569,125 +166,16 @@
|
||
reg = <0x40019000 0x400>;
|
||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc UART8_K>;
|
||
+ resets = <&rcc UART8_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
- timers1: timer@44000000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x44000000 0x400>;
|
||
- clocks = <&rcc TIM1_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 11 0x400 0x1>,
|
||
- <&dmamux1 12 0x400 0x1>,
|
||
- <&dmamux1 13 0x400 0x1>,
|
||
- <&dmamux1 14 0x400 0x1>,
|
||
- <&dmamux1 15 0x400 0x1>,
|
||
- <&dmamux1 16 0x400 0x1>,
|
||
- <&dmamux1 17 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4",
|
||
- "up", "trig", "com";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@0 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers8: timer@44001000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x44001000 0x400>;
|
||
- clocks = <&rcc TIM8_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 47 0x400 0x1>,
|
||
- <&dmamux1 48 0x400 0x1>,
|
||
- <&dmamux1 49 0x400 0x1>,
|
||
- <&dmamux1 50 0x400 0x1>,
|
||
- <&dmamux1 51 0x400 0x1>,
|
||
- <&dmamux1 52 0x400 0x1>,
|
||
- <&dmamux1 53 0x400 0x1>;
|
||
- dma-names = "ch1", "ch2", "ch3", "ch4",
|
||
- "up", "trig", "com";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@7 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <7>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-timer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
usart6: serial@44003000 {
|
||
compatible = "st,stm32h7-uart";
|
||
reg = <0x44003000 0x400>;
|
||
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc USART6_K>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- spi1: spi@44004000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32h7-spi";
|
||
- reg = <0x44004000 0x400>;
|
||
- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc SPI1_K>;
|
||
- resets = <&rcc SPI1_R>;
|
||
- dmas = <&dmamux1 37 0x400 0x05>,
|
||
- <&dmamux1 38 0x400 0x05>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- i2s1: audio-controller@44004000 {
|
||
- compatible = "st,stm32h7-i2s";
|
||
- #sound-dai-cells = <0>;
|
||
- reg = <0x44004000 0x400>;
|
||
- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 37 0x400 0x01>,
|
||
- <&dmamux1 38 0x400 0x01>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- spi4: spi@44005000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32h7-spi";
|
||
- reg = <0x44005000 0x400>;
|
||
- interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc SPI4_K>;
|
||
- resets = <&rcc SPI4_R>;
|
||
- dmas = <&dmamux1 83 0x400 0x05>,
|
||
- <&dmamux1 84 0x400 0x05>;
|
||
- dma-names = "rx", "tx";
|
||
+ resets = <&rcc USART6_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
@@ -698,401 +186,42 @@
|
||
reg = <0x44006000 0x400>;
|
||
clocks = <&rcc TIM15_K>;
|
||
clock-names = "int";
|
||
- dmas = <&dmamux1 105 0x400 0x1>,
|
||
- <&dmamux1 106 0x400 0x1>,
|
||
- <&dmamux1 107 0x400 0x1>,
|
||
- <&dmamux1 108 0x400 0x1>;
|
||
- dma-names = "ch1", "up", "trig", "com";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@14 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <14>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers16: timer@44007000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x44007000 0x400>;
|
||
- clocks = <&rcc TIM16_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 109 0x400 0x1>,
|
||
- <&dmamux1 110 0x400 0x1>;
|
||
- dma-names = "ch1", "up";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
- timer@15 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <15>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- timers17: timer@44008000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-timers";
|
||
- reg = <0x44008000 0x400>;
|
||
- clocks = <&rcc TIM17_K>;
|
||
- clock-names = "int";
|
||
- dmas = <&dmamux1 111 0x400 0x1>,
|
||
- <&dmamux1 112 0x400 0x1>;
|
||
- dma-names = "ch1", "up";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- timer@16 {
|
||
- compatible = "st,stm32h7-timer-trigger";
|
||
- reg = <16>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- spi5: spi@44009000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32h7-spi";
|
||
- reg = <0x44009000 0x400>;
|
||
- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc SPI5_K>;
|
||
- resets = <&rcc SPI5_R>;
|
||
- dmas = <&dmamux1 85 0x400 0x05>,
|
||
- <&dmamux1 86 0x400 0x05>;
|
||
- dma-names = "rx", "tx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai1: sai@4400a000 {
|
||
- compatible = "st,stm32h7-sai";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges = <0 0x4400a000 0x400>;
|
||
- reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
|
||
- interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
|
||
- resets = <&rcc SAI1_R>;
|
||
- status = "disabled";
|
||
-
|
||
- sai1a: audio-controller@4400a004 {
|
||
- #sound-dai-cells = <0>;
|
||
-
|
||
- compatible = "st,stm32-sai-sub-a";
|
||
- reg = <0x4 0x1c>;
|
||
- clocks = <&rcc SAI1_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 87 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai1b: audio-controller@4400a024 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-b";
|
||
- reg = <0x24 0x1c>;
|
||
- clocks = <&rcc SAI1_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 88 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- sai2: sai@4400b000 {
|
||
- compatible = "st,stm32h7-sai";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges = <0 0x4400b000 0x400>;
|
||
- reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
|
||
- interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
|
||
- resets = <&rcc SAI2_R>;
|
||
- status = "disabled";
|
||
-
|
||
- sai2a: audio-controller@4400b004 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-a";
|
||
- reg = <0x4 0x1c>;
|
||
- clocks = <&rcc SAI2_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 89 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai2b: audio-controller@4400b024 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-b";
|
||
- reg = <0x24 0x1c>;
|
||
- clocks = <&rcc SAI2_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 90 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- sai3: sai@4400c000 {
|
||
- compatible = "st,stm32h7-sai";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges = <0 0x4400c000 0x400>;
|
||
- reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
|
||
- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||
- resets = <&rcc SAI3_R>;
|
||
- status = "disabled";
|
||
-
|
||
- sai3a: audio-controller@4400c004 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-a";
|
||
- reg = <0x04 0x1c>;
|
||
- clocks = <&rcc SAI3_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 113 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai3b: audio-controller@4400c024 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-b";
|
||
- reg = <0x24 0x1c>;
|
||
- clocks = <&rcc SAI3_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 114 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- dfsdm: dfsdm@4400d000 {
|
||
- compatible = "st,stm32mp1-dfsdm";
|
||
- reg = <0x4400d000 0x800>;
|
||
- clocks = <&rcc DFSDM_K>;
|
||
- clock-names = "dfsdm";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
-
|
||
- dfsdm0: filter@0 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <0>;
|
||
- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 101 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dfsdm1: filter@1 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <1>;
|
||
- interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 102 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dfsdm2: filter@2 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <2>;
|
||
- interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 103 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dfsdm3: filter@3 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <3>;
|
||
- interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 104 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dfsdm4: filter@4 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <4>;
|
||
- interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 91 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dfsdm5: filter@5 {
|
||
- compatible = "st,stm32-dfsdm-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <5>;
|
||
- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&dmamux1 92 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- dma1: dma-controller@48000000 {
|
||
- compatible = "st,stm32-dma";
|
||
- reg = <0x48000000 0x400>;
|
||
- interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc DMA1>;
|
||
- #dma-cells = <4>;
|
||
- st,mem2mem;
|
||
- dma-requests = <8>;
|
||
- };
|
||
-
|
||
- dma2: dma-controller@48001000 {
|
||
- compatible = "st,stm32-dma";
|
||
- reg = <0x48001000 0x400>;
|
||
- interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc DMA2>;
|
||
- #dma-cells = <4>;
|
||
- st,mem2mem;
|
||
- dma-requests = <8>;
|
||
- };
|
||
-
|
||
- dmamux1: dma-router@48002000 {
|
||
- compatible = "st,stm32h7-dmamux";
|
||
- reg = <0x48002000 0x1c>;
|
||
- #dma-cells = <3>;
|
||
- dma-requests = <128>;
|
||
- dma-masters = <&dma1 &dma2>;
|
||
- dma-channels = <16>;
|
||
- clocks = <&rcc DMAMUX>;
|
||
- };
|
||
-
|
||
- adc: adc@48003000 {
|
||
- compatible = "st,stm32mp1-adc-core";
|
||
- reg = <0x48003000 0x400>;
|
||
- interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc ADC12>, <&rcc ADC12_K>;
|
||
- clock-names = "bus", "adc";
|
||
- interrupt-controller;
|
||
- st,syscfg = <&syscfg>;
|
||
- #interrupt-cells = <1>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "disabled";
|
||
-
|
||
- adc1: adc@0 {
|
||
- compatible = "st,stm32mp1-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <0x0>;
|
||
- interrupt-parent = <&adc>;
|
||
- interrupts = <0>;
|
||
- dmas = <&dmamux1 9 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- adc2: adc@100 {
|
||
- compatible = "st,stm32mp1-adc";
|
||
- #io-channel-cells = <1>;
|
||
- reg = <0x100>;
|
||
- interrupt-parent = <&adc>;
|
||
- interrupts = <1>;
|
||
- dmas = <&dmamux1 10 0x400 0x01>;
|
||
- dma-names = "rx";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- sdmmc3: sdmmc@48004000 {
|
||
- compatible = "arm,pl18x", "arm,primecell";
|
||
- arm,primecell-periphid = <0x10153180>;
|
||
- reg = <0x48004000 0x400>;
|
||
- interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
|
||
- interrupt-names = "cmd_irq";
|
||
- clocks = <&rcc SDMMC3_K>;
|
||
- clock-names = "apb_pclk";
|
||
- resets = <&rcc SDMMC3_R>;
|
||
- cap-sd-highspeed;
|
||
- cap-mmc-highspeed;
|
||
- max-frequency = <120000000>;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
usbotg_hs: usb-otg@49000000 {
|
||
- compatible = "snps,dwc2";
|
||
+ compatible = "st,stm32mp1-hsotg", "snps,dwc2";
|
||
reg = <0x49000000 0x10000>;
|
||
clocks = <&rcc USBO_K>;
|
||
clock-names = "otg";
|
||
resets = <&rcc USBO_R>;
|
||
reset-names = "dwc2";
|
||
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
|
||
- g-rx-fifo-size = <256>;
|
||
+ g-rx-fifo-size = <512>;
|
||
g-np-tx-fifo-size = <32>;
|
||
- g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
|
||
+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
|
||
dr_mode = "otg";
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- ipcc: mailbox@4c001000 {
|
||
- compatible = "st,stm32mp1-ipcc";
|
||
- #mbox-cells = <1>;
|
||
- reg = <0x4c001000 0x400>;
|
||
- st,proc-id = <0>;
|
||
- interrupts-extended =
|
||
- <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <&exti 61 1>;
|
||
- interrupt-names = "rx", "tx", "wakeup";
|
||
- clocks = <&rcc IPCC>;
|
||
- wakeup-source;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dcmi: dcmi@4c006000 {
|
||
- compatible = "st,stm32-dcmi";
|
||
- reg = <0x4c006000 0x400>;
|
||
- interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
|
||
- resets = <&rcc CAMITF_R>;
|
||
- clocks = <&rcc DCMI>;
|
||
- clock-names = "mclk";
|
||
- dmas = <&dmamux1 75 0x400 0x0d>;
|
||
- dma-names = "tx";
|
||
+ usb33d-supply = <&usb33>;
|
||
status = "disabled";
|
||
};
|
||
|
||
rcc: rcc@50000000 {
|
||
compatible = "st,stm32mp1-rcc", "syscon";
|
||
reg = <0x50000000 0x1000>;
|
||
+ #address-cells = <1>;
|
||
+ #size-cells = <0>;
|
||
#clock-cells = <1>;
|
||
#reset-cells = <1>;
|
||
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ secure-interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ secure-interrupt-names = "wakeup";
|
||
};
|
||
|
||
pwr_regulators: pwr@50001000 {
|
||
compatible = "st,stm32mp1,pwr-reg";
|
||
reg = <0x50001000 0x10>;
|
||
+ st,tzcr = <&rcc 0x0 0x1>;
|
||
|
||
reg11: reg11 {
|
||
regulator-name = "reg11";
|
||
@@ -1113,11 +242,35 @@
|
||
};
|
||
};
|
||
|
||
+ pwr_mcu: pwr_mcu@50001014 {
|
||
+ compatible = "syscon";
|
||
+ reg = <0x50001014 0x4>;
|
||
+ };
|
||
+
|
||
+ pwr_irq: pwr@50001020 {
|
||
+ compatible = "st,stm32mp1-pwr";
|
||
+ reg = <0x50001020 0x100>;
|
||
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ interrupt-controller;
|
||
+ #interrupt-cells = <3>;
|
||
+ };
|
||
+
|
||
exti: interrupt-controller@5000d000 {
|
||
compatible = "st,stm32mp1-exti", "syscon";
|
||
interrupt-controller;
|
||
#interrupt-cells = <2>;
|
||
reg = <0x5000d000 0x400>;
|
||
+
|
||
+ /* exti_pwr is an extra interrupt controller used for
|
||
+ * EXTI 55 to 60. It's mapped on pwr interrupt
|
||
+ * controller.
|
||
+ */
|
||
+ exti_pwr: exti-pwr {
|
||
+ interrupt-controller;
|
||
+ #interrupt-cells = <2>;
|
||
+ interrupt-parent = <&pwr_irq>;
|
||
+ st,irq-number = <6>;
|
||
+ };
|
||
};
|
||
|
||
syscfg: syscon@50020000 {
|
||
@@ -1126,143 +279,14 @@
|
||
clocks = <&rcc SYSCFG>;
|
||
};
|
||
|
||
- lptimer2: timer@50021000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-lptimer";
|
||
- reg = <0x50021000 0x400>;
|
||
- clocks = <&rcc LPTIM2_K>;
|
||
- clock-names = "mux";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm-lp";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- trigger@1 {
|
||
- compatible = "st,stm32-lptimer-trigger";
|
||
- reg = <1>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- counter {
|
||
- compatible = "st,stm32-lptimer-counter";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- lptimer3: timer@50022000 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "st,stm32-lptimer";
|
||
- reg = <0x50022000 0x400>;
|
||
- clocks = <&rcc LPTIM3_K>;
|
||
- clock-names = "mux";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm-lp";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- trigger@2 {
|
||
- compatible = "st,stm32-lptimer-trigger";
|
||
- reg = <2>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- lptimer4: timer@50023000 {
|
||
- compatible = "st,stm32-lptimer";
|
||
- reg = <0x50023000 0x400>;
|
||
- clocks = <&rcc LPTIM4_K>;
|
||
- clock-names = "mux";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm-lp";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- lptimer5: timer@50024000 {
|
||
- compatible = "st,stm32-lptimer";
|
||
- reg = <0x50024000 0x400>;
|
||
- clocks = <&rcc LPTIM5_K>;
|
||
- clock-names = "mux";
|
||
- status = "disabled";
|
||
-
|
||
- pwm {
|
||
- compatible = "st,stm32-pwm-lp";
|
||
- #pwm-cells = <3>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- vrefbuf: vrefbuf@50025000 {
|
||
- compatible = "st,stm32-vrefbuf";
|
||
- reg = <0x50025000 0x8>;
|
||
- regulator-min-microvolt = <1500000>;
|
||
- regulator-max-microvolt = <2500000>;
|
||
- clocks = <&rcc VREF>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai4: sai@50027000 {
|
||
- compatible = "st,stm32h7-sai";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges = <0 0x50027000 0x400>;
|
||
- reg = <0x50027000 0x4>, <0x500273f0 0x10>;
|
||
- interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
|
||
- resets = <&rcc SAI4_R>;
|
||
- status = "disabled";
|
||
-
|
||
- sai4a: audio-controller@50027004 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-a";
|
||
- reg = <0x04 0x1c>;
|
||
- clocks = <&rcc SAI4_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 99 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- sai4b: audio-controller@50027024 {
|
||
- #sound-dai-cells = <0>;
|
||
- compatible = "st,stm32-sai-sub-b";
|
||
- reg = <0x24 0x1c>;
|
||
- clocks = <&rcc SAI4_K>;
|
||
- clock-names = "sai_ck";
|
||
- dmas = <&dmamux1 100 0x400 0x01>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-
|
||
- dts: thermal@50028000 {
|
||
- compatible = "st,stm32-thermal";
|
||
- reg = <0x50028000 0x100>;
|
||
- interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc TMPSENS>;
|
||
- clock-names = "pclk";
|
||
- #thermal-sensor-cells = <0>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
hash1: hash@54002000 {
|
||
compatible = "st,stm32f756-hash";
|
||
reg = <0x54002000 0x400>;
|
||
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc HASH1>;
|
||
resets = <&rcc HASH1_R>;
|
||
- dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>;
|
||
- dma-names = "in";
|
||
- dma-maxburst = <2>;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
rng1: rng@54003000 {
|
||
@@ -1271,16 +295,7 @@
|
||
clocks = <&rcc RNG1_K>;
|
||
resets = <&rcc RNG1_R>;
|
||
status = "disabled";
|
||
- };
|
||
-
|
||
- mdma1: dma-controller@58000000 {
|
||
- compatible = "st,stm32h7-mdma";
|
||
- reg = <0x58000000 0x1000>;
|
||
- interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc MDMA>;
|
||
- #dma-cells = <5>;
|
||
- dma-channels = <32>;
|
||
- dma-requests = <48>;
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
fmc: nand-controller@58002000 {
|
||
@@ -1293,10 +308,6 @@
|
||
<0x89010000 0x1000>,
|
||
<0x89020000 0x1000>;
|
||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>,
|
||
- <&mdma1 20 0x10 0x12000a08 0x0 0x0>,
|
||
- <&mdma1 21 0x10 0x12000a0a 0x0 0x0>;
|
||
- dma-names = "tx", "rx", "ecc";
|
||
clocks = <&rcc FMC_K>;
|
||
resets = <&rcc FMC_R>;
|
||
status = "disabled";
|
||
@@ -1307,18 +318,15 @@
|
||
reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
|
||
reg-names = "qspi", "qspi_mm";
|
||
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
|
||
- dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>,
|
||
- <&mdma1 22 0x10 0x100008 0x0 0x0>;
|
||
- dma-names = "tx", "rx";
|
||
clocks = <&rcc QSPI_K>;
|
||
resets = <&rcc QSPI_R>;
|
||
status = "disabled";
|
||
};
|
||
|
||
sdmmc1: sdmmc@58005000 {
|
||
- compatible = "arm,pl18x", "arm,primecell";
|
||
- arm,primecell-periphid = <0x10153180>;
|
||
- reg = <0x58005000 0x1000>;
|
||
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
|
||
+ arm,primecell-periphid = <0x00253180>;
|
||
+ reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
|
||
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
|
||
interrupt-names = "cmd_irq";
|
||
clocks = <&rcc SDMMC1_K>;
|
||
@@ -1331,9 +339,9 @@
|
||
};
|
||
|
||
sdmmc2: sdmmc@58007000 {
|
||
- compatible = "arm,pl18x", "arm,primecell";
|
||
- arm,primecell-periphid = <0x10153180>;
|
||
- reg = <0x58007000 0x1000>;
|
||
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
|
||
+ arm,primecell-periphid = <0x00253180>;
|
||
+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
|
||
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
|
||
interrupt-names = "cmd_irq";
|
||
clocks = <&rcc SDMMC2_K>;
|
||
@@ -1345,87 +353,26 @@
|
||
status = "disabled";
|
||
};
|
||
|
||
- crc1: crc@58009000 {
|
||
- compatible = "st,stm32f7-crc";
|
||
- reg = <0x58009000 0x400>;
|
||
- clocks = <&rcc CRC1>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- stmmac_axi_config_0: stmmac-axi-config {
|
||
- snps,wr_osr_lmt = <0x7>;
|
||
- snps,rd_osr_lmt = <0x7>;
|
||
- snps,blen = <0 0 0 0 16 8 4>;
|
||
- };
|
||
-
|
||
- ethernet0: ethernet@5800a000 {
|
||
- compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
|
||
- reg = <0x5800a000 0x2000>;
|
||
- reg-names = "stmmaceth";
|
||
- interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
|
||
- interrupt-names = "macirq";
|
||
- clock-names = "stmmaceth",
|
||
- "mac-clk-tx",
|
||
- "mac-clk-rx",
|
||
- "ethstp";
|
||
- clocks = <&rcc ETHMAC>,
|
||
- <&rcc ETHTX>,
|
||
- <&rcc ETHRX>,
|
||
- <&rcc ETHSTP>;
|
||
- st,syscon = <&syscfg 0x4>;
|
||
- snps,mixed-burst;
|
||
- snps,pbl = <2>;
|
||
- snps,en-tx-lpi-clockgating;
|
||
- snps,axi-config = <&stmmac_axi_config_0>;
|
||
- snps,tso;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- usbh_ohci: usbh-ohci@5800c000 {
|
||
- compatible = "generic-ohci";
|
||
- reg = <0x5800c000 0x1000>;
|
||
- clocks = <&rcc USBH>;
|
||
- resets = <&rcc USBH_R>;
|
||
- interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- usbh_ehci: usbh-ehci@5800d000 {
|
||
- compatible = "generic-ehci";
|
||
- reg = <0x5800d000 0x1000>;
|
||
- clocks = <&rcc USBH>;
|
||
- resets = <&rcc USBH_R>;
|
||
- interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
|
||
- companion = <&usbh_ohci>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- ltdc: display-controller@5a001000 {
|
||
- compatible = "st,stm32-ltdc";
|
||
- reg = <0x5a001000 0x400>;
|
||
- interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc LTDC_PX>;
|
||
- clock-names = "lcd";
|
||
- resets = <&rcc LTDC_R>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
iwdg2: watchdog@5a002000 {
|
||
compatible = "st,stm32mp1-iwdg";
|
||
reg = <0x5a002000 0x400>;
|
||
+ secure-interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
|
||
clock-names = "pclk", "lsi";
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
usbphyc: usbphyc@5a006000 {
|
||
#address-cells = <1>;
|
||
#size-cells = <0>;
|
||
+ #clock-cells = <0>;
|
||
compatible = "st,stm32mp1-usbphyc";
|
||
reg = <0x5a006000 0x1000>;
|
||
clocks = <&rcc USBPHY_K>;
|
||
resets = <&rcc USBPHY_R>;
|
||
+ vdda1v1-supply = <®11>;
|
||
+ vdda1v8-supply = <®18>;
|
||
status = "disabled";
|
||
|
||
usbphyc_port0: usb-phy@0 {
|
||
@@ -1446,6 +393,7 @@
|
||
clocks = <&rcc USART1_K>;
|
||
resets = <&rcc USART1_R>;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
spi6: spi@5c001000 {
|
||
@@ -1456,22 +404,34 @@
|
||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc SPI6_K>;
|
||
resets = <&rcc SPI6_R>;
|
||
- dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
|
||
- <&mdma1 35 0x0 0x40002 0x0 0x0>;
|
||
- dma-names = "rx", "tx";
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
i2c4: i2c@5c002000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
+ compatible = "st,stm32mp15-i2c";
|
||
reg = <0x5c002000 0x400>;
|
||
interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>,
|
||
+ <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc I2C4_K>;
|
||
resets = <&rcc I2C4_R>;
|
||
#address-cells = <1>;
|
||
#size-cells = <0>;
|
||
+ st,syscfg-fmp = <&syscfg 0x4 0x8>;
|
||
+ wakeup-source;
|
||
+ status = "disabled";
|
||
+ secure-status = "disabled";
|
||
+ };
|
||
+
|
||
+ iwdg1: watchdog@5c003000 {
|
||
+ compatible = "st,stm32mp1-iwdg";
|
||
+ reg = <0x5C003000 0x400>;
|
||
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ clocks = <&rcc IWDG1>, <&rcc CK_LSI>;
|
||
+ clock-names = "pclk", "lsi";
|
||
+ status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
rtc: rtc@5c004000 {
|
||
@@ -1479,21 +439,47 @@
|
||
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";
|
||
+ secure-status = "disabled";
|
||
};
|
||
|
||
- bsec: efuse@5c005000 {
|
||
+ bsec: nvmem@5c005000 {
|
||
compatible = "st,stm32mp15-bsec";
|
||
reg = <0x5c005000 0x400>;
|
||
#address-cells = <1>;
|
||
#size-cells = <1>;
|
||
+
|
||
+ cfg0_otp: cfg0_otp@0 {
|
||
+ reg = <0x0 0x1>;
|
||
+ };
|
||
+ part_number_otp: part_number_otp@4 {
|
||
+ reg = <0x4 0x1>;
|
||
+ };
|
||
+ monotonic_otp: monotonic_otp@10 {
|
||
+ reg = <0x10 0x4>;
|
||
+ };
|
||
+ nand_otp: nand_otp@24 {
|
||
+ reg = <0x24 0x4>;
|
||
+ };
|
||
+ uid_otp: uid_otp@34 {
|
||
+ reg = <0x34 0xc>;
|
||
+ };
|
||
+ package_otp: package_otp@40 {
|
||
+ reg = <0x40 0x4>;
|
||
+ };
|
||
+ hw2_otp: hw2_otp@48 {
|
||
+ reg = <0x48 0x4>;
|
||
+ };
|
||
ts_cal1: calib@5c {
|
||
reg = <0x5c 0x2>;
|
||
};
|
||
ts_cal2: calib@5e {
|
||
reg = <0x5e 0x2>;
|
||
};
|
||
+ pkh_otp: pkh_otp@60 {
|
||
+ reg = <0x60 0x20>;
|
||
+ };
|
||
mac_addr: mac_addr@e4 {
|
||
reg = <0xe4 0x8>;
|
||
st,non-secure-otp;
|
||
@@ -1508,17 +494,32 @@
|
||
secure-status = "okay";
|
||
};
|
||
|
||
+ stgen: stgen@5c008000 {
|
||
+ compatible = "st,stm32-stgen";
|
||
+ reg = <0x5C008000 0x1000>;
|
||
+ };
|
||
+
|
||
i2c6: i2c@5c009000 {
|
||
- compatible = "st,stm32f7-i2c";
|
||
+ compatible = "st,stm32mp15-i2c";
|
||
reg = <0x5c009000 0x400>;
|
||
interrupt-names = "event", "error";
|
||
- interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ interrupts-extended = <&exti 54 IRQ_TYPE_LEVEL_HIGH>,
|
||
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
||
clocks = <&rcc I2C6_K>;
|
||
resets = <&rcc I2C6_R>;
|
||
#address-cells = <1>;
|
||
#size-cells = <0>;
|
||
+ st,syscfg-fmp = <&syscfg 0x4 0x20>;
|
||
+ wakeup-source;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
+ };
|
||
+
|
||
+ tamp: tamp@5c00a000 {
|
||
+ compatible = "st,stm32-tamp", "simple-bus", "syscon", "simple-mfd";
|
||
+ reg = <0x5c00a000 0x400>;
|
||
+ secure-interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ clocks = <&rcc RTCAPB>;
|
||
};
|
||
|
||
/*
|
||
@@ -1675,28 +676,8 @@
|
||
st,bank-name = "GPIOZ";
|
||
st,bank-ioport = <11>;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
};
|
||
};
|
||
-
|
||
- mlahb: ahb {
|
||
- compatible = "st,mlahb", "simple-bus";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges;
|
||
- dma-ranges = <0x00000000 0x38000000 0x10000>,
|
||
- <0x10000000 0x10000000 0x60000>,
|
||
- <0x30000000 0x30000000 0x60000>;
|
||
-
|
||
- m4_rproc: m4@10000000 {
|
||
- compatible = "st,stm32mp1-m4";
|
||
- reg = <0x10000000 0x40000>,
|
||
- <0x30000000 0x40000>,
|
||
- <0x38000000 0x10000>;
|
||
- resets = <&rcc MCU_R>;
|
||
- st,syscfg-holdboot = <&rcc 0x10C 0x1>;
|
||
- st,syscfg-tz = <&rcc 0x000 0x1>;
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp153.dtsi b/core/arch/arm/dts/stm32mp153.dtsi
|
||
index 2d759fc..617380a 100644
|
||
--- a/core/arch/arm/dts/stm32mp153.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp153.dtsi
|
||
@@ -12,34 +12,9 @@
|
||
compatible = "arm,cortex-a7";
|
||
device_type = "cpu";
|
||
reg = <1>;
|
||
- };
|
||
- };
|
||
-
|
||
- soc {
|
||
- m_can1: can@4400e000 {
|
||
- compatible = "bosch,m_can";
|
||
- reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
|
||
- reg-names = "m_can", "message_ram";
|
||
- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||
- interrupt-names = "int0", "int1";
|
||
- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
|
||
- clock-names = "hclk", "cclk";
|
||
- bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- m_can2: can@4400f000 {
|
||
- compatible = "bosch,m_can";
|
||
- reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
|
||
- reg-names = "m_can", "message_ram";
|
||
- interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
|
||
- <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
|
||
- interrupt-names = "int0", "int1";
|
||
- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
|
||
- clock-names = "hclk", "cclk";
|
||
- bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
|
||
- status = "disabled";
|
||
+ clocks = <&rcc CK_MPU>;
|
||
+ clock-names = "cpu";
|
||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||
};
|
||
};
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp157.dtsi b/core/arch/arm/dts/stm32mp157.dtsi
|
||
index 3f0a4a9..c834029 100644
|
||
--- a/core/arch/arm/dts/stm32mp157.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp157.dtsi
|
||
@@ -5,27 +5,3 @@
|
||
*/
|
||
|
||
#include "stm32mp153.dtsi"
|
||
-
|
||
-/ {
|
||
- soc {
|
||
- gpu: gpu@59000000 {
|
||
- compatible = "vivante,gc";
|
||
- reg = <0x59000000 0x800>;
|
||
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||
- clocks = <&rcc GPU>, <&rcc GPU_K>;
|
||
- clock-names = "bus" ,"core";
|
||
- resets = <&rcc GPU_R>;
|
||
- status = "disabled";
|
||
- };
|
||
-
|
||
- dsi: dsi@5a000000 {
|
||
- compatible = "st,stm32-dsi";
|
||
- reg = <0x5a000000 0x800>;
|
||
- clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
|
||
- clock-names = "pclk", "ref", "px_clk";
|
||
- resets = <&rcc DSI_R>;
|
||
- reset-names = "apb";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-};
|
||
diff --git a/core/arch/arm/dts/stm32mp157a-dk1.dts b/core/arch/arm/dts/stm32mp157a-dk1.dts
|
||
index bc9ee69..4d506bc 100644
|
||
--- a/core/arch/arm/dts/stm32mp157a-dk1.dts
|
||
+++ b/core/arch/arm/dts/stm32mp157a-dk1.dts
|
||
@@ -7,17 +7,20 @@
|
||
/dts-v1/;
|
||
|
||
#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xa.dtsi"
|
||
#include "stm32mp15-pinctrl.dtsi"
|
||
#include "stm32mp15xxac-pinctrl.dtsi"
|
||
#include "stm32mp15xx-dkx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
|
||
/ {
|
||
model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
|
||
compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
|
||
|
||
aliases {
|
||
- ethernet0 = ðernet0;
|
||
serial0 = &uart4;
|
||
+ serial1 = &usart3;
|
||
+ serial2 = &uart7;
|
||
};
|
||
|
||
chosen {
|
||
@@ -25,14 +28,18 @@
|
||
};
|
||
};
|
||
|
||
-&rcc {
|
||
- status = "okay";
|
||
- secure-status = "disable";
|
||
-};
|
||
-
|
||
-&bsec {
|
||
- board_id: board_id@ec {
|
||
- reg = <0xec 0x4>;
|
||
- st,non-secure-otp;
|
||
- };
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp157a-ed1.dts b/core/arch/arm/dts/stm32mp157a-ed1.dts
|
||
new file mode 100644
|
||
index 0000000..4f84ec6
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157a-ed1.dts
|
||
@@ -0,0 +1,46 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xa.dtsi"
|
||
+#include "stm32mp15-pinctrl.dtsi"
|
||
+#include "stm32mp15xxaa-pinctrl.dtsi"
|
||
+#include "stm32mp15xx-edx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157A eval daughter";
|
||
+ compatible = "st,stm32mp157a-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial0 = &uart4;
|
||
+ };
|
||
+};
|
||
+
|
||
+&cpu1 {
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157a-ev1.dts b/core/arch/arm/dts/stm32mp157a-ev1.dts
|
||
new file mode 100644
|
||
index 0000000..c577a90
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157a-ev1.dts
|
||
@@ -0,0 +1,23 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157a-ed1.dts"
|
||
+#include "stm32mp15xx-evx.dtsi"
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157A eval daughter on eval mother";
|
||
+ compatible = "st,stm32mp157a-ev1", "st,stm32mp157a-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial1 = &usart3;
|
||
+ };
|
||
+};
|
||
+
|
||
diff --git a/core/arch/arm/dts/stm32mp157c-dk2.dts b/core/arch/arm/dts/stm32mp157c-dk2.dts
|
||
index c5b226d..436a159 100644
|
||
--- a/core/arch/arm/dts/stm32mp157c-dk2.dts
|
||
+++ b/core/arch/arm/dts/stm32mp157c-dk2.dts
|
||
@@ -11,14 +11,17 @@
|
||
#include "stm32mp15-pinctrl.dtsi"
|
||
#include "stm32mp15xxac-pinctrl.dtsi"
|
||
#include "stm32mp15xx-dkx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
|
||
/ {
|
||
model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
|
||
compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
|
||
|
||
aliases {
|
||
- ethernet0 = ðernet0;
|
||
serial0 = &uart4;
|
||
+ serial1 = &usart3;
|
||
+ serial2 = &uart7;
|
||
+ serial3 = &usart2;
|
||
};
|
||
|
||
chosen {
|
||
@@ -26,81 +29,23 @@
|
||
};
|
||
};
|
||
|
||
-&dsi {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
+&cryp1 {
|
||
status = "okay";
|
||
- phy-dsi-supply = <®18>;
|
||
-
|
||
- ports {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- port@0 {
|
||
- reg = <0>;
|
||
- dsi_in: endpoint {
|
||
- remote-endpoint = <<dc_ep1_out>;
|
||
- };
|
||
- };
|
||
-
|
||
- port@1 {
|
||
- reg = <1>;
|
||
- dsi_out: endpoint {
|
||
- remote-endpoint = <&panel_in>;
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- panel@0 {
|
||
- compatible = "orisetech,otm8009a";
|
||
- reg = <0>;
|
||
- reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>;
|
||
- power-supply = <&v3v3>;
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- panel_in: endpoint {
|
||
- remote-endpoint = <&dsi_out>;
|
||
- };
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&i2c1 {
|
||
- touchscreen@38 {
|
||
- compatible = "focaltech,ft6236";
|
||
- reg = <0x38>;
|
||
- interrupts = <2 2>;
|
||
- interrupt-parent = <&gpiof>;
|
||
- interrupt-controller;
|
||
- touchscreen-size-x = <480>;
|
||
- touchscreen-size-y = <800>;
|
||
- status = "okay";
|
||
- };
|
||
};
|
||
|
||
-<dc {
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- ltdc_ep1_out: endpoint@1 {
|
||
- reg = <1>;
|
||
- remote-endpoint = <&dsi_in>;
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&rcc {
|
||
- status = "okay";
|
||
- secure-status = "disable";
|
||
-};
|
||
-
|
||
-&bsec {
|
||
- board_id: board_id@ec {
|
||
- reg = <0xec 0x4>;
|
||
- st,non-secure-otp;
|
||
- };
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp157c-ed1.dts b/core/arch/arm/dts/stm32mp157c-ed1.dts
|
||
index ea301c5..5aadb1f 100644
|
||
--- a/core/arch/arm/dts/stm32mp157c-ed1.dts
|
||
+++ b/core/arch/arm/dts/stm32mp157c-ed1.dts
|
||
@@ -1,7 +1,7 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
||
- * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
*/
|
||
/dts-v1/;
|
||
|
||
@@ -9,8 +9,8 @@
|
||
#include "stm32mp15xc.dtsi"
|
||
#include "stm32mp15-pinctrl.dtsi"
|
||
#include "stm32mp15xxaa-pinctrl.dtsi"
|
||
-#include <dt-bindings/gpio/gpio.h>
|
||
-#include <dt-bindings/mfd/st,stpmic1.h>
|
||
+#include "stm32mp15xx-edx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
|
||
/ {
|
||
model = "STMicroelectronics STM32MP157C eval daughter";
|
||
@@ -20,361 +20,32 @@
|
||
stdout-path = "serial0:115200n8";
|
||
};
|
||
|
||
- memory@c0000000 {
|
||
- device_type = "memory";
|
||
- reg = <0xC0000000 0x40000000>;
|
||
- };
|
||
-
|
||
- reserved-memory {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges;
|
||
-
|
||
- mcuram2: mcuram2@10000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10000000 0x40000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0vring0: vdev0vring0@10040000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10040000 0x1000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0vring1: vdev0vring1@10041000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10041000 0x1000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0buffer: vdev0buffer@10042000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10042000 0x4000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- mcuram: mcuram@30000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x30000000 0x40000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- retram: retram@38000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x38000000 0x10000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- gpu_reserved: gpu@e8000000 {
|
||
- reg = <0xe8000000 0x8000000>;
|
||
- no-map;
|
||
- };
|
||
- };
|
||
-
|
||
aliases {
|
||
serial0 = &uart4;
|
||
};
|
||
-
|
||
- sd_switch: regulator-sd_switch {
|
||
- compatible = "regulator-gpio";
|
||
- regulator-name = "sd_switch";
|
||
- regulator-min-microvolt = <1800000>;
|
||
- regulator-max-microvolt = <2900000>;
|
||
- regulator-type = "voltage";
|
||
- regulator-always-on;
|
||
-
|
||
- gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>;
|
||
- gpios-states = <0>;
|
||
- states = <1800000 0x1>,
|
||
- <2900000 0x0>;
|
||
- };
|
||
-};
|
||
-
|
||
-&adc {
|
||
- /* ANA0, ANA1 are dedicated pins and don't need pinctrl: only in6. */
|
||
- pinctrl-0 = <&adc1_in6_pins_a>;
|
||
- pinctrl-names = "default";
|
||
- vdd-supply = <&vdd>;
|
||
- vdda-supply = <&vdda>;
|
||
- vref-supply = <&vdda>;
|
||
- status = "disabled";
|
||
- adc1: adc@0 {
|
||
- st,adc-channels = <0 1 6>;
|
||
- /* 16.5 ck_cycles sampling time */
|
||
- st,min-sample-time-nsecs = <400>;
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&dac {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;
|
||
- vref-supply = <&vdda>;
|
||
- status = "disabled";
|
||
- dac1: dac@1 {
|
||
- status = "okay";
|
||
- };
|
||
- dac2: dac@2 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&dts {
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&gpu {
|
||
- contiguous-area = <&gpu_reserved>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&i2c4 {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&i2c4_pins_a>;
|
||
- i2c-scl-rising-time-ns = <185>;
|
||
- i2c-scl-falling-time-ns = <20>;
|
||
- status = "okay";
|
||
- /* spare dmas for other usage */
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
-
|
||
- pmic: stpmic@33 {
|
||
- compatible = "st,stpmic1";
|
||
- reg = <0x33>;
|
||
- interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
|
||
- interrupt-controller;
|
||
- #interrupt-cells = <2>;
|
||
- status = "okay";
|
||
-
|
||
- regulators {
|
||
- compatible = "st,stpmic1-regulators";
|
||
- ldo1-supply = <&v3v3>;
|
||
- ldo2-supply = <&v3v3>;
|
||
- ldo3-supply = <&vdd_ddr>;
|
||
- ldo5-supply = <&v3v3>;
|
||
- ldo6-supply = <&v3v3>;
|
||
- pwr_sw1-supply = <&bst_out>;
|
||
- pwr_sw2-supply = <&bst_out>;
|
||
-
|
||
- vddcore: buck1 {
|
||
- regulator-name = "vddcore";
|
||
- regulator-min-microvolt = <1200000>;
|
||
- regulator-max-microvolt = <1350000>;
|
||
- regulator-always-on;
|
||
- regulator-initial-mode = <0>;
|
||
- regulator-over-current-protection;
|
||
- };
|
||
-
|
||
- vdd_ddr: buck2 {
|
||
- regulator-name = "vdd_ddr";
|
||
- regulator-min-microvolt = <1350000>;
|
||
- regulator-max-microvolt = <1350000>;
|
||
- regulator-always-on;
|
||
- regulator-initial-mode = <0>;
|
||
- regulator-over-current-protection;
|
||
- };
|
||
-
|
||
- vdd: buck3 {
|
||
- regulator-name = "vdd";
|
||
- regulator-min-microvolt = <3300000>;
|
||
- regulator-max-microvolt = <3300000>;
|
||
- regulator-always-on;
|
||
- st,mask-reset;
|
||
- regulator-initial-mode = <0>;
|
||
- regulator-over-current-protection;
|
||
- };
|
||
-
|
||
- v3v3: buck4 {
|
||
- regulator-name = "v3v3";
|
||
- regulator-min-microvolt = <3300000>;
|
||
- regulator-max-microvolt = <3300000>;
|
||
- regulator-always-on;
|
||
- regulator-over-current-protection;
|
||
- regulator-initial-mode = <0>;
|
||
- };
|
||
-
|
||
- vdda: ldo1 {
|
||
- regulator-name = "vdda";
|
||
- regulator-min-microvolt = <2900000>;
|
||
- regulator-max-microvolt = <2900000>;
|
||
- interrupts = <IT_CURLIM_LDO1 0>;
|
||
- };
|
||
-
|
||
- v2v8: ldo2 {
|
||
- regulator-name = "v2v8";
|
||
- regulator-min-microvolt = <2800000>;
|
||
- regulator-max-microvolt = <2800000>;
|
||
- interrupts = <IT_CURLIM_LDO2 0>;
|
||
- };
|
||
-
|
||
- vtt_ddr: ldo3 {
|
||
- regulator-name = "vtt_ddr";
|
||
- regulator-min-microvolt = <500000>;
|
||
- regulator-max-microvolt = <750000>;
|
||
- regulator-always-on;
|
||
- regulator-over-current-protection;
|
||
- };
|
||
-
|
||
- vdd_usb: ldo4 {
|
||
- regulator-name = "vdd_usb";
|
||
- regulator-min-microvolt = <3300000>;
|
||
- regulator-max-microvolt = <3300000>;
|
||
- interrupts = <IT_CURLIM_LDO4 0>;
|
||
- };
|
||
-
|
||
- vdd_sd: ldo5 {
|
||
- regulator-name = "vdd_sd";
|
||
- regulator-min-microvolt = <2900000>;
|
||
- regulator-max-microvolt = <2900000>;
|
||
- interrupts = <IT_CURLIM_LDO5 0>;
|
||
- regulator-boot-on;
|
||
- };
|
||
-
|
||
- v1v8: ldo6 {
|
||
- regulator-name = "v1v8";
|
||
- regulator-min-microvolt = <1800000>;
|
||
- regulator-max-microvolt = <1800000>;
|
||
- interrupts = <IT_CURLIM_LDO6 0>;
|
||
- };
|
||
-
|
||
- vref_ddr: vref_ddr {
|
||
- regulator-name = "vref_ddr";
|
||
- regulator-always-on;
|
||
- regulator-over-current-protection;
|
||
- };
|
||
-
|
||
- bst_out: boost {
|
||
- regulator-name = "bst_out";
|
||
- interrupts = <IT_OCP_BOOST 0>;
|
||
- };
|
||
-
|
||
- vbus_otg: pwr_sw1 {
|
||
- regulator-name = "vbus_otg";
|
||
- interrupts = <IT_OCP_OTG 0>;
|
||
- };
|
||
-
|
||
- vbus_sw: pwr_sw2 {
|
||
- regulator-name = "vbus_sw";
|
||
- interrupts = <IT_OCP_SWOUT 0>;
|
||
- regulator-active-discharge = <1>;
|
||
- };
|
||
- };
|
||
-
|
||
- onkey {
|
||
- compatible = "st,stpmic1-onkey";
|
||
- interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
|
||
- interrupt-names = "onkey-falling", "onkey-rising";
|
||
- power-off-time-sec = <10>;
|
||
- status = "okay";
|
||
- };
|
||
-
|
||
- watchdog {
|
||
- compatible = "st,stpmic1-wdt";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
};
|
||
|
||
-&ipcc {
|
||
- status = "okay";
|
||
+&cpu1 {
|
||
+ cpu-supply = <&vddcore>;
|
||
};
|
||
|
||
-&iwdg2 {
|
||
- timeout-sec = <32>;
|
||
+&cryp1 {
|
||
status = "okay";
|
||
};
|
||
|
||
-&m4_rproc {
|
||
- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
|
||
- <&vdev0vring1>, <&vdev0buffer>;
|
||
- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
|
||
- mbox-names = "vq0", "vq1", "shutdown";
|
||
- interrupt-parent = <&exti>;
|
||
- interrupts = <68 1>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&pwr_regulators {
|
||
- vdd-supply = <&vdd>;
|
||
- vdd_3v3_usbfs-supply = <&vdd_usb>;
|
||
-};
|
||
-
|
||
-&rng1 {
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&rtc {
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&sdmmc1 {
|
||
- pinctrl-names = "default", "opendrain", "sleep";
|
||
- pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
|
||
- pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>;
|
||
- pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>;
|
||
- broken-cd;
|
||
- st,sig-dir;
|
||
- st,neg-edge;
|
||
- st,use-ckin;
|
||
- bus-width = <4>;
|
||
- vmmc-supply = <&vdd_sd>;
|
||
- vqmmc-supply = <&sd_switch>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&sdmmc2 {
|
||
- pinctrl-names = "default", "opendrain", "sleep";
|
||
- pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
|
||
- pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
|
||
- pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
|
||
- non-removable;
|
||
- no-sd;
|
||
- no-sdio;
|
||
- st,neg-edge;
|
||
- bus-width = <8>;
|
||
- vmmc-supply = <&v3v3>;
|
||
- vqmmc-supply = <&v3v3>;
|
||
- mmc-ddr-3_3v;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&timers6 {
|
||
- status = "okay";
|
||
- /* spare dmas for other usage */
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- timer@5 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&uart4 {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&uart4_pins_a>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&usbphyc_port0 {
|
||
- phy-supply = <&vdd_usb>;
|
||
- vdda1v1-supply = <®11>;
|
||
- vdda1v8-supply = <®18>;
|
||
-};
|
||
-
|
||
-&usbphyc_port1 {
|
||
- phy-supply = <&vdd_usb>;
|
||
- vdda1v1-supply = <®11>;
|
||
- vdda1v8-supply = <®18>;
|
||
-};
|
||
-
|
||
-&rcc {
|
||
- status = "okay";
|
||
- secure-status = "disable";
|
||
-};
|
||
-
|
||
-&bsec {
|
||
- board_id: board_id@ec {
|
||
- reg = <0xec 0x4>;
|
||
- st,non-secure-otp;
|
||
- };
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp157c-ev1.dts b/core/arch/arm/dts/stm32mp157c-ev1.dts
|
||
index fd8c958..dd7da41 100644
|
||
--- a/core/arch/arm/dts/stm32mp157c-ev1.dts
|
||
+++ b/core/arch/arm/dts/stm32mp157c-ev1.dts
|
||
@@ -1,13 +1,12 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
||
- * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
*/
|
||
/dts-v1/;
|
||
|
||
#include "stm32mp157c-ed1.dts"
|
||
-#include <dt-bindings/gpio/gpio.h>
|
||
-/* #include <dt-bindings/input/input.h> Remove due to BSD license issue */
|
||
+#include "stm32mp15xx-evx.dtsi"
|
||
|
||
/ {
|
||
model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
|
||
@@ -18,347 +17,6 @@
|
||
};
|
||
|
||
aliases {
|
||
- serial0 = &uart4;
|
||
- ethernet0 = ðernet0;
|
||
+ serial1 = &usart3;
|
||
};
|
||
-
|
||
- clocks {
|
||
- clk_ext_camera: clk-ext-camera {
|
||
- #clock-cells = <0>;
|
||
- compatible = "fixed-clock";
|
||
- clock-frequency = <24000000>;
|
||
- };
|
||
- };
|
||
-
|
||
- joystick {
|
||
- compatible = "gpio-keys";
|
||
- pinctrl-0 = <&joystick_pins>;
|
||
- pinctrl-names = "default";
|
||
- button-0 {
|
||
- label = "JoySel";
|
||
- /* linux,code = <KEY_ENTER>; BSD license issue */
|
||
- interrupt-parent = <&stmfx_pinctrl>;
|
||
- interrupts = <0 IRQ_TYPE_EDGE_RISING>;
|
||
- };
|
||
- button-1 {
|
||
- label = "JoyDown";
|
||
- /* linux,code = <KEY_DOWN>; BSD license issue */
|
||
- interrupt-parent = <&stmfx_pinctrl>;
|
||
- interrupts = <1 IRQ_TYPE_EDGE_RISING>;
|
||
- };
|
||
- button-2 {
|
||
- label = "JoyLeft";
|
||
- /* linux,code = <KEY_LEFT>; BSD license issue */
|
||
- interrupt-parent = <&stmfx_pinctrl>;
|
||
- interrupts = <2 IRQ_TYPE_EDGE_RISING>;
|
||
- };
|
||
- button-3 {
|
||
- label = "JoyRight";
|
||
- /* linux,code = <KEY_RIGHT>; BSD license issue */
|
||
- interrupt-parent = <&stmfx_pinctrl>;
|
||
- interrupts = <3 IRQ_TYPE_EDGE_RISING>;
|
||
- };
|
||
- button-4 {
|
||
- label = "JoyUp";
|
||
- /* linux,code = <KEY_UP>; BSD license issue */
|
||
- interrupt-parent = <&stmfx_pinctrl>;
|
||
- interrupts = <4 IRQ_TYPE_EDGE_RISING>;
|
||
- };
|
||
- };
|
||
-
|
||
- panel_backlight: panel-backlight {
|
||
- compatible = "gpio-backlight";
|
||
- gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;
|
||
- default-on;
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&cec {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&cec_pins_a>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&dcmi {
|
||
- status = "okay";
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&dcmi_pins_a>;
|
||
- pinctrl-1 = <&dcmi_sleep_pins_a>;
|
||
-
|
||
- port {
|
||
- dcmi_0: endpoint {
|
||
- remote-endpoint = <&ov5640_0>;
|
||
- bus-width = <8>;
|
||
- hsync-active = <0>;
|
||
- vsync-active = <0>;
|
||
- pclk-sample = <1>;
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&dsi {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- phy-dsi-supply = <®18>;
|
||
- status = "okay";
|
||
-
|
||
- ports {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- port@0 {
|
||
- reg = <0>;
|
||
- dsi_in: endpoint {
|
||
- remote-endpoint = <<dc_ep0_out>;
|
||
- };
|
||
- };
|
||
-
|
||
- port@1 {
|
||
- reg = <1>;
|
||
- dsi_out: endpoint {
|
||
- remote-endpoint = <&dsi_panel_in>;
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- panel-dsi@0 {
|
||
- compatible = "raydium,rm68200";
|
||
- reg = <0>;
|
||
- reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>;
|
||
- backlight = <&panel_backlight>;
|
||
- power-supply = <&v3v3>;
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- dsi_panel_in: endpoint {
|
||
- remote-endpoint = <&dsi_out>;
|
||
- };
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-ðernet0 {
|
||
- status = "okay";
|
||
- pinctrl-0 = <ðernet0_rgmii_pins_a>;
|
||
- pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- phy-mode = "rgmii-id";
|
||
- max-speed = <1000>;
|
||
- phy-handle = <&phy0>;
|
||
-
|
||
- mdio0 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "snps,dwmac-mdio";
|
||
- phy0: ethernet-phy@0 {
|
||
- reg = <0>;
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&fmc {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&fmc_pins_a>;
|
||
- pinctrl-1 = <&fmc_sleep_pins_a>;
|
||
- status = "okay";
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- nand@0 {
|
||
- reg = <0>;
|
||
- nand-on-flash-bbt;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- };
|
||
-};
|
||
-
|
||
-&i2c2 {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&i2c2_pins_a>;
|
||
- i2c-scl-rising-time-ns = <185>;
|
||
- i2c-scl-falling-time-ns = <20>;
|
||
- status = "okay";
|
||
-
|
||
- ov5640: camera@3c {
|
||
- compatible = "ovti,ov5640";
|
||
- reg = <0x3c>;
|
||
- clocks = <&clk_ext_camera>;
|
||
- clock-names = "xclk";
|
||
- DOVDD-supply = <&v2v8>;
|
||
- powerdown-gpios = <&stmfx_pinctrl 18 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL)>;
|
||
- reset-gpios = <&stmfx_pinctrl 19 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
|
||
- rotation = <180>;
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- ov5640_0: endpoint {
|
||
- remote-endpoint = <&dcmi_0>;
|
||
- bus-width = <8>;
|
||
- data-shift = <2>; /* lines 9:2 are used */
|
||
- hsync-active = <0>;
|
||
- vsync-active = <0>;
|
||
- pclk-sample = <1>;
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- stmfx: stmfx@42 {
|
||
- compatible = "st,stmfx-0300";
|
||
- reg = <0x42>;
|
||
- interrupts = <8 IRQ_TYPE_EDGE_RISING>;
|
||
- interrupt-parent = <&gpioi>;
|
||
- vdd-supply = <&v3v3>;
|
||
-
|
||
- stmfx_pinctrl: stmfx-pin-controller {
|
||
- compatible = "st,stmfx-0300-pinctrl";
|
||
- gpio-controller;
|
||
- #gpio-cells = <2>;
|
||
- interrupt-controller;
|
||
- #interrupt-cells = <2>;
|
||
- gpio-ranges = <&stmfx_pinctrl 0 0 24>;
|
||
-
|
||
- joystick_pins: joystick {
|
||
- pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
|
||
- bias-pull-down;
|
||
- };
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&i2c5 {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&i2c5_pins_a>;
|
||
- i2c-scl-rising-time-ns = <185>;
|
||
- i2c-scl-falling-time-ns = <20>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-<dc {
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- ltdc_ep0_out: endpoint@0 {
|
||
- reg = <0>;
|
||
- remote-endpoint = <&dsi_in>;
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&m_can1 {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&m_can1_pins_a>;
|
||
- pinctrl-1 = <&m_can1_sleep_pins_a>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&qspi {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
|
||
- pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>;
|
||
- reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- status = "okay";
|
||
-
|
||
- flash0: mx66l51235l@0 {
|
||
- compatible = "jedec,spi-nor";
|
||
- reg = <0>;
|
||
- spi-rx-bus-width = <4>;
|
||
- spi-max-frequency = <108000000>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- };
|
||
-
|
||
- flash1: mx66l51235l@1 {
|
||
- compatible = "jedec,spi-nor";
|
||
- reg = <1>;
|
||
- spi-rx-bus-width = <4>;
|
||
- spi-max-frequency = <108000000>;
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- };
|
||
-};
|
||
-
|
||
-&sdmmc3 {
|
||
- pinctrl-names = "default", "opendrain", "sleep";
|
||
- pinctrl-0 = <&sdmmc3_b4_pins_a>;
|
||
- pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
|
||
- pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
|
||
- broken-cd;
|
||
- st,neg-edge;
|
||
- bus-width = <4>;
|
||
- vmmc-supply = <&v3v3>;
|
||
- status = "disabled";
|
||
-};
|
||
-
|
||
-&spi1 {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&spi1_pins_a>;
|
||
- status = "disabled";
|
||
-};
|
||
-
|
||
-&timers2 {
|
||
- /* spare dmas for other usage (un-delete to enable pwm capture) */
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm2_pins_a>;
|
||
- pinctrl-1 = <&pwm2_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@1 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers8 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm8_pins_a>;
|
||
- pinctrl-1 = <&pwm8_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@7 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers12 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm12_pins_a>;
|
||
- pinctrl-1 = <&pwm12_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@11 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&usbh_ehci {
|
||
- phys = <&usbphyc_port0>;
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&usbotg_hs {
|
||
- dr_mode = "peripheral";
|
||
- phys = <&usbphyc_port1 0>;
|
||
- phy-names = "usb2-phy";
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
-&usbphyc {
|
||
- status = "okay";
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp157d-dk1.dts b/core/arch/arm/dts/stm32mp157d-dk1.dts
|
||
new file mode 100644
|
||
index 0000000..d320f99
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157d-dk1.dts
|
||
@@ -0,0 +1,49 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xd.dtsi"
|
||
+#include "stm32mp15-pinctrl.dtsi"
|
||
+#include "stm32mp15xxac-pinctrl.dtsi"
|
||
+#include "stm32mp15xx-dkx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157D-DK1 Discovery Board";
|
||
+ compatible = "st,stm32mp157d-dk1", "st,stm32mp157";
|
||
+
|
||
+ aliases {
|
||
+ serial0 = &uart4;
|
||
+ serial1 = &usart3;
|
||
+ serial2 = &uart7;
|
||
+ };
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+};
|
||
+
|
||
+&cpu1 {
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157d-ed1.dts b/core/arch/arm/dts/stm32mp157d-ed1.dts
|
||
new file mode 100644
|
||
index 0000000..76f0614
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157d-ed1.dts
|
||
@@ -0,0 +1,46 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xd.dtsi"
|
||
+#include "stm32mp15-pinctrl.dtsi"
|
||
+#include "stm32mp15xxaa-pinctrl.dtsi"
|
||
+#include "stm32mp15xx-edx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157D eval daughter";
|
||
+ compatible = "st,stm32mp157d-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial0 = &uart4;
|
||
+ };
|
||
+};
|
||
+
|
||
+&cpu1 {
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157d-ev1.dts b/core/arch/arm/dts/stm32mp157d-ev1.dts
|
||
new file mode 100644
|
||
index 0000000..47d962b
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157d-ev1.dts
|
||
@@ -0,0 +1,22 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157d-ed1.dts"
|
||
+#include "stm32mp15xx-evx.dtsi"
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157D eval daughter on eval mother";
|
||
+ compatible = "st,stm32mp157d-ev1", "st,stm32mp157d-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial1 = &usart3;
|
||
+ };
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157f-dk2.dts b/core/arch/arm/dts/stm32mp157f-dk2.dts
|
||
new file mode 100644
|
||
index 0000000..9c79bfb
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157f-dk2.dts
|
||
@@ -0,0 +1,55 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xf.dtsi"
|
||
+#include "stm32mp15-pinctrl.dtsi"
|
||
+#include "stm32mp15xxac-pinctrl.dtsi"
|
||
+#include "stm32mp15xx-dkx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157F-DK2 Discovery Board";
|
||
+ compatible = "st,stm32mp157f-dk2", "st,stm32mp157";
|
||
+
|
||
+ aliases {
|
||
+ serial0 = &uart4;
|
||
+ serial1 = &usart3;
|
||
+ serial2 = &uart7;
|
||
+ serial3 = &usart2;
|
||
+ };
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+};
|
||
+
|
||
+&cpu1 {
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&cryp1 {
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157f-ed1.dts b/core/arch/arm/dts/stm32mp157f-ed1.dts
|
||
new file mode 100644
|
||
index 0000000..a659cf8
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157f-ed1.dts
|
||
@@ -0,0 +1,51 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157.dtsi"
|
||
+#include "stm32mp15xf.dtsi"
|
||
+#include "stm32mp15-pinctrl.dtsi"
|
||
+#include "stm32mp15xxaa-pinctrl.dtsi"
|
||
+#include "stm32mp15xx-edx.dtsi"
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157F eval daughter";
|
||
+ compatible = "st,stm32mp157f-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial0 = &uart4;
|
||
+ };
|
||
+};
|
||
+
|
||
+&cpu1{
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&cryp1 {
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&etzpc {
|
||
+ st,decprot = <
|
||
+ DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_SPI6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C4_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK)
|
||
+ >;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp157f-ev1.dts b/core/arch/arm/dts/stm32mp157f-ev1.dts
|
||
new file mode 100644
|
||
index 0000000..c8598ce
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp157f-ev1.dts
|
||
@@ -0,0 +1,22 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+/dts-v1/;
|
||
+
|
||
+#include "stm32mp157f-ed1.dts"
|
||
+#include "stm32mp15xx-evx.dtsi"
|
||
+
|
||
+/ {
|
||
+ model = "STMicroelectronics STM32MP157F eval daughter on eval mother";
|
||
+ compatible = "st,stm32mp157f-ev1", "st,stm32mp157f-ed1", "st,stm32mp157";
|
||
+
|
||
+ chosen {
|
||
+ stdout-path = "serial0:115200n8";
|
||
+ };
|
||
+
|
||
+ aliases {
|
||
+ serial1 = &usart3;
|
||
+ };
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xa.dtsi b/core/arch/arm/dts/stm32mp15xa.dtsi
|
||
new file mode 100644
|
||
index 0000000..5ed7e59
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp15xa.dtsi
|
||
@@ -0,0 +1,13 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+&cpu0_opp_table {
|
||
+ opp-650000000 {
|
||
+ opp-hz = /bits/ 64 <650000000>;
|
||
+ opp-microvolt = <1200000>;
|
||
+ opp-supported-hw = <0x1>;
|
||
+ };
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xc.dtsi b/core/arch/arm/dts/stm32mp15xc.dtsi
|
||
index b06a55a..68d822d 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xc.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xc.dtsi
|
||
@@ -4,6 +4,8 @@
|
||
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
*/
|
||
|
||
+#include "stm32mp15xa.dtsi"
|
||
+
|
||
/ {
|
||
soc {
|
||
cryp1: cryp@54001000 {
|
||
@@ -13,6 +15,7 @@
|
||
clocks = <&rcc CRYP1>;
|
||
resets = <&rcc CRYP1_R>;
|
||
status = "disabled";
|
||
+ secure-status = "disabled";
|
||
};
|
||
};
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xd.dtsi b/core/arch/arm/dts/stm32mp15xd.dtsi
|
||
new file mode 100644
|
||
index 0000000..18b05ee
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp15xd.dtsi
|
||
@@ -0,0 +1,19 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+&cpu0_opp_table {
|
||
+ opp-800000000 {
|
||
+ opp-hz = /bits/ 64 <800000000>;
|
||
+ opp-microvolt = <1350000>;
|
||
+ opp-supported-hw = <0x2>;
|
||
+ };
|
||
+ opp-400000000 {
|
||
+ opp-hz = /bits/ 64 <400000000>;
|
||
+ opp-microvolt = <1200000>;
|
||
+ opp-supported-hw = <0x2>;
|
||
+ opp-suspend;
|
||
+ };
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xf.dtsi b/core/arch/arm/dts/stm32mp15xf.dtsi
|
||
new file mode 100644
|
||
index 0000000..526a162
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp15xf.dtsi
|
||
@@ -0,0 +1,21 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+#include "stm32mp15xd.dtsi"
|
||
+
|
||
+/ {
|
||
+ soc {
|
||
+ cryp1: cryp@54001000 {
|
||
+ compatible = "st,stm32mp1-cryp";
|
||
+ reg = <0x54001000 0x400>;
|
||
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
|
||
+ clocks = <&rcc CRYP1>;
|
||
+ resets = <&rcc CRYP1_R>;
|
||
+ status = "disabled";
|
||
+ secure-status = "disabled";
|
||
+ };
|
||
+ };
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi
|
||
index f6672e8..7254f9a 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi
|
||
@@ -4,8 +4,8 @@
|
||
* Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
*/
|
||
|
||
-#include <dt-bindings/gpio/gpio.h>
|
||
-#include <dt-bindings/mfd/st,stpmic1.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
|
||
/ {
|
||
memory@c0000000 {
|
||
@@ -13,206 +13,36 @@
|
||
reg = <0xc0000000 0x20000000>;
|
||
};
|
||
|
||
- reserved-memory {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <1>;
|
||
- ranges;
|
||
-
|
||
- mcuram2: mcuram2@10000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10000000 0x40000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0vring0: vdev0vring0@10040000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10040000 0x1000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0vring1: vdev0vring1@10041000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10041000 0x1000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- vdev0buffer: vdev0buffer@10042000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x10042000 0x4000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- mcuram: mcuram@30000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x30000000 0x40000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- retram: retram@38000000 {
|
||
- compatible = "shared-dma-pool";
|
||
- reg = <0x38000000 0x10000>;
|
||
- no-map;
|
||
- };
|
||
-
|
||
- gpu_reserved: gpu@d4000000 {
|
||
- reg = <0xd4000000 0x4000000>;
|
||
- no-map;
|
||
- };
|
||
- };
|
||
-
|
||
- led {
|
||
- compatible = "gpio-leds";
|
||
- blue {
|
||
- label = "heartbeat";
|
||
- gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
|
||
- linux,default-trigger = "heartbeat";
|
||
- default-state = "off";
|
||
- };
|
||
- };
|
||
-
|
||
- sound {
|
||
- compatible = "audio-graph-card";
|
||
- label = "STM32MP1-DK";
|
||
- routing =
|
||
- "Playback" , "MCLK",
|
||
- "Capture" , "MCLK",
|
||
- "MICL" , "Mic Bias";
|
||
- dais = <&sai2a_port &sai2b_port &i2s2_port>;
|
||
- status = "okay";
|
||
+ vin: vin {
|
||
+ compatible = "regulator-fixed";
|
||
+ regulator-name = "vin";
|
||
+ regulator-min-microvolt = <5000000>;
|
||
+ regulator-max-microvolt = <5000000>;
|
||
+ regulator-always-on;
|
||
};
|
||
};
|
||
|
||
-&adc {
|
||
- pinctrl-names = "default";
|
||
- pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>;
|
||
- vdd-supply = <&vdd>;
|
||
- vdda-supply = <&vdd>;
|
||
- vref-supply = <&vrefbuf>;
|
||
- status = "disabled";
|
||
- adc1: adc@0 {
|
||
- /*
|
||
- * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19.
|
||
- * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
|
||
- * 5 * (56 + 47kOhms) * 5pF => 2.5us.
|
||
- * Use arbitrary margin here (e.g. 5us).
|
||
- */
|
||
- st,min-sample-time-nsecs = <5000>;
|
||
- /* AIN connector, USB Type-C CC1 & CC2 */
|
||
- st,adc-channels = <0 1 6 13 18 19>;
|
||
- status = "okay";
|
||
- };
|
||
- adc2: adc@100 {
|
||
- /* AIN connector, USB Type-C CC1 & CC2 */
|
||
- st,adc-channels = <0 1 2 6 18 19>;
|
||
- st,min-sample-time-nsecs = <5000>;
|
||
- status = "okay";
|
||
+&bsec {
|
||
+ board_id: board_id@ec {
|
||
+ reg = <0xec 0x4>;
|
||
+ st,non-secure-otp;
|
||
};
|
||
};
|
||
|
||
-&cec {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&cec_pins_b>;
|
||
- pinctrl-1 = <&cec_pins_sleep_b>;
|
||
- status = "okay";
|
||
+&clk_hse {
|
||
+ st,digbypass;
|
||
};
|
||
|
||
-ðernet0 {
|
||
- status = "okay";
|
||
- pinctrl-0 = <ðernet0_rgmii_pins_a>;
|
||
- pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- phy-mode = "rgmii-id";
|
||
- max-speed = <1000>;
|
||
- phy-handle = <&phy0>;
|
||
-
|
||
- mdio0 {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
- compatible = "snps,dwmac-mdio";
|
||
- phy0: ethernet-phy@0 {
|
||
- reg = <0>;
|
||
- };
|
||
- };
|
||
+&cpu0{
|
||
+ cpu-supply = <&vddcore>;
|
||
};
|
||
|
||
-&gpu {
|
||
- contiguous-area = <&gpu_reserved>;
|
||
- status = "okay";
|
||
+&cpu1{
|
||
+ cpu-supply = <&vddcore>;
|
||
};
|
||
|
||
-&i2c1 {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&i2c1_pins_a>;
|
||
- pinctrl-1 = <&i2c1_pins_sleep_a>;
|
||
- i2c-scl-rising-time-ns = <100>;
|
||
- i2c-scl-falling-time-ns = <7>;
|
||
+&hash1 {
|
||
status = "okay";
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
-
|
||
- hdmi-transmitter@39 {
|
||
- compatible = "sil,sii9022";
|
||
- reg = <0x39>;
|
||
- iovcc-supply = <&v3v3_hdmi>;
|
||
- cvcc12-supply = <&v1v2_hdmi>;
|
||
- reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
|
||
- interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
|
||
- interrupt-parent = <&gpiog>;
|
||
- #sound-dai-cells = <0>;
|
||
- status = "okay";
|
||
-
|
||
- ports {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- port@0 {
|
||
- reg = <0>;
|
||
- sii9022_in: endpoint {
|
||
- remote-endpoint = <<dc_ep0_out>;
|
||
- };
|
||
- };
|
||
-
|
||
- port@3 {
|
||
- reg = <3>;
|
||
- sii9022_tx_endpoint: endpoint {
|
||
- remote-endpoint = <&i2s2_endpoint>;
|
||
- };
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- cs42l51: cs42l51@4a {
|
||
- compatible = "cirrus,cs42l51";
|
||
- reg = <0x4a>;
|
||
- #sound-dai-cells = <0>;
|
||
- VL-supply = <&v3v3>;
|
||
- VD-supply = <&v1v8_audio>;
|
||
- VA-supply = <&v1v8_audio>;
|
||
- VAHP-supply = <&v1v8_audio>;
|
||
- reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
|
||
- clocks = <&sai2a>;
|
||
- clock-names = "MCLK";
|
||
- status = "okay";
|
||
-
|
||
- cs42l51_port: port {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- cs42l51_tx_endpoint: endpoint@0 {
|
||
- reg = <0>;
|
||
- remote-endpoint = <&sai2a_endpoint>;
|
||
- frame-master;
|
||
- bitclock-master;
|
||
- };
|
||
-
|
||
- cs42l51_rx_endpoint: endpoint@1 {
|
||
- reg = <1>;
|
||
- remote-endpoint = <&sai2b_endpoint>;
|
||
- frame-master;
|
||
- bitclock-master;
|
||
- };
|
||
- };
|
||
- };
|
||
};
|
||
|
||
&i2c4 {
|
||
@@ -220,24 +50,33 @@
|
||
pinctrl-0 = <&i2c4_pins_a>;
|
||
i2c-scl-rising-time-ns = <185>;
|
||
i2c-scl-falling-time-ns = <20>;
|
||
+ clock-frequency = <400000>;
|
||
status = "okay";
|
||
- /* spare dmas for other usage */
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
+ secure-status = "okay";
|
||
|
||
pmic: stpmic@33 {
|
||
compatible = "st,stpmic1";
|
||
reg = <0x33>;
|
||
- interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
|
||
+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
|
||
interrupt-controller;
|
||
#interrupt-cells = <2>;
|
||
status = "okay";
|
||
+ secure-status = "okay";
|
||
|
||
regulators {
|
||
compatible = "st,stpmic1-regulators";
|
||
+ buck1-supply = <&vin>;
|
||
+ buck2-supply = <&vin>;
|
||
+ buck3-supply = <&vin>;
|
||
+ buck4-supply = <&vin>;
|
||
ldo1-supply = <&v3v3>;
|
||
+ ldo2-supply = <&vin>;
|
||
ldo3-supply = <&vdd_ddr>;
|
||
+ ldo4-supply = <&vin>;
|
||
+ ldo5-supply = <&vin>;
|
||
ldo6-supply = <&v3v3>;
|
||
+ vref_ddr-supply = <&vin>;
|
||
+ boost-supply = <&vin>;
|
||
pwr_sw1-supply = <&bst_out>;
|
||
pwr_sw2-supply = <&bst_out>;
|
||
|
||
@@ -248,6 +87,16 @@
|
||
regulator-always-on;
|
||
regulator-initial-mode = <0>;
|
||
regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ regulator-suspend-microvolt = <1200000>;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vdd_ddr: buck2 {
|
||
@@ -257,6 +106,17 @@
|
||
regulator-always-on;
|
||
regulator-initial-mode = <0>;
|
||
regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-suspend-microvolt = <1350000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-suspend-microvolt = <1350000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vdd: buck3 {
|
||
@@ -267,6 +127,18 @@
|
||
st,mask-reset;
|
||
regulator-initial-mode = <0>;
|
||
regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
v3v3: buck4 {
|
||
@@ -276,6 +148,16 @@
|
||
regulator-always-on;
|
||
regulator-over-current-protection;
|
||
regulator-initial-mode = <0>;
|
||
+ lp-stop {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
v1v8_audio: ldo1 {
|
||
@@ -283,7 +165,12 @@
|
||
regulator-min-microvolt = <1800000>;
|
||
regulator-max-microvolt = <1800000>;
|
||
regulator-always-on;
|
||
- interrupts = <IT_CURLIM_LDO1 0>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
v3v3_hdmi: ldo2 {
|
||
@@ -291,7 +178,12 @@
|
||
regulator-min-microvolt = <3300000>;
|
||
regulator-max-microvolt = <3300000>;
|
||
regulator-always-on;
|
||
- interrupts = <IT_CURLIM_LDO2 0>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vtt_ddr: ldo3 {
|
||
@@ -300,21 +192,41 @@
|
||
regulator-max-microvolt = <750000>;
|
||
regulator-always-on;
|
||
regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vdd_usb: ldo4 {
|
||
regulator-name = "vdd_usb";
|
||
regulator-min-microvolt = <3300000>;
|
||
regulator-max-microvolt = <3300000>;
|
||
- interrupts = <IT_CURLIM_LDO4 0>;
|
||
+ regulator-always-on;
|
||
+ standby-ddr-sr {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vdda: ldo5 {
|
||
regulator-name = "vdda";
|
||
regulator-min-microvolt = <2900000>;
|
||
regulator-max-microvolt = <2900000>;
|
||
- interrupts = <IT_CURLIM_LDO5 0>;
|
||
regulator-boot-on;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
v1v2_hdmi: ldo6 {
|
||
@@ -322,265 +234,200 @@
|
||
regulator-min-microvolt = <1200000>;
|
||
regulator-max-microvolt = <1200000>;
|
||
regulator-always-on;
|
||
- interrupts = <IT_CURLIM_LDO6 0>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
vref_ddr: vref_ddr {
|
||
regulator-name = "vref_ddr";
|
||
regulator-always-on;
|
||
regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
};
|
||
|
||
- bst_out: boost {
|
||
+ bst_out: boost {
|
||
regulator-name = "bst_out";
|
||
- interrupts = <IT_OCP_BOOST 0>;
|
||
- };
|
||
+ };
|
||
|
||
vbus_otg: pwr_sw1 {
|
||
regulator-name = "vbus_otg";
|
||
- interrupts = <IT_OCP_OTG 0>;
|
||
- };
|
||
+ };
|
||
|
||
- vbus_sw: pwr_sw2 {
|
||
+ vbus_sw: pwr_sw2 {
|
||
regulator-name = "vbus_sw";
|
||
- interrupts = <IT_OCP_SWOUT 0>;
|
||
regulator-active-discharge = <1>;
|
||
- };
|
||
- };
|
||
-
|
||
- onkey {
|
||
- compatible = "st,stpmic1-onkey";
|
||
- interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
|
||
- interrupt-names = "onkey-falling", "onkey-rising";
|
||
- power-off-time-sec = <10>;
|
||
- status = "okay";
|
||
- };
|
||
-
|
||
- watchdog {
|
||
- compatible = "st,stpmic1-wdt";
|
||
- status = "disabled";
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&i2s2 {
|
||
- clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
|
||
- clock-names = "pclk", "i2sclk", "x8k", "x11k";
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&i2s2_pins_a>;
|
||
- pinctrl-1 = <&i2s2_pins_sleep_a>;
|
||
- status = "okay";
|
||
-
|
||
- i2s2_port: port {
|
||
- i2s2_endpoint: endpoint {
|
||
- remote-endpoint = <&sii9022_tx_endpoint>;
|
||
- format = "i2s";
|
||
- mclk-fs = <256>;
|
||
+ };
|
||
};
|
||
};
|
||
};
|
||
|
||
-&ipcc {
|
||
- status = "okay";
|
||
-};
|
||
-
|
||
&iwdg2 {
|
||
timeout-sec = <32>;
|
||
status = "okay";
|
||
+ secure-status = "okay";
|
||
};
|
||
|
||
-<dc {
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <<dc_pins_a>;
|
||
- pinctrl-1 = <<dc_pins_sleep_a>;
|
||
- status = "okay";
|
||
-
|
||
- port {
|
||
- #address-cells = <1>;
|
||
- #size-cells = <0>;
|
||
-
|
||
- ltdc_ep0_out: endpoint@0 {
|
||
- reg = <0>;
|
||
- remote-endpoint = <&sii9022_in>;
|
||
- };
|
||
- };
|
||
-};
|
||
-
|
||
-&m4_rproc {
|
||
- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
|
||
- <&vdev0vring1>, <&vdev0buffer>;
|
||
- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
|
||
- mbox-names = "vq0", "vq1", "shutdown";
|
||
- interrupt-parent = <&exti>;
|
||
- interrupts = <68 1>;
|
||
- status = "okay";
|
||
+&nvmem_layout {
|
||
+ nvmem-cells = <&cfg0_otp>,
|
||
+ <&part_number_otp>,
|
||
+ <&monotonic_otp>,
|
||
+ <&nand_otp>,
|
||
+ <&uid_otp>,
|
||
+ <&package_otp>,
|
||
+ <&hw2_otp>,
|
||
+ <&pkh_otp>,
|
||
+ <&board_id>;
|
||
+
|
||
+ nvmem-cell-names = "cfg0_otp",
|
||
+ "part_number_otp",
|
||
+ "monotonic_otp",
|
||
+ "nand_otp",
|
||
+ "uid_otp",
|
||
+ "package_otp",
|
||
+ "hw2_otp",
|
||
+ "pkh_otp",
|
||
+ "board_id";
|
||
};
|
||
|
||
&pwr_regulators {
|
||
+ system_suspend_supported_soc_modes = <
|
||
+ STM32_PM_CSLEEP_RUN
|
||
+ STM32_PM_CSTOP_ALLOW_LP_STOP
|
||
+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR
|
||
+ >;
|
||
+ system_off_soc_mode = <STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF>;
|
||
vdd-supply = <&vdd>;
|
||
vdd_3v3_usbfs-supply = <&vdd_usb>;
|
||
};
|
||
|
||
+&rcc {
|
||
+ st,hsi-cal;
|
||
+ st,csi-cal;
|
||
+ st,cal-sec = <60>;
|
||
+ st,clksrc = <
|
||
+ CLK_MPU_PLL1P
|
||
+ CLK_AXI_PLL2P
|
||
+ CLK_MCU_PLL3P
|
||
+ CLK_PLL12_HSE
|
||
+ CLK_PLL3_HSE
|
||
+ CLK_PLL4_HSE
|
||
+ CLK_RTC_LSE
|
||
+ CLK_MCO1_DISABLED
|
||
+ CLK_MCO2_DISABLED
|
||
+ >;
|
||
+
|
||
+ st,clkdiv = <
|
||
+ 1 /*MPU*/
|
||
+ 0 /*AXI*/
|
||
+ 0 /*MCU*/
|
||
+ 1 /*APB1*/
|
||
+ 1 /*APB2*/
|
||
+ 1 /*APB3*/
|
||
+ 1 /*APB4*/
|
||
+ 2 /*APB5*/
|
||
+ 23 /*RTC*/
|
||
+ 0 /*MCO1*/
|
||
+ 0 /*MCO2*/
|
||
+ >;
|
||
+
|
||
+ st,pkcs = <
|
||
+ CLK_CKPER_HSE
|
||
+ CLK_FMC_ACLK
|
||
+ CLK_QSPI_ACLK
|
||
+ CLK_ETH_DISABLED
|
||
+ CLK_SDMMC12_PLL4P
|
||
+ CLK_DSI_DSIPLL
|
||
+ CLK_STGEN_HSE
|
||
+ CLK_USBPHY_HSE
|
||
+ CLK_SPI2S1_PLL3Q
|
||
+ CLK_SPI2S23_PLL3Q
|
||
+ CLK_SPI45_HSI
|
||
+ CLK_SPI6_HSI
|
||
+ CLK_I2C46_HSI
|
||
+ CLK_SDMMC3_PLL4P
|
||
+ CLK_USBO_USBPHY
|
||
+ CLK_ADC_CKPER
|
||
+ CLK_CEC_LSE
|
||
+ CLK_I2C12_HSI
|
||
+ CLK_I2C35_HSI
|
||
+ CLK_UART1_HSI
|
||
+ CLK_UART24_HSI
|
||
+ CLK_UART35_HSI
|
||
+ CLK_UART6_HSI
|
||
+ CLK_UART78_HSI
|
||
+ CLK_SPDIF_PLL4P
|
||
+ CLK_FDCAN_PLL4R
|
||
+ CLK_SAI1_PLL3Q
|
||
+ CLK_SAI2_PLL3Q
|
||
+ CLK_SAI3_PLL3Q
|
||
+ CLK_SAI4_PLL3Q
|
||
+ CLK_RNG1_LSI
|
||
+ CLK_RNG2_LSI
|
||
+ CLK_LPTIM1_PCLK1
|
||
+ CLK_LPTIM23_PCLK3
|
||
+ CLK_LPTIM45_LSE
|
||
+ >;
|
||
+
|
||
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
|
||
+ pll2: st,pll@1 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <1>;
|
||
+ cfg = <2 65 1 0 0 PQR(1,1,1)>;
|
||
+ frac = <0x1400>;
|
||
+ };
|
||
+
|
||
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
|
||
+ pll3: st,pll@2 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <2>;
|
||
+ cfg = <1 33 1 16 36 PQR(1,1,1)>;
|
||
+ frac = <0x1a04>;
|
||
+ };
|
||
+
|
||
+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
|
||
+ pll4: st,pll@3 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <3>;
|
||
+ cfg = <3 98 5 7 7 PQR(1,1,1)>;
|
||
+ };
|
||
+};
|
||
+
|
||
&rng1 {
|
||
status = "okay";
|
||
+ secure-status = "okay";
|
||
};
|
||
|
||
&rtc {
|
||
status = "okay";
|
||
-};
|
||
-
|
||
-&sai2 {
|
||
- clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
|
||
- clock-names = "pclk", "x8k", "x11k";
|
||
- pinctrl-names = "default", "sleep";
|
||
- pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
|
||
- pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
|
||
- status = "okay";
|
||
-
|
||
- sai2a: audio-controller@4400b004 {
|
||
- #clock-cells = <0>;
|
||
- dma-names = "tx";
|
||
- clocks = <&rcc SAI2_K>;
|
||
- clock-names = "sai_ck";
|
||
- status = "okay";
|
||
-
|
||
- sai2a_port: port {
|
||
- sai2a_endpoint: endpoint {
|
||
- remote-endpoint = <&cs42l51_tx_endpoint>;
|
||
- format = "i2s";
|
||
- mclk-fs = <256>;
|
||
- dai-tdm-slot-num = <2>;
|
||
- dai-tdm-slot-width = <32>;
|
||
- };
|
||
- };
|
||
- };
|
||
-
|
||
- sai2b: audio-controller@4400b024 {
|
||
- dma-names = "rx";
|
||
- st,sync = <&sai2a 2>;
|
||
- clocks = <&rcc SAI2_K>, <&sai2a>;
|
||
- clock-names = "sai_ck", "MCLK";
|
||
- status = "okay";
|
||
-
|
||
- sai2b_port: port {
|
||
- sai2b_endpoint: endpoint {
|
||
- remote-endpoint = <&cs42l51_rx_endpoint>;
|
||
- format = "i2s";
|
||
- mclk-fs = <256>;
|
||
- dai-tdm-slot-num = <2>;
|
||
- dai-tdm-slot-width = <32>;
|
||
- };
|
||
- };
|
||
- };
|
||
+ secure-status = "okay";
|
||
};
|
||
|
||
&sdmmc1 {
|
||
- pinctrl-names = "default", "opendrain", "sleep";
|
||
+ pinctrl-names = "default";
|
||
pinctrl-0 = <&sdmmc1_b4_pins_a>;
|
||
- pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
|
||
- pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
|
||
- broken-cd;
|
||
+ disable-wp;
|
||
st,neg-edge;
|
||
bus-width = <4>;
|
||
vmmc-supply = <&v3v3>;
|
||
status = "okay";
|
||
};
|
||
|
||
-&sdmmc3 {
|
||
- pinctrl-names = "default", "opendrain", "sleep";
|
||
- pinctrl-0 = <&sdmmc3_b4_pins_a>;
|
||
- pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
|
||
- pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
|
||
- broken-cd;
|
||
- st,neg-edge;
|
||
- bus-width = <4>;
|
||
- vmmc-supply = <&v3v3>;
|
||
- status = "disabled";
|
||
-};
|
||
-
|
||
-&timers1 {
|
||
- /* spare dmas for other usage */
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm1_pins_a>;
|
||
- pinctrl-1 = <&pwm1_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@0 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers3 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm3_pins_a>;
|
||
- pinctrl-1 = <&pwm3_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@2 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers4 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>;
|
||
- pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@3 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers5 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm5_pins_a>;
|
||
- pinctrl-1 = <&pwm5_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@4 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers6 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- timer@5 {
|
||
- status = "okay";
|
||
- };
|
||
-};
|
||
-
|
||
-&timers12 {
|
||
- /delete-property/dmas;
|
||
- /delete-property/dma-names;
|
||
- status = "disabled";
|
||
- pwm {
|
||
- pinctrl-0 = <&pwm12_pins_a>;
|
||
- pinctrl-1 = <&pwm12_sleep_pins_a>;
|
||
- pinctrl-names = "default", "sleep";
|
||
- status = "okay";
|
||
- };
|
||
- timer@11 {
|
||
- status = "okay";
|
||
- };
|
||
+&timers15 {
|
||
+ secure-status = "okay";
|
||
+ st,hsi-cal-input = <7>;
|
||
+ st,csi-cal-input = <8>;
|
||
};
|
||
|
||
&uart4 {
|
||
@@ -589,15 +436,23 @@
|
||
status = "okay";
|
||
};
|
||
|
||
-&usbh_ehci {
|
||
- phys = <&usbphyc_port0>;
|
||
- status = "okay";
|
||
+&uart7 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&uart7_pins_b>;
|
||
+ status = "disabled";
|
||
+};
|
||
+
|
||
+&usart3 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&usart3_pins_b>;
|
||
+ uart-has-rtscts;
|
||
+ status = "disabled";
|
||
};
|
||
|
||
&usbotg_hs {
|
||
- dr_mode = "peripheral";
|
||
phys = <&usbphyc_port1 0>;
|
||
phy-names = "usb2-phy";
|
||
+ usb-role-switch;
|
||
status = "okay";
|
||
};
|
||
|
||
@@ -607,19 +462,8 @@
|
||
|
||
&usbphyc_port0 {
|
||
phy-supply = <&vdd_usb>;
|
||
- vdda1v1-supply = <®11>;
|
||
- vdda1v8-supply = <®18>;
|
||
};
|
||
|
||
&usbphyc_port1 {
|
||
phy-supply = <&vdd_usb>;
|
||
- vdda1v1-supply = <®11>;
|
||
- vdda1v8-supply = <®18>;
|
||
-};
|
||
-
|
||
-&vrefbuf {
|
||
- regulator-min-microvolt = <2500000>;
|
||
- regulator-max-microvolt = <2500000>;
|
||
- vdda-supply = <&vdd>;
|
||
- status = "okay";
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xx-edx.dtsi b/core/arch/arm/dts/stm32mp15xx-edx.dtsi
|
||
new file mode 100644
|
||
index 0000000..b7683a6
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp15xx-edx.dtsi
|
||
@@ -0,0 +1,478 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
||
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+
|
||
+/ {
|
||
+ memory@c0000000 {
|
||
+ device_type = "memory";
|
||
+ reg = <0xC0000000 0x40000000>;
|
||
+ };
|
||
+
|
||
+ vin: vin {
|
||
+ compatible = "regulator-fixed";
|
||
+ regulator-name = "vin";
|
||
+ regulator-min-microvolt = <5000000>;
|
||
+ regulator-max-microvolt = <5000000>;
|
||
+ regulator-always-on;
|
||
+ };
|
||
+};
|
||
+
|
||
+&bsec {
|
||
+ board_id: board_id@ec {
|
||
+ reg = <0xec 0x4>;
|
||
+ st,non-secure-otp;
|
||
+ };
|
||
+};
|
||
+
|
||
+&clk_hse {
|
||
+ st,digbypass;
|
||
+};
|
||
+
|
||
+&cpu0{
|
||
+ cpu-supply = <&vddcore>;
|
||
+};
|
||
+
|
||
+&hash1 {
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&i2c4 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&i2c4_pins_a>;
|
||
+ i2c-scl-rising-time-ns = <185>;
|
||
+ i2c-scl-falling-time-ns = <20>;
|
||
+ clock-frequency = <400000>;
|
||
+ status = "okay";
|
||
+ secure-status = "okay";
|
||
+
|
||
+ pmic: stpmic@33 {
|
||
+ compatible = "st,stpmic1";
|
||
+ reg = <0x33>;
|
||
+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
|
||
+ interrupt-controller;
|
||
+ #interrupt-cells = <2>;
|
||
+ status = "okay";
|
||
+ secure-status = "okay";
|
||
+
|
||
+ regulators {
|
||
+ compatible = "st,stpmic1-regulators";
|
||
+ buck1-supply = <&vin>;
|
||
+ buck2-supply = <&vin>;
|
||
+ buck3-supply = <&vin>;
|
||
+ buck4-supply = <&vin>;
|
||
+ ldo1-supply = <&v3v3>;
|
||
+ ldo2-supply = <&v3v3>;
|
||
+ ldo3-supply = <&vdd_ddr>;
|
||
+ ldo4-supply = <&vin>;
|
||
+ ldo5-supply = <&v3v3>;
|
||
+ ldo6-supply = <&v3v3>;
|
||
+ vref_ddr-supply = <&vin>;
|
||
+ boost-supply = <&vin>;
|
||
+ pwr_sw1-supply = <&bst_out>;
|
||
+ pwr_sw2-supply = <&bst_out>;
|
||
+
|
||
+ vddcore: buck1 {
|
||
+ regulator-name = "vddcore";
|
||
+ regulator-min-microvolt = <1200000>;
|
||
+ regulator-max-microvolt = <1350000>;
|
||
+ regulator-always-on;
|
||
+ regulator-initial-mode = <0>;
|
||
+ regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ regulator-suspend-microvolt = <1200000>;
|
||
+ };
|
||
+ lplv-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ regulator-suspend-microvolt = <900000>;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vdd_ddr: buck2 {
|
||
+ regulator-name = "vdd_ddr";
|
||
+ regulator-min-microvolt = <1350000>;
|
||
+ regulator-max-microvolt = <1350000>;
|
||
+ regulator-always-on;
|
||
+ regulator-initial-mode = <0>;
|
||
+ regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-suspend-microvolt = <1350000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ lplv-stop {
|
||
+ regulator-suspend-microvolt = <1350000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-suspend-microvolt = <1350000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vdd: buck3 {
|
||
+ regulator-name = "vdd";
|
||
+ regulator-min-microvolt = <3300000>;
|
||
+ regulator-max-microvolt = <3300000>;
|
||
+ regulator-always-on;
|
||
+ st,mask-reset;
|
||
+ regulator-initial-mode = <0>;
|
||
+ regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ lplv-stop {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-suspend-microvolt = <3300000>;
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ v3v3: buck4 {
|
||
+ regulator-name = "v3v3";
|
||
+ regulator-min-microvolt = <3300000>;
|
||
+ regulator-max-microvolt = <3300000>;
|
||
+ regulator-always-on;
|
||
+ regulator-over-current-protection;
|
||
+ regulator-initial-mode = <0>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vdda: ldo1 {
|
||
+ regulator-name = "vdda";
|
||
+ regulator-min-microvolt = <2900000>;
|
||
+ regulator-max-microvolt = <2900000>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ v2v8: ldo2 {
|
||
+ regulator-name = "v2v8";
|
||
+ regulator-min-microvolt = <2800000>;
|
||
+ regulator-max-microvolt = <2800000>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vtt_ddr: ldo3 {
|
||
+ regulator-name = "vtt_ddr";
|
||
+ regulator-min-microvolt = <500000>;
|
||
+ regulator-max-microvolt = <750000>;
|
||
+ regulator-always-on;
|
||
+ regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ lplv-stop {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vdd_usb: ldo4 {
|
||
+ regulator-name = "vdd_usb";
|
||
+ regulator-min-microvolt = <3300000>;
|
||
+ regulator-max-microvolt = <3300000>;
|
||
+ regulator-always-on;
|
||
+ standby-ddr-sr {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vdd_sd: ldo5 {
|
||
+ regulator-name = "vdd_sd";
|
||
+ regulator-min-microvolt = <2900000>;
|
||
+ regulator-max-microvolt = <2900000>;
|
||
+ regulator-boot-on;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ v1v8: ldo6 {
|
||
+ regulator-name = "v1v8";
|
||
+ regulator-min-microvolt = <1800000>;
|
||
+ regulator-max-microvolt = <1800000>;
|
||
+ standby-ddr-sr {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ vref_ddr: vref_ddr {
|
||
+ regulator-name = "vref_ddr";
|
||
+ regulator-always-on;
|
||
+ regulator-over-current-protection;
|
||
+ lp-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ lplv-stop {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-sr {
|
||
+ regulator-on-in-suspend;
|
||
+ };
|
||
+ standby-ddr-off {
|
||
+ regulator-off-in-suspend;
|
||
+ };
|
||
+ };
|
||
+
|
||
+ bst_out: boost {
|
||
+ regulator-name = "bst_out";
|
||
+ };
|
||
+
|
||
+ vbus_otg: pwr_sw1 {
|
||
+ regulator-name = "vbus_otg";
|
||
+ };
|
||
+
|
||
+ vbus_sw: pwr_sw2 {
|
||
+ regulator-name = "vbus_sw";
|
||
+ regulator-active-discharge = <1>;
|
||
+ };
|
||
+ };
|
||
+ };
|
||
+};
|
||
+
|
||
+&iwdg2 {
|
||
+ timeout-sec = <32>;
|
||
+ status = "okay";
|
||
+ secure-status = "okay";
|
||
+};
|
||
+
|
||
+&nvmem_layout {
|
||
+ nvmem-cells = <&cfg0_otp>,
|
||
+ <&part_number_otp>,
|
||
+ <&monotonic_otp>,
|
||
+ <&nand_otp>,
|
||
+ <&uid_otp>,
|
||
+ <&package_otp>,
|
||
+ <&hw2_otp>,
|
||
+ <&pkh_otp>,
|
||
+ <&board_id>;
|
||
+
|
||
+ nvmem-cell-names = "cfg0_otp",
|
||
+ "part_number_otp",
|
||
+ "monotonic_otp",
|
||
+ "nand_otp",
|
||
+ "uid_otp",
|
||
+ "package_otp",
|
||
+ "hw2_otp",
|
||
+ "pkh_otp",
|
||
+ "board_id";
|
||
+};
|
||
+
|
||
+&pwr_regulators {
|
||
+ system_suspend_supported_soc_modes = <
|
||
+ STM32_PM_CSLEEP_RUN
|
||
+ STM32_PM_CSTOP_ALLOW_LP_STOP
|
||
+ STM32_PM_CSTOP_ALLOW_LPLV_STOP
|
||
+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR
|
||
+ >;
|
||
+ system_off_soc_mode = <STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF>;
|
||
+ vdd-supply = <&vdd>;
|
||
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
|
||
+};
|
||
+
|
||
+&rcc {
|
||
+ st,hsi-cal;
|
||
+ st,csi-cal;
|
||
+ st,cal-sec = <60>;
|
||
+ st,clksrc = <
|
||
+ CLK_MPU_PLL1P
|
||
+ CLK_AXI_PLL2P
|
||
+ CLK_MCU_PLL3P
|
||
+ CLK_PLL12_HSE
|
||
+ CLK_PLL3_HSE
|
||
+ CLK_PLL4_HSE
|
||
+ CLK_RTC_LSE
|
||
+ CLK_MCO1_DISABLED
|
||
+ CLK_MCO2_DISABLED
|
||
+ >;
|
||
+
|
||
+ st,clkdiv = <
|
||
+ 1 /*MPU*/
|
||
+ 0 /*AXI*/
|
||
+ 0 /*MCU*/
|
||
+ 1 /*APB1*/
|
||
+ 1 /*APB2*/
|
||
+ 1 /*APB3*/
|
||
+ 1 /*APB4*/
|
||
+ 2 /*APB5*/
|
||
+ 23 /*RTC*/
|
||
+ 0 /*MCO1*/
|
||
+ 0 /*MCO2*/
|
||
+ >;
|
||
+
|
||
+ st,pkcs = <
|
||
+ CLK_CKPER_HSE
|
||
+ CLK_FMC_ACLK
|
||
+ CLK_QSPI_ACLK
|
||
+ CLK_ETH_DISABLED
|
||
+ CLK_SDMMC12_PLL4P
|
||
+ CLK_DSI_DSIPLL
|
||
+ CLK_STGEN_HSE
|
||
+ CLK_USBPHY_HSE
|
||
+ CLK_SPI2S1_PLL3Q
|
||
+ CLK_SPI2S23_PLL3Q
|
||
+ CLK_SPI45_HSI
|
||
+ CLK_SPI6_HSI
|
||
+ CLK_I2C46_HSI
|
||
+ CLK_SDMMC3_PLL4P
|
||
+ CLK_USBO_USBPHY
|
||
+ CLK_ADC_CKPER
|
||
+ CLK_CEC_LSE
|
||
+ CLK_I2C12_HSI
|
||
+ CLK_I2C35_HSI
|
||
+ CLK_UART1_HSI
|
||
+ CLK_UART24_HSI
|
||
+ CLK_UART35_HSI
|
||
+ CLK_UART6_HSI
|
||
+ CLK_UART78_HSI
|
||
+ CLK_SPDIF_PLL4P
|
||
+ CLK_FDCAN_PLL4R
|
||
+ CLK_SAI1_PLL3Q
|
||
+ CLK_SAI2_PLL3Q
|
||
+ CLK_SAI3_PLL3Q
|
||
+ CLK_SAI4_PLL3Q
|
||
+ CLK_RNG1_LSI
|
||
+ CLK_RNG2_LSI
|
||
+ CLK_LPTIM1_PCLK1
|
||
+ CLK_LPTIM23_PCLK3
|
||
+ CLK_LPTIM45_LSE
|
||
+ >;
|
||
+
|
||
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
|
||
+ pll2: st,pll@1 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <1>;
|
||
+ cfg = <2 65 1 0 0 PQR(1,1,1)>;
|
||
+ frac = <0x1400>;
|
||
+ };
|
||
+
|
||
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
|
||
+ pll3: st,pll@2 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <2>;
|
||
+ cfg = <1 33 1 16 36 PQR(1,1,1)>;
|
||
+ frac = <0x1a04>;
|
||
+ };
|
||
+
|
||
+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
|
||
+ pll4: st,pll@3 {
|
||
+ compatible = "st,stm32mp1-pll";
|
||
+ reg = <3>;
|
||
+ cfg = <3 98 5 7 7 PQR(1,1,1)>;
|
||
+ };
|
||
+};
|
||
+
|
||
+&rng1 {
|
||
+ status = "okay";
|
||
+ secure-status = "okay";
|
||
+};
|
||
+
|
||
+&rtc {
|
||
+ status = "okay";
|
||
+ secure-status = "okay";
|
||
+};
|
||
+
|
||
+&sdmmc1 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
|
||
+ disable-wp;
|
||
+ st,sig-dir;
|
||
+ st,neg-edge;
|
||
+ st,use-ckin;
|
||
+ bus-width = <4>;
|
||
+ vmmc-supply = <&vdd_sd>;
|
||
+ sd-uhs-sdr12;
|
||
+ sd-uhs-sdr25;
|
||
+ sd-uhs-sdr50;
|
||
+ sd-uhs-ddr50;
|
||
+ sd-uhs-sdr104;
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&sdmmc2 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
|
||
+ non-removable;
|
||
+ no-sd;
|
||
+ no-sdio;
|
||
+ st,neg-edge;
|
||
+ bus-width = <8>;
|
||
+ vmmc-supply = <&v3v3>;
|
||
+ vqmmc-supply = <&vdd>;
|
||
+ mmc-ddr-3_3v;
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&timers15 {
|
||
+ secure-status = "okay";
|
||
+ st,hsi-cal-input = <7>;
|
||
+ st,csi-cal-input = <8>;
|
||
+};
|
||
+
|
||
+&uart4 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&uart4_pins_a>;
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&usbotg_hs {
|
||
+ vbus-supply = <&vbus_otg>;
|
||
+};
|
||
+
|
||
+&usbphyc_port0 {
|
||
+ phy-supply = <&vdd_usb>;
|
||
+};
|
||
+
|
||
+&usbphyc_port1 {
|
||
+ phy-supply = <&vdd_usb>;
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xx-evx.dtsi b/core/arch/arm/dts/stm32mp15xx-evx.dtsi
|
||
new file mode 100644
|
||
index 0000000..fee2bac
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/dts/stm32mp15xx-evx.dtsi
|
||
@@ -0,0 +1,71 @@
|
||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
||
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+&fmc {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&fmc_pins_a>;
|
||
+ status = "okay";
|
||
+ #address-cells = <1>;
|
||
+ #size-cells = <0>;
|
||
+
|
||
+ nand@0 {
|
||
+ reg = <0>;
|
||
+ nand-on-flash-bbt;
|
||
+ #address-cells = <1>;
|
||
+ #size-cells = <1>;
|
||
+ };
|
||
+};
|
||
+
|
||
+&i2c4 {
|
||
+ pmic: stpmic@33 {
|
||
+ regulators {
|
||
+ v1v8: ldo6 {
|
||
+ regulator-enable-ramp-delay = <300000>;
|
||
+ };
|
||
+ };
|
||
+ };
|
||
+};
|
||
+
|
||
+&qspi {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
|
||
+ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
|
||
+ #address-cells = <1>;
|
||
+ #size-cells = <0>;
|
||
+ status = "okay";
|
||
+
|
||
+ flash0: mx66l51235l@0 {
|
||
+ compatible = "jedec,spi-nor";
|
||
+ reg = <0>;
|
||
+ spi-rx-bus-width = <4>;
|
||
+ spi-max-frequency = <108000000>;
|
||
+ #address-cells = <1>;
|
||
+ #size-cells = <1>;
|
||
+ };
|
||
+};
|
||
+
|
||
+&timers12 {
|
||
+ status = "disabled";
|
||
+};
|
||
+
|
||
+&usart3 {
|
||
+ pinctrl-names = "default";
|
||
+ pinctrl-0 = <&usart3_pins_a>;
|
||
+ uart-has-rtscts;
|
||
+ status = "disabled";
|
||
+};
|
||
+
|
||
+&usbotg_hs {
|
||
+ pinctrl-0 = <&usbotg_hs_pins_a>;
|
||
+ pinctrl-names = "default";
|
||
+ phys = <&usbphyc_port1 0>;
|
||
+ phy-names = "usb2-phy";
|
||
+ status = "okay";
|
||
+};
|
||
+
|
||
+&usbphyc {
|
||
+ status = "okay";
|
||
+};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi
|
||
index 04f7a43..341529b 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi
|
||
@@ -1,7 +1,7 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
* Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
- * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
|
||
*/
|
||
|
||
&pinctrl {
|
||
@@ -79,6 +79,7 @@
|
||
|
||
gpioz: gpio@54004000 {
|
||
status = "okay";
|
||
+ secure-status = "okay";
|
||
ngpios = <8>;
|
||
gpio-ranges = <&pinctrl_z 0 400 8>;
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi
|
||
index 328dad1..d29af89 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi
|
||
@@ -1,7 +1,7 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
* Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
- * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
|
||
*/
|
||
|
||
&pinctrl {
|
||
diff --git a/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi
|
||
index 7eaa245..02070bb 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi
|
||
@@ -1,7 +1,7 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
* Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
- * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
|
||
*/
|
||
|
||
&pinctrl {
|
||
@@ -67,6 +67,7 @@
|
||
|
||
gpioz: gpio@54004000 {
|
||
status = "okay";
|
||
+ secure-status = "okay";
|
||
ngpios = <8>;
|
||
gpio-ranges = <&pinctrl_z 0 400 8>;
|
||
};
|
||
diff --git a/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi
|
||
index b63e207..023f540 100644
|
||
--- a/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi
|
||
+++ b/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi
|
||
@@ -1,7 +1,7 @@
|
||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||
/*
|
||
* Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||
- * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
|
||
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
|
||
*/
|
||
|
||
&pinctrl {
|
||
diff --git a/core/arch/arm/include/arm32.h b/core/arch/arm/include/arm32.h
|
||
index 286f4e7..4a6f7a2 100644
|
||
--- a/core/arch/arm/include/arm32.h
|
||
+++ b/core/arch/arm/include/arm32.h
|
||
@@ -1,6 +1,6 @@
|
||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||
/*
|
||
- * Copyright (c) 2016, Linaro Limited
|
||
+ * Copyright (c) 2016-2019, Linaro Limited
|
||
* Copyright (c) 2014, STMicroelectronics International N.V.
|
||
*/
|
||
|
||
@@ -162,6 +162,15 @@
|
||
#define IDPFR1_GENTIMER_SHIFT 16
|
||
#define IDPFR1_GENTIMER_MASK (0xF << IDPFR1_GENTIMER_SHIFT)
|
||
|
||
+/* Generic timer registers and fields */
|
||
+#define CNTCR_OFFSET 0x000
|
||
+#define CNTSR_OFFSET 0x004
|
||
+#define CNTCVL_OFFSET 0x008
|
||
+#define CNTCVU_OFFSET 0x00C
|
||
+#define CNTFID_OFFSET 0x020
|
||
+
|
||
+#define CNTCR_EN BIT(0)
|
||
+
|
||
#ifndef __ASSEMBLER__
|
||
#include <generated/arm32_sysreg.h>
|
||
#ifdef CFG_ARM_GICV3
|
||
diff --git a/core/arch/arm/include/mm/core_mmu.h b/core/arch/arm/include/mm/core_mmu.h
|
||
index a3dbdc0..05db229 100644
|
||
--- a/core/arch/arm/include/mm/core_mmu.h
|
||
+++ b/core/arch/arm/include/mm/core_mmu.h
|
||
@@ -96,6 +96,7 @@
|
||
* MEM_AREA_NSEC_SHM: NonSecure shared RAM between NSec and TEE.
|
||
* MEM_AREA_RAM_NSEC: NonSecure RAM storing data
|
||
* MEM_AREA_RAM_SEC: Secure RAM storing some secrets
|
||
+ * MEM_AREA_ROM_SEC: Secure read only memory storing some secrets
|
||
* MEM_AREA_IO_NSEC: NonSecure HW mapped registers
|
||
* MEM_AREA_IO_SEC: Secure HW mapped registers
|
||
* MEM_AREA_EXT_DT: Memory loads external device tree
|
||
@@ -120,6 +121,7 @@ enum teecore_memtypes {
|
||
MEM_AREA_NSEC_SHM,
|
||
MEM_AREA_RAM_NSEC,
|
||
MEM_AREA_RAM_SEC,
|
||
+ MEM_AREA_ROM_SEC,
|
||
MEM_AREA_IO_NSEC,
|
||
MEM_AREA_IO_SEC,
|
||
MEM_AREA_EXT_DT,
|
||
@@ -149,6 +151,7 @@ static inline const char *teecore_memtype_name(enum teecore_memtypes type)
|
||
[MEM_AREA_NSEC_SHM] = "NSEC_SHM",
|
||
[MEM_AREA_RAM_NSEC] = "RAM_NSEC",
|
||
[MEM_AREA_RAM_SEC] = "RAM_SEC",
|
||
+ [MEM_AREA_ROM_SEC] = "ROM_SEC",
|
||
[MEM_AREA_IO_NSEC] = "IO_NSEC",
|
||
[MEM_AREA_IO_SEC] = "IO_SEC",
|
||
[MEM_AREA_EXT_DT] = "EXT_DT",
|
||
diff --git a/core/arch/arm/include/sm/pm.h b/core/arch/arm/include/sm/pm.h
|
||
index 939f966..90f031a 100644
|
||
--- a/core/arch/arm/include/sm/pm.h
|
||
+++ b/core/arch/arm/include/sm/pm.h
|
||
@@ -34,7 +34,11 @@
|
||
struct sm_pm_ctx {
|
||
uint32_t sp;
|
||
paddr_t cpu_resume_addr;
|
||
+#ifdef CFG_WITH_LPAE
|
||
+ uint32_t suspend_regs[18];
|
||
+#else
|
||
uint32_t suspend_regs[16];
|
||
+#endif
|
||
};
|
||
|
||
/* suspend/resume core functions */
|
||
diff --git a/core/arch/arm/mm/core_mmu.c b/core/arch/arm/mm/core_mmu.c
|
||
index fced2df..2131d0b 100644
|
||
--- a/core/arch/arm/mm/core_mmu.c
|
||
+++ b/core/arch/arm/mm/core_mmu.c
|
||
@@ -510,7 +510,6 @@ static bool pbuf_is_sdp_mem(paddr_t pbuf __unused, size_t len __unused)
|
||
|
||
/* Check special memories comply with registered memories */
|
||
static void verify_special_mem_areas(struct tee_mmap_region *mem_map,
|
||
- size_t len,
|
||
const struct core_mmu_phys_mem *start,
|
||
const struct core_mmu_phys_mem *end,
|
||
const char *area_name __maybe_unused)
|
||
@@ -518,7 +517,6 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map,
|
||
const struct core_mmu_phys_mem *mem;
|
||
const struct core_mmu_phys_mem *mem2;
|
||
struct tee_mmap_region *mmap;
|
||
- size_t n;
|
||
|
||
if (start == end) {
|
||
DMSG("No %s memory area defined", area_name);
|
||
@@ -545,15 +543,16 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map,
|
||
* Check memories do not intersect any mapped memory.
|
||
* This is called before reserved VA space is loaded in mem_map.
|
||
*
|
||
- * Only exception is with MEM_AREA_RAM_NSEC and MEM_AREA_NSEC_SHM,
|
||
+ * Exceptions are the memory areas that maps with the same attributes
|
||
+ * as for example MEM_AREA_RAM_NSEC and MEM_AREA_NSEC_SHM
|
||
* which may overlap since they are used for the same purpose
|
||
* except that MEM_AREA_NSEC_SHM is always mapped and
|
||
* MEM_AREA_RAM_NSEC only uses a dynamic mapping.
|
||
*/
|
||
for (mem = start; mem < end; mem++) {
|
||
- for (mmap = mem_map, n = 0; n < len; mmap++, n++) {
|
||
- if (mem->type == MEM_AREA_RAM_NSEC &&
|
||
- mmap->type == MEM_AREA_NSEC_SHM)
|
||
+ for (mmap = mem_map; mmap->type != MEM_AREA_END; mmap++) {
|
||
+ if (core_mmu_type_to_attr(mem->type) ==
|
||
+ core_mmu_type_to_attr(mmap->type))
|
||
continue;
|
||
if (core_is_buffer_intersect(mem->addr, mem->size,
|
||
mmap->pa, mmap->size)) {
|
||
@@ -678,6 +677,8 @@ uint32_t core_mmu_type_to_attr(enum teecore_memtypes t)
|
||
case MEM_AREA_RAM_SEC:
|
||
case MEM_AREA_SEC_RAM_OVERALL:
|
||
return attr | TEE_MATTR_SECURE | TEE_MATTR_PRW | cached;
|
||
+ case MEM_AREA_ROM_SEC:
|
||
+ return attr | TEE_MATTR_SECURE | TEE_MATTR_PR | cached;
|
||
case MEM_AREA_RES_VASPACE:
|
||
case MEM_AREA_SHM_VASPACE:
|
||
return 0;
|
||
@@ -869,13 +870,13 @@ static size_t collect_mem_ranges(struct tee_mmap_region *memory_map,
|
||
}
|
||
|
||
#ifdef CFG_SECURE_DATA_PATH
|
||
- verify_special_mem_areas(memory_map, num_elems, phys_sdp_mem_begin,
|
||
+ verify_special_mem_areas(memory_map, phys_sdp_mem_begin,
|
||
phys_sdp_mem_end, "SDP");
|
||
|
||
check_sdp_intersection_with_nsec_ddr();
|
||
#endif
|
||
|
||
- verify_special_mem_areas(memory_map, num_elems, phys_nsec_ddr_begin,
|
||
+ verify_special_mem_areas(memory_map, phys_nsec_ddr_begin,
|
||
phys_nsec_ddr_end, "NSEC DDR");
|
||
|
||
add_va_space(memory_map, num_elems, MEM_AREA_RES_VASPACE,
|
||
@@ -1176,6 +1177,7 @@ static void check_mem_map(struct tee_mmap_region *map)
|
||
case MEM_AREA_IO_NSEC:
|
||
case MEM_AREA_EXT_DT:
|
||
case MEM_AREA_RAM_SEC:
|
||
+ case MEM_AREA_ROM_SEC:
|
||
case MEM_AREA_RAM_NSEC:
|
||
case MEM_AREA_RES_VASPACE:
|
||
case MEM_AREA_SHM_VASPACE:
|
||
diff --git a/core/arch/arm/mm/mobj.c b/core/arch/arm/mm/mobj.c
|
||
index 65ab033..d1bbf32 100644
|
||
--- a/core/arch/arm/mm/mobj.c
|
||
+++ b/core/arch/arm/mm/mobj.c
|
||
@@ -49,6 +49,7 @@ static void *mobj_phys_get_va(struct mobj *mobj, size_t offset)
|
||
|
||
return (void *)(moph->va + offset);
|
||
}
|
||
+DECLARE_KEEP_PAGER(mobj_phys_get_va);
|
||
|
||
static TEE_Result mobj_phys_get_pa(struct mobj *mobj, size_t offs,
|
||
size_t granule, paddr_t *pa)
|
||
@@ -228,7 +229,7 @@ static void *mobj_mm_get_va(struct mobj *mobj, size_t offs)
|
||
return mobj_get_va(to_mobj_mm(mobj)->parent_mobj,
|
||
mobj_mm_offs(mobj, offs));
|
||
}
|
||
-
|
||
+DECLARE_KEEP_PAGER(mobj_mm_get_va);
|
||
|
||
static TEE_Result mobj_mm_get_pa(struct mobj *mobj, size_t offs,
|
||
size_t granule, paddr_t *pa)
|
||
@@ -657,4 +658,4 @@ static TEE_Result mobj_init(void)
|
||
return TEE_SUCCESS;
|
||
}
|
||
|
||
-driver_init_late(mobj_init);
|
||
+service_init(mobj_init);
|
||
diff --git a/core/arch/arm/plat-stm32mp1/boot_api.h b/core/arch/arm/plat-stm32mp1/boot_api.h
|
||
index 62e38b5..a7daffd 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/boot_api.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/boot_api.h
|
||
@@ -14,7 +14,9 @@
|
||
#define BCKR_CORE1_MAGIC_NUMBER 4
|
||
|
||
/* Value for BCKR_CORE1_MAGIC_NUMBER entry */
|
||
+#define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xca7face0
|
||
#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xca7face1
|
||
+#define BOOT_API_A7_RESET_MAGIC_NUMBER 0xca7dead0
|
||
|
||
/* Backup register #5: physical address of core1 entry at boot up */
|
||
#define BCKR_CORE1_BRANCH_ADDRESS 5
|
||
diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk
|
||
index e82d2b9..8a449b5 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/conf.mk
|
||
+++ b/core/arch/arm/plat-stm32mp1/conf.mk
|
||
@@ -1,22 +1,41 @@
|
||
# 1GB and 512MB DDR targets do not locate secure DDR at the same place.
|
||
flavor_dts_file-157A_DK1 = stm32mp157a-dk1.dts
|
||
+flavor_dts_file-157A_ED1 = stm32mp157a-ed1.dts
|
||
+flavor_dts_file-157A_EV1 = stm32mp157a-ev1.dts
|
||
flavor_dts_file-157C_DK2 = stm32mp157c-dk2.dts
|
||
flavor_dts_file-157C_ED1 = stm32mp157c-ed1.dts
|
||
flavor_dts_file-157C_EV1 = stm32mp157c-ev1.dts
|
||
+flavor_dts_file-157D_DK1 = stm32mp157d-dk1.dts
|
||
+flavor_dts_file-157D_ED1 = stm32mp157d-ed1.dts
|
||
+flavor_dts_file-157D_EV1 = stm32mp157d-ev1.dts
|
||
+flavor_dts_file-157F_DK2 = stm32mp157f-dk2.dts
|
||
+flavor_dts_file-157F_ED1 = stm32mp157f-ed1.dts
|
||
+flavor_dts_file-157F_EV1 = stm32mp157f-ev1.dts
|
||
|
||
-flavorlist-cryp-512M = $(flavor_dts_file-157C_DK2)
|
||
+flavorlist-cryp-512M = $(flavor_dts_file-157C_DK2) \
|
||
+ $(flavor_dts_file-157F_DK2)
|
||
|
||
-flavorlist-no_cryp-512M = $(flavor_dts_file-157A_DK1)
|
||
+flavorlist-no_cryp-512M = $(flavor_dts_file-157A_DK1) \
|
||
+ $(flavor_dts_file-157D_DK1)
|
||
|
||
flavorlist-cryp-1G = $(flavor_dts_file-157C_ED1) \
|
||
- $(flavor_dts_file-157C_EV1)
|
||
+ $(flavor_dts_file-157C_EV1) \
|
||
+ $(flavor_dts_file-157F_ED1) \
|
||
+ $(flavor_dts_file-157F_EV1)
|
||
|
||
-flavorlist-no_cryp = $(flavorlist-no_cryp-512M)
|
||
+flavorlist-no_cryp-1G = $(flavor_dts_file-157A_ED1) \
|
||
+ $(flavor_dts_file-157A_EV1) \
|
||
+ $(flavor_dts_file-157D_ED1) \
|
||
+ $(flavor_dts_file-157D_EV1)
|
||
+
|
||
+flavorlist-no_cryp = $(flavorlist-no_cryp-512M) \
|
||
+ $(flavorlist-no_cryp-1G)
|
||
|
||
flavorlist-512M = $(flavorlist-cryp-512M) \
|
||
$(flavorlist-no_cryp-512M)
|
||
|
||
-flavorlist-1G = $(flavorlist-cryp-1G)
|
||
+flavorlist-1G = $(flavorlist-cryp-1G) \
|
||
+ $(flavorlist-no_cryp-1G)
|
||
|
||
ifneq ($(PLATFORM_FLAVOR),)
|
||
ifeq ($(flavor_dts_file-$(PLATFORM_FLAVOR)),)
|
||
@@ -31,10 +50,13 @@ endif
|
||
|
||
include core/arch/arm/cpu/cortex-a7.mk
|
||
|
||
+$(call force,CFG_ARM_GIC_PM,y)
|
||
$(call force,CFG_BOOT_SECONDARY_REQUEST,y)
|
||
$(call force,CFG_GENERIC_BOOT,y)
|
||
$(call force,CFG_GIC,y)
|
||
$(call force,CFG_INIT_CNTVOFF,y)
|
||
+$(call force,CFG_PM,y)
|
||
+$(call force,CFG_PM_ARM32,y)
|
||
$(call force,CFG_PM_STUBS,y)
|
||
$(call force,CFG_PSCI_ARM32,y)
|
||
$(call force,CFG_SCMI_MSG_DRIVERS,y)
|
||
@@ -67,24 +89,36 @@ CFG_TEE_CORE_NB_CORE ?= 2
|
||
CFG_WITH_PAGER ?= y
|
||
CFG_WITH_LPAE ?= y
|
||
CFG_WITH_STACK_CANARIES ?= y
|
||
-CFG_MMAP_REGIONS ?= 23
|
||
+CFG_MMAP_REGIONS ?= 25
|
||
+CFG_CORE_HEAP_SIZE ?= 49152
|
||
|
||
ifeq ($(CFG_EMBED_DTB_SOURCE_FILE),)
|
||
# Some drivers mandate DT support
|
||
+$(call force,CFG_STM32_CLKCALIB,n)
|
||
$(call force,CFG_STM32_I2C,n)
|
||
+$(call force,CFG_STM32_IWDG,n)
|
||
+$(call force,CFG_STM32_TIM,n)
|
||
$(call force,CFG_STPMIC1,n)
|
||
endif
|
||
|
||
CFG_STM32_BSEC ?= y
|
||
+CFG_STM32_CLKCALIB ?= y
|
||
+CFG_STM32_CRYP ?= y
|
||
CFG_STM32_ETZPC ?= y
|
||
CFG_STM32_GPIO ?= y
|
||
CFG_STM32_I2C ?= y
|
||
+CFG_STM32_IWDG ?= y
|
||
CFG_STM32_RNG ?= y
|
||
-CFG_STM32_RNG ?= y
|
||
+CFG_STM32_RTC ?= y
|
||
+CFG_STM32_TIM ?= y
|
||
CFG_STM32_UART ?= y
|
||
CFG_STPMIC1 ?= y
|
||
CFG_TZC400 ?= y
|
||
|
||
+ifeq ($(CFG_STM32_CLKCALIB),y)
|
||
+$(call force,CFG_STM32_TIM,y)
|
||
+endif
|
||
+
|
||
ifeq ($(CFG_STPMIC1),y)
|
||
$(call force,CFG_STM32_I2C,y)
|
||
$(call force,CFG_STM32_GPIO,y)
|
||
@@ -95,12 +129,23 @@ CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION ?= y
|
||
|
||
# SiP/OEM service for non-secure world
|
||
CFG_STM32_BSEC_SIP ?= y
|
||
+CFG_STM32_CLKCALIB_SIP ?= y
|
||
+CFG_STM32_LOWPOWER_SIP ?= $(CFG_PM)
|
||
+CFG_STM32_PWR_SIP ?= y
|
||
+CFG_STM32_RCC_SIP ?= y
|
||
+
|
||
+# Default use stm32mp1 PM mailbox context version 2
|
||
+# Use CFG_STM32MP15_PM_CONTEX_VERSION=1 to force version 0 when dealing with
|
||
+# a TF-A firmware that supports version 1 of the context mailbox.
|
||
+CFG_STM32MP15_PM_CONTEX_VERSION ?= 2
|
||
|
||
# Default enable some test facitilites
|
||
CFG_TEE_CORE_EMBED_INTERNAL_TESTS ?= y
|
||
CFG_WITH_STATS ?= y
|
||
+CFG_WERROR ?= y
|
||
|
||
# Default disable some support for pager memory size constraint
|
||
+CFG_TEE_CORE_LOG_LEVEL ?= 2
|
||
CFG_TEE_CORE_DEBUG ?= n
|
||
CFG_UNWIND ?= n
|
||
CFG_LOCKDEP ?= n
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c
|
||
new file mode 100644
|
||
index 0000000..b1b9f43
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c
|
||
@@ -0,0 +1,501 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#include <arm.h>
|
||
+#include <drivers/stm32_tim.h>
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <initcall.h>
|
||
+#include <io.h>
|
||
+#include <libfdt.h>
|
||
+#include <keep.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/dt.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/interrupt.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <kernel/pm.h>
|
||
+#include <limits.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <stm32_util.h>
|
||
+#include <string.h>
|
||
+
|
||
+#define CALIBRATION_TIMEOUT_US 10000
|
||
+
|
||
+/* List of forbiden values for HSI and CSI */
|
||
+static const uint16_t fbv_hsi[] = {
|
||
+ 512, 480, 448, 416, 384, 352, 320, 288,
|
||
+ 256, 224, 192, 160, 128, 96, 64, 32, 0,
|
||
+};
|
||
+static const uint16_t fbv_csi[] = {
|
||
+ 256, 240, 224, 208, 192, 176, 160, 144,
|
||
+ 128, 112, 96, 80, 64, 48, 32, 16, 0,
|
||
+};
|
||
+
|
||
+struct stm32mp1_trim_boundary_t {
|
||
+ unsigned int max; /* Max boundary trim value around forbidden value */
|
||
+ unsigned int min; /* Min boundary trim value around forbidden value */
|
||
+};
|
||
+
|
||
+struct stm32mp1_clk_cal {
|
||
+ const uint16_t *fbv;
|
||
+ unsigned int cal_ref;
|
||
+ int trim_max;
|
||
+ int trim_min;
|
||
+ unsigned int boundary_max;
|
||
+ unsigned long ref_freq;
|
||
+ unsigned int freq_margin;
|
||
+ unsigned long (*get_freq)(void);
|
||
+ void (*set_trim)(unsigned int cal);
|
||
+ unsigned int (*get_trim)(void);
|
||
+ struct stm32mp1_trim_boundary_t boundary[16];
|
||
+};
|
||
+
|
||
+static void hsi_set_trim(unsigned int cal);
|
||
+static unsigned int hsi_get_trimed_cal(void);
|
||
+static void csi_set_trim(unsigned int cal);
|
||
+static unsigned int csi_get_trimed_cal(void);
|
||
+
|
||
+static struct stm32mp1_clk_cal *hsi_calib;
|
||
+static struct stm32mp1_clk_cal *csi_calib;
|
||
+
|
||
+static const struct stm32mp1_clk_cal hsi_calib_config = {
|
||
+ .fbv = fbv_hsi,
|
||
+ .trim_max = 63,
|
||
+ .trim_min = -64,
|
||
+ .ref_freq = 0,
|
||
+ .freq_margin = 5,
|
||
+ .set_trim = hsi_set_trim,
|
||
+ .get_trim = hsi_get_trimed_cal,
|
||
+};
|
||
+
|
||
+static const struct stm32mp1_clk_cal csi_calib_config = {
|
||
+ .fbv = fbv_csi,
|
||
+ .trim_max = 15,
|
||
+ .trim_min = -16,
|
||
+ .ref_freq = 0,
|
||
+ .freq_margin = 8,
|
||
+ .set_trim = csi_set_trim,
|
||
+ .get_trim = csi_get_trimed_cal,
|
||
+};
|
||
+
|
||
+static int get_signed_value(uint8_t val)
|
||
+{
|
||
+ return (int8_t)(val << 1) / 2;
|
||
+}
|
||
+
|
||
+static void hsi_set_trim(unsigned int cal)
|
||
+{
|
||
+ int clk_trim = (int)cal - (int)hsi_calib->cal_ref;
|
||
+ uint32_t trim = ((uint32_t)clk_trim << RCC_HSICFGR_HSITRIM_SHIFT) &
|
||
+ RCC_HSICFGR_HSITRIM_MASK;
|
||
+
|
||
+ io_clrsetbits32(stm32_rcc_base() + RCC_HSICFGR,
|
||
+ RCC_HSICFGR_HSITRIM_MASK, trim);
|
||
+}
|
||
+DECLARE_KEEP_PAGER(hsi_set_trim);
|
||
+
|
||
+static unsigned int hsi_get_trimed_cal(void)
|
||
+{
|
||
+ uint32_t utrim = (io_read32(stm32_rcc_base() + RCC_HSICFGR) &
|
||
+ RCC_HSICFGR_HSITRIM_MASK) >>
|
||
+ RCC_HSICFGR_HSITRIM_SHIFT;
|
||
+ int trim = get_signed_value((uint8_t)utrim);
|
||
+
|
||
+ if (trim + (int)hsi_calib->cal_ref < 0)
|
||
+ return 0;
|
||
+
|
||
+ return hsi_calib->cal_ref + trim;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(hsi_get_trimed_cal);
|
||
+
|
||
+static void csi_set_trim(unsigned int cal)
|
||
+{
|
||
+ int clk_trim = (int)cal - (int)csi_calib->cal_ref +
|
||
+ csi_calib->trim_max + 1;
|
||
+ uint32_t trim = ((uint32_t)clk_trim << RCC_CSICFGR_CSITRIM_SHIFT) &
|
||
+ RCC_CSICFGR_CSITRIM_MASK;
|
||
+
|
||
+ io_clrsetbits32(stm32_rcc_base() + RCC_CSICFGR,
|
||
+ RCC_CSICFGR_CSITRIM_MASK, trim);
|
||
+}
|
||
+DECLARE_KEEP_PAGER(csi_set_trim);
|
||
+
|
||
+static unsigned int csi_get_trimed_cal(void)
|
||
+{
|
||
+ uint32_t trim = (io_read32(stm32_rcc_base() + RCC_CSICFGR) &
|
||
+ RCC_CSICFGR_CSITRIM_MASK) >>
|
||
+ RCC_CSICFGR_CSITRIM_SHIFT;
|
||
+
|
||
+ return (int)trim - csi_calib->trim_max + (int)csi_calib->cal_ref - 1;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(csi_get_trimed_cal);
|
||
+
|
||
+static unsigned int trim_increase(struct stm32mp1_clk_cal *clk_cal,
|
||
+ unsigned int cal)
|
||
+{
|
||
+ struct stm32mp1_trim_boundary_t *boundary = NULL;
|
||
+ unsigned int new_cal = 0;
|
||
+ int i = 0;
|
||
+
|
||
+ /* By default: last calibration value */
|
||
+ new_cal = cal;
|
||
+
|
||
+ /* Start from Lowest cal value */
|
||
+ for (i = (int)clk_cal->boundary_max - 1; i >= 0; i--) {
|
||
+ boundary = &clk_cal->boundary[i];
|
||
+
|
||
+ if (cal < boundary->min) {
|
||
+ new_cal = boundary->min;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if ((cal >= boundary->min) && (cal < boundary->max)) {
|
||
+ new_cal = cal + 1;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return new_cal;
|
||
+}
|
||
+
|
||
+static unsigned int trim_decrease(struct stm32mp1_clk_cal *clk_cal,
|
||
+ unsigned int cal)
|
||
+{
|
||
+ struct stm32mp1_trim_boundary_t *boundary = NULL;
|
||
+ unsigned int new_cal = 0;
|
||
+ unsigned int i = 0;
|
||
+
|
||
+ /* By default: last calibration value */
|
||
+ new_cal = cal;
|
||
+
|
||
+ /* Start from Highest cal value */
|
||
+ for (i = 0; i < clk_cal->boundary_max; i++) {
|
||
+ boundary = &clk_cal->boundary[i];
|
||
+
|
||
+ if (cal > boundary->max) {
|
||
+ new_cal = boundary->max;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if ((cal > boundary->min) && (cal <= boundary->max)) {
|
||
+ new_cal = cal - 1;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return new_cal;
|
||
+}
|
||
+
|
||
+static void rcc_calibration(struct stm32mp1_clk_cal *clk_cal)
|
||
+{
|
||
+ unsigned long margin = (clk_cal->ref_freq *
|
||
+ clk_cal->freq_margin) / 1000;
|
||
+ unsigned long min = clk_cal->ref_freq - margin;
|
||
+ unsigned long max = clk_cal->ref_freq + margin;
|
||
+ unsigned long freq = clk_cal->get_freq();
|
||
+ int trim = 0;
|
||
+ int new_trim = 0;
|
||
+ unsigned long conv = 0;
|
||
+ unsigned long min_conv = ULONG_MAX;
|
||
+ uint64_t timeout_ref = 0;
|
||
+
|
||
+ if ((freq >= min) && (freq <= max))
|
||
+ return;
|
||
+
|
||
+ trim = clk_cal->get_trim();
|
||
+ timeout_ref = timeout_init_us(CALIBRATION_TIMEOUT_US);
|
||
+ do {
|
||
+ if (freq < clk_cal->ref_freq)
|
||
+ new_trim = trim_increase(clk_cal, trim);
|
||
+ else
|
||
+ new_trim = trim_decrease(clk_cal, trim);
|
||
+
|
||
+ clk_cal->set_trim(new_trim);
|
||
+ freq = clk_cal->get_freq();
|
||
+ if (freq == 0) {
|
||
+ /* Calibration will be stopped */
|
||
+ clk_cal->ref_freq = 0U;
|
||
+ return;
|
||
+ }
|
||
+ conv = (clk_cal->ref_freq < freq) ?
|
||
+ freq - clk_cal->ref_freq : clk_cal->ref_freq - freq;
|
||
+ if (conv < min_conv) {
|
||
+ min_conv = conv;
|
||
+ trim = new_trim;
|
||
+ }
|
||
+
|
||
+ if (timeout_elapsed(timeout_ref))
|
||
+ break;
|
||
+
|
||
+ } while (conv == min_conv);
|
||
+
|
||
+ clk_cal->set_trim(trim);
|
||
+ freq = clk_cal->get_freq();
|
||
+ if ((freq < min) || (freq > max)) {
|
||
+ EMSG("%s Calibration : Freq %lu , trim %i\n",
|
||
+ (clk_cal->set_trim == hsi_set_trim) ? "HSI" : "CSI",
|
||
+ freq, trim);
|
||
+ }
|
||
+}
|
||
+
|
||
+static void save_trim(struct stm32mp1_clk_cal *clk_cal,
|
||
+ unsigned int i, unsigned int max, unsigned int min)
|
||
+{
|
||
+ clk_cal->boundary[i].max = max;
|
||
+ clk_cal->boundary[i].min = min;
|
||
+}
|
||
+
|
||
+static int trim_find_prev_boundary(struct stm32mp1_clk_cal *clk_cal,
|
||
+ unsigned int x1)
|
||
+{
|
||
+ unsigned int x = x1;
|
||
+ unsigned long freq = 0;
|
||
+
|
||
+ clk_cal->set_trim(x1 + 1);
|
||
+ freq = clk_cal->get_freq();
|
||
+
|
||
+ while (x >= (clk_cal->cal_ref + clk_cal->trim_min)) {
|
||
+ x--;
|
||
+ clk_cal->set_trim(x);
|
||
+
|
||
+ if (clk_cal->get_freq() <= freq)
|
||
+ break;
|
||
+ };
|
||
+
|
||
+ return x;
|
||
+}
|
||
+
|
||
+static void trim_table_init(struct stm32mp1_clk_cal *clk_cal)
|
||
+{
|
||
+ const uint16_t *trim_fbv = clk_cal->fbv;
|
||
+ unsigned int min = 0;
|
||
+ unsigned int max = 0;
|
||
+ int boundary = 0;
|
||
+ int i = 0;
|
||
+
|
||
+ max = clk_cal->cal_ref + clk_cal->trim_max;
|
||
+ min = clk_cal->cal_ref + clk_cal->trim_min;
|
||
+
|
||
+ while (trim_fbv[i]) {
|
||
+ unsigned int x = 0;
|
||
+ unsigned int x1 = trim_fbv[i];
|
||
+ unsigned int x2 = trim_fbv[i + 1];
|
||
+
|
||
+ if ((max <= x2) || (min >= x1)) {
|
||
+ i++;
|
||
+ if (boundary != 0)
|
||
+ goto out;
|
||
+
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ /* Take forbiden value + 1 */
|
||
+ x2 = x2 + 1;
|
||
+ if (x2 < min)
|
||
+ x2 = min;
|
||
+
|
||
+ if (boundary == 0) {
|
||
+ /* Save first boundary */
|
||
+ save_trim(clk_cal, boundary, max, x2);
|
||
+ boundary++;
|
||
+ i++;
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ x = trim_find_prev_boundary(clk_cal, x1);
|
||
+ /* Save boundary values */
|
||
+ save_trim(clk_cal, boundary, x - 1, x2);
|
||
+ boundary++;
|
||
+ i++;
|
||
+ };
|
||
+out:
|
||
+ clk_cal->boundary_max = boundary;
|
||
+}
|
||
+
|
||
+/* Timer countdown/delay argument for the target calibration periodicity */
|
||
+static uint32_t timer_val;
|
||
+
|
||
+#define CNTP_CTL_ENABLE BIT(0)
|
||
+#define CNTP_CTL_IMASK BIT(1)
|
||
+#define CNTP_CTL_ISTATUS BIT(2)
|
||
+
|
||
+static void arm_timer(void)
|
||
+{
|
||
+ if (!timer_val)
|
||
+ return;
|
||
+
|
||
+ write_cntp_ctl(read_cntp_ctl() & ~(CNTP_CTL_ENABLE | CNTP_CTL_IMASK));
|
||
+ write_cntp_tval(timer_val);
|
||
+ write_cntp_ctl(read_cntp_ctl() | CNTP_CTL_ENABLE);
|
||
+}
|
||
+
|
||
+static void arm_timer_with_period(uint32_t period_sec)
|
||
+{
|
||
+ timer_val = period_sec * read_cntfrq();
|
||
+
|
||
+ arm_timer();
|
||
+}
|
||
+
|
||
+static void calib_period(void)
|
||
+{
|
||
+ (void)stm32mp_start_clock_calib(CK_HSI);
|
||
+ (void)stm32mp_start_clock_calib(CK_CSI);
|
||
+
|
||
+ arm_timer();
|
||
+}
|
||
+
|
||
+static enum itr_return arm_cntp_it_handler(struct itr_handler *handler __unused)
|
||
+{
|
||
+ if (timer_val)
|
||
+ calib_period();
|
||
+
|
||
+ return ITRR_HANDLED;
|
||
+}
|
||
+static struct itr_handler arm_cntp_handler = {
|
||
+ .it = GIC_SPI_SEC_PHY_TIMER,
|
||
+ .handler = arm_cntp_it_handler,
|
||
+};
|
||
+DECLARE_KEEP_PAGER(arm_cntp_handler);
|
||
+
|
||
+static TEE_Result timer_pm(enum pm_op op, uint32_t pm_hint __unused,
|
||
+ const struct pm_callback_handle *handle __unused)
|
||
+{
|
||
+ if (op == PM_OP_RESUME && timer_val)
|
||
+ calib_period();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(timer_pm);
|
||
+
|
||
+static TEE_Result init_arm_cntp_timer(void)
|
||
+{
|
||
+ itr_add(&arm_cntp_handler);
|
||
+ itr_enable(arm_cntp_handler.it);
|
||
+
|
||
+ register_pm_driver_cb(timer_pm, NULL);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+driver_init(init_arm_cntp_timer);
|
||
+
|
||
+static void init_periodic_calibration(void *fdt, int node)
|
||
+{
|
||
+ uint32_t period = 0;
|
||
+ int lenp = 0;
|
||
+ const fdt32_t *cuint = fdt_getprop(fdt, node, "st,cal-sec", &lenp);
|
||
+
|
||
+ if (cuint)
|
||
+ period = fdt32_to_cpu(*cuint);
|
||
+
|
||
+ DMSG("Calib period %us", period);
|
||
+ arm_timer_with_period(period);
|
||
+}
|
||
+
|
||
+int stm32mp_start_clock_calib(unsigned int clock_id)
|
||
+{
|
||
+ struct stm32mp1_clk_cal *clk_calib = NULL;
|
||
+
|
||
+ switch (clock_id) {
|
||
+ case CK_HSI:
|
||
+ clk_calib = hsi_calib;
|
||
+ break;
|
||
+ case CK_CSI:
|
||
+ clk_calib = csi_calib;
|
||
+ break;
|
||
+ default:
|
||
+ DMSG("Cannot calibrate clock %u", clock_id);
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (clk_calib->ref_freq == 0U)
|
||
+ return 1;
|
||
+
|
||
+ DMSG("%s", clock_id == CK_HSI ? "HSI" : "CSI");
|
||
+ rcc_calibration(clk_calib);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int init_hsi_calibration(void *fdt, int node)
|
||
+{
|
||
+ if (!fdt_getprop(fdt, node, "st,hsi-cal", NULL))
|
||
+ return 0;
|
||
+
|
||
+ hsi_calib = calloc(1, sizeof(*hsi_calib));
|
||
+ assert(hsi_calib);
|
||
+ memcpy(hsi_calib, &hsi_calib_config, sizeof(*hsi_calib));
|
||
+
|
||
+ stm32_tim_freq_func(&hsi_calib->get_freq, HSI_CAL);
|
||
+ if (hsi_calib->get_freq == NULL) {
|
||
+ free(hsi_calib);
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ hsi_calib->ref_freq = stm32_clock_get_rate(CK_HSI);
|
||
+
|
||
+ hsi_calib->cal_ref = (io_read32(stm32_rcc_base() + RCC_HSICFGR) &
|
||
+ RCC_HSICFGR_HSICAL_MASK) >>
|
||
+ RCC_HSICFGR_HSICAL_SHIFT;
|
||
+
|
||
+ trim_table_init(hsi_calib);
|
||
+ hsi_calib->set_trim(hsi_calib->cal_ref);
|
||
+ stm32mp_start_clock_calib(CK_HSI);
|
||
+ return 1;
|
||
+}
|
||
+
|
||
+static int init_csi_calibration(void *fdt, int node)
|
||
+{
|
||
+ if (!fdt_getprop(fdt, node, "st,csi-cal", NULL))
|
||
+ return 0;
|
||
+
|
||
+ csi_calib = calloc(1, sizeof(*csi_calib));
|
||
+ assert(csi_calib);
|
||
+ memcpy(csi_calib, &csi_calib_config, sizeof(*csi_calib));
|
||
+
|
||
+ stm32_tim_freq_func(&csi_calib->get_freq, CSI_CAL);
|
||
+ if (csi_calib->get_freq == NULL) {
|
||
+ free(csi_calib);
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ csi_calib->ref_freq = stm32_clock_get_rate(CK_CSI);
|
||
+
|
||
+ csi_calib->cal_ref = (io_read32(stm32_rcc_base() + RCC_CSICFGR) &
|
||
+ RCC_CSICFGR_CSICAL_MASK) >>
|
||
+ RCC_CSICFGR_CSICAL_SHIFT;
|
||
+ trim_table_init(csi_calib);
|
||
+ csi_calib->set_trim(csi_calib->cal_ref);
|
||
+ stm32mp_start_clock_calib(CK_CSI);
|
||
+ return 1;
|
||
+}
|
||
+
|
||
+static TEE_Result init_stm32mp1_calib(void)
|
||
+{
|
||
+ void *fdt = NULL;
|
||
+ int rcc_node = 0;
|
||
+ int res_csi = 0;
|
||
+ int res_hsi = 0;
|
||
+
|
||
+ fdt = get_embedded_dt();
|
||
+ if (!fdt)
|
||
+ panic();
|
||
+
|
||
+ rcc_node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
|
||
+ if (rcc_node < 0)
|
||
+ panic();
|
||
+
|
||
+ res_hsi = init_hsi_calibration(fdt, rcc_node);
|
||
+ if (res_hsi < 0)
|
||
+ panic("HSI calibration init failed");
|
||
+ res_csi = init_csi_calibration(fdt, rcc_node);
|
||
+ if (res_csi < 0)
|
||
+ panic("CSI calibration init failed");
|
||
+ if (res_csi || res_hsi)
|
||
+ init_periodic_calibration(fdt, rcc_node);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+driver_init(init_stm32mp1_calib);
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c
|
||
index 47240ab..7912948 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c
|
||
@@ -6,20 +6,41 @@
|
||
#include <assert.h>
|
||
#include <drivers/stm32mp1_rcc.h>
|
||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
||
#include <initcall.h>
|
||
#include <io.h>
|
||
#include <keep.h>
|
||
+#include <kernel/delay.h>
|
||
#include <kernel/dt.h>
|
||
#include <kernel/generic_boot.h>
|
||
#include <kernel/panic.h>
|
||
+#include <kernel/pm.h>
|
||
#include <kernel/spinlock.h>
|
||
#include <libfdt.h>
|
||
#include <platform_config.h>
|
||
#include <stdio.h>
|
||
#include <stm32_util.h>
|
||
+#include <tee_api_types.h>
|
||
#include <trace.h>
|
||
#include <util.h>
|
||
|
||
+#define DT_OPP_COMPAT "operating-points-v2"
|
||
+
|
||
+/* PLL settings computation related definitions */
|
||
+#define POST_DIVM_MIN 8000000
|
||
+#define POST_DIVM_MAX 16000000
|
||
+#define DIVM_MIN 0
|
||
+#define DIVM_MAX 63
|
||
+#define DIVN_MIN 24
|
||
+#define DIVN_MAX 99
|
||
+#define DIVP_MIN 0
|
||
+#define DIVP_MAX 127
|
||
+#define FRAC_MAX 8192
|
||
+#define VCO_MIN 800000000
|
||
+#define VCO_MAX 1600000000
|
||
+
|
||
+#define PLL1_SETTINGS_VALID_ID 0x504C4C31 /* "PLL1" */
|
||
+
|
||
/* Identifiers for root oscillators */
|
||
enum stm32mp_osc_id {
|
||
_HSI = 0,
|
||
@@ -85,11 +106,14 @@ enum stm32mp1_parent_sel {
|
||
_UART24_SEL,
|
||
_UART35_SEL,
|
||
_UART78_SEL,
|
||
+ _SDMMC12_SEL,
|
||
+ _SDMMC3_SEL,
|
||
_AXISS_SEL,
|
||
_MCUSS_SEL,
|
||
_USBPHY_SEL,
|
||
_USBO_SEL,
|
||
_RTC_SEL,
|
||
+ _MPU_SEL,
|
||
_PARENT_SEL_NB,
|
||
_UNKNOWN_SEL = 0xff,
|
||
};
|
||
@@ -160,6 +184,16 @@ enum stm32mp1_div_id {
|
||
_DIV_NB,
|
||
};
|
||
|
||
+enum stm32mp1_pllcfg {
|
||
+ PLLCFG_M,
|
||
+ PLLCFG_N,
|
||
+ PLLCFG_P,
|
||
+ PLLCFG_Q,
|
||
+ PLLCFG_R,
|
||
+ PLLCFG_O,
|
||
+ PLLCFG_NB
|
||
+};
|
||
+
|
||
enum stm32mp1_plltype {
|
||
PLL_800,
|
||
PLL_1600,
|
||
@@ -212,6 +246,21 @@ struct stm32mp1_clk_pll {
|
||
enum stm32mp_osc_id refclk[REFCLK_SIZE];
|
||
};
|
||
|
||
+struct stm32mp1_pll {
|
||
+ uint8_t refclk_min;
|
||
+ uint8_t refclk_max;
|
||
+ uint8_t divn_max;
|
||
+};
|
||
+
|
||
+/* Compact structure of 32bit cells, copied raw when suspending */
|
||
+struct stm32mp1_pll_settings {
|
||
+ uint32_t valid_id;
|
||
+ uint32_t freq[PLAT_MAX_OPP_NB];
|
||
+ uint32_t volt[PLAT_MAX_OPP_NB];
|
||
+ uint32_t cfg[PLAT_MAX_OPP_NB][PLAT_MAX_PLLCFG_NB];
|
||
+ uint32_t frac[PLAT_MAX_OPP_NB];
|
||
+};
|
||
+
|
||
#define N_S 0 /* Non-secure can access RCC interface */
|
||
#define SEC 1 /* RCC[TZEN] protects RCC interface */
|
||
|
||
@@ -380,6 +429,18 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
|
||
_CLK_SC_FIXED(N_S, RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID),
|
||
_CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
|
||
_CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 0, LTDC_PX, _UNKNOWN_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 0, DMA1, _UNKNOWN_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 1, DMA2, _UNKNOWN_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 5, GPU, _UNKNOWN_SEL),
|
||
+ _CLK_SC_FIXED(N_S, RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
|
||
+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
|
||
+#endif
|
||
|
||
_CLK_SELEC(N_S, RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
|
||
};
|
||
@@ -406,6 +467,10 @@ static const uint8_t rng1_parents[] = {
|
||
_CSI, _PLL4_R, _LSE, _LSI
|
||
};
|
||
|
||
+static const uint8_t mpu_parents[] = {
|
||
+ _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */
|
||
+};
|
||
+
|
||
/* Parents for (some) non-secure clocks */
|
||
#ifdef CFG_WITH_NSEC_UARTS
|
||
static const uint8_t uart6_parents[] = {
|
||
@@ -429,6 +494,24 @@ static const uint8_t rtc_parents[] = {
|
||
_UNKNOWN_ID, _LSE, _LSI, _HSE
|
||
};
|
||
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+static const uint8_t usbphy_parents[] = {
|
||
+ _HSE_KER, _PLL4_R, _HSE_KER_DIV2
|
||
+};
|
||
+
|
||
+static const uint8_t usbo_parents[] = {
|
||
+ _PLL4_R, _USB_PHY_48
|
||
+};
|
||
+
|
||
+static const uint8_t sdmmc12_parents[] = {
|
||
+ _HCLK6, _PLL3_R, _PLL4_P, _HSI_KER
|
||
+};
|
||
+
|
||
+static const uint8_t sdmmc3_parents[] = {
|
||
+ _HCLK2, _PLL3_R, _PLL4_P, _HSI_KER
|
||
+};
|
||
+#endif
|
||
+
|
||
static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
|
||
/* Secure aware clocks */
|
||
_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents),
|
||
@@ -437,6 +520,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
|
||
_CLK_PARENT(_USART1_SEL, RCC_UART1CKSELR, 0, 0x7, usart1_parents),
|
||
_CLK_PARENT(_RNG1_SEL, RCC_RNG1CKSELR, 0, 0x3, rng1_parents),
|
||
_CLK_PARENT(_RTC_SEL, RCC_BDCR, 0, 0x3, rtc_parents),
|
||
+ _CLK_PARENT(_MPU_SEL, RCC_MPCKSELR, 0, 0x3, mpu_parents),
|
||
+ _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents),
|
||
+ _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents),
|
||
/* Always non-secure clocks (maybe used in some way in secure world) */
|
||
#ifdef CFG_WITH_NSEC_UARTS
|
||
_CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents),
|
||
@@ -444,8 +530,26 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
|
||
_CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7, uart234578_parents),
|
||
_CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7, uart234578_parents),
|
||
#endif
|
||
- _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents),
|
||
- _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents),
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ _CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7, sdmmc12_parents),
|
||
+ _CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, sdmmc3_parents),
|
||
+ _CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
|
||
+ _CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents),
|
||
+#endif
|
||
+};
|
||
+
|
||
+/* Define characteristics of PLL according type */
|
||
+static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
|
||
+ [PLL_800] = {
|
||
+ .refclk_min = 4,
|
||
+ .refclk_max = 16,
|
||
+ .divn_max = 99,
|
||
+ },
|
||
+ [PLL_1600] = {
|
||
+ .refclk_min = 8,
|
||
+ .refclk_max = 16,
|
||
+ .divn_max = 199,
|
||
+ },
|
||
};
|
||
|
||
/* PLLNCFGR2 register divider by output */
|
||
@@ -549,6 +653,10 @@ static unsigned long osc_frequency(enum stm32mp_osc_id idx)
|
||
static unsigned int gate_refcounts[NB_GATES];
|
||
static unsigned int refcount_lock;
|
||
|
||
+/* Storage of the precomputed SoC settings for PLL1 various OPPs */
|
||
+static struct stm32mp1_pll_settings pll1_settings;
|
||
+static uint32_t current_opp_khz;
|
||
+
|
||
static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx)
|
||
{
|
||
return &stm32mp1_clk_gate[idx];
|
||
@@ -701,6 +809,152 @@ static unsigned long stm32mp1_read_pll_freq(enum stm32mp1_pll_id pll_id,
|
||
return dfout;
|
||
}
|
||
|
||
+static void pll_start(enum stm32mp1_pll_id pll_id)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr;
|
||
+
|
||
+ if (io_read32(pllxcr) & RCC_PLLNCR_PLLON)
|
||
+ return;
|
||
+
|
||
+ io_clrsetbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
|
||
+ RCC_PLLNCR_DIVREN, RCC_PLLNCR_PLLON);
|
||
+}
|
||
+
|
||
+#define PLLRDY_TIMEOUT_US (200 * 1000)
|
||
+
|
||
+static int pll_output(enum stm32mp1_pll_id pll_id, uint32_t output)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr;
|
||
+ uint64_t start = 0;
|
||
+
|
||
+ start = timeout_init_us(PLLRDY_TIMEOUT_US);
|
||
+ /* Wait PLL lock */
|
||
+ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY))
|
||
+ if (timeout_elapsed(start)) {
|
||
+ EMSG("PLL%d start failed @ 0x%"PRIx32": 0x%"PRIx32,
|
||
+ pll_id, pllxcr, io_read32(pllxcr));
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ /* Start the requested output */
|
||
+ io_setbits32(pllxcr, output << RCC_PLLNCR_DIVEN_SHIFT);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int pll_stop(enum stm32mp1_pll_id pll_id)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr;
|
||
+ uint64_t start = 0;
|
||
+
|
||
+ /* Stop all output */
|
||
+ io_clrbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
|
||
+ RCC_PLLNCR_DIVREN);
|
||
+
|
||
+ /* Stop PLL */
|
||
+ io_clrbits32(pllxcr, RCC_PLLNCR_PLLON);
|
||
+
|
||
+ start = timeout_init_us(PLLRDY_TIMEOUT_US);
|
||
+ /* Wait PLL stopped */
|
||
+ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY))
|
||
+ if (timeout_elapsed(start)) {
|
||
+ EMSG("PLL%d stop failed @ 0x%"PRIx32": 0x%"PRIx32,
|
||
+ pll_id, pllxcr, io_read32(pllxcr));
|
||
+
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static uint32_t pll_compute_pllxcfgr2(uint32_t *pllcfg)
|
||
+{
|
||
+ uint32_t value = 0;
|
||
+
|
||
+ value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) &
|
||
+ RCC_PLLNCFGR2_DIVP_MASK;
|
||
+ value |= (pllcfg[PLLCFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) &
|
||
+ RCC_PLLNCFGR2_DIVQ_MASK;
|
||
+ value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) &
|
||
+ RCC_PLLNCFGR2_DIVR_MASK;
|
||
+
|
||
+ return value;
|
||
+}
|
||
+
|
||
+static void pll_config_output(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t value = 0;
|
||
+
|
||
+ value = pll_compute_pllxcfgr2(pllcfg);
|
||
+
|
||
+ io_write32(rcc_base + pll->pllxcfgr2, value);
|
||
+}
|
||
+
|
||
+static int pll_compute_pllxcfgr1(const struct stm32mp1_clk_pll *pll,
|
||
+ uint32_t *pllcfg, uint32_t *cfgr1)
|
||
+{
|
||
+ uint32_t rcc_base = stm32_rcc_base();
|
||
+ enum stm32mp1_plltype type = pll->plltype;
|
||
+ unsigned long refclk = 0;
|
||
+ uint32_t ifrge = 0;
|
||
+ uint32_t src = 0;
|
||
+
|
||
+ src = io_read32(rcc_base + pll->rckxselr) &
|
||
+ RCC_SELR_REFCLK_SRC_MASK;
|
||
+
|
||
+ refclk = osc_frequency(pll->refclk[src]) /
|
||
+ (pllcfg[PLLCFG_M] + 1U);
|
||
+
|
||
+ if ((refclk < (stm32mp1_pll[type].refclk_min * 1000000U)) ||
|
||
+ (refclk > (stm32mp1_pll[type].refclk_max * 1000000U)))
|
||
+ return -1;
|
||
+
|
||
+ if ((type == PLL_800) && (refclk >= 8000000U))
|
||
+ ifrge = 1U;
|
||
+
|
||
+ *cfgr1 = (pllcfg[PLLCFG_N] << RCC_PLLNCFGR1_DIVN_SHIFT) &
|
||
+ RCC_PLLNCFGR1_DIVN_MASK;
|
||
+ *cfgr1 |= (pllcfg[PLLCFG_M] << RCC_PLLNCFGR1_DIVM_SHIFT) &
|
||
+ RCC_PLLNCFGR1_DIVM_MASK;
|
||
+ *cfgr1 |= (ifrge << RCC_PLLNCFGR1_IFRGE_SHIFT) &
|
||
+ RCC_PLLNCFGR1_IFRGE_MASK;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int pll_config(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg,
|
||
+ uint32_t fracv)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uint32_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t value = 0;
|
||
+ int ret = 0;
|
||
+
|
||
+ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ io_write32(rcc_base + pll->pllxcfgr1, value);
|
||
+
|
||
+ /* Fractional configuration */
|
||
+ io_write32(rcc_base + pll->pllxfracr, value);
|
||
+
|
||
+ /* Frac must be enabled only once its configuration is loaded */
|
||
+ value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
|
||
+ io_write32(rcc_base + pll->pllxfracr, value);
|
||
+ value = io_read32(rcc_base + pll->pllxfracr);
|
||
+ io_write32(rcc_base + pll->pllxfracr, value | RCC_PLLNFRACR_FRACLE);
|
||
+
|
||
+ pll_config_output(pll_id, pllcfg);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
static unsigned long get_clock_rate(int p)
|
||
{
|
||
uint32_t reg = 0;
|
||
@@ -1214,7 +1468,7 @@ void stm32mp_register_clock_parents_secure(unsigned long clock_id)
|
||
|
||
if (parent_id < 0) {
|
||
DMSG("No parent for clock %lu", clock_id);
|
||
- panic();
|
||
+ return;
|
||
}
|
||
|
||
secure_parent_clocks(parent_id);
|
||
@@ -1299,7 +1553,7 @@ static void enable_static_secure_clocks(void)
|
||
stm32_clock_enable(RTCAPB);
|
||
}
|
||
|
||
-static TEE_Result stm32mp1_clk_early_init(void)
|
||
+static void stm32mp1_clk_early_init(void)
|
||
{
|
||
void *fdt = NULL;
|
||
int node = 0;
|
||
@@ -1360,11 +1614,1011 @@ static TEE_Result stm32mp1_clk_early_init(void)
|
||
|
||
if (ignored != 0)
|
||
IMSG("DT clock tree configurations were ignored");
|
||
+}
|
||
|
||
- enable_static_secure_clocks();
|
||
+/*
|
||
+ * Gets OPP parameters (frequency in KHz and voltage in mV) from an OPP table
|
||
+ * subnode. Platform HW support capabilities are also checked.
|
||
+ */
|
||
+static int get_opp_freqvolt_from_dt_subnode(void *fdt, int subnode,
|
||
+ uint32_t *freq_khz,
|
||
+ uint32_t *voltage_mv)
|
||
+{
|
||
+ const fdt64_t *cuint64 = NULL;
|
||
+ const fdt32_t *cuint32 = NULL;
|
||
+ uint64_t read_freq_64 = 0;
|
||
+ uint32_t read_voltage_32 = 0;
|
||
+
|
||
+ assert(freq_khz);
|
||
+ assert(voltage_mv);
|
||
+
|
||
+ cuint32 = fdt_getprop(fdt, subnode, "opp-supported-hw", NULL);
|
||
+ if (cuint32)
|
||
+ if (!stm32mp_supports_cpu_opp(fdt32_to_cpu(*cuint32))) {
|
||
+ DMSG("Invalid opp-supported-hw 0x%"PRIx32,
|
||
+ fdt32_to_cpu(*cuint32));
|
||
+ return -FDT_ERR_BADVALUE;
|
||
+ }
|
||
|
||
- return TEE_SUCCESS;
|
||
+ cuint64 = fdt_getprop(fdt, subnode, "opp-hz", NULL);
|
||
+ if (!cuint64) {
|
||
+ DMSG("Missing opp-hz");
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+ }
|
||
+
|
||
+ /* Frequency value expressed in KHz must fit on 32 bits */
|
||
+ read_freq_64 = fdt64_to_cpu(*cuint64) / 1000ULL;
|
||
+ if (read_freq_64 > (uint64_t)UINT32_MAX) {
|
||
+ DMSG("Invalid opp-hz %"PRIu64, read_freq_64);
|
||
+ return -FDT_ERR_BADVALUE;
|
||
+ }
|
||
+
|
||
+ cuint32 = fdt_getprop(fdt, subnode, "opp-microvolt", NULL);
|
||
+ if (!cuint32) {
|
||
+ DMSG("Missing opp-microvolt");
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+ }
|
||
+
|
||
+ /* Millivolt value must fit on 16 bits */
|
||
+ read_voltage_32 = fdt32_to_cpu(*cuint32) / 1000U;
|
||
+ if (read_voltage_32 > UINT16_MAX) {
|
||
+ DMSG("Invalid opp-microvolt %"PRIu32, read_voltage_32);
|
||
+ return -FDT_ERR_BADVALUE;
|
||
+ }
|
||
+
|
||
+ *freq_khz = (uint32_t)read_freq_64;
|
||
+
|
||
+ *voltage_mv = read_voltage_32;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Parses OPP table in DT and finds all parameters supported by the HW
|
||
+ * platform. If found, the corresponding frequency and voltage values are
|
||
+ * respectively stored in @pll1_settings structure.
|
||
+ * Note that @*count has to be set by caller to the effective size allocated
|
||
+ * for both tables. Its value is then replaced by the number of filled elements.
|
||
+ */
|
||
+static int get_all_opp_freqvolt_from_dt(uint32_t *count)
|
||
+{
|
||
+ void *fdt = NULL;
|
||
+ int node = 0;
|
||
+ int subnode = 0;
|
||
+ uint32_t idx = 0;
|
||
+
|
||
+ assert(count);
|
||
+
|
||
+ fdt = get_embedded_dt();
|
||
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_OPP_COMPAT);
|
||
+ if (node < 0)
|
||
+ return node;
|
||
+
|
||
+ fdt_for_each_subnode(subnode, fdt, node) {
|
||
+ uint32_t read_freq = 0;
|
||
+ uint32_t read_voltage = 0;
|
||
+
|
||
+ if (get_opp_freqvolt_from_dt_subnode(fdt, subnode, &read_freq,
|
||
+ &read_voltage))
|
||
+ continue;
|
||
+
|
||
+ if (idx >= *count)
|
||
+ return -FDT_ERR_NOSPACE;
|
||
+
|
||
+ pll1_settings.freq[idx] = read_freq;
|
||
+ pll1_settings.volt[idx] = read_voltage;
|
||
+ idx++;
|
||
+ }
|
||
+
|
||
+ if (!idx)
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+
|
||
+ *count = idx;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int clk_compute_pll1_settings(unsigned long input_freq, int idx)
|
||
+{
|
||
+ unsigned long post_divm = 0;
|
||
+ unsigned long long output_freq = pll1_settings.freq[idx] * 1000U;
|
||
+ unsigned long long freq = 0;
|
||
+ unsigned long long vco = 0;
|
||
+ int divm = 0;
|
||
+ int divn = 0;
|
||
+ int divp = 0;
|
||
+ int frac = 0;
|
||
+ int i = 0;
|
||
+ unsigned int diff = 0;
|
||
+ unsigned int best_diff = UINT_MAX;
|
||
+
|
||
+ /* Following parameters have always the same value */
|
||
+ pll1_settings.cfg[idx][PLLCFG_Q] = 0;
|
||
+ pll1_settings.cfg[idx][PLLCFG_R] = 0;
|
||
+ pll1_settings.cfg[idx][PLLCFG_O] = PQR(1, 0, 0);
|
||
+
|
||
+ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) {
|
||
+ post_divm = input_freq / (unsigned long)(divm + 1);
|
||
+
|
||
+ if ((post_divm < POST_DIVM_MIN) ||
|
||
+ (post_divm > POST_DIVM_MAX))
|
||
+ continue;
|
||
+
|
||
+ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
|
||
+
|
||
+ freq = output_freq * (divm + 1) * (divp + 1);
|
||
+
|
||
+ divn = (int)((freq / input_freq) - 1);
|
||
+ if ((divn < DIVN_MIN) || (divn > DIVN_MAX))
|
||
+ continue;
|
||
+
|
||
+ frac = (int)(((freq * FRAC_MAX) / input_freq) -
|
||
+ ((divn + 1) * FRAC_MAX));
|
||
+
|
||
+ /* 2 loops to refine the fractional part */
|
||
+ for (i = 2; i != 0; i--) {
|
||
+ if (frac > FRAC_MAX)
|
||
+ break;
|
||
+
|
||
+ vco = (post_divm * (divn + 1)) +
|
||
+ ((post_divm * (unsigned long long)frac) /
|
||
+ FRAC_MAX);
|
||
+
|
||
+ if ((vco < (VCO_MIN / 2)) ||
|
||
+ (vco > (VCO_MAX / 2))) {
|
||
+ frac++;
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ freq = vco / (divp + 1);
|
||
+ if (output_freq < freq)
|
||
+ diff = (unsigned int)(freq -
|
||
+ output_freq);
|
||
+ else
|
||
+ diff = (unsigned int)(output_freq -
|
||
+ freq);
|
||
+
|
||
+ if (diff < best_diff) {
|
||
+ pll1_settings.cfg[idx][PLLCFG_M] = divm;
|
||
+ pll1_settings.cfg[idx][PLLCFG_N] = divn;
|
||
+ pll1_settings.cfg[idx][PLLCFG_P] = divp;
|
||
+ pll1_settings.frac[idx] = frac;
|
||
+
|
||
+ if (!diff)
|
||
+ return 0;
|
||
+
|
||
+ best_diff = diff;
|
||
+ }
|
||
+
|
||
+ frac++;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (best_diff == UINT_MAX) {
|
||
+ pll1_settings.cfg[idx][PLLCFG_O] = 0;
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int clk_get_pll1_settings(uint32_t clksrc, int index)
|
||
+{
|
||
+ unsigned long input_freq = 0;
|
||
+ unsigned int i = 0;
|
||
+
|
||
+ for (i = 0; i < PLAT_MAX_OPP_NB; i++)
|
||
+ if (pll1_settings.freq[i] == pll1_settings.freq[index])
|
||
+ break;
|
||
+
|
||
+ if (((i == PLAT_MAX_OPP_NB) &&
|
||
+ !stm32mp1_clk_pll1_settings_are_valid()) ||
|
||
+ ((i < PLAT_MAX_OPP_NB) && !pll1_settings.cfg[i][PLLCFG_O])) {
|
||
+ /*
|
||
+ * Either PLL1 settings structure is completely empty,
|
||
+ * or these settings are not yet computed: do it.
|
||
+ */
|
||
+ switch (clksrc) {
|
||
+ case CLK_PLL12_HSI:
|
||
+ input_freq = stm32_clock_get_rate(CK_HSI);
|
||
+ break;
|
||
+ case CLK_PLL12_HSE:
|
||
+ input_freq = stm32_clock_get_rate(CK_HSE);
|
||
+ break;
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ return clk_compute_pll1_settings(input_freq, index);
|
||
+ }
|
||
+
|
||
+ if (i < PLAT_MAX_OPP_NB) {
|
||
+ if (pll1_settings.cfg[i][PLLCFG_O])
|
||
+ return 0;
|
||
+
|
||
+ /*
|
||
+ * Index is in range and PLL1 settings are computed:
|
||
+ * use content to answer to the request.
|
||
+ */
|
||
+ memcpy(&pll1_settings.cfg[index][0], &pll1_settings.cfg[i][0],
|
||
+ sizeof(uint32_t) * PLAT_MAX_PLLCFG_NB);
|
||
+ pll1_settings.frac[index] = pll1_settings.frac[i];
|
||
+
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ return -1;
|
||
+}
|
||
+
|
||
+static int clk_save_current_pll1_settings(uint32_t buck1_voltage)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1);
|
||
+ uint32_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t freq = 0;
|
||
+ unsigned int i = 0;
|
||
+
|
||
+ freq = UDIV_ROUND_NEAREST(stm32_clock_get_rate(CK_MPU), 1000L);
|
||
+
|
||
+ for (i = 0; i < PLAT_MAX_OPP_NB; i++)
|
||
+ if (pll1_settings.freq[i] == freq)
|
||
+ break;
|
||
+
|
||
+ if ((i == PLAT_MAX_OPP_NB) ||
|
||
+ ((pll1_settings.volt[i] != buck1_voltage) && buck1_voltage))
|
||
+ return -1;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_M] = (io_read32(rcc_base + pll->pllxcfgr1) &
|
||
+ RCC_PLLNCFGR1_DIVM_MASK) >>
|
||
+ RCC_PLLNCFGR1_DIVM_SHIFT;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_N] = (io_read32(rcc_base + pll->pllxcfgr1) &
|
||
+ RCC_PLLNCFGR1_DIVN_MASK) >>
|
||
+ RCC_PLLNCFGR1_DIVN_SHIFT;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_P] = (io_read32(rcc_base + pll->pllxcfgr2) &
|
||
+ RCC_PLLNCFGR2_DIVP_MASK) >>
|
||
+ RCC_PLLNCFGR2_DIVP_SHIFT;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_Q] = (io_read32(rcc_base + pll->pllxcfgr2) &
|
||
+ RCC_PLLNCFGR2_DIVQ_MASK) >>
|
||
+ RCC_PLLNCFGR2_DIVQ_SHIFT;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_R] = (io_read32(rcc_base + pll->pllxcfgr2) &
|
||
+ RCC_PLLNCFGR2_DIVR_MASK) >>
|
||
+ RCC_PLLNCFGR2_DIVR_SHIFT;
|
||
+
|
||
+ pll1_settings.cfg[i][PLLCFG_O] = io_read32(rcc_base + pll->pllxcr) >>
|
||
+ RCC_PLLNCR_DIVEN_SHIFT;
|
||
+
|
||
+ pll1_settings.frac[i] = (io_read32(rcc_base + pll->pllxfracr) &
|
||
+ RCC_PLLNFRACR_FRACV_MASK) >>
|
||
+ RCC_PLLNFRACR_FRACV_SHIFT;
|
||
+
|
||
+ return i;
|
||
+}
|
||
+
|
||
+static uint32_t stm32mp1_clk_get_pll1_current_clksrc(void)
|
||
+{
|
||
+ uint32_t value = 0;
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1);
|
||
+ uint32_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ value = io_read32(rcc_base + pll->rckxselr);
|
||
+
|
||
+ switch (value & RCC_SELR_REFCLK_SRC_MASK) {
|
||
+ case 0:
|
||
+ return CLK_PLL12_HSI;
|
||
+ case 1:
|
||
+ return CLK_PLL12_HSE;
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage)
|
||
+{
|
||
+ unsigned int i = 0;
|
||
+ int ret = 0;
|
||
+ int index = 0;
|
||
+ uint32_t count = PLAT_MAX_OPP_NB;
|
||
+ uint32_t clksrc = 0;
|
||
+
|
||
+ ret = get_all_opp_freqvolt_from_dt(&count);
|
||
+ switch (ret) {
|
||
+ case 0:
|
||
+ break;
|
||
+ case -FDT_ERR_NOTFOUND:
|
||
+ DMSG("Cannot find all OPP info in DT: use default settings.");
|
||
+ return 0;
|
||
+ default:
|
||
+ EMSG("Inconsistent OPP settings found in DT, ignored.");
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ index = clk_save_current_pll1_settings(buck1_voltage);
|
||
+
|
||
+ clksrc = stm32mp1_clk_get_pll1_current_clksrc();
|
||
+
|
||
+ for (i = 0; i < count; i++) {
|
||
+ if (index >= 0 && i == (unsigned int)index)
|
||
+ continue;
|
||
+
|
||
+ ret = clk_get_pll1_settings(clksrc, i);
|
||
+ if (ret != 0)
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ pll1_settings.valid_id = PLL1_SETTINGS_VALID_ID;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data, size_t size)
|
||
+{
|
||
+ if ((size != sizeof(pll1_settings)) ||
|
||
+ !stm32mp1_clk_pll1_settings_are_valid())
|
||
+ panic();
|
||
+
|
||
+ memcpy(data, &pll1_settings, size);
|
||
+}
|
||
+
|
||
+bool stm32mp1_clk_pll1_settings_are_valid(void)
|
||
+{
|
||
+ return pll1_settings.valid_id == PLL1_SETTINGS_VALID_ID;
|
||
+}
|
||
+#else
|
||
+static void stm32mp1_clk_early_init(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ /* Expect booting from a secure setup */
|
||
+ if ((io_read32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) == 0)
|
||
+ panic("RCC TZC[TZEN]");
|
||
+}
|
||
+
|
||
+int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage __unused)
|
||
+{
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data __unused,
|
||
+ size_t size __unused)
|
||
+{
|
||
+}
|
||
+
|
||
+bool stm32mp1_clk_pll1_settings_are_valid(void)
|
||
+{
|
||
+ return false;
|
||
}
|
||
|
||
-service_init(stm32mp1_clk_early_init);
|
||
+static void enable_static_secure_clocks(void)
|
||
+{
|
||
+}
|
||
#endif /*CFG_EMBED_DTB*/
|
||
+
|
||
+/* Start PMU OPP */
|
||
+#define CLKSRC_TIMEOUT_US (200 * 1000)
|
||
+#define CLKDIV_TIMEOUT_US (200 * 1000)
|
||
+#define CLK_MPU_PLL1P 0x00000202
|
||
+#define CLK_MPU_PLL1P_DIV 0x00000203
|
||
+
|
||
+static int stm32mp1_set_clksrc(unsigned int clksrc)
|
||
+{
|
||
+ uintptr_t address = stm32_rcc_base() + (clksrc >> 4);
|
||
+ uint64_t timeout_ref = 0;
|
||
+
|
||
+ io_clrsetbits32(address, RCC_SELR_SRC_MASK, clksrc & RCC_SELR_SRC_MASK);
|
||
+
|
||
+ timeout_ref = timeout_init_us(CLKSRC_TIMEOUT_US);
|
||
+ while ((io_read32(address) & RCC_SELR_SRCRDY) == 0U) {
|
||
+ if (timeout_elapsed(timeout_ref)) {
|
||
+ EMSG("CLKSRC %u start failed @ 0x%"PRIxPTR": 0x%"PRIx32,
|
||
+ clksrc, address, io_read32(address));
|
||
+ return -1;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address)
|
||
+{
|
||
+ uint64_t timeout_ref = 0;
|
||
+
|
||
+ io_clrsetbits32(address, RCC_DIVR_DIV_MASK, clkdiv & RCC_DIVR_DIV_MASK);
|
||
+
|
||
+ timeout_ref = timeout_init_us(CLKDIV_TIMEOUT_US);
|
||
+ while ((io_read32(address) & RCC_DIVR_DIVRDY) == 0U) {
|
||
+ if (timeout_elapsed(timeout_ref)) {
|
||
+ EMSG("CLKDIV 0x%x start failed @ 0x%"PRIxPTR": 0x%"PRIx32,
|
||
+ clkdiv, address, io_read32(address));
|
||
+ return -1;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Check if PLL1 can be configured on the fly.
|
||
+ * @result (-1) => config on the fly is not possible.
|
||
+ * (0) => config on the fly is possible.
|
||
+ * (+1) => same parameters as those in place, no need to reconfig.
|
||
+ * Return value is 0 if no error.
|
||
+ */
|
||
+static int is_pll_config_on_the_fly(enum stm32mp1_pll_id pll_id,
|
||
+ uint32_t *pllcfg, uint32_t fracv,
|
||
+ int *result)
|
||
+{
|
||
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t fracr = 0;
|
||
+ uint32_t value = 0;
|
||
+ int ret = 0;
|
||
+
|
||
+ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ if (io_read32(rcc_base + pll->pllxcfgr1) != value) {
|
||
+ /* Different DIVN/DIVM, can't config on the fly */
|
||
+ *result = -1;
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ *result = true;
|
||
+
|
||
+ fracr = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
|
||
+ fracr |= RCC_PLLNFRACR_FRACLE;
|
||
+ value = pll_compute_pllxcfgr2(pllcfg);
|
||
+
|
||
+ if ((io_read32(rcc_base + pll->pllxfracr) == fracr) &&
|
||
+ (io_read32(rcc_base + pll->pllxcfgr2) == value))
|
||
+ /* Same parameters, no need to config */
|
||
+ *result = 1;
|
||
+ else
|
||
+ *result = 0;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int stm32mp1_get_mpu_div(uint32_t freq_khz)
|
||
+{
|
||
+ unsigned long freq_pll1_p;
|
||
+ unsigned long div;
|
||
+
|
||
+ freq_pll1_p = get_clock_rate(_PLL1_P) / 1000UL;
|
||
+ if ((freq_pll1_p % freq_khz) != 0U)
|
||
+ return -1;
|
||
+
|
||
+ div = freq_pll1_p / freq_khz;
|
||
+
|
||
+ switch (div) {
|
||
+ case 1UL:
|
||
+ case 2UL:
|
||
+ case 4UL:
|
||
+ case 8UL:
|
||
+ case 16UL:
|
||
+ return __builtin_ffs(div) - 1;
|
||
+ default:
|
||
+ return -1;
|
||
+ }
|
||
+}
|
||
+
|
||
+/* Configure PLL1 from input frequency OPP parameters */
|
||
+static int pll1_config_from_opp_khz(uint32_t freq_khz)
|
||
+{
|
||
+ unsigned int idx = 0;
|
||
+ int ret = 0;
|
||
+ int div = 0;
|
||
+ int config_on_the_fly = -1;
|
||
+
|
||
+ for (idx = 0; idx < PLAT_MAX_OPP_NB; idx++)
|
||
+ if (pll1_settings.freq[idx] == freq_khz)
|
||
+ break;
|
||
+
|
||
+ if (idx == PLAT_MAX_OPP_NB)
|
||
+ return -1;
|
||
+
|
||
+ div = stm32mp1_get_mpu_div(freq_khz);
|
||
+ switch (div) {
|
||
+ case -1:
|
||
+ break;
|
||
+ case 0:
|
||
+ return stm32mp1_set_clksrc(CLK_MPU_PLL1P);
|
||
+ default:
|
||
+ ret = stm32mp1_set_clkdiv(div, stm32_rcc_base() +
|
||
+ RCC_MPCKDIVR);
|
||
+ if (ret == 0)
|
||
+ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P_DIV);
|
||
+
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ ret = is_pll_config_on_the_fly(_PLL1, &pll1_settings.cfg[idx][0],
|
||
+ pll1_settings.frac[idx],
|
||
+ &config_on_the_fly);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ if (config_on_the_fly == 1)
|
||
+ return 0;
|
||
+
|
||
+ if (config_on_the_fly == -1) {
|
||
+ /* Switch to HSI and stop PLL1 before reconfiguration */
|
||
+ ret = stm32mp1_set_clksrc(CLK_MPU_HSI);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ ret = pll_stop(_PLL1);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ ret = pll_config(_PLL1, &pll1_settings.cfg[idx][0],
|
||
+ pll1_settings.frac[idx]);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ if (config_on_the_fly == -1) {
|
||
+ /* Start PLL1 and switch back to after reconfiguration */
|
||
+ pll_start(_PLL1);
|
||
+
|
||
+ ret = pll_output(_PLL1, pll1_settings.cfg[idx][PLLCFG_O]);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static void save_current_opp(void)
|
||
+{
|
||
+ unsigned long freq_khz = UDIV_ROUND_NEAREST(stm32_clock_get_rate(CK_MPU),
|
||
+ 1000UL);
|
||
+ if (freq_khz > (unsigned long)UINT32_MAX)
|
||
+ panic();
|
||
+
|
||
+ current_opp_khz = (uint32_t)freq_khz;
|
||
+}
|
||
+
|
||
+int stm32mp1_set_opp_khz(uint32_t freq_khz)
|
||
+{
|
||
+ uint32_t mpu_src = 0;
|
||
+
|
||
+ if (freq_khz == current_opp_khz)
|
||
+ return 0;
|
||
+
|
||
+ if (!stm32mp1_clk_pll1_settings_are_valid()) {
|
||
+ /*
|
||
+ * No OPP table in DT or an error occurred during PLL1
|
||
+ * settings computation, system can only work on current
|
||
+ * operating point so return error.
|
||
+ */
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ /* Check that PLL1 is MPU clock source */
|
||
+ mpu_src = io_read32(stm32_rcc_base() + RCC_MPCKSELR) &
|
||
+ RCC_SELR_SRC_MASK;
|
||
+ if ((mpu_src != RCC_MPCKSELR_PLL) &&
|
||
+ (mpu_src != RCC_MPCKSELR_PLL_MPUDIV))
|
||
+ return -1;
|
||
+
|
||
+ if (pll1_config_from_opp_khz(freq_khz)) {
|
||
+ /* Restore original value */
|
||
+ if (pll1_config_from_opp_khz(current_opp_khz)) {
|
||
+ EMSG("No CPU operating point can be set");
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ current_opp_khz = freq_khz;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+int stm32mp1_round_opp_khz(uint32_t *freq_khz)
|
||
+{
|
||
+ unsigned int i = 0;
|
||
+ uint32_t round_opp = 0;
|
||
+
|
||
+ if (!stm32mp1_clk_pll1_settings_are_valid()) {
|
||
+ /*
|
||
+ * No OPP table in DT, or an error occurred during PLL1
|
||
+ * settings computation, system can only work on current
|
||
+ * operating point, so return current CPU frequency.
|
||
+ */
|
||
+ *freq_khz = current_opp_khz;
|
||
+
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ for (i = 0; i < PLAT_MAX_OPP_NB; i++)
|
||
+ if ((pll1_settings.freq[i] <= *freq_khz) &&
|
||
+ (pll1_settings.freq[i] > round_opp))
|
||
+ round_opp = pll1_settings.freq[i];
|
||
+
|
||
+ *freq_khz = round_opp;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+/* End PMU OPP */
|
||
+
|
||
+#ifdef CFG_PM
|
||
+struct soc_stop_context {
|
||
+ uint32_t pll3cr;
|
||
+ uint32_t pll4cr;
|
||
+ uint32_t mssckselr;
|
||
+ uint32_t mcudivr;
|
||
+};
|
||
+
|
||
+static struct soc_stop_context soc_stop_ctx;
|
||
+
|
||
+static void save_pll34_state(void)
|
||
+{
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ struct soc_stop_context *ctx = &soc_stop_ctx;
|
||
+
|
||
+ ctx->pll3cr = io_read32(rcc_base + RCC_PLL3CR);
|
||
+ ctx->pll4cr = io_read32(rcc_base + RCC_PLL4CR);
|
||
+}
|
||
+
|
||
+static void save_mcu_subsys_clocks(void)
|
||
+{
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ struct soc_stop_context *ctx = &soc_stop_ctx;
|
||
+
|
||
+ ctx->mssckselr = io_read32(rcc_base + RCC_MSSCKSELR);
|
||
+ ctx->mcudivr = io_read32(rcc_base + RCC_MCUDIVR) &
|
||
+ RCC_MCUDIV_MASK;
|
||
+}
|
||
+
|
||
+static void restore_pll34_state(void)
|
||
+{
|
||
+ struct soc_stop_context *ctx = &soc_stop_ctx;
|
||
+
|
||
+ /* Let PLL4 start while we're starting and waiting for PLL3 */
|
||
+ if (ctx->pll4cr & RCC_PLLNCR_PLLON)
|
||
+ pll_start(_PLL4);
|
||
+
|
||
+ if (ctx->pll3cr & RCC_PLLNCR_PLLON) {
|
||
+ pll_start(_PLL3);
|
||
+ if (pll_output(_PLL3, ctx->pll3cr >> RCC_PLLNCR_DIVEN_SHIFT)) {
|
||
+ EMSG("Failed to restore PLL3");
|
||
+ panic();
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (ctx->pll4cr & RCC_PLLNCR_PLLON) {
|
||
+ if (pll_output(_PLL4, ctx->pll4cr >> RCC_PLLNCR_DIVEN_SHIFT)) {
|
||
+ EMSG("Failed to restore PLL4");
|
||
+ panic();
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+static void restore_mcu_subsys_clocks(void)
|
||
+{
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ struct soc_stop_context *ctx = &soc_stop_ctx;
|
||
+
|
||
+ io_write32(rcc_base + RCC_MSSCKSELR, ctx->mssckselr);
|
||
+
|
||
+ if (stm32mp1_set_clkdiv(ctx->mcudivr, rcc_base + RCC_MCUDIVR)) {
|
||
+ EMSG("Failed to restore MCUDIVR");
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Sequence to save/restore the non-secure configuration.
|
||
+ * Restoring clocks and muxes need IPs to run on kernel clock
|
||
+ * hence on configuration is restored at resume, kernel clock
|
||
+ * should be disable: this mandates secure access.
|
||
+ *
|
||
+ * backup_mux*_cfg for the clock muxes.
|
||
+ * backup_clock_sc_cfg for the set/clear clock gating registers
|
||
+ * backup_clock_cfg for the regular full write registers
|
||
+ */
|
||
+
|
||
+struct backup_mux_cfg {
|
||
+ uint16_t offset;
|
||
+ uint8_t value;
|
||
+ uint8_t bit_len;
|
||
+};
|
||
+
|
||
+#define MUXCFG(_offset, _bit_len) \
|
||
+ { .offset = (_offset), .bit_len = (_bit_len) }
|
||
+
|
||
+struct backup_mux_cfg backup_mux0_cfg[] = {
|
||
+ MUXCFG(RCC_SDMMC12CKSELR, 3),
|
||
+ MUXCFG(RCC_SPI2S23CKSELR, 3),
|
||
+ MUXCFG(RCC_SPI45CKSELR, 3),
|
||
+ MUXCFG(RCC_I2C12CKSELR, 3),
|
||
+ MUXCFG(RCC_I2C35CKSELR, 3),
|
||
+ MUXCFG(RCC_LPTIM23CKSELR, 3),
|
||
+ MUXCFG(RCC_LPTIM45CKSELR, 3),
|
||
+ MUXCFG(RCC_UART24CKSELR, 3),
|
||
+ MUXCFG(RCC_UART35CKSELR, 3),
|
||
+ MUXCFG(RCC_UART78CKSELR, 3),
|
||
+ MUXCFG(RCC_SAI1CKSELR, 3),
|
||
+ MUXCFG(RCC_ETHCKSELR, 2),
|
||
+ MUXCFG(RCC_I2C46CKSELR, 3),
|
||
+ MUXCFG(RCC_RNG2CKSELR, 2),
|
||
+ MUXCFG(RCC_SDMMC3CKSELR, 3),
|
||
+ MUXCFG(RCC_FMCCKSELR, 2),
|
||
+ MUXCFG(RCC_QSPICKSELR, 2),
|
||
+ MUXCFG(RCC_USBCKSELR, 2),
|
||
+ MUXCFG(RCC_SPDIFCKSELR, 2),
|
||
+ MUXCFG(RCC_SPI2S1CKSELR, 3),
|
||
+ MUXCFG(RCC_CECCKSELR, 2),
|
||
+ MUXCFG(RCC_LPTIM1CKSELR, 3),
|
||
+ MUXCFG(RCC_UART6CKSELR, 3),
|
||
+ MUXCFG(RCC_FDCANCKSELR, 2),
|
||
+ MUXCFG(RCC_SAI2CKSELR, 3),
|
||
+ MUXCFG(RCC_SAI3CKSELR, 3),
|
||
+ MUXCFG(RCC_SAI4CKSELR, 3),
|
||
+ MUXCFG(RCC_ADCCKSELR, 2),
|
||
+ MUXCFG(RCC_DSICKSELR, 1),
|
||
+ MUXCFG(RCC_CPERCKSELR, 2),
|
||
+ MUXCFG(RCC_RNG1CKSELR, 2),
|
||
+ MUXCFG(RCC_STGENCKSELR, 2),
|
||
+ MUXCFG(RCC_UART1CKSELR, 3),
|
||
+ MUXCFG(RCC_SPI6CKSELR, 3),
|
||
+};
|
||
+
|
||
+struct backup_mux_cfg backup_mux4_cfg[] = {
|
||
+ MUXCFG(RCC_USBCKSELR, 1),
|
||
+};
|
||
+
|
||
+static void backup_mux_cfg(void)
|
||
+{
|
||
+ struct backup_mux_cfg *cfg = backup_mux0_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_mux0_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ cfg[i].value = io_read32(base + cfg[i].offset) &
|
||
+ GENMASK_32(cfg[i].bit_len - 1, 0);
|
||
+
|
||
+ cfg = backup_mux4_cfg;
|
||
+ count = ARRAY_SIZE(backup_mux4_cfg);
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ cfg[i].value = io_read32(base + cfg[i].offset) &
|
||
+ GENMASK_32(4 + cfg[i].bit_len - 1, 4);
|
||
+}
|
||
+
|
||
+static void restore_mux_cfg(void)
|
||
+{
|
||
+ struct backup_mux_cfg *cfg = backup_mux0_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_mux0_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ io_clrsetbits32(base + cfg[i].offset,
|
||
+ GENMASK_32(cfg[i].bit_len - 1, 0),
|
||
+ cfg[i].value);
|
||
+
|
||
+ cfg = backup_mux4_cfg;
|
||
+ count = ARRAY_SIZE(backup_mux4_cfg);
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ io_clrsetbits32(base + cfg[i].offset,
|
||
+ GENMASK_32(4 + cfg[i].bit_len - 1, 4),
|
||
+ cfg[i].value);
|
||
+}
|
||
+
|
||
+/* Structure is used for set/clear registers and for regular registers */
|
||
+struct backup_clock_cfg {
|
||
+ uint32_t offset;
|
||
+ uint32_t value;
|
||
+};
|
||
+
|
||
+static struct backup_clock_cfg backup_clock_sc_cfg[] = {
|
||
+ { .offset = RCC_MP_APB1ENSETR },
|
||
+ { .offset = RCC_MP_APB2ENSETR },
|
||
+ { .offset = RCC_MP_APB3ENSETR },
|
||
+ { .offset = RCC_MP_APB4ENSETR },
|
||
+ { .offset = RCC_MP_APB5ENSETR },
|
||
+ { .offset = RCC_MP_AHB2ENSETR },
|
||
+ { .offset = RCC_MP_AHB3ENSETR },
|
||
+ { .offset = RCC_MP_AHB4ENSETR },
|
||
+ { .offset = RCC_MP_AHB5ENSETR },
|
||
+ { .offset = RCC_MP_AHB6ENSETR },
|
||
+ { .offset = RCC_MP_MLAHBENSETR },
|
||
+};
|
||
+
|
||
+static struct backup_clock_cfg backup_clock_cfg[] = {
|
||
+ { .offset = RCC_MCO1CFGR },
|
||
+ { .offset = RCC_MCO2CFGR },
|
||
+ { .offset = RCC_PLL3CR },
|
||
+ { .offset = RCC_PLL4CR },
|
||
+ { .offset = RCC_PLL4CFGR2 },
|
||
+ { .offset = RCC_MCUDIVR },
|
||
+ { .offset = RCC_MSSCKSELR },
|
||
+};
|
||
+
|
||
+static void backup_sc_cfg(void)
|
||
+{
|
||
+ struct backup_clock_cfg *cfg = backup_clock_sc_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_clock_sc_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ cfg[i].value = io_read32(base + cfg[i].offset);
|
||
+}
|
||
+
|
||
+static void restore_sc_cfg(void)
|
||
+{
|
||
+ struct backup_clock_cfg *cfg = backup_clock_sc_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_clock_sc_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++) {
|
||
+ io_write32(base + cfg[i].offset, cfg[i].value);
|
||
+ io_write32(base + cfg[i].offset + RCC_MP_ENCLRR_OFFSET,
|
||
+ ~cfg[i].value);
|
||
+ }
|
||
+}
|
||
+
|
||
+static void backup_regular_cfg(void)
|
||
+{
|
||
+ struct backup_clock_cfg *cfg = backup_clock_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_clock_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ cfg[i].value = io_read32(base + cfg[i].offset);
|
||
+}
|
||
+
|
||
+static void restore_regular_cfg(void)
|
||
+{
|
||
+ struct backup_clock_cfg *cfg = backup_clock_cfg;
|
||
+ size_t count = ARRAY_SIZE(backup_clock_cfg);
|
||
+ size_t i = 0;
|
||
+ uintptr_t base = stm32_rcc_base();
|
||
+
|
||
+ for (i = 0; i < count; i++)
|
||
+ io_write32(base + cfg[i].offset, cfg[i].value);
|
||
+}
|
||
+
|
||
+static void disable_kernel_clocks(void)
|
||
+{
|
||
+ const uint32_t ker_mask = RCC_OCENR_HSIKERON |
|
||
+ RCC_OCENR_CSIKERON |
|
||
+ RCC_OCENR_HSEKERON;
|
||
+
|
||
+ /* Disable all ck_xxx_ker clocks */
|
||
+ io_write32(stm32_rcc_base() + RCC_OCENCLRR, ker_mask);
|
||
+}
|
||
+
|
||
+static void enable_kernel_clocks(void)
|
||
+{
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t reg = 0;
|
||
+ const uint32_t ker_mask = RCC_OCENR_HSIKERON |
|
||
+ RCC_OCENR_CSIKERON |
|
||
+ RCC_OCENR_HSEKERON;
|
||
+
|
||
+ /* Enable ck_xxx_ker clocks if ck_xxx was on */
|
||
+ reg = io_read32(rcc_base + RCC_OCENSETR) << 1;
|
||
+ io_write32(rcc_base + RCC_OCENSETR, reg & ker_mask);
|
||
+}
|
||
+
|
||
+static void clear_rcc_reset_status(void)
|
||
+{
|
||
+ /* Clear reset status fields */
|
||
+ io_write32(stm32_rcc_base() + RCC_MP_RSTSCLRR, 0);
|
||
+}
|
||
+
|
||
+void stm32mp1_clk_save_context_for_stop(void)
|
||
+{
|
||
+ enable_kernel_clocks();
|
||
+ save_mcu_subsys_clocks();
|
||
+ save_pll34_state();
|
||
+}
|
||
+
|
||
+void stm32mp1_clk_restore_context_for_stop(void)
|
||
+{
|
||
+ restore_pll34_state();
|
||
+ /* Restore MCU clock source after PLL3 is ready */
|
||
+ restore_mcu_subsys_clocks();
|
||
+ disable_kernel_clocks();
|
||
+}
|
||
+
|
||
+static void stm32_clock_suspend(void)
|
||
+{
|
||
+ backup_regular_cfg();
|
||
+ backup_sc_cfg();
|
||
+ backup_mux_cfg();
|
||
+ save_pll34_state();
|
||
+
|
||
+ enable_kernel_clocks();
|
||
+ clear_rcc_reset_status();
|
||
+}
|
||
+
|
||
+static void stm32_clock_resume(void)
|
||
+{
|
||
+ unsigned int idx = 0;
|
||
+
|
||
+ restore_pll34_state();
|
||
+ restore_mux_cfg();
|
||
+ restore_sc_cfg();
|
||
+ restore_regular_cfg();
|
||
+
|
||
+ /* Sync secure and shared clocks physical state on functional state */
|
||
+ for (idx = 0; idx < NB_GATES; idx++) {
|
||
+ struct stm32mp1_clk_gate const *gate = gate_ref(idx);
|
||
+
|
||
+ if (gate_is_non_secure(gate))
|
||
+ continue;
|
||
+
|
||
+ if (gate_refcounts[idx]) {
|
||
+ DMSG("Force clock %d enable", gate->clock_id);
|
||
+ __clk_enable(gate);
|
||
+ } else {
|
||
+ DMSG("Force clock %d disable", gate->clock_id);
|
||
+ __clk_disable(gate);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ disable_kernel_clocks();
|
||
+}
|
||
+
|
||
+static TEE_Result stm32_clock_pm(enum pm_op op, unsigned int pm_hint __unused,
|
||
+ const struct pm_callback_handle *hdl __unused)
|
||
+{
|
||
+ if (op == PM_OP_SUSPEND)
|
||
+ stm32_clock_suspend();
|
||
+ else
|
||
+ stm32_clock_resume();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_clock_pm);
|
||
+#else
|
||
+static TEE_Result stm32_clock_pm(enum pm_op op __unused,
|
||
+ unsigned int pm_hint __unused,
|
||
+ const struct pm_callback_handle *hdl __unused)
|
||
+{
|
||
+ return TEE_ERROR_SECURITY;
|
||
+}
|
||
+#endif /*CFG_PM*/
|
||
+
|
||
+static void init_non_secure_rcc(void)
|
||
+{
|
||
+ uintptr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ /* Clear all interrupt flags and core stop requests */
|
||
+ io_write32(rcc_base + RCC_MP_CIFR, 0x110F1F);
|
||
+ io_write32(rcc_base + RCC_MP_SREQCLRR, 0x3);
|
||
+}
|
||
+
|
||
+static TEE_Result stm32_clk_probe(void)
|
||
+{
|
||
+ assert(PLLCFG_NB == PLAT_MAX_PLLCFG_NB);
|
||
+
|
||
+ stm32mp1_clk_early_init();
|
||
+ enable_static_secure_clocks();
|
||
+ save_current_opp();
|
||
+ init_non_secure_rcc();
|
||
+ register_pm_core_service_cb(stm32_clock_pm, NULL);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+/* Setup clock support before driver initialization */
|
||
+service_init(stm32_clk_probe);
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c
|
||
new file mode 100644
|
||
index 0000000..1c2d9b2
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c
|
||
@@ -0,0 +1,469 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
|
||
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#include <arm32.h>
|
||
+#include <boot_api.h>
|
||
+#include <drivers/stm32_rtc.h>
|
||
+#include <drivers/stm32mp1_ddrc.h>
|
||
+#include <drivers/stm32mp1_pwr.h>
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <io.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <platform_config.h>
|
||
+#include <string.h>
|
||
+#include <trace.h>
|
||
+
|
||
+#define TIMEOUT_500US 500
|
||
+
|
||
+static enum stm32mp1_ddr_sr_mode saved_ddr_sr_mode;
|
||
+
|
||
+static vaddr_t get_ddrctrl_base(void)
|
||
+{
|
||
+ static struct io_pa_va base __nex_data = { .pa = DDRCTRL_BASE };
|
||
+
|
||
+ return io_pa_or_va(&base);
|
||
+}
|
||
+
|
||
+static vaddr_t get_ddrphy_base(void)
|
||
+{
|
||
+ static struct io_pa_va base __nex_data = { .pa = DDRPHYC_BASE };
|
||
+
|
||
+ return io_pa_or_va(&base);
|
||
+}
|
||
+
|
||
+static void ddr_disable_clock(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ /* Disable all clocks */
|
||
+ io_clrbits32(rcc_base + RCC_DDRITFCR,
|
||
+ RCC_DDRITFCR_DDRC1EN |
|
||
+ RCC_DDRITFCR_DDRC2EN |
|
||
+ RCC_DDRITFCR_DDRPHYCAPBEN |
|
||
+ RCC_DDRITFCR_DDRCAPBEN);
|
||
+}
|
||
+
|
||
+static void ddr_enable_clock(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ /* Enable all clocks */
|
||
+ io_setbits32(rcc_base + RCC_DDRITFCR,
|
||
+ RCC_DDRITFCR_DDRC1EN |
|
||
+ RCC_DDRITFCR_DDRC2EN |
|
||
+ RCC_DDRITFCR_DDRPHYCEN |
|
||
+ RCC_DDRITFCR_DDRPHYCAPBEN |
|
||
+ RCC_DDRITFCR_DDRCAPBEN);
|
||
+}
|
||
+
|
||
+static void do_sw_handshake(void)
|
||
+{
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
|
||
+}
|
||
+
|
||
+static void do_sw_ack(void)
|
||
+{
|
||
+ uint64_t timeout_ref = 0;
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
|
||
+
|
||
+ timeout_ref = timeout_init_us(TIMEOUT_500US);
|
||
+ while (!timeout_elapsed(timeout_ref))
|
||
+ if (io_read32(ddrctrl_base + DDRCTRL_SWSTAT) &
|
||
+ DDRCTRL_SWSTAT_SW_DONE_ACK)
|
||
+ return;
|
||
+
|
||
+ panic();
|
||
+}
|
||
+
|
||
+static int ddr_sw_self_refresh_in(void)
|
||
+{
|
||
+ uint64_t timeout_ref = 0;
|
||
+ uint32_t operating_mode = 0;
|
||
+ uint32_t selref_type = 0;
|
||
+ uint8_t op_mode_changed = 0;
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+ vaddr_t ddrphy_base = get_ddrphy_base();
|
||
+
|
||
+ io_clrbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
|
||
+
|
||
+ /* Blocks AXI ports from taking anymore transactions */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PCTRL_0, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PCTRL_1, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+
|
||
+ /*
|
||
+ * Waits unit all AXI ports are idle
|
||
+ * Poll PSTAT.rd_port_busy_n = 0
|
||
+ * Poll PSTAT.wr_port_busy_n = 0
|
||
+ */
|
||
+ timeout_ref = timeout_init_us(TIMEOUT_500US);
|
||
+ while (io_read32(ddrctrl_base + DDRCTRL_PSTAT))
|
||
+ if (timeout_elapsed(timeout_ref))
|
||
+ goto pstat_failed;
|
||
+
|
||
+ /* SW Self-Refresh entry */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
|
||
+
|
||
+ /*
|
||
+ * Wait operating mode change in self-refresh mode
|
||
+ * with STAT.operating_mode[1:0]==11.
|
||
+ * Ensure transition to self-refresh was due to software
|
||
+ * by checking also that STAT.selfref_type[1:0]=2.
|
||
+ */
|
||
+ timeout_ref = timeout_init_us(TIMEOUT_500US);
|
||
+ while (!timeout_elapsed(timeout_ref)) {
|
||
+ uint32_t stat = io_read32(ddrctrl_base + DDRCTRL_STAT);
|
||
+
|
||
+ operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
|
||
+ selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
|
||
+
|
||
+ if ((operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) &&
|
||
+ (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) {
|
||
+ op_mode_changed = 1;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (op_mode_changed == 0U)
|
||
+ goto selfref_sw_failed;
|
||
+
|
||
+ /* IOs powering down (PUBL registers) */
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDR);
|
||
+ io_clrsetbits32(ddrphy_base + DDRPHYC_ACIOCR,
|
||
+ DDRPHYC_ACIOCR_CKPDD_MASK, DDRPHYC_ACIOCR_CKPDD_0);
|
||
+ io_clrsetbits32(ddrphy_base + DDRPHYC_ACIOCR,
|
||
+ DDRPHYC_ACIOCR_CKPDR_MASK, DDRPHYC_ACIOCR_CKPDR_0);
|
||
+ io_clrsetbits32(ddrphy_base + DDRPHYC_ACIOCR,
|
||
+ DDRPHYC_ACIOCR_CSPDD_MASK, DDRPHYC_ACIOCR_CSPDD_0);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACOE);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR);
|
||
+ io_clrsetbits32(ddrphy_base + DDRPHYC_DSGCR,
|
||
+ DDRPHYC_DSGCR_ODTPDD_MASK, DDRPHYC_DSGCR_ODTPDD_0);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD);
|
||
+ io_clrsetbits32(ddrphy_base + DDRPHYC_DSGCR,
|
||
+ DDRPHYC_DSGCR_CKEPDD_MASK, DDRPHYC_DSGCR_CKEPDD_0);
|
||
+
|
||
+ /* Disable PZQ cell (PUBL register) */
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD);
|
||
+
|
||
+ /* Activate sw retention in PWRCTRL */
|
||
+ io_setbits32(pwr_base + PWR_CR3_OFF, PWR_CR3_DDRRETEN);
|
||
+
|
||
+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
|
||
+ io_setbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
|
||
+
|
||
+ /* Disable all DLLs: GLITCH window */
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLDIS);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DX0DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DX1DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DX2DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_DX3DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+
|
||
+ /* Switch controller clocks (uMCTL2/PUBL) to DLL output clock */
|
||
+ io_clrbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
|
||
+
|
||
+ /* Disable all clocks */
|
||
+ ddr_disable_clock();
|
||
+
|
||
+ return 0;
|
||
+
|
||
+selfref_sw_failed:
|
||
+ /* This bit should be cleared to restore DDR in its previous state */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
|
||
+
|
||
+pstat_failed:
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PCTRL_0, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PCTRL_1, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+
|
||
+ return -1;
|
||
+}
|
||
+
|
||
+static int ddr_sw_self_refresh_exit(void)
|
||
+{
|
||
+ uint64_t timeout_ref = 0;
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+ vaddr_t ddrphy_base = get_ddrphy_base();
|
||
+
|
||
+ /* Enable all clocks */
|
||
+ ddr_enable_clock();
|
||
+
|
||
+ do_sw_handshake();
|
||
+
|
||
+ /* Mask dfi_init_complete_en */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_DFIMISC,
|
||
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||
+
|
||
+ do_sw_ack();
|
||
+
|
||
+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
|
||
+ io_setbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
|
||
+
|
||
+ /* Enable all DLLs: GLITCH window */
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLDIS);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DX0DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DX1DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DX2DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DX3DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
|
||
+
|
||
+ /* Additional delay to avoid early DLL clock switch */
|
||
+ udelay(50);
|
||
+
|
||
+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
|
||
+ io_clrbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLSRST);
|
||
+ udelay(10);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLSRST);
|
||
+
|
||
+ /* PHY partial init: (DLL lock and ITM reset) */
|
||
+ io_write32(ddrphy_base + DDRPHYC_PIR,
|
||
+ DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK |
|
||
+ DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_INIT);
|
||
+
|
||
+ /* Need to wait at least 10 clock cycles before accessing PGSR */
|
||
+ udelay(10);
|
||
+
|
||
+ timeout_ref = timeout_init_us(TIMEOUT_500US);
|
||
+ while (!(io_read32(ddrphy_base + DDRPHYC_PGSR) & DDRPHYC_PGSR_IDONE))
|
||
+ if (timeout_elapsed(timeout_ref))
|
||
+ return -1;
|
||
+
|
||
+ do_sw_handshake();
|
||
+
|
||
+ /* Unmask dfi_init_complete_en to uMCTL2 */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_DFIMISC,
|
||
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||
+
|
||
+ do_sw_ack();
|
||
+
|
||
+ /* Deactivate sw retention in PWR */
|
||
+ io_clrbits32(pwr_base + PWR_CR3_OFF, PWR_CR3_DDRRETEN);
|
||
+
|
||
+ /* Enable PZQ cell (PUBL register) */
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD);
|
||
+
|
||
+ /* Enable pad drivers */
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD);
|
||
+ io_setbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACOE);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_CKPDD_MASK);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_CSPDD_MASK);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_ODTPDD_MASK);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD);
|
||
+ io_clrbits32(ddrphy_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_CKEPDD_MASK);
|
||
+
|
||
+ /* Remove selfrefresh */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
|
||
+
|
||
+ /* Wait operating_mode == normal */
|
||
+ timeout_ref = timeout_init_us(TIMEOUT_500US);
|
||
+ while (1) {
|
||
+ if ((io_read32(ddrctrl_base + DDRCTRL_STAT) &
|
||
+ DDRCTRL_STAT_OPERATING_MODE_MASK) ==
|
||
+ DDRCTRL_STAT_OPERATING_MODE_NORMAL)
|
||
+ break;
|
||
+
|
||
+ if (timeout_elapsed(timeout_ref))
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ /* AXI ports are no longer blocked from taking transactions */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PCTRL_0, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PCTRL_1, DDRCTRL_PCTRL_N_PORT_EN);
|
||
+
|
||
+ io_setbits32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+uint32_t get_ddrphy_calibration(void)
|
||
+{
|
||
+ vaddr_t ddrphy_base = get_ddrphy_base();
|
||
+ uint32_t zcal = io_read32(ddrphy_base + DDRPHYC_ZQ0CR0);
|
||
+
|
||
+ return (zcal & DDRPHYC_ZQ0CRN_ZDATA_MASK) >> DDRPHYC_ZQ0CRN_ZDATA_SHIFT;
|
||
+}
|
||
+
|
||
+int ddr_standby_sr_entry(void)
|
||
+{
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+
|
||
+ if (ddr_sw_self_refresh_in())
|
||
+ return -1;
|
||
+
|
||
+ /* Enable I/O retention mode in standby */
|
||
+ io_setbits32(pwr_base + PWR_CR3_OFF, PWR_CR3_DDRSREN);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+int ddr_standby_sr_exit(void)
|
||
+{
|
||
+ return ddr_sw_self_refresh_exit();
|
||
+}
|
||
+
|
||
+static void ddr_sr_mode_ssr(void)
|
||
+{
|
||
+ vaddr_t rcc_ddritfcr = stm32_rcc_base() + RCC_DDRITFCR;
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1EN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2EN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBLPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBLPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCEN);
|
||
+ io_clrbits32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN);
|
||
+ io_clrbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK);
|
||
+
|
||
+ /* Disable HW LP interface of uMCTL2 */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_HWLPCTL, DDRCTRL_HWLPCTL_HW_LP_EN);
|
||
+
|
||
+ /* Configure Automatic LP modes of uMCTL2 */
|
||
+ io_clrsetbits32(ddrctrl_base + DDRCTRL_PWRTMG,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0);
|
||
+
|
||
+ /*
|
||
+ * Disable Clock disable with LP modes
|
||
+ * (used in RUN mode for LPDDR2 with specific timing).
|
||
+ */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PWRCTL,
|
||
+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
|
||
+
|
||
+ /* Disable automatic Self-Refresh mode */
|
||
+ io_clrbits32(ddrctrl_base + DDRCTRL_PWRCTL,
|
||
+ DDRCTRL_PWRCTL_SELFREF_EN);
|
||
+}
|
||
+
|
||
+static void ddr_sr_mode_asr(void)
|
||
+{
|
||
+ vaddr_t rcc_ddritfcr = stm32_rcc_base() + RCC_DDRITFCR;
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN);
|
||
+ io_clrsetbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK,
|
||
+ RCC_DDRITFCR_DDRCKMOD_ASR1);
|
||
+
|
||
+ /* Enable HW LP interface of uMCTL2 */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_HWLPCTL, DDRCTRL_HWLPCTL_HW_LP_EN);
|
||
+
|
||
+ /* Configure Automatic LP modes of uMCTL2 */
|
||
+ io_clrsetbits32(ddrctrl_base + DDRCTRL_PWRTMG,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0);
|
||
+
|
||
+ /*
|
||
+ * Enable Clock disable with LP modes
|
||
+ * (used in RUN mode for LPDDR2 with specific timing).
|
||
+ */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PWRCTL,
|
||
+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
|
||
+
|
||
+ /* Enable automatic Self-Refresh for ASR mode */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PWRCTL,
|
||
+ DDRCTRL_PWRCTL_SELFREF_EN);
|
||
+}
|
||
+
|
||
+static void ddr_sr_mode_hsr(void)
|
||
+{
|
||
+ vaddr_t rcc_ddritfcr = stm32_rcc_base() + RCC_DDRITFCR;
|
||
+ vaddr_t ddrctrl_base = get_ddrctrl_base();
|
||
+
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN);
|
||
+ io_clrbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN);
|
||
+ io_clrbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN);
|
||
+ io_setbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN);
|
||
+ io_clrsetbits32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK,
|
||
+ RCC_DDRITFCR_DDRCKMOD_HSR1);
|
||
+
|
||
+ /* Enable HW LP interface of uMCTL2 */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_HWLPCTL, DDRCTRL_HWLPCTL_HW_LP_EN);
|
||
+
|
||
+ /* Configure Automatic LP modes of uMCTL2 */
|
||
+ io_clrsetbits32(ddrctrl_base + DDRCTRL_PWRTMG,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK,
|
||
+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0);
|
||
+
|
||
+ /*
|
||
+ * Enable Clock disable with LP modes
|
||
+ * (used in RUN mode for LPDDR2 with specific timing).
|
||
+ */
|
||
+ io_setbits32(ddrctrl_base + DDRCTRL_PWRCTL,
|
||
+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
|
||
+}
|
||
+
|
||
+static enum stm32mp1_ddr_sr_mode ddr_read_sr_mode(void)
|
||
+{
|
||
+ uint32_t pwrctl = io_read32(get_ddrctrl_base() + DDRCTRL_PWRCTL);
|
||
+ uint32_t mask = DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE |
|
||
+ DDRCTRL_PWRCTL_SELFREF_EN;
|
||
+
|
||
+ switch (pwrctl & mask) {
|
||
+ case 0U:
|
||
+ return DDR_SSR_MODE;
|
||
+
|
||
+ case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE:
|
||
+ return DDR_HSR_MODE;
|
||
+
|
||
+ case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE | DDRCTRL_PWRCTL_SELFREF_EN:
|
||
+ return DDR_ASR_MODE;
|
||
+
|
||
+ default:
|
||
+ return DDR_SR_MODE_INVALID;
|
||
+ }
|
||
+}
|
||
+
|
||
+static void ddr_set_sr_mode(enum stm32mp1_ddr_sr_mode mode)
|
||
+{
|
||
+ switch (mode) {
|
||
+ case DDR_SSR_MODE:
|
||
+ ddr_sr_mode_ssr();
|
||
+ break;
|
||
+
|
||
+ case DDR_HSR_MODE:
|
||
+ ddr_sr_mode_hsr();
|
||
+ break;
|
||
+
|
||
+ case DDR_ASR_MODE:
|
||
+ ddr_sr_mode_asr();
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ EMSG("Unknown Self Refresh mode\n");
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+void ddr_save_sr_mode(enum stm32mp1_ddr_sr_mode mode)
|
||
+{
|
||
+ /* Save current mode before setting new one */
|
||
+ saved_ddr_sr_mode = ddr_read_sr_mode();
|
||
+ ddr_set_sr_mode(mode);
|
||
+}
|
||
+
|
||
+void ddr_restore_sr_mode(void)
|
||
+{
|
||
+ ddr_set_sr_mode(saved_ddr_sr_mode);
|
||
+}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h
|
||
new file mode 100644
|
||
index 0000000..e2d809b
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h
|
||
@@ -0,0 +1,219 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
|
||
+ */
|
||
+
|
||
+#ifndef __STM32MP1_DDRC_H__
|
||
+#define __STM32MP1_DDRC_H__
|
||
+
|
||
+#include <util.h>
|
||
+
|
||
+/* DDR Controller */
|
||
+/* DDR Controller registers offsets */
|
||
+#define DDRCTRL_MSTR 0x000
|
||
+#define DDRCTRL_STAT 0x004
|
||
+#define DDRCTRL_MRCTRL0 0x010
|
||
+#define DDRCTRL_MRSTAT 0x018
|
||
+#define DDRCTRL_PWRCTL 0x030
|
||
+#define DDRCTRL_PWRTMG 0x034
|
||
+#define DDRCTRL_HWLPCTL 0x038
|
||
+#define DDRCTRL_RFSHCTL3 0x060
|
||
+#define DDRCTRL_RFSHTMG 0x064
|
||
+#define DDRCTRL_INIT0 0x0D0
|
||
+#define DDRCTRL_DFIMISC 0x1B0
|
||
+#define DDRCTRL_DBG1 0x304
|
||
+#define DDRCTRL_DBGCAM 0x308
|
||
+#define DDRCTRL_DBGCMD 0x30C
|
||
+#define DDRCTRL_DBGSTAT 0x310
|
||
+#define DDRCTRL_SWCTL 0x320
|
||
+#define DDRCTRL_SWSTAT 0x324
|
||
+#define DDRCTRL_PSTAT 0x3FC
|
||
+#define DDRCTRL_PCTRL_0 0x490
|
||
+#define DDRCTRL_PCTRL_1 0x540
|
||
+
|
||
+/* DDR Controller Register fields */
|
||
+#define DDRCTRL_MSTR_DDR3 BIT(0)
|
||
+#define DDRCTRL_MSTR_LPDDR2 BIT(2)
|
||
+#define DDRCTRL_MSTR_LPDDR3 BIT(3)
|
||
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK_32(13, 12)
|
||
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL 0
|
||
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF BIT(12)
|
||
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER BIT(13)
|
||
+#define DDRCTRL_MSTR_DLL_OFF_MODE BIT(15)
|
||
+
|
||
+#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK_32(2, 0)
|
||
+#define DDRCTRL_STAT_OPERATING_MODE_NORMAL BIT(0)
|
||
+#define DDRCTRL_STAT_OPERATING_MODE_SR (BIT(0) | BIT(1))
|
||
+#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK_32(5, 4)
|
||
+#define DDRCTRL_STAT_SELFREF_TYPE_ASR (BIT(4) | BIT(5))
|
||
+#define DDRCTRL_STAT_SELFREF_TYPE_SR BIT(5)
|
||
+
|
||
+#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE 0
|
||
+/* only one rank supported */
|
||
+#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4
|
||
+#define DDRCTRL_MRCTRL0_MR_RANK_ALL \
|
||
+ BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
|
||
+#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12
|
||
+#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK_32(15, 12)
|
||
+#define DDRCTRL_MRCTRL0_MR_WR BIT(31)
|
||
+
|
||
+#define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0)
|
||
+
|
||
+#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0)
|
||
+#define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1)
|
||
+#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3)
|
||
+#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5)
|
||
+
|
||
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK_32(19, 12)
|
||
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16)
|
||
+
|
||
+#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0)
|
||
+
|
||
+#define DDRCTRL_HWLPCTL_HW_LP_EN BIT(0)
|
||
+
|
||
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK GENMASK_32(27, 16)
|
||
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT 16
|
||
+
|
||
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK GENMASK_32(31, 30)
|
||
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL BIT(30)
|
||
+
|
||
+#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0)
|
||
+
|
||
+#define DDRCTRL_DBG1_DIS_HIF BIT(1)
|
||
+
|
||
+#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29)
|
||
+#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28)
|
||
+#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26)
|
||
+#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK_32(12, 8)
|
||
+#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK_32(4, 0)
|
||
+
|
||
+#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
|
||
+ (DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
|
||
+ DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
|
||
+
|
||
+#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
|
||
+ (DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
|
||
+ DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
|
||
+ DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH)
|
||
+
|
||
+#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0)
|
||
+
|
||
+#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0)
|
||
+
|
||
+#define DDRCTRL_SWCTL_SW_DONE BIT(0)
|
||
+
|
||
+#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0)
|
||
+
|
||
+#define DDRCTRL_PCTRL_N_PORT_EN BIT(0)
|
||
+
|
||
+/* DDR PHY registers offsets */
|
||
+#define DDRPHYC_PIR 0x004
|
||
+#define DDRPHYC_PGCR 0x008
|
||
+#define DDRPHYC_PGSR 0x00C
|
||
+#define DDRPHYC_DLLGCR 0x010
|
||
+#define DDRPHYC_ACDLLCR 0x014
|
||
+#define DDRPHYC_PTR0 0x018
|
||
+#define DDRPHYC_ACIOCR 0x024
|
||
+#define DDRPHYC_DXCCR 0x028
|
||
+#define DDRPHYC_DSGCR 0x02C
|
||
+#define DDRPHYC_ZQ0CR0 0x180
|
||
+#define DDRPHYC_DX0GCR 0x1C0
|
||
+#define DDRPHYC_DX0DLLCR 0x1CC
|
||
+#define DDRPHYC_DX1GCR 0x200
|
||
+#define DDRPHYC_DX1DLLCR 0x20C
|
||
+#define DDRPHYC_DX2GCR 0x240
|
||
+#define DDRPHYC_DX2DLLCR 0x24C
|
||
+#define DDRPHYC_DX3GCR 0x280
|
||
+#define DDRPHYC_DX3DLLCR 0x28C
|
||
+
|
||
+/* DDR PHY Register fields */
|
||
+#define DDRPHYC_PIR_INIT BIT(0)
|
||
+#define DDRPHYC_PIR_DLLSRST BIT(1)
|
||
+#define DDRPHYC_PIR_DLLLOCK BIT(2)
|
||
+#define DDRPHYC_PIR_ZCAL BIT(3)
|
||
+#define DDRPHYC_PIR_ITMSRST BIT(4)
|
||
+#define DDRPHYC_PIR_DRAMRST BIT(5)
|
||
+#define DDRPHYC_PIR_DRAMINIT BIT(6)
|
||
+#define DDRPHYC_PIR_QSTRN BIT(7)
|
||
+#define DDRPHYC_PIR_ICPC BIT(16)
|
||
+#define DDRPHYC_PIR_ZCALBYP BIT(30)
|
||
+#define DDRPHYC_PIR_INITSTEPS_MASK GENMASK(31, 7)
|
||
+
|
||
+#define DDRPHYC_PGCR_DFTCMP BIT(2)
|
||
+#define DDRPHYC_PGCR_PDDISDX BIT(24)
|
||
+#define DDRPHYC_PGCR_RFSHDT_MASK GENMASK_32(28, 25)
|
||
+
|
||
+#define DDRPHYC_PGSR_IDONE BIT(0)
|
||
+#define DDRPHYC_PGSR_DTERR BIT(5)
|
||
+#define DDRPHYC_PGSR_DTIERR BIT(6)
|
||
+#define DDRPHYC_PGSR_DFTERR BIT(7)
|
||
+#define DDRPHYC_PGSR_RVERR BIT(8)
|
||
+#define DDRPHYC_PGSR_RVEIRR BIT(9)
|
||
+
|
||
+#define DDRPHYC_DLLGCR_BPS200 BIT(23)
|
||
+
|
||
+#define DDRPHYC_ACDLLCR_DLLSRST BIT(30)
|
||
+#define DDRPHYC_ACDLLCR_DLLDIS BIT(31)
|
||
+
|
||
+#define DDRPHYC_PTR0_TDLLSRST_OFFSET 0
|
||
+#define DDRPHYC_PTR0_TDLLSRST_MASK GENMASK_32(5, 0)
|
||
+#define DDRPHYC_PTR0_TDLLLOCK_OFFSET 6
|
||
+#define DDRPHYC_PTR0_TDLLLOCK_MASK GENMASK_32(17, 6)
|
||
+#define DDRPHYC_PTR0_TITMSRST_OFFSET 18
|
||
+#define DDRPHYC_PTR0_TITMSRST_MASK GENMASK_32(21, 18)
|
||
+
|
||
+#define DDRPHYC_ACIOCR_ACOE BIT(1)
|
||
+#define DDRPHYC_ACIOCR_ACPDD BIT(3)
|
||
+#define DDRPHYC_ACIOCR_ACPDR BIT(4)
|
||
+#define DDRPHYC_ACIOCR_CKPDD_MASK GENMASK_32(10, 8)
|
||
+#define DDRPHYC_ACIOCR_CKPDD_0 BIT(8)
|
||
+#define DDRPHYC_ACIOCR_CKPDR_MASK GENMASK_32(13, 11)
|
||
+#define DDRPHYC_ACIOCR_CKPDR_0 BIT(11)
|
||
+#define DDRPHYC_ACIOCR_CSPDD_MASK GENMASK_32(21, 18)
|
||
+#define DDRPHYC_ACIOCR_CSPDD_0 BIT(18)
|
||
+#define DDRPHYC_ACIOCR_RSTPDD BIT(27)
|
||
+#define DDRPHYC_ACIOCR_RSTPDR BIT(28)
|
||
+
|
||
+#define DDRPHYC_DXCCR_DXPDD BIT(2)
|
||
+#define DDRPHYC_DXCCR_DXPDR BIT(3)
|
||
+
|
||
+#define DDRPHYC_DSGCR_CKEPDD_MASK GENMASK_32(19, 16)
|
||
+#define DDRPHYC_DSGCR_CKEPDD_0 BIT(16)
|
||
+#define DDRPHYC_DSGCR_ODTPDD_MASK GENMASK_32(23, 20)
|
||
+#define DDRPHYC_DSGCR_ODTPDD_0 BIT(20)
|
||
+#define DDRPHYC_DSGCR_NL2PD BIT(24)
|
||
+
|
||
+#define DDRPHYC_ZQ0CRN_ZDATA_MASK GENMASK_32(27, 0)
|
||
+#define DDRPHYC_ZQ0CRN_ZDATA_SHIFT 0
|
||
+#define DDRPHYC_ZQ0CRN_ZDEN BIT(28)
|
||
+#define DDRPHYC_ZQ0CRN_ZQPD BIT(31)
|
||
+
|
||
+#define DDRPHYC_DXNGCR_DXEN BIT(0)
|
||
+
|
||
+#define DDRPHYC_DXNDLLCR_DLLSRST BIT(30)
|
||
+#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31)
|
||
+#define DDRPHYC_DXNDLLCR_SDPHASE_MASK GENMASK(17, 14)
|
||
+#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT 14
|
||
+
|
||
+/* DDR Self Refresh (SR) modes */
|
||
+enum stm32mp1_ddr_sr_mode {
|
||
+ DDR_SR_MODE_INVALID = 0,
|
||
+ DDR_SSR_MODE,
|
||
+ DDR_HSR_MODE,
|
||
+ DDR_ASR_MODE,
|
||
+};
|
||
+
|
||
+void ddr_save_sr_mode(enum stm32mp1_ddr_sr_mode mode);
|
||
+void ddr_restore_sr_mode(void);
|
||
+
|
||
+/* Return 32bit calibration value used for DDRPHY */
|
||
+uint32_t get_ddrphy_calibration(void);
|
||
+
|
||
+/*
|
||
+ * Entry/exit DDR selfrefresh mode
|
||
+ * Return 0 on success and a non-null value on error
|
||
+ */
|
||
+int ddr_standby_sr_entry(void);
|
||
+int ddr_standby_sr_exit(void);
|
||
+
|
||
+#endif /*__STM32MP1_DDRC_H__*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h
|
||
index 9ba95df..41a8469 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h
|
||
@@ -6,6 +6,7 @@
|
||
#ifndef __STM32MP1_PWR_H
|
||
#define __STM32MP1_PWR_H
|
||
|
||
+#include <io.h>
|
||
#include <util.h>
|
||
|
||
#define PWR_CR1_OFF 0x00
|
||
@@ -15,7 +16,35 @@
|
||
#define PWR_WKUPCR_OFF 0x20
|
||
#define PWR_MPUWKUPENR_OFF 0x28
|
||
|
||
-#define PWR_OFFSET_MASK 0x3fUL
|
||
+#define PWR_OFFSET_MASK GENMASK_32(5, 0)
|
||
+
|
||
+#define PWR_CR1_LPDS BIT(0)
|
||
+#define PWR_CR1_LPCFG BIT(1)
|
||
+#define PWR_CR1_LVDS BIT(2)
|
||
+#define PWR_CR1_DBP BIT(8)
|
||
+
|
||
+#define PWR_CR2_BREN BIT(0)
|
||
+#define PWR_CR2_RREN BIT(1)
|
||
+#define PWR_CR2_BRRDY BIT(16)
|
||
+#define PWR_CR2_RRRDY BIT(17)
|
||
+
|
||
+#define PWR_CR3_VBE BIT(8)
|
||
+#define PWR_CR3_VBRS BIT(9)
|
||
+#define PWR_CR3_DDRSREN BIT(10)
|
||
+#define PWR_CR3_DDRSRDIS BIT(11)
|
||
+#define PWR_CR3_DDRRETEN BIT(12)
|
||
+#define PWR_CR3_USB33DEN BIT(24)
|
||
+#define PWR_CR3_REG18EN BIT(28)
|
||
+#define PWR_CR3_REG11EN BIT(30)
|
||
+
|
||
+#define PWR_MPUCR_PDDS BIT(0)
|
||
+#define PWR_MPUCR_CSTDBYDIS BIT(3)
|
||
+#define PWR_MPUCR_CSSF BIT(9)
|
||
+
|
||
+#define PWR_WKUPCR_MASK (GENMASK_32(27, 16) | \
|
||
+ GENMASK_32(13, 8) | GENMASK_32(5, 0))
|
||
+
|
||
+#define PWR_MPUWKUPENR_MASK GENMASK_32(5, 0)
|
||
|
||
vaddr_t stm32_pwr_base(void);
|
||
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h
|
||
index 95aefcf..3498022 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h
|
||
@@ -6,8 +6,6 @@
|
||
#ifndef __STM32MP1_RCC_H__
|
||
#define __STM32MP1_RCC_H__
|
||
|
||
-#include <io.h>
|
||
-#include <stdbool.h>
|
||
#include <util.h>
|
||
|
||
#define RCC_TZCR 0x00
|
||
@@ -392,7 +390,8 @@
|
||
#define RCC_HSICFGR_HSITRIM_SHIFT 8
|
||
#define RCC_HSICFGR_HSITRIM_MASK GENMASK_32(14, 8)
|
||
#define RCC_HSICFGR_HSICAL_SHIFT 16
|
||
-#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(27, 16)
|
||
+#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(24, 16)
|
||
+#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK_32(27, 25)
|
||
|
||
/* Fields of RCC_CSICFGR register */
|
||
#define RCC_CSICFGR_CSITRIM_SHIFT 8
|
||
@@ -455,6 +454,9 @@
|
||
#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
|
||
#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
|
||
|
||
+/* Global Control Register */
|
||
+#define RCC_MP_GCR_BOOT_MCU BIT(0)
|
||
+
|
||
/* RCC_MP_APB5RST(SET|CLR)R bit fields */
|
||
#define RCC_APB5RSTSETR_SPI6RST BIT(0)
|
||
#define RCC_APB5RSTSETR_I2C4RST BIT(2)
|
||
@@ -508,6 +510,9 @@
|
||
#define RCC_AHB5RSTSETR_RNG1RST BIT(6)
|
||
#define RCC_AHB5RSTSETR_AXIMCRST BIT(16)
|
||
|
||
+/* RCC_MP_AHB6RST(SET|CLR)R bit fields */
|
||
+#define RCC_AHB6RSTSETR_GPURST BIT(5)
|
||
+
|
||
/* RCC_MP_AHB5EN(SET|CLR)R bit fields */
|
||
#define RCC_MP_AHB5ENSETR_GPIOZEN_POS 0
|
||
#define RCC_MP_AHB5ENSETR_CRYP1EN_POS 4
|
||
@@ -531,8 +536,9 @@
|
||
#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
|
||
|
||
/* RCC_MP_TZAHB6EN(SET|CLR)R bit fields */
|
||
-#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0
|
||
-#define RCC_MP_TZAHB6ENSETR_MDMA BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS)
|
||
+#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0
|
||
+#define RCC_MP_TZAHB6ENSETR_MDMA \
|
||
+ BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS)
|
||
|
||
/* RCC_MP_IWDGFZ(SET|CLR)R bit fields */
|
||
#define RCC_MP_IWDGFZSETR_IWDG1 BIT(0)
|
||
@@ -541,16 +547,31 @@
|
||
#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"
|
||
|
||
#ifndef __ASSEMBLER__
|
||
+#include <io.h>
|
||
+#include <stdbool.h>
|
||
+#include <types_ext.h>
|
||
+
|
||
vaddr_t stm32_rcc_base(void);
|
||
|
||
static inline bool stm32_rcc_is_secure(void)
|
||
{
|
||
- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN;
|
||
+ static int state = -1;
|
||
+
|
||
+ if (state < 0)
|
||
+ state = io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN;
|
||
+
|
||
+ return state;
|
||
}
|
||
|
||
static inline bool stm32_rcc_is_mckprot(void)
|
||
{
|
||
- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_MCKPROT;
|
||
+ const uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT;
|
||
+ static int state = -1;
|
||
+
|
||
+ if (state < 0)
|
||
+ state = (io_read32(stm32_rcc_base() + RCC_TZCR) & mask) == mask;
|
||
+
|
||
+ return state;
|
||
}
|
||
#endif /*__ASSEMBLER__*/
|
||
|
||
diff --git a/core/arch/arm/plat-stm32mp1/drivers/sub.mk b/core/arch/arm/plat-stm32mp1/drivers/sub.mk
|
||
index 42b6893..1718bd6 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/drivers/sub.mk
|
||
+++ b/core/arch/arm/plat-stm32mp1/drivers/sub.mk
|
||
@@ -1,4 +1,6 @@
|
||
+srcs-$(CFG_STM32_CLKCALIB) += stm32mp1_calib.c
|
||
srcs-y += stm32mp1_clk.c
|
||
+srcs-y += stm32mp1_ddrc.c
|
||
srcs-$(CFG_STPMIC1) += stm32mp1_pmic.c
|
||
srcs-y += stm32mp1_pwr.c
|
||
srcs-y += stm32mp1_rcc.c
|
||
diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c
|
||
index 9947e71..40e4263 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/main.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/main.c
|
||
@@ -1,6 +1,6 @@
|
||
// SPDX-License-Identifier: BSD-2-Clause
|
||
/*
|
||
- * Copyright (c) 2017-2018, STMicroelectronics
|
||
+ * Copyright (c) 2017-2020, STMicroelectronics
|
||
* Copyright (c) 2016-2018, Linaro Limited
|
||
*/
|
||
|
||
@@ -9,9 +9,14 @@
|
||
#include <console.h>
|
||
#include <drivers/gic.h>
|
||
#include <drivers/stm32_etzpc.h>
|
||
-#include <drivers/stm32mp1_etzpc.h>
|
||
+#include <drivers/stm32_iwdg.h>
|
||
#include <drivers/stm32_uart.h>
|
||
+#include <drivers/stm32mp1_etzpc.h>
|
||
+#include <drivers/stm32mp1_pmic.h>
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <drivers/stpmic1.h>
|
||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <io.h>
|
||
#include <kernel/dt.h>
|
||
#include <kernel/generic_boot.h>
|
||
#include <kernel/interrupt.h>
|
||
@@ -19,6 +24,7 @@
|
||
#include <kernel/panic.h>
|
||
#include <kernel/pm_stubs.h>
|
||
#include <kernel/spinlock.h>
|
||
+#include <kernel/tee_misc.h>
|
||
#include <mm/core_memprot.h>
|
||
#include <platform_config.h>
|
||
#include <sm/psci.h>
|
||
@@ -32,7 +38,10 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, GPIOS_NSEC_BASE, GPIOS_NSEC_SIZE);
|
||
#endif
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, I2C4_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, I2C6_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_NSEC, IWDG1_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_NSEC, IWDG2_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, RNG1_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_NSEC, RTC_BASE, SMALL_PAGE_SIZE);
|
||
#ifdef CFG_WITH_NSEC_UARTS
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, USART1_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, USART2_BASE, SMALL_PAGE_SIZE);
|
||
@@ -44,17 +53,38 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART7_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART8_BASE, SMALL_PAGE_SIZE);
|
||
#endif
|
||
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, BKPSRAM_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, BSEC_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, DBGMCU_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, DDRCTRL_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, DDRPHYC_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, ETZPC_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, GPIOZ_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, I2C4_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, I2C6_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, IWDG1_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, PWR_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, RCC_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, RNG1_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, RTC_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, STGEN_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, SYSCFG_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, TAMP_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM1_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM2_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM3_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM4_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM5_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM6_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM7_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM8_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM12_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM13_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM14_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM15_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM16_BASE, SMALL_PAGE_SIZE);
|
||
+register_phys_mem_pgdir(MEM_AREA_IO_SEC, TIM17_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, TZC_BASE, SMALL_PAGE_SIZE);
|
||
register_phys_mem_pgdir(MEM_AREA_IO_SEC, USART1_BASE, SMALL_PAGE_SIZE);
|
||
|
||
@@ -69,6 +99,12 @@ register_dynamic_shm(DDR_BASE, CFG_TZDRAM_START - DDR_BASE);
|
||
register_dynamic_shm(TZDRAM_END, DRAM_END - TZDRAM_END);
|
||
#endif
|
||
|
||
+/* Map non-secure DDR bottom for the low power sequence */
|
||
+register_phys_mem(MEM_AREA_RAM_NSEC, DDR_BASE, SMALL_PAGE_SIZE);
|
||
+
|
||
+/* Map TEE physical RAM as read-only for content storage when suspending */
|
||
+register_phys_mem(MEM_AREA_ROM_SEC, TEE_RAM_START, TEE_RAM_PH_SIZE);
|
||
+
|
||
static const struct thread_handlers handlers = {
|
||
.cpu_on = pm_panic,
|
||
.cpu_off = pm_panic,
|
||
@@ -185,8 +221,86 @@ static TEE_Result init_console_from_dt(void)
|
||
|
||
/* Probe console from DT once clock inits (service init level) are completed */
|
||
service_init_late(init_console_from_dt);
|
||
+
|
||
+static TEE_Result initialize_pll1_settings(void)
|
||
+{
|
||
+ uint32_t cpu_voltage = 0U;
|
||
+ int ret = 0;
|
||
+
|
||
+ if (stm32mp1_clk_pll1_settings_are_valid())
|
||
+ return TEE_SUCCESS;
|
||
+
|
||
+ if (stm32mp_dt_pmic_status() > 0) {
|
||
+ stm32mp_get_pmic();
|
||
+
|
||
+ ret = stpmic1_regulator_voltage_get(
|
||
+ stm32mp_pmic_get_cpu_supply_name());
|
||
+ if (ret < 0)
|
||
+ return ret;
|
||
+
|
||
+ cpu_voltage = (uint32_t)ret;
|
||
+
|
||
+ stm32mp_put_pmic();
|
||
+ }
|
||
+
|
||
+ if (stm32mp1_clk_compute_all_pll1_settings(cpu_voltage))
|
||
+ panic();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+
|
||
+/* Compute PLL1 settings once PMIC init is completed */
|
||
+driver_init_late(initialize_pll1_settings);
|
||
+
|
||
#endif
|
||
|
||
+static uintptr_t stm32_dbgmcu_base(void)
|
||
+{
|
||
+ static void *va;
|
||
+
|
||
+ if (!cpu_mmu_enabled())
|
||
+ return DBGMCU_BASE;
|
||
+
|
||
+ if (!va)
|
||
+ va = phys_to_virt(DBGMCU_BASE, MEM_AREA_IO_SEC);
|
||
+
|
||
+ return (uintptr_t)va;
|
||
+}
|
||
+
|
||
+/* SoC versioning util, returns default ID if can't access DBGMCU */
|
||
+TEE_Result stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version)
|
||
+{
|
||
+ uint32_t id = STM32MP1_CHIP_DEFAULT_VERSION;
|
||
+
|
||
+ if (!chip_version)
|
||
+ return TEE_ERROR_BAD_PARAMETERS;
|
||
+
|
||
+ if (stm32_bsec_read_debug_conf() & BSEC_DBGSWGEN)
|
||
+ id = (io_read32(stm32_dbgmcu_base() + DBGMCU_IDC) &
|
||
+ DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
|
||
+
|
||
+ *chip_version = id;
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+
|
||
+/* SoC device ID util, returns default ID if can't access DBGMCU */
|
||
+TEE_Result stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id)
|
||
+{
|
||
+ uint32_t id = STM32MP1_CHIP_ID;
|
||
+
|
||
+ if (!chip_dev_id)
|
||
+ return TEE_ERROR_BAD_PARAMETERS;
|
||
+
|
||
+ if (stm32_bsec_read_debug_conf() & BSEC_DBGSWGEN)
|
||
+ id = io_read32(stm32_dbgmcu_base() + DBGMCU_IDC) &
|
||
+ DBGMCU_IDC_DEV_ID_MASK;
|
||
+
|
||
+ *chip_dev_id = id;
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+
|
||
/*
|
||
* GIC init, used also for primary/secondary boot core wake completion
|
||
*/
|
||
@@ -211,6 +325,13 @@ void main_secondary_init_gic(void)
|
||
{
|
||
gic_cpu_init(&gic_data);
|
||
|
||
+#if CFG_TEE_CORE_NB_CORE == 2
|
||
+ /* Secondary core release constraint on APB5 clock */
|
||
+ io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER),
|
||
+ BOOT_API_A7_RESET_MAGIC_NUMBER);
|
||
+ stm32_clock_disable(RTCAPB);
|
||
+#endif
|
||
+
|
||
stm32mp_register_online_cpu();
|
||
}
|
||
|
||
@@ -229,7 +350,11 @@ static TEE_Result init_stm32mp1_drivers(void)
|
||
(SYSRAM_SEC_SIZE >= CFG_TZSRAM_SIZE)));
|
||
|
||
etzpc_configure_tzma(1, SYSRAM_SEC_SIZE >> SMALL_PAGE_SHIFT);
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ /* BootROM needs unlocked for independent reset */
|
||
+#else
|
||
etzpc_lock_tzma(1);
|
||
+#endif
|
||
|
||
return TEE_SUCCESS;
|
||
}
|
||
@@ -258,12 +383,20 @@ void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg)
|
||
|
||
bool stm32mp_is_closed_device(void)
|
||
{
|
||
- uint32_t otp = 0;
|
||
+ uint32_t otp_id = 0;
|
||
+ size_t bit_len = 0;
|
||
+ uint32_t otp_value = 0;
|
||
TEE_Result result = TEE_ERROR_GENERIC;
|
||
|
||
+ if (stm32_bsec_find_otp_in_nvmem_layout(CFG0_OTP, &otp_id, &bit_len))
|
||
+ panic();
|
||
+
|
||
+ if (bit_len != 8)
|
||
+ panic();
|
||
+
|
||
/* Non closed_device platform expects fuse well programmed to 0 */
|
||
- result = stm32_bsec_shadow_read_otp(&otp, DATA0_OTP);
|
||
- if (!result && !(otp & BIT(DATA0_OTP_SECURED_POS)))
|
||
+ result = stm32_bsec_shadow_read_otp(&otp_value, otp_id);
|
||
+ if (!result && !(otp_value & BIT(CFG0_OTP_SECURED_POS)))
|
||
return false;
|
||
|
||
return true;
|
||
@@ -307,6 +440,20 @@ vaddr_t stm32mp_bkpreg(unsigned int idx)
|
||
return bkpreg_base() + (idx * sizeof(uint32_t));
|
||
}
|
||
|
||
+vaddr_t stm32mp_bkpsram_base(void)
|
||
+{
|
||
+ struct io_pa_va base = { .pa = BKPSRAM_BASE };
|
||
+
|
||
+ return io_pa_or_va(&base);
|
||
+}
|
||
+
|
||
+vaddr_t stm32mp_stgen_base(void)
|
||
+{
|
||
+ struct io_pa_va base = { .pa = STGEN_BASE };
|
||
+
|
||
+ return io_pa_or_va(&base);
|
||
+}
|
||
+
|
||
vaddr_t stm32_get_gpio_bank_base(unsigned int bank)
|
||
{
|
||
static struct io_pa_va gpios_nsec_base = { .pa = GPIOS_NSEC_BASE };
|
||
@@ -339,3 +486,162 @@ unsigned int stm32_get_gpio_bank_clock(unsigned int bank)
|
||
assert(bank <= GPIO_BANK_K);
|
||
return GPIOA + bank;
|
||
}
|
||
+
|
||
+static int get_part_number(uint32_t *part_nb)
|
||
+{
|
||
+ uint32_t part_number = 0;
|
||
+ uint32_t dev_id = 0;
|
||
+ uint32_t otp = 0;
|
||
+ size_t bit_len = 0;
|
||
+
|
||
+ assert(part_nb);
|
||
+
|
||
+ if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id))
|
||
+ return -1;
|
||
+
|
||
+ if (stm32_bsec_find_otp_in_nvmem_layout(PART_NUMBER_OTP,
|
||
+ &otp, &bit_len))
|
||
+ return -1;
|
||
+
|
||
+ if (bit_len != 8)
|
||
+ panic();
|
||
+
|
||
+ if (stm32_bsec_read_otp(&part_number, otp))
|
||
+ return -1;
|
||
+
|
||
+ part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
|
||
+ PART_NUMBER_OTP_PART_SHIFT;
|
||
+
|
||
+ *part_nb = part_number | (dev_id << 16);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+bool stm32mp_supports_cpu_opp(uint32_t opp_id)
|
||
+{
|
||
+ uint32_t part_number = 0;
|
||
+ uint32_t id = 0;
|
||
+
|
||
+ if (get_part_number(&part_number)) {
|
||
+ DMSG("Cannot get part number\n");
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ switch (opp_id) {
|
||
+ case PLAT_OPP_ID1:
|
||
+ case PLAT_OPP_ID2:
|
||
+ id = opp_id;
|
||
+ break;
|
||
+ default:
|
||
+ return false;
|
||
+ }
|
||
+
|
||
+ switch (part_number) {
|
||
+ case STM32MP157F_PART_NB:
|
||
+ case STM32MP157D_PART_NB:
|
||
+ case STM32MP153F_PART_NB:
|
||
+ case STM32MP153D_PART_NB:
|
||
+ case STM32MP151F_PART_NB:
|
||
+ case STM32MP151D_PART_NB:
|
||
+ return true;
|
||
+ default:
|
||
+ return id == PLAT_OPP_ID1;
|
||
+ }
|
||
+}
|
||
+
|
||
+unsigned int stm32mp_iwdg_irq2instance(size_t irq)
|
||
+{
|
||
+ int id = irq - STM32MP1_IRQ_IWDG1;
|
||
+
|
||
+ assert(id >= IWDG1_INST && id <= IWDG2_INST);
|
||
+ return (unsigned int)id;
|
||
+}
|
||
+
|
||
+size_t stm32mp_iwdg_instance2irq(unsigned int instance)
|
||
+{
|
||
+ return instance + STM32MP1_IRQ_IWDG1;
|
||
+}
|
||
+
|
||
+unsigned int stm32mp_iwdg_iomem2instance(vaddr_t pbase)
|
||
+{
|
||
+ switch (pbase) {
|
||
+ case IWDG1_BASE:
|
||
+ return IWDG1_INST;
|
||
+ case IWDG2_BASE:
|
||
+ return IWDG2_INST;
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+unsigned long stm32_get_iwdg_otp_config(vaddr_t pbase)
|
||
+{
|
||
+ unsigned int idx = 0;
|
||
+ unsigned long iwdg_cfg = 0;
|
||
+ uint32_t otp_id = 0;
|
||
+ size_t bit_len = 0;
|
||
+ uint32_t otp_value = 0;
|
||
+
|
||
+ idx = stm32mp_iwdg_iomem2instance(pbase);
|
||
+
|
||
+ if (stm32_bsec_find_otp_in_nvmem_layout(HW2_OTP, &otp_id, &bit_len))
|
||
+ panic();
|
||
+
|
||
+ if (bit_len != 32)
|
||
+ panic();
|
||
+
|
||
+ if (stm32_bsec_read_otp(&otp_value, otp_id))
|
||
+ panic();
|
||
+
|
||
+ if (otp_value & BIT(idx + HW2_OTP_IWDG_HW_ENABLE_SHIFT))
|
||
+ iwdg_cfg |= IWDG_HW_ENABLED;
|
||
+
|
||
+ if (otp_value & BIT(idx + HW2_OTP_IWDG_FZ_STOP_SHIFT))
|
||
+ iwdg_cfg |= IWDG_DISABLE_ON_STOP;
|
||
+
|
||
+ if (otp_value & BIT(idx + HW2_OTP_IWDG_FZ_STANDBY_SHIFT))
|
||
+ iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
|
||
+
|
||
+ return iwdg_cfg;
|
||
+}
|
||
+
|
||
+#ifdef CFG_STM32_RTC
|
||
+/*
|
||
+ * Return true if RTC needs to be read twice not once for a reliable value.
|
||
+ *
|
||
+ * This function determines the number of needed RTC calendar read operations
|
||
+ * to get consistent values: RTC may need to be read twice depending on clock
|
||
+ * frequencies.
|
||
+ * If APB1 frequency is less than 7 times the RTC one, the software has to
|
||
+ * read the calendar time and date register twice.
|
||
+ */
|
||
+bool stm32_rtc_get_read_twice(void)
|
||
+{
|
||
+ unsigned long apb1_freq = 0;
|
||
+ unsigned long rtc_freq = 0;
|
||
+ uint32_t apb1_div = 0;
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ switch ((io_read32(rcc_base + RCC_BDCR) &
|
||
+ RCC_BDCR_RTCSRC_MASK) >> RCC_BDCR_RTCSRC_SHIFT) {
|
||
+ case 1:
|
||
+ rtc_freq = stm32_clock_get_rate(CK_LSE);
|
||
+ break;
|
||
+ case 2:
|
||
+ rtc_freq = stm32_clock_get_rate(CK_LSI);
|
||
+ break;
|
||
+ case 3:
|
||
+ rtc_freq = stm32_clock_get_rate(CK_HSE);
|
||
+ rtc_freq /= (io_read32(rcc_base + RCC_RTCDIVR) &
|
||
+ RCC_DIVR_DIV_MASK) + 1U;
|
||
+ break;
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ apb1_div = io_read32(rcc_base + RCC_APB1DIVR) & RCC_APBXDIV_MASK;
|
||
+ apb1_freq = stm32_clock_get_rate(CK_MCU) >> apb1_div;
|
||
+
|
||
+ return apb1_freq < (rtc_freq * 7U);
|
||
+}
|
||
+#endif
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c
|
||
new file mode 100644
|
||
index 0000000..d99ee32
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c
|
||
@@ -0,0 +1,152 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
|
||
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#include <arm32.h>
|
||
+#include <drivers/stm32mp1_ddrc.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/interrupt.h>
|
||
+#include <kernel/misc.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <platform_config.h>
|
||
+#include <sm/pm.h>
|
||
+#include <sm/psci.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <stm32_util.h>
|
||
+#include <trace.h>
|
||
+
|
||
+#include "stm32mp1_smc.h"
|
||
+#include "low_power_svc.h"
|
||
+#include "../pm/power.h"
|
||
+#include "../pm/context.h"
|
||
+
|
||
+#undef DDR_SR_TEST
|
||
+
|
||
+#ifdef DDR_SR_TEST
|
||
+uint32_t sr_mode_scv_handler(uint32_t __maybe_unused x1, uint32_t x2)
|
||
+{
|
||
+ unsigned int mode = x2;
|
||
+
|
||
+ DMSG("DDR selfrefresh mode 0x%" PRIx32 ", 0x%" PRIx32, mode, x1);
|
||
+
|
||
+ switch (mode) {
|
||
+ case STM32_SIP_SVC_SR_MODE_SSR:
|
||
+ ddr_sr_mode_ssr();
|
||
+ break;
|
||
+ case STM32_SIP_SVC_SR_MODE_ASR:
|
||
+ ddr_sr_mode_asr();
|
||
+ break;
|
||
+ case STM32_SIP_SVC_SR_MODE_HSR:
|
||
+ ddr_sr_mode_hsr();
|
||
+ break;
|
||
+ default:
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+ }
|
||
+
|
||
+ return STM32_SIP_SVC_OK;
|
||
+}
|
||
+#else
|
||
+uint32_t sr_mode_scv_handler(uint32_t __unused x1, uint32_t __unused x2)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif
|
||
+
|
||
+uint32_t cstop_scv_handler(struct sm_ctx __unused *ctx, uint32_t __unused x1,
|
||
+ uint32_t __unused x2, uint32_t __unused x3)
|
||
+{
|
||
+ DMSG("core %u", get_core_pos());
|
||
+
|
||
+ stm32mp1_set_lp_deepest_soc_mode(PSCI_MODE_SYSTEM_SUSPEND,
|
||
+ STM32_PM_CSTOP_ALLOW_LPLV_STOP);
|
||
+
|
||
+ return (psci_system_suspend(ctx->nsec.mon_lr, 0, &ctx->nsec) == 0) ?
|
||
+ STM32_SIP_SVC_OK : STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t standby_scv_handler(struct sm_ctx *ctx, uint32_t __unused x1,
|
||
+ uint32_t __unused x2, uint32_t x3)
|
||
+{
|
||
+ uint32_t nsec_resume_ep = x3;
|
||
+
|
||
+ DMSG("core %u", get_core_pos());
|
||
+
|
||
+ if (nsec_resume_ep == 0U) {
|
||
+ shutdown_scv_handler();
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ stm32mp1_set_lp_deepest_soc_mode(PSCI_MODE_SYSTEM_SUSPEND,
|
||
+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR);
|
||
+
|
||
+ return (psci_system_suspend(nsec_resume_ep, 0, &ctx->nsec) == 0) ?
|
||
+ STM32_SIP_SVC_OK : STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t shutdown_scv_handler(void)
|
||
+{
|
||
+ DMSG("core %u", get_core_pos());
|
||
+
|
||
+ if (!stm32mp_with_pmic()) {
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+ }
|
||
+
|
||
+ psci_system_off();
|
||
+ panic();
|
||
+}
|
||
+
|
||
+uint32_t pm_domain_scv_handler(uint32_t id, uint32_t enable)
|
||
+{
|
||
+ unsigned int pd = id;
|
||
+
|
||
+ DMSG("%sable PD %u", enable != 0 ? "En" : "Dis", pd);
|
||
+
|
||
+ switch (pd) {
|
||
+ case STM32MP1_PD_VSW:
|
||
+ case STM32MP1_PD_CORE_RET:
|
||
+ case STM32MP1_PD_CORE:
|
||
+ break;
|
||
+ default:
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+ }
|
||
+
|
||
+ stm32mp1_set_pm_domain_state(pd, enable);
|
||
+
|
||
+ return STM32_SIP_SVC_OK;
|
||
+}
|
||
+
|
||
+#ifdef CFG_TEE_CORE_DEBUG
|
||
+uint32_t pm_set_lp_state_scv_handler(uint32_t request, uint32_t state)
|
||
+{
|
||
+ uint32_t power_mode;
|
||
+
|
||
+ switch (request) {
|
||
+ case STM32_OEM_SVC_LP_FORCE_SUSPEND_PARAMS:
|
||
+ DMSG("Set suspend mode to %u", state);
|
||
+ power_mode = PSCI_MODE_SYSTEM_SUSPEND;
|
||
+ break;
|
||
+ case STM32_OEM_SVC_LP_FORCE_OFF_PARAMS:
|
||
+ DMSG("Set off mode to %u", state);
|
||
+ power_mode = PSCI_MODE_SYSTEM_OFF;
|
||
+ break;
|
||
+ default:
|
||
+ return STM32_OEM_SVC_INVALID_PARAMS;
|
||
+ }
|
||
+
|
||
+ if (stm32mp1_set_lp_deepest_soc_mode(power_mode, state) < 0) {
|
||
+ return STM32_OEM_SVC_FAILED;
|
||
+ }
|
||
+
|
||
+ return STM32_OEM_SVC_OK;
|
||
+}
|
||
+#else
|
||
+uint32_t pm_set_lp_state_scv_handler(uint32_t __unused mode,
|
||
+ uint32_t __unused state)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h
|
||
new file mode 100644
|
||
index 0000000..3d7d247
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h
|
||
@@ -0,0 +1,55 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#ifndef LOW_POWER_SVC_H
|
||
+#define LOW_POWER_SVC_H
|
||
+
|
||
+#include <sm/sm.h>
|
||
+#include <stdint.h>
|
||
+
|
||
+#ifdef CFG_STM32_LOWPOWER_SIP
|
||
+uint32_t sr_mode_scv_handler(uint32_t x1, uint32_t x2);
|
||
+uint32_t cstop_scv_handler(struct sm_ctx *nsec,
|
||
+ uint32_t x1, uint32_t x2, uint32_t x3);
|
||
+uint32_t standby_scv_handler(struct sm_ctx *nsec,
|
||
+ uint32_t x1, uint32_t x2, uint32_t x3);
|
||
+uint32_t shutdown_scv_handler(void);
|
||
+uint32_t pm_domain_scv_handler(uint32_t x1, uint32_t x2);
|
||
+
|
||
+uint32_t pm_set_lp_state_scv_handler(uint32_t x1, uint32_t x2);
|
||
+#else
|
||
+uint32_t sr_mode_scv_handler(uint32_t x1 __unused, uint32_t x2 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t cstop_scv_handler(struct sm_ctx *nsec __unused, uint32_t x1 __unused,
|
||
+ uint32_t x2 __unused, uint32_t x3 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t standby_scv_handler(struct sm_ctx *nsec __unused, uint32_t x1 __unused,
|
||
+ uint32_t x2 __unused, uint32_t x3 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t shutdown_scv_handler(void)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t pm_domain_scv_handler(uint32_t x1 __unused, uint32_t x2 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+
|
||
+uint32_t pm_set_lp_state_scv_handler(uint32_t x1 __unused, uint32_t x2 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif /* CFG_STM32_LOWPOWER_SIP */
|
||
+#endif /* LOW_POWER_SVC_H */
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c
|
||
new file mode 100644
|
||
index 0000000..6c78d82
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c
|
||
@@ -0,0 +1,89 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#include <inttypes.h>
|
||
+#include <drivers/stm32mp1_pwr.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <io.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <mm/core_mmu.h>
|
||
+#include <platform_config.h>
|
||
+#include <stm32_util.h>
|
||
+#include <trace.h>
|
||
+
|
||
+#include "pwr_svc.h"
|
||
+#include "stm32mp1_smc.h"
|
||
+
|
||
+struct pwr_reg_prop {
|
||
+ uint32_t offset;
|
||
+ uint32_t mask;
|
||
+};
|
||
+
|
||
+#define PWR_ALLOWED_MASK(_off, _mask) { .offset = (_off), .mask = (_mask), }
|
||
+
|
||
+static const struct pwr_reg_prop allowed_regs[] = {
|
||
+ PWR_ALLOWED_MASK(PWR_CR3_OFF, PWR_CR3_VBE | PWR_CR3_VBRS |
|
||
+ PWR_CR3_USB33DEN |
|
||
+ PWR_CR3_REG18EN | PWR_CR3_REG11EN),
|
||
+ PWR_ALLOWED_MASK(PWR_WKUPCR_OFF, PWR_WKUPCR_MASK),
|
||
+ PWR_ALLOWED_MASK(PWR_MPUWKUPENR_OFF, PWR_MPUWKUPENR_MASK),
|
||
+};
|
||
+
|
||
+uint32_t pwr_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3)
|
||
+{
|
||
+ uint32_t req = x1;
|
||
+ uint32_t offset = x2;
|
||
+ uint32_t value = x3;
|
||
+ vaddr_t va = 0;
|
||
+ uint32_t allowed = 0;
|
||
+ unsigned int i = 0;
|
||
+
|
||
+ /*
|
||
+ * Argument x2 can be either the register physical address of the
|
||
+ * register offset toward PWR_BASE.
|
||
+ */
|
||
+ if ((offset & ~PWR_OFFSET_MASK) != 0) {
|
||
+ if ((offset & ~PWR_OFFSET_MASK) != PWR_BASE)
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+
|
||
+ offset &= PWR_OFFSET_MASK;
|
||
+ }
|
||
+
|
||
+ DMSG("PWR service: %s 0x%" PRIx32 " at offset 0x%" PRIx32,
|
||
+ req == STM32_SIP_SVC_REG_WRITE ? "write" :
|
||
+ req == STM32_SIP_SVC_REG_SET ? "set" : "clear",
|
||
+ value, offset);
|
||
+
|
||
+ for (i = 0; i < ARRAY_SIZE(allowed_regs); i++) {
|
||
+ if (offset != allowed_regs[i].offset)
|
||
+ continue;
|
||
+
|
||
+ va = stm32_pwr_base() + offset;
|
||
+ allowed = allowed_regs[i].mask;
|
||
+ value &= allowed;
|
||
+
|
||
+ switch (req) {
|
||
+ case STM32_SIP_SVC_REG_WRITE:
|
||
+ io_mask32_stm32shregs(va, value, allowed);
|
||
+ FMSG("wrt off %" PRIx32 "=%" PRIx32 " => %" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ return STM32_SIP_SVC_OK;
|
||
+ case STM32_SIP_SVC_REG_SET:
|
||
+ io_setbits32_stm32shregs(va, value);
|
||
+ FMSG("set off %" PRIx32 "=%" PRIx32 " => %" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ return STM32_SIP_SVC_OK;
|
||
+ case STM32_SIP_SVC_REG_CLEAR:
|
||
+ io_clrbits32_stm32shregs(va, value);
|
||
+ FMSG("clr off %" PRIx32 "=%" PRIx32 " => %" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ return STM32_SIP_SVC_OK;
|
||
+ default:
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h
|
||
new file mode 100644
|
||
index 0000000..429d620
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h
|
||
@@ -0,0 +1,22 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#ifndef __PWR_SVC_H__
|
||
+#define __PWR_SVC_H__
|
||
+
|
||
+#include <stm32mp1_smc.h>
|
||
+
|
||
+#ifdef CFG_STM32_PWR_SIP
|
||
+uint32_t pwr_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3);
|
||
+#else
|
||
+static inline uint32_t pwr_scv_handler(uint32_t x1 __unused,
|
||
+ uint32_t x2 __unused,
|
||
+ uint32_t x3 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif
|
||
+
|
||
+#endif /* __PWR_SVC_H__*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c
|
||
new file mode 100644
|
||
index 0000000..362e6d6
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c
|
||
@@ -0,0 +1,195 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2019, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <inttypes.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <io.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <platform_config.h>
|
||
+#include <stm32_util.h>
|
||
+#include <trace.h>
|
||
+
|
||
+#include "rcc_svc.h"
|
||
+#include "stm32mp1_smc.h"
|
||
+
|
||
+#undef FULL_RCC_ACCESS
|
||
+
|
||
+static bool offset_is_clear_register(uint32_t __maybe_unused offset)
|
||
+{
|
||
+#ifdef FULL_RCC_ACCESS
|
||
+ switch (offset) {
|
||
+ case RCC_OCENCLRR:
|
||
+ case RCC_MP_SREQCLRR:
|
||
+ case RCC_APB5RSTCLRR:
|
||
+ case RCC_AHB5RSTCLRR:
|
||
+ case RCC_MP_APB5ENCLRR:
|
||
+ case RCC_MP_AHB5ENCLRR:
|
||
+ case RCC_MP_APB5LPENCLRR:
|
||
+ case RCC_MP_AHB5LPENCLRR:
|
||
+ case RCC_MP_IWDGFZCLRR:
|
||
+ return true;
|
||
+ default:
|
||
+ return false;
|
||
+ }
|
||
+#else
|
||
+ /* All allowed registers are non set/clear registers */
|
||
+ return false;
|
||
+#endif
|
||
+}
|
||
+
|
||
+static void access_allowed_mask(uint32_t request, uint32_t offset,
|
||
+ uint32_t value, uint32_t allowed_mask)
|
||
+{
|
||
+ vaddr_t va = stm32_rcc_base() + offset;
|
||
+
|
||
+ if (!allowed_mask)
|
||
+ return;
|
||
+
|
||
+ switch (request) {
|
||
+ case STM32_SIP_SVC_REG_WRITE:
|
||
+ if (offset_is_clear_register(offset)) {
|
||
+ /* CLR registers show SET state, not CLR state */
|
||
+ io_write32(va, value & allowed_mask);
|
||
+ } else {
|
||
+ io_mask32_stm32shregs(va, value, allowed_mask);
|
||
+ }
|
||
+ FMSG("wrt 0x%" PRIx32 "=0x%" PRIx32 " => 0x%" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ break;
|
||
+
|
||
+ case STM32_SIP_SVC_REG_SET:
|
||
+ if (offset_is_clear_register(offset)) {
|
||
+ /* CLR registers show SET state, not CLR state */
|
||
+ io_write32(va, value & allowed_mask);
|
||
+ } else {
|
||
+ io_setbits32_stm32shregs(va, value & allowed_mask);
|
||
+ }
|
||
+ FMSG("set 0x%" PRIx32 "=0x%" PRIx32 " => 0x%" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ break;
|
||
+
|
||
+ case STM32_SIP_SVC_REG_CLEAR:
|
||
+ /* Nothing to do on CLR registers */
|
||
+ if (!offset_is_clear_register(offset))
|
||
+ io_clrbits32_stm32shregs(va, value & allowed_mask);
|
||
+ FMSG("clear 0x%" PRIx32 "=0x%" PRIx32 " => 0x%" PRIx32,
|
||
+ offset, value, io_read32(va));
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ break;
|
||
+ }
|
||
+}
|
||
+
|
||
+static void raw_allowed_access_request(uint32_t request,
|
||
+ uint32_t offset, uint32_t value)
|
||
+{
|
||
+ uint32_t allowed_mask = 0;
|
||
+
|
||
+ switch (offset) {
|
||
+ case RCC_MP_CIER:
|
||
+ case RCC_MP_CIFR:
|
||
+ allowed_mask = RCC_MP_CIFR_WKUPF;
|
||
+ break;
|
||
+ case RCC_MP_GCR:
|
||
+ allowed_mask = RCC_MP_GCR_BOOT_MCU;
|
||
+ break;
|
||
+
|
||
+#ifdef FULL_RCC_ACCESS
|
||
+ case RCC_OCENSETR:
|
||
+ case RCC_OCENCLRR:
|
||
+ case RCC_HSICFGR:
|
||
+ case RCC_CSICFGR:
|
||
+ case RCC_MP_BOOTCR: /* Allowed MPU/MCU reboot cfg */
|
||
+ case RCC_MP_GCR: /* Allowed MPU/MCU reboot cfg */
|
||
+ case RCC_MP_GRSTCSETR: /* Allowed MCU and system reset */
|
||
+ case RCC_BR_RSTSCLRR: /* Allowed system reset status */
|
||
+ case RCC_MC_RSTSCLRR: /* Allowed system reset status */
|
||
+ case RCC_MP_RSTSCLRR: /* Allowed system reset status */
|
||
+ case RCC_BDCR:
|
||
+ case RCC_RDLSICR:
|
||
+ case RCC_APB5RSTSETR:
|
||
+ case RCC_APB5RSTCLRR:
|
||
+ case RCC_MP_APB5ENSETR:
|
||
+ case RCC_MP_APB5ENCLRR:
|
||
+ case RCC_MP_APB5LPENSETR:
|
||
+ case RCC_MP_APB5LPENCLRR:
|
||
+ case RCC_AHB5RSTSETR:
|
||
+ case RCC_AHB5RSTCLRR:
|
||
+ case RCC_MP_AHB5ENSETR:
|
||
+ case RCC_MP_AHB5ENCLRR:
|
||
+ case RCC_MP_AHB5LPENSETR:
|
||
+ case RCC_MP_AHB5LPENCLRR:
|
||
+ case RCC_RTCDIVR:
|
||
+ case RCC_I2C46CKSELR:
|
||
+ case RCC_SPI6CKSELR:
|
||
+ case RCC_UART1CKSELR:
|
||
+ case RCC_RNG1CKSELR:
|
||
+ case RCC_MP_IWDGFZSETR:
|
||
+ case RCC_MP_IWDGFZCLRR:
|
||
+ allowed_mask = UINT32_MAX;
|
||
+ break;
|
||
+#endif
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ access_allowed_mask(request, offset, value, allowed_mask);
|
||
+}
|
||
+
|
||
+uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3)
|
||
+{
|
||
+ uint32_t request = x1;
|
||
+ uint32_t offset = x2;
|
||
+ uint32_t value = x3;
|
||
+
|
||
+ /*
|
||
+ * Argument x2 can be either the register physical address of the
|
||
+ * register offset toward RCC_BASE.
|
||
+ */
|
||
+ if (offset & ~RCC_OFFSET_MASK) {
|
||
+ if ((offset & ~RCC_OFFSET_MASK) != RCC_BASE)
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+
|
||
+ offset &= RCC_OFFSET_MASK;
|
||
+ }
|
||
+
|
||
+ DMSG_RAW("RCC service: %s 0x%" PRIx32 " at offset 0x%" PRIx32,
|
||
+ request == STM32_SIP_SVC_REG_WRITE ? "write" :
|
||
+ request == STM32_SIP_SVC_REG_SET ? "set" : "clear",
|
||
+ value, offset);
|
||
+
|
||
+ raw_allowed_access_request(request, offset, value);
|
||
+
|
||
+ return STM32_SIP_SVC_OK;
|
||
+}
|
||
+
|
||
+uint32_t rcc_opp_scv_handler(uint32_t x1, uint32_t x2, uint32_t *res)
|
||
+{
|
||
+ uint32_t cmd = x1;
|
||
+ uint32_t opp = x2 / 1000U; /* KHz */
|
||
+
|
||
+ switch (cmd) {
|
||
+ case STM32_SIP_SVC_RCC_OPP_SET:
|
||
+ if (stm32mp1_set_opp_khz(opp))
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+ break;
|
||
+
|
||
+ case STM32_SIP_SVC_RCC_OPP_ROUND:
|
||
+ if(stm32mp1_round_opp_khz(&opp))
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+
|
||
+ if (MUL_OVERFLOW(opp, 1000, res))
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ return STM32_SIP_SVC_INVALID_PARAMS;
|
||
+ }
|
||
+
|
||
+ return STM32_SIP_SVC_OK;
|
||
+}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h
|
||
new file mode 100644
|
||
index 0000000..873458f
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h
|
||
@@ -0,0 +1,30 @@
|
||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2019, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#ifndef RCC_SVC_H
|
||
+#define RCC_SVC_H
|
||
+
|
||
+#include <stm32mp1_smc.h>
|
||
+
|
||
+#ifdef CFG_STM32_RCC_SIP
|
||
+uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3);
|
||
+uint32_t rcc_opp_scv_handler(uint32_t x1, uint32_t x2, uint32_t *res);
|
||
+#else
|
||
+static inline uint32_t rcc_scv_handler(uint32_t x1 __unused,
|
||
+ uint32_t x2 __unused,
|
||
+ uint32_t x3 __unused)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+static inline uint32_t rcc_opp_scv_handler(uint32_t x1 __unused,
|
||
+ uint32_t x2 __unused,
|
||
+ uint32_t *res __unused)
|
||
+
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif
|
||
+
|
||
+#endif /*RCC_SVC_H*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h
|
||
index 7f16160..86deb59 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h
|
||
@@ -14,7 +14,7 @@
|
||
#define STM32_SIP_SVC_VERSION_MAJOR 0x0
|
||
#define STM32_SIP_SVC_VERSION_MINOR 0x1
|
||
|
||
-#define STM32_SIP_SVC_FUNCTION_COUNT 0x3
|
||
+#define STM32_SIP_SVC_FUNCTION_COUNT 12
|
||
|
||
/* STM32 SIP service generic return codes */
|
||
#define STM32_SIP_SVC_OK 0x0
|
||
@@ -72,6 +72,51 @@
|
||
#define STM32_SIP_SVC_FUNC_VERSION 0xff03
|
||
|
||
/*
|
||
+ * SIP function STM32_SIP_SVC_FUNC_RCC
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (input) Service ID (STM32_SIP_SVC_REG_xxx)
|
||
+ * Argument a2: (input) register offset or physical address
|
||
+ * (output) register read value, if applicable
|
||
+ * Argument a3: (input) register target value if applicable
|
||
+ */
|
||
+#define STM32_SIP_SVC_FUNC_RCC 0x1000
|
||
+
|
||
+/* Service ID for STM32_SIP_FUNC_RCC */
|
||
+#define STM32_SIP_SVC_REG_READ 0x0
|
||
+#define STM32_SIP_SVC_REG_WRITE 0x1
|
||
+#define STM32_SIP_SVC_REG_SET 0x2
|
||
+#define STM32_SIP_SVC_REG_CLEAR 0x3
|
||
+
|
||
+/*
|
||
+ * SIP functions STM32_SIP_SVC_FUNC_CAL
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (input) Clock ID (from DT clock bindings)
|
||
+ */
|
||
+#define STM32_SIP_SVC_FUNC_CAL 0x1002
|
||
+
|
||
+/*
|
||
+ * SIP functions STM32_SIP_FUNC_PWR
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (input) Service ID (STM32_SIP_REG_xxx)
|
||
+ * Argument a2: (input) register offset or physical address
|
||
+ * (output) register read value, if applicable
|
||
+ * Argument a3: (input) register target value if applicable
|
||
+ */
|
||
+#define STM32_SIP_SVC_FUNC_PWR 0x1001
|
||
+
|
||
+/* Service ID for STM32_SIP_SVC_FUNC_RCC/_PWR */
|
||
+#define STM32_SIP_SVC_REG_READ 0x0
|
||
+#define STM32_SIP_SVC_REG_WRITE 0x1
|
||
+#define STM32_SIP_SVC_REG_SET 0x2
|
||
+#define STM32_SIP_SVC_REG_CLEAR 0x3
|
||
+
|
||
+/*
|
||
* SIP functions STM32_SIP_SVC_FUNC_BSEC
|
||
*
|
||
* Argument a0: (input) SMCCC function ID
|
||
@@ -91,6 +136,91 @@
|
||
#define STM32_SIP_SVC_BSEC_WRLOCK_OTP 0x5
|
||
|
||
/*
|
||
+ * SIP functions STM32_SIP_FUNC_SR_MODE
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (unused)
|
||
+ * Argument a2: (input) Target selfrefresh mode
|
||
+ */
|
||
+#define STM32_SIP_FUNC_SR_MODE 0x1004
|
||
+
|
||
+/* DDR Self-Refresh modes */
|
||
+#define STM32_SIP_SR_MODE_SSR 0x0
|
||
+#define STM32_SIP_SR_MODE_ASR 0x1
|
||
+#define STM32_SIP_SR_MODE_HSR 0x2
|
||
+
|
||
+/*
|
||
+ * SIP functions STM32_SIP_FUNC_CSTOP
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (unused)
|
||
+ * Argument a2: (unused)
|
||
+ * Argument a3: (input) Target SoC mode
|
||
+ */
|
||
+#define STM32_SIP_FUNC_CSTOP 0x1005
|
||
+
|
||
+/* Valid SoC modes used for CSTOP, */
|
||
+#define STM32_SIP_CSLEEP_RUN 0x0
|
||
+#define STM32_SIP_CSTOP_ALLOW_STOP 0x1
|
||
+#define STM32_SIP_CSTOP_ALLOW_LP_STOP 0x2
|
||
+#define STM32_SIP_CSTOP_ALLOW_LPLV_STOP 0x3
|
||
+#define STM32_SIP_CSTOP_ALLOW_STANDBY 0x4
|
||
+#define STM32_SIP_CSTOP_ALLOW_STANDBY_DDR_OFF 0x5
|
||
+#define STM32_SIP_CSTOP_SHUTDOWN 0x6
|
||
+
|
||
+/*
|
||
+ * SIP functions STM32_SIP_FUNC_STANDBY
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a1: (unused)
|
||
+ * Argument a2: (unused)
|
||
+ * Argument a3: (input) non null only for DDR off standby
|
||
+ */
|
||
+#define STM32_SIP_FUNC_STANDBY 0x1006
|
||
+
|
||
+/*
|
||
+ * SIP function STM32_SIP_FUNC_SHUTDOWN
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ */
|
||
+#define STM32_SIP_FUNC_SHUTDOWN 0x1007
|
||
+
|
||
+/*
|
||
+ * SIP function STM32_SIP_FUNC_PD_DOMAIN
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a2: (index) ID of target power domain to be enabled/disabled
|
||
+ * Argument a3: (input) 0 to disable, 1 to eanble target domain
|
||
+ */
|
||
+#define STM32_SIP_FUNC_PD_DOMAIN 0x1008
|
||
+
|
||
+/* Valid IDs for power domain for function STM32_SIP_FUNC_PD_DOMAIN */
|
||
+#define STM32_SIP_PD_VSW 0x0
|
||
+#define STM32_SIP_PD_CORE_RET 0x1
|
||
+#define STM32_SIP_PD_CORE 0x2
|
||
+#define STM32_SIP_PD_MAX_PM_DOMAIN 0x3
|
||
+
|
||
+/*
|
||
+ * SIP function STM32_SIP_FUNC_RCC_OPP.
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID.
|
||
+ * (output) Status return code.
|
||
+ * Argument a1: (input) Service ID (STM32_SIP_RCC_OPP_xxx).
|
||
+ * (output) Rounded frequency, if applicable.
|
||
+ * Argument a2: (input) Requested frequency.
|
||
+ */
|
||
+#define STM32_SIP_SVC_FUNC_RCC_OPP 0x1009
|
||
+
|
||
+/* Service ID for STM32_SIP_FUNC_RCC_OPP */
|
||
+#define STM32_SIP_SVC_RCC_OPP_SET 0x0
|
||
+#define STM32_SIP_SVC_RCC_OPP_ROUND 0x1
|
||
+
|
||
+/*
|
||
* SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT0
|
||
* SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT1
|
||
*
|
||
@@ -101,4 +231,68 @@
|
||
#define STM32_SIP_SVC_FUNC_SCMI_AGENT0 0x2000
|
||
#define STM32_SIP_SVC_FUNC_SCMI_AGENT1 0x2001
|
||
|
||
+/*
|
||
+ * OEM Functions
|
||
+ */
|
||
+#define STM32_OEM_SVC_VERSION_MAJOR 0x0
|
||
+#define STM32_OEM_SVC_VERSION_MINOR 0x1
|
||
+
|
||
+#define STM32_OEM_SVC_FUNCTION_COUNT 1
|
||
+
|
||
+/* Use the same UID as for SiP service */
|
||
+#define STM32_OEM_SVC_UID_0 STM32_SIP_SVC_UID_0
|
||
+#define STM32_OEM_SVC_UID_1 STM32_SIP_SVC_UID_1
|
||
+#define STM32_OEM_SVC_UID_2 STM32_SIP_SVC_UID_2
|
||
+#define STM32_OEM_SVC_UID_3 STM32_SIP_SVC_UID_3
|
||
+
|
||
+
|
||
+/* OEM service generic return codes */
|
||
+#define STM32_OEM_SVC_OK 0x0
|
||
+#define STM32_OEM_SVC_NOT_SUPPORTED 0xffffffffU
|
||
+#define STM32_OEM_SVC_FAILED 0xfffffffeU
|
||
+#define STM32_OEM_SVC_INVALID_PARAMS 0xfffffffdU
|
||
+
|
||
+/*
|
||
+ * OEM function STM32_OEM_FUNC_CALL_COUNT
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) Count of defined function IDs
|
||
+ */
|
||
+#define STM32_OEM_SVC_FUNC_CALL_COUNT 0xff00
|
||
+
|
||
+/*
|
||
+ * OEM function STM32_OEM_SVC_FUNC_UID
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) Lowest 32bit of the stm32mp1 OEM service UUID
|
||
+ * Argument a1: (output) Next 32bit of the stm32mp1 OEM service UUID
|
||
+ * Argument a2: (output) Next 32bit of the stm32mp1 OEM service UUID
|
||
+ * Argument a3: (output) Last 32bit of the stm32mp1 OEM service UUID
|
||
+ */
|
||
+#define STM32_OEM_SVC_FUNC_UID 0xff01
|
||
+
|
||
+/*
|
||
+ * OEM function STM32_OEM_FUNC_VERSION
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) STM32 OEM service major
|
||
+ * Argument a1: (output) STM32 OEM service minor
|
||
+ */
|
||
+#define STM32_OEM_SVC_FUNC_VERSION 0xff03
|
||
+
|
||
+/*
|
||
+ * OEM function STM32_OEM_SVC_FUNC_LP_FORCE_PARAMS
|
||
+ *
|
||
+ * Argument a0: (input) SMCC ID
|
||
+ * (output) status return code
|
||
+ * Argument a2: (input) ID of the mode: suspend or shutdown (off)
|
||
+ * Argument a3: (input) ID of the power state to be reached for the mode
|
||
+ * Refer to stm32mp1 power bindings.
|
||
+ */
|
||
+#define STM32_OEM_SVC_FUNC_LP_FORCE_PARAMS 0x0f800
|
||
+
|
||
+/* Valid IDs for power mode in STM32_OEM_SVC_FUNC_LP_FORCE_PARAMS */
|
||
+#define STM32_OEM_SVC_LP_FORCE_SUSPEND_PARAMS 0
|
||
+#define STM32_OEM_SVC_LP_FORCE_OFF_PARAMS 1
|
||
+
|
||
#endif /* __STM32MP1_SMC_H__*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c
|
||
index 49d23ff..f5f131d 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c
|
||
@@ -7,11 +7,32 @@
|
||
#include <drivers/scmi-msg.h>
|
||
#include <sm/optee_smc.h>
|
||
#include <sm/sm.h>
|
||
+#include <stm32_util.h>
|
||
|
||
#include "bsec_svc.h"
|
||
+#include "low_power_svc.h"
|
||
+#include "pwr_svc.h"
|
||
+#include "rcc_svc.h"
|
||
#include "stm32mp1_smc.h"
|
||
|
||
-static enum sm_handler_ret sip_service(struct sm_ctx *ctx __unused,
|
||
+#ifdef CFG_STM32_CLKCALIB_SIP
|
||
+static uint32_t calib_scv_handler(uint32_t x1)
|
||
+{
|
||
+ unsigned long clock_id = x1;
|
||
+
|
||
+ if (stm32mp_start_clock_calib(clock_id))
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+
|
||
+ return STM32_SIP_SVC_OK;
|
||
+}
|
||
+#else
|
||
+static uint32_t calib_scv_handler(uint32_t __unused x1)
|
||
+{
|
||
+ return STM32_SIP_SVC_FAILED;
|
||
+}
|
||
+#endif
|
||
+
|
||
+static enum sm_handler_ret sip_service(struct sm_ctx *ctx,
|
||
struct thread_smc_args *args)
|
||
{
|
||
switch (OPTEE_SMC_FUNC_NUM(args->a0)) {
|
||
@@ -39,6 +60,60 @@ static enum sm_handler_ret sip_service(struct sm_ctx *ctx __unused,
|
||
case STM32_SIP_SVC_FUNC_BSEC:
|
||
bsec_main(args);
|
||
break;
|
||
+ case STM32_SIP_SVC_FUNC_RCC:
|
||
+ args->a0 = rcc_scv_handler(args->a1, args->a2, args->a3);
|
||
+ break;
|
||
+ case STM32_SIP_SVC_FUNC_RCC_OPP:
|
||
+ args->a0 = rcc_opp_scv_handler(args->a1, args->a2, &args->a1);
|
||
+ break;
|
||
+ case STM32_SIP_SVC_FUNC_CAL:
|
||
+ args->a0 = calib_scv_handler(args->a1);
|
||
+ break;
|
||
+ case STM32_SIP_SVC_FUNC_PWR:
|
||
+ args->a0 = pwr_scv_handler(args->a1, args->a2, args->a3);
|
||
+ break;
|
||
+ case STM32_SIP_FUNC_SR_MODE:
|
||
+ args->a0 = sr_mode_scv_handler(args->a1, args->a2);
|
||
+ break;
|
||
+ case STM32_SIP_FUNC_CSTOP:
|
||
+ args->a0 = cstop_scv_handler(ctx, args->a1, args->a2, args->a3);
|
||
+ break;
|
||
+ case STM32_SIP_FUNC_STANDBY:
|
||
+ args->a0 = standby_scv_handler(ctx, args->a1, args->a2, args->a3);
|
||
+ break;
|
||
+ case STM32_SIP_FUNC_SHUTDOWN:
|
||
+ args->a0 = shutdown_scv_handler();
|
||
+ break;
|
||
+ case STM32_SIP_FUNC_PD_DOMAIN:
|
||
+ args->a0 = pm_domain_scv_handler(args->a1, args->a2);
|
||
+ break;
|
||
+ default:
|
||
+ return SM_HANDLER_PENDING_SMC;
|
||
+ }
|
||
+
|
||
+ return SM_HANDLER_SMC_HANDLED;
|
||
+}
|
||
+
|
||
+static enum sm_handler_ret oem_service(struct sm_ctx *ctx __unused,
|
||
+ struct thread_smc_args *args)
|
||
+{
|
||
+ switch (OPTEE_SMC_FUNC_NUM(args->a0)) {
|
||
+ case STM32_OEM_SVC_FUNC_CALL_COUNT:
|
||
+ args->a0 = STM32_OEM_SVC_FUNCTION_COUNT;
|
||
+ break;
|
||
+ case STM32_OEM_SVC_FUNC_VERSION:
|
||
+ args->a0 = STM32_OEM_SVC_VERSION_MAJOR;
|
||
+ args->a1 = STM32_OEM_SVC_VERSION_MINOR;
|
||
+ break;
|
||
+ case STM32_OEM_SVC_FUNC_UID:
|
||
+ args->a0 = STM32_OEM_SVC_UID_0;
|
||
+ args->a1 = STM32_OEM_SVC_UID_1;
|
||
+ args->a2 = STM32_OEM_SVC_UID_2;
|
||
+ args->a3 = STM32_OEM_SVC_UID_3;
|
||
+ break;
|
||
+ case STM32_OEM_SVC_FUNC_LP_FORCE_PARAMS:
|
||
+ args->a0 = pm_set_lp_state_scv_handler(args->a1, args->a2);
|
||
+ break;
|
||
default:
|
||
return SM_HANDLER_PENDING_SMC;
|
||
}
|
||
@@ -56,6 +131,8 @@ enum sm_handler_ret sm_platform_handler(struct sm_ctx *ctx)
|
||
switch (OPTEE_SMC_OWNER_NUM(args->a0)) {
|
||
case OPTEE_SMC_OWNER_SIP:
|
||
return sip_service(ctx, args);
|
||
+ case OPTEE_SMC_OWNER_OEM:
|
||
+ return oem_service(ctx, args);
|
||
default:
|
||
return SM_HANDLER_PENDING_SMC;
|
||
}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk b/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk
|
||
index 6e1abcb..acccda1 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk
|
||
+++ b/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk
|
||
@@ -2,3 +2,6 @@ global-incdirs-y += .
|
||
|
||
srcs-y += stm32mp1_svc_setup.c
|
||
srcs-$(CFG_STM32_BSEC_SIP) += bsec_svc.c
|
||
+srcs-$(CFG_STM32_LOWPOWER_SIP) += low_power_svc.c
|
||
+srcs-$(CFG_STM32_PWR_SIP) += pwr_svc.c
|
||
+srcs-$(CFG_STM32_RCC_SIP) += rcc_svc.c
|
||
diff --git a/core/arch/arm/plat-stm32mp1/platform_config.h b/core/arch/arm/plat-stm32mp1/platform_config.h
|
||
index cf68f45..2b4bd95 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/platform_config.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/platform_config.h
|
||
@@ -8,14 +8,45 @@
|
||
|
||
#include <mm/generic_ram_layout.h>
|
||
|
||
+/* Enable/disable use of the core0 reset control from RCC */
|
||
+#undef STM32MP1_USE_MPU0_RESET
|
||
+
|
||
/* Make stacks aligned to data cache line length */
|
||
#define STACK_ALIGNMENT 32
|
||
|
||
+#if defined(CFG_WITH_PAGER)
|
||
+#if defined(CFG_WITH_LPAE)
|
||
+/*
|
||
+ * Optimize unpaged memory size:
|
||
+ * - one table for the level2 table for overall vmem range
|
||
+ * - two tables for TEE RAM fine grain mapping [2ffc.0000 301f.ffff]
|
||
+ * - one table for a 2MByte dynamic shared virtual memory (SHM_VASPACE)
|
||
+ */
|
||
+#define MAX_XLAT_TABLES 4
|
||
+#else
|
||
+/*
|
||
+ * Optimize unpaged memory size:
|
||
+ * - two tables for TEE RAM mapping [2ffc.0000 300f.ffff]
|
||
+ * - one table for secure internal RAMs (PM: ROMed core TEE RAM)
|
||
+ * - one table for non-secure internal RAMs (PM: DDR first page)
|
||
+ * - two tables for a 2MByte dynamiq shared virtual memory (SHM_VASPACE)
|
||
+ */
|
||
+#define MAX_XLAT_TABLES 6
|
||
+#endif /*CFG_WITH_LPAE*/
|
||
+#else
|
||
+/* Be generous with this setup that has plenty of secure RAM */
|
||
+#define MAX_XLAT_TABLES 10
|
||
+#endif /*CFG_WITH_PAGER*/
|
||
+
|
||
/* SoC interface registers base address */
|
||
+#define BKPSRAM_BASE 0x54000000
|
||
#define BSEC_BASE 0x5c005000
|
||
#define ETZPC_BASE 0x5c007000
|
||
#define CRYP1_BASE 0x54001000
|
||
+#define DBGMCU_BASE 0x50081000
|
||
#define DDR_BASE 0xc0000000ul
|
||
+#define DDRCTRL_BASE 0x5a003000
|
||
+#define DDRPHYC_BASE 0x5a004000
|
||
#define GIC_BASE 0xa0021000ul
|
||
#define GPIOA_BASE 0x50002000
|
||
#define GPIOB_BASE 0x50003000
|
||
@@ -39,9 +70,24 @@
|
||
#define RNG1_BASE 0x54003000
|
||
#define RTC_BASE 0x5c004000
|
||
#define SPI6_BASE 0x5c001000
|
||
+#define STGEN_BASE 0x5c008000
|
||
#define SYSCFG_BASE 0x50020000
|
||
#define SYSRAM_BASE 0x2ffc0000
|
||
#define TAMP_BASE 0x5c00a000
|
||
+#define TIM1_BASE 0x44000000
|
||
+#define TIM2_BASE 0x40000000
|
||
+#define TIM3_BASE 0x40001000
|
||
+#define TIM4_BASE 0x40002000
|
||
+#define TIM5_BASE 0x40003000
|
||
+#define TIM6_BASE 0x40004000
|
||
+#define TIM7_BASE 0x40005000
|
||
+#define TIM8_BASE 0x44001000
|
||
+#define TIM12_BASE 0x40006000
|
||
+#define TIM13_BASE 0x40007000
|
||
+#define TIM14_BASE 0x40008000
|
||
+#define TIM15_BASE 0x44006000
|
||
+#define TIM16_BASE 0x44007000
|
||
+#define TIM17_BASE 0x44008000
|
||
#define TZC_BASE 0x5c006000
|
||
#define UART1_BASE 0x5c000000
|
||
#define UART2_BASE 0x4000e000
|
||
@@ -52,6 +98,9 @@
|
||
#define UART7_BASE 0x40018000
|
||
#define UART8_BASE 0x40019000
|
||
|
||
+/* DDR expected size if not found in device tree */
|
||
+#define STM32MP1_DDR_SIZE_DFLT (1 * 1024 * 1024 * 1024)
|
||
+
|
||
/* Console configuration */
|
||
#define STM32MP1_DEBUG_USART_BASE UART4_BASE
|
||
#define GIC_SPI_UART4 84
|
||
@@ -65,16 +114,21 @@
|
||
|
||
#define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U)
|
||
|
||
-#define DATA0_OTP 0
|
||
-#define PART_NUMBER_OTP 1
|
||
-#define MONOTONIC_OTP 4
|
||
-#define NAND_OTP 9
|
||
-#define UID0_OTP 13
|
||
-#define UID1_OTP 14
|
||
-#define UID2_OTP 15
|
||
-#define HW2_OTP 18
|
||
+#define CFG0_OTP "cfg0_otp"
|
||
+#define CFG0_OTP_SECURED_POS 6
|
||
|
||
-#define DATA0_OTP_SECURED_POS 6
|
||
+#define HW2_OTP "hw2_otp"
|
||
+#define HW2_OTP_IWDG_HW_ENABLE_SHIFT 3
|
||
+#define HW2_OTP_IWDG_FZ_STOP_SHIFT 5
|
||
+#define HW2_OTP_IWDG_FZ_STANDBY_SHIFT 7
|
||
+
|
||
+#define PART_NUMBER_OTP "part_number_otp"
|
||
+#define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0)
|
||
+#define PART_NUMBER_OTP_PART_SHIFT 0
|
||
+
|
||
+#define HW2_OTP_IWDG_HW_ENABLE_SHIFT 3
|
||
+#define HW2_OTP_IWDG_FZ_STOP_SHIFT 5
|
||
+#define HW2_OTP_IWDG_FZ_STANDBY_SHIFT 7
|
||
|
||
/* GIC resources */
|
||
#define GIC_SIZE 0x2000
|
||
@@ -84,11 +138,14 @@
|
||
#define GIC_NON_SEC_SGI_0 0
|
||
#define GIC_SEC_SGI_0 8
|
||
#define GIC_SEC_SGI_1 9
|
||
+#define GIC_SPI_SEC_PHY_TIMER 29
|
||
|
||
#define TARGET_CPU0_GIC_MASK BIT(0)
|
||
#define TARGET_CPU1_GIC_MASK BIT(1)
|
||
#define TARGET_CPUS_GIC_MASK GENMASK_32(CFG_TEE_CORE_NB_CORE - 1, 0)
|
||
|
||
+#define STM32MP_GIC_PRIORITY_CSTOP 0xc0
|
||
+
|
||
/*
|
||
* GPIO banks: 11 non secure banks (A to K) and 1 secure bank (Z)
|
||
* Bank register's base address is computed from the bank ID listed here.
|
||
@@ -116,6 +173,16 @@
|
||
#define GPIO_BANK_K 10U
|
||
#define GPIO_BANK_Z 25U
|
||
|
||
+/* IWDG resources */
|
||
+#define IWDG1_INST 0
|
||
+#define IWDG2_INST 1
|
||
+
|
||
+#define STM32MP1_IRQ_IWDG1 182U
|
||
+#define STM32MP1_IRQ_IWDG2 183U
|
||
+
|
||
+/* RCC platform resources */
|
||
+#define RCC_WAKEUP_IT 177
|
||
+
|
||
/* TAMP resources */
|
||
#define TAMP_BKP_REGISTER_OFF 0x100
|
||
|
||
@@ -140,6 +207,24 @@
|
||
#define USART3_BASE UART3_BASE
|
||
#define USART6_BASE UART6_BASE
|
||
|
||
+/* DBGMCU resources */
|
||
+#define DBGMCU_IDC 0x0
|
||
+#define DBGMCU_IDC_DEV_ID_MASK GENMASK_32(11, 0)
|
||
+#define DBGMCU_IDC_REV_ID_MASK GENMASK_32(31, 16)
|
||
+#define DBGMCU_IDC_REV_ID_SHIFT 16
|
||
+
|
||
+/* BKPSRAM layout */
|
||
+#define BKPSRAM_SIZE 0x1000
|
||
+#define BKPSRAM_PM_OFFSET 0x000
|
||
+#define BKPSRAM_PM_SIZE (BKPSRAM_PM_MAILBOX_SIZE + \
|
||
+ BKPSRAM_PM_CONTEXT_SIZE)
|
||
+
|
||
+#define BKPSRAM_PM_MAILBOX_OFFSET BKPSRAM_PM_OFFSET
|
||
+#define BKPSRAM_PM_MAILBOX_SIZE 0x100
|
||
+#define BKPSRAM_PM_CONTEXT_OFFSET (BKPSRAM_PM_MAILBOX_OFFSET + \
|
||
+ BKPSRAM_PM_MAILBOX_SIZE)
|
||
+#define BKPSRAM_PM_CONTEXT_SIZE 0xF00
|
||
+
|
||
/* SYSRAM layout */
|
||
#define SYSRAM_SIZE 0x40000
|
||
#define SYSRAM_NS_SIZE (SYSRAM_SIZE - SYSRAM_SEC_SIZE)
|
||
@@ -153,4 +238,32 @@
|
||
#define SYSRAM_SEC_SIZE SYSRAM_SIZE
|
||
#endif
|
||
|
||
+/* SoC part numbers and revisions */
|
||
+#define STM32MP1_CHIP_ID 0x500
|
||
+
|
||
+#define STM32MP157C_PART_NB 0x05000000
|
||
+#define STM32MP157A_PART_NB 0x05000001
|
||
+#define STM32MP153C_PART_NB 0x05000024
|
||
+#define STM32MP153A_PART_NB 0x05000025
|
||
+#define STM32MP151C_PART_NB 0x0500002E
|
||
+#define STM32MP151A_PART_NB 0x0500002F
|
||
+#define STM32MP157F_PART_NB 0x05000080
|
||
+#define STM32MP157D_PART_NB 0x05000081
|
||
+#define STM32MP153F_PART_NB 0x050000A4
|
||
+#define STM32MP153D_PART_NB 0x050000A5
|
||
+#define STM32MP151F_PART_NB 0x050000AE
|
||
+#define STM32MP151D_PART_NB 0x050000AF
|
||
+
|
||
+#define STM32MP1_CHIP_DEFAULT_VERSION 0
|
||
+
|
||
+#define STM32MP1_REV_A 0x00001000
|
||
+#define STM32MP1_REV_B 0x00002000
|
||
+#define STM32MP1_REV_Z 0x00002001
|
||
+
|
||
+/* OPP */
|
||
+#define PLAT_OPP_ID1 1U
|
||
+#define PLAT_OPP_ID2 2U
|
||
+#define PLAT_MAX_OPP_NB 2U
|
||
+#define PLAT_MAX_PLLCFG_NB 6U
|
||
+
|
||
#endif /*PLATFORM_CONFIG_H*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/context.c b/core/arch/arm/plat-stm32mp1/pm/context.c
|
||
new file mode 100644
|
||
index 0000000..7a518a3
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/context.c
|
||
@@ -0,0 +1,521 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
|
||
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#include <arm32.h>
|
||
+#include <boot_api.h>
|
||
+#include <drivers/gic.h>
|
||
+#include <drivers/stm32_rng.h>
|
||
+#include <drivers/stm32_rtc.h>
|
||
+#include <drivers/stm32mp1_ddrc.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+#include <generated/context_asm_defines.h>
|
||
+#include <initcall.h>
|
||
+#include <io.h>
|
||
+#include <kernel/cache_helpers.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <keep.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <kernel/pm.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <mm/mobj.h>
|
||
+#include <platform_config.h>
|
||
+#include <stdlib.h>
|
||
+#include <stm32_util.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <string.h>
|
||
+
|
||
+#include "context.h"
|
||
+#include "power.h"
|
||
+
|
||
+#define TRAINING_AREA_SIZE 64
|
||
+
|
||
+/*
|
||
+ * STANDBY_CONTEXT_MAGIC0:
|
||
+ * Context provides magic, resume entry, zq0cr0 zdata and DDR training buffer.
|
||
+ *
|
||
+ * STANDBY_CONTEXT_MAGIC1:
|
||
+ * Context provides magic, resume entry, zq0cr0 zdata, DDR training buffer
|
||
+ * and PLL1 dual OPP settings structure (86 bytes).
|
||
+ */
|
||
+#define STANDBY_CONTEXT_MAGIC0 (0x0001 << 16)
|
||
+#define STANDBY_CONTEXT_MAGIC1 (0x0002 << 16)
|
||
+
|
||
+#if CFG_STM32MP15_PM_CONTEX_VERSION == 1
|
||
+#define STANDBY_CONTEXT_MAGIC (STANDBY_CONTEXT_MAGIC0 | TRAINING_AREA_SIZE)
|
||
+#elif CFG_STM32MP15_PM_CONTEX_VERSION == 2
|
||
+#define STANDBY_CONTEXT_MAGIC (STANDBY_CONTEXT_MAGIC1 | TRAINING_AREA_SIZE)
|
||
+#else
|
||
+#error Invalid value for CFG_STM32MP15_PM_CONTEX_VERSION
|
||
+#endif
|
||
+
|
||
+#if (PLAT_MAX_OPP_NB != 2) || (PLAT_MAX_PLLCFG_NB != 6)
|
||
+#error STANDBY_CONTEXT_MAGIC1 does not support expected PLL1 settings
|
||
+#endif
|
||
+
|
||
+/* pll_settings structure size definitions (reference to clock driver) */
|
||
+#define PLL1_SETTINGS_SIZE (((PLAT_MAX_OPP_NB * \
|
||
+ (PLAT_MAX_PLLCFG_NB + 3)) + 1) * \
|
||
+ sizeof(uint32_t))
|
||
+
|
||
+/*
|
||
+ * Context saved in TEE RAM during lower power sequence.
|
||
+ * Can be allocated if to big for static allocation.
|
||
+ *
|
||
+ * @stgen_cnt_h: Upper 32bit of the STGEN counter
|
||
+ * @stgen_cnt_l: Lower 32bit of the STGEN counter
|
||
+ * @rtc: RTC time read at suspend
|
||
+ */
|
||
+struct pm_context {
|
||
+ uint32_t stgen_cnt_h;
|
||
+ uint32_t stgen_cnt_l;
|
||
+ struct stm32_rtc_calendar rtc;
|
||
+};
|
||
+
|
||
+static struct pm_context plat_ctx;
|
||
+
|
||
+/*
|
||
+ * BKPSRAM contains a mailbox used with early boot stages for resume sequence.
|
||
+ * The mailbox content data that must be restored before OP-TEE is resumed.
|
||
+ *
|
||
+ * @magic: magic value read by early boot stage for consistency
|
||
+ * @zq0cr0_zdata: DDRPHY configuration to be restored.
|
||
+ * @ddr_training_backup: DDR area saved at suspend and backed up at resume
|
||
+ */
|
||
+struct pm_mailbox {
|
||
+ uint32_t magic;
|
||
+ uint32_t core0_resume_ep;
|
||
+ uint32_t zq0cr0_zdata;
|
||
+ uint8_t ddr_training_backup[TRAINING_AREA_SIZE];
|
||
+#if CFG_STM32MP15_PM_CONTEX_VERSION >= 2
|
||
+ uint8_t pll1_settings[PLL1_SETTINGS_SIZE];
|
||
+#endif
|
||
+};
|
||
+
|
||
+/*
|
||
+ * BKPSRAM contains OP-TEE resume instruction sequence which restores
|
||
+ * TEE RAM content. The BKPSRAM contains restoration materials
|
||
+ * (key, tag) and the resume entry point in restored TEE RAM.
|
||
+ */
|
||
+static struct retram_resume_ctx *get_retram_resume_ctx(void)
|
||
+{
|
||
+ vaddr_t bkpsram_base = stm32mp_bkpsram_base();
|
||
+ vaddr_t context_base = bkpsram_base + BKPSRAM_PM_CONTEXT_OFFSET;
|
||
+
|
||
+ return (struct retram_resume_ctx *)context_base;
|
||
+}
|
||
+
|
||
+static struct pm_mailbox *get_pm_mailbox(void)
|
||
+{
|
||
+ vaddr_t bkpsram_base = stm32mp_bkpsram_base();
|
||
+ vaddr_t mailbox_base = bkpsram_base + BKPSRAM_PM_MAILBOX_OFFSET;
|
||
+
|
||
+ return (struct pm_mailbox *)mailbox_base;
|
||
+}
|
||
+
|
||
+#if TRACE_LEVEL >= TRACE_DEBUG
|
||
+static void __maybe_unused dump_context(void)
|
||
+{
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+
|
||
+ stm32_clock_enable(RTCAPB);
|
||
+
|
||
+ DMSG("Backup registers: address 0x%" PRIx32 ", magic 0x%" PRIx32,
|
||
+ *(uint32_t *)stm32mp_bkpreg(BCKR_CORE1_BRANCH_ADDRESS),
|
||
+ *(uint32_t *)stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER));
|
||
+
|
||
+ stm32_clock_disable(RTCAPB);
|
||
+
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+
|
||
+ DMSG("BKPSRAM mailbox: 0x%" PRIx32 ", zd 0x%" PRIx32 ", ep 0x%" PRIx32,
|
||
+ mailbox->magic, mailbox->zq0cr0_zdata,
|
||
+ mailbox->core0_resume_ep);
|
||
+
|
||
+ DMSG("BKPSRAM context: teeram backup @%" PRIx32 ", resume @0x%" PRIx32,
|
||
+ ctx->teeram_bkp_pa, ctx->resume_pa);
|
||
+
|
||
+ stm32_clock_disable(BKPSRAM);
|
||
+}
|
||
+#else
|
||
+static void __maybe_unused dump_context(void)
|
||
+{
|
||
+}
|
||
+#endif
|
||
+
|
||
+/*
|
||
+ * Save and restore functions
|
||
+ */
|
||
+static void save_time(void)
|
||
+{
|
||
+ vaddr_t stgen = stm32mp_stgen_base();
|
||
+
|
||
+ plat_ctx.stgen_cnt_h = io_read32(stgen + CNTCVU_OFFSET);
|
||
+ plat_ctx.stgen_cnt_l = io_read32(stgen + CNTCVL_OFFSET);
|
||
+ if (plat_ctx.stgen_cnt_l < 10)
|
||
+ plat_ctx.stgen_cnt_h = io_read32(stgen + CNTCVU_OFFSET);
|
||
+
|
||
+ stm32_clock_enable(RTC);
|
||
+ stm32_rtc_get_calendar(&plat_ctx.rtc);
|
||
+}
|
||
+
|
||
+#if TRACE_LEVEL >= TRACE_DEBUG
|
||
+static void print_ccm_decryption_duration(void)
|
||
+{
|
||
+ vaddr_t stgen = stm32mp_stgen_base();
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+
|
||
+ DMSG("CCM decryption duration %llums",
|
||
+ ((unsigned long long)ctx->stgen_cnt * 1000) /
|
||
+ io_read32(stgen + CNTFID_OFFSET));
|
||
+
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+}
|
||
+#else
|
||
+static void print_ccm_decryption_duration(void)
|
||
+{
|
||
+}
|
||
+#endif
|
||
+
|
||
+static void restore_time(void)
|
||
+{
|
||
+ struct stm32_rtc_calendar current_calendar = { };
|
||
+ unsigned long long stdby_time_in_ms = 0;
|
||
+ unsigned long long cnt = 0;
|
||
+ vaddr_t stgen = stm32mp_stgen_base();
|
||
+ struct retram_resume_ctx __maybe_unused *ctx = get_retram_resume_ctx();
|
||
+
|
||
+ stm32_rtc_get_calendar(¤t_calendar);
|
||
+ stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar,
|
||
+ &plat_ctx.rtc);
|
||
+
|
||
+ cnt = ((uint64_t)plat_ctx.stgen_cnt_h << 32) | plat_ctx.stgen_cnt_l;
|
||
+ cnt += (stdby_time_in_ms * io_read32(stgen + CNTFID_OFFSET)) / 1000U;
|
||
+
|
||
+ io_clrbits32(stgen + CNTCR_OFFSET, CNTCR_EN);
|
||
+ io_write32(stgen + CNTCVL_OFFSET, (uint32_t)cnt);
|
||
+ io_write32(stgen + CNTCVU_OFFSET, (uint32_t)(cnt >> 32));
|
||
+ io_setbits32(stgen + CNTCR_OFFSET, CNTCR_EN);
|
||
+
|
||
+ /* Balance clock enable(RTC) at save_time() */
|
||
+ stm32_clock_disable(RTC);
|
||
+
|
||
+ print_ccm_decryption_duration();
|
||
+}
|
||
+
|
||
+static bool __maybe_unused pm_cb_is_valid(void (*cb)(enum pm_op op, void *hdl),
|
||
+ void *hdl)
|
||
+{
|
||
+ void *cb_voidp = (void *)(vaddr_t)cb;
|
||
+ paddr_t cb_phy = virt_to_phys(cb_voidp);
|
||
+ paddr_t hdl_phy = virt_to_phys(hdl);
|
||
+ bool valid = false;
|
||
+
|
||
+ valid = (phys_to_virt(cb_phy, MEM_AREA_TEE_RAM_RX) == cb_voidp) &&
|
||
+ ((phys_to_virt(hdl_phy, MEM_AREA_TEE_RAM_RX) == hdl) ||
|
||
+ (phys_to_virt(hdl_phy, MEM_AREA_TEE_RAM_RO) == hdl) ||
|
||
+ (phys_to_virt(hdl_phy, MEM_AREA_TEE_RAM_RW) == hdl));
|
||
+
|
||
+ if (!valid)
|
||
+ EMSG("pm_cb mandates unpaged arguments %p %p", cb_voidp, hdl);
|
||
+
|
||
+ return valid;
|
||
+}
|
||
+
|
||
+uintptr_t stm32mp_pm_retram_resume_ep(void)
|
||
+{
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+
|
||
+ return (uintptr_t)&ctx->resume_sequence;
|
||
+}
|
||
+
|
||
+/* Clear the content of the PM mailbox */
|
||
+void stm32mp_pm_wipe_context(void)
|
||
+{
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+
|
||
+ memset(ctx, 0xa5, sizeof(*ctx));
|
||
+ memset(mailbox, 0xa5, sizeof(*mailbox));
|
||
+
|
||
+ stm32_clock_disable(BKPSRAM);
|
||
+}
|
||
+
|
||
+static struct mobj *teeram_bkp_mobj;
|
||
+
|
||
+static void init_retram_resume_resources(void)
|
||
+{
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+ size_t __maybe_unused csize = 0;
|
||
+ paddr_t __maybe_unused pa = 0;
|
||
+
|
||
+ COMPILE_TIME_ASSERT(sizeof(struct pm_mailbox) <
|
||
+ BKPSRAM_PM_MAILBOX_SIZE);
|
||
+ COMPILE_TIME_ASSERT(sizeof(struct retram_resume_ctx) <
|
||
+ BKPSRAM_PM_CONTEXT_SIZE);
|
||
+ csize = (vaddr_t)stm32mp_bkpsram_image_end -
|
||
+ (vaddr_t)stm32mp_bkpsram_resume;
|
||
+ assert((sizeof(*ctx) + csize) < BKPSRAM_PM_CONTEXT_SIZE);
|
||
+
|
||
+ teeram_bkp_mobj = mobj_mm_alloc(mobj_sec_ddr, TEE_RAM_PH_SIZE,
|
||
+ &tee_mm_sec_ddr);
|
||
+ if (!teeram_bkp_mobj)
|
||
+ panic();
|
||
+
|
||
+ assert((mobj_get_va(teeram_bkp_mobj, 0) != NULL) &&
|
||
+ (mobj_get_pa(teeram_bkp_mobj, 0, 0, &pa) == 0));
|
||
+
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+ memset(ctx, 0, sizeof(*ctx));
|
||
+ stm32_clock_disable(BKPSRAM);
|
||
+}
|
||
+
|
||
+/*
|
||
+ * When returning from STANDBY, the 64 first bytes of DDR will be overwritten
|
||
+ * during DDR DQS training. This area must then be saved before going to
|
||
+ * standby in the PM mailbox with the earlier boot stages.
|
||
+ */
|
||
+static void save_ddr_training_area(void)
|
||
+{
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+ size_t size = sizeof(mailbox->ddr_training_backup);
|
||
+ paddr_t pa = DDR_BASE;
|
||
+ void *va = phys_to_virt(pa, MEM_AREA_RAM_NSEC);
|
||
+
|
||
+ memcpy(&mailbox->ddr_training_backup[0], va, size);
|
||
+
|
||
+}
|
||
+
|
||
+/*
|
||
+ * When returning from STANDBY, warm boot boot stage needs to access to PLL1
|
||
+ * settings. This avoids to re-compute them and optimizes performances. This
|
||
+ * structure must then be saved before going to STANDBY in the PM mailbox
|
||
+ * shared with the warm boot boot stage.
|
||
+ */
|
||
+#if CFG_STM32MP15_PM_CONTEX_VERSION >= 2
|
||
+static void save_pll1_settings(void)
|
||
+{
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+ size_t size = sizeof(mailbox->pll1_settings);
|
||
+ uint8_t *data = &mailbox->pll1_settings[0];
|
||
+
|
||
+ stm32mp1_clk_lp_save_opp_pll1_settings(data, size);
|
||
+}
|
||
+#endif
|
||
+
|
||
+static void load_earlyboot_pm_mailbox(void)
|
||
+{
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+
|
||
+ COMPILE_TIME_ASSERT(sizeof(struct pm_mailbox) <
|
||
+ BKPSRAM_PM_MAILBOX_SIZE);
|
||
+
|
||
+ assert(stm32_clock_is_enabled(BKPSRAM));
|
||
+
|
||
+ memset(mailbox, 0, sizeof(*mailbox));
|
||
+
|
||
+ mailbox->zq0cr0_zdata = get_ddrphy_calibration();
|
||
+
|
||
+ save_ddr_training_area();
|
||
+
|
||
+#if CFG_STM32MP15_PM_CONTEX_VERSION >= 2
|
||
+ save_pll1_settings();
|
||
+#endif
|
||
+}
|
||
+
|
||
+#if defined(CFG_STM32_RNG) && defined(CFG_STM32_CRYP)
|
||
+/*
|
||
+ * CRYP relies on standard format for CCM IV/B0/CRT0 data. Our sequence uses
|
||
+ * no AAD, 4 bytes to encode the payload byte size and a 11 byte nonce.
|
||
+ */
|
||
+#define PM_CCM_Q 4
|
||
+#define PM_CCM_Q_FLAGS (PM_CCM_Q - 1)
|
||
+#define PM_CCM_TAG_LEN 16
|
||
+#define PM_CCM_TAG_FLAGS (((PM_CCM_TAG_LEN - 2) / 2) << 3)
|
||
+
|
||
+static void save_teeram_in_ddr(void)
|
||
+{
|
||
+ struct retram_resume_ctx *ctx = get_retram_resume_ctx();
|
||
+ size_t __maybe_unused size = (vaddr_t)stm32mp_bkpsram_image_end -
|
||
+ (vaddr_t)stm32mp_bkpsram_resume;
|
||
+ paddr_t pa = 0;
|
||
+ struct ccm_unpg_ctx *ccm = &ctx->ccm_ctx;
|
||
+ void *teeram = phys_to_virt(TEE_RAM_START, MEM_AREA_ROM_SEC);
|
||
+ void *teeram_bkp = mobj_get_va(teeram_bkp_mobj, 0);
|
||
+
|
||
+ COMPILE_TIME_ASSERT(PM_CTX_CCM_KEY_SIZE == sizeof(ccm->key));
|
||
+ COMPILE_TIME_ASSERT(PM_CTX_CCM_CTR1_SIZE == sizeof(ccm->ctr1));
|
||
+ COMPILE_TIME_ASSERT(PM_CTX_CCM_B0_SIZE == sizeof(ccm->b0));
|
||
+ COMPILE_TIME_ASSERT(PM_CTX_CCM_CTR0_SIZE == sizeof(ccm->ctr0));
|
||
+ COMPILE_TIME_ASSERT(PM_CTX_CCM_TAG_SIZE == sizeof(ccm->tag));
|
||
+
|
||
+ assert(stm32_clock_is_enabled(BKPSRAM) &&
|
||
+ stm32_clock_is_enabled(CRYP1));
|
||
+
|
||
+ memcpy(ctx->resume_sequence,
|
||
+ (void *)(vaddr_t)stm32mp_bkpsram_resume, size);
|
||
+
|
||
+ memset(ctx, 0, sizeof(*ctx));
|
||
+ ctx->resume_pa = virt_to_phys((void *)(vaddr_t)stm32mp_sysram_resume);
|
||
+ if (mobj_get_pa(teeram_bkp_mobj, 0, 0, &pa))
|
||
+ panic();
|
||
+
|
||
+ ctx->teeram_bkp_pa = (uint32_t)pa;
|
||
+ ctx->cryp1_base = (uint32_t)phys_to_virt(CRYP1_BASE, MEM_AREA_IO_SEC);
|
||
+ ctx->rcc_base = (uint32_t)phys_to_virt(RCC_BASE, MEM_AREA_IO_SEC);
|
||
+ ctx->stgen_base = (uint32_t)phys_to_virt(STGEN_BASE, MEM_AREA_IO_SEC);
|
||
+
|
||
+ if (stm32_rng_read((uint8_t *)ccm->key, sizeof(ccm->key)))
|
||
+ panic();
|
||
+
|
||
+ assert(((PM_CCM_TAG_FLAGS & ~0x38U) | (PM_CCM_Q_FLAGS & ~0x07U)) == 0);
|
||
+ COMPILE_TIME_ASSERT(PM_CCM_Q <= 4);
|
||
+ COMPILE_TIME_ASSERT(TEE_RAM_PH_SIZE > UINT16_MAX);
|
||
+ COMPILE_TIME_ASSERT(TEE_RAM_PH_SIZE < UINT32_MAX);
|
||
+
|
||
+ if (stm32_rng_read((uint8_t *)ccm->ctr1, sizeof(ccm->ctr1)))
|
||
+ panic();
|
||
+
|
||
+ ccm->ctr1[0] &= GENMASK_32(24, 0);
|
||
+ memcpy(ccm->b0, ccm->ctr1, sizeof(ccm->b0));
|
||
+ memcpy(ccm->ctr0, ccm->ctr1, sizeof(ccm->ctr0));
|
||
+
|
||
+ ccm->ctr0[0] |= PM_CCM_Q_FLAGS << 24;
|
||
+ ccm->ctr0[3] = 0;
|
||
+ ccm->ctr1[0] |= PM_CCM_Q_FLAGS << 24;
|
||
+ ccm->ctr1[3] = 1;
|
||
+ ccm->b0[0] |= (PM_CCM_Q_FLAGS | PM_CCM_TAG_FLAGS) << 24;
|
||
+ ccm->b0[3] = TEE_RAM_PH_SIZE;
|
||
+
|
||
+ stm32mp_ccm_encrypt_teeram(ctx, teeram_bkp, teeram, TEE_RAM_PH_SIZE);
|
||
+ dcache_clean_range(teeram_bkp, TEE_RAM_PH_SIZE);
|
||
+
|
||
+ memcpy(ctx->ccm_ref_tag, ccm->tag, sizeof(ctx->ccm_ref_tag));
|
||
+
|
||
+ DMSG("CCM encryption duration %llums",
|
||
+ ((unsigned long long)ctx->stgen_cnt * 1000) /
|
||
+ io_read32(ctx->stgen_base + CNTFID_OFFSET));
|
||
+ ctx->stgen_cnt = 0;
|
||
+}
|
||
+#else
|
||
+static void save_teeram_in_ddr(void)
|
||
+{
|
||
+ panic("Mandates RNG and CRYP support");
|
||
+}
|
||
+#endif /*CFG_STM32_RNG*/
|
||
+
|
||
+/* Finalize the PM mailbox now that everything is loaded */
|
||
+static void enable_pm_mailbox(unsigned int suspend)
|
||
+{
|
||
+ struct pm_mailbox *mailbox = get_pm_mailbox();
|
||
+ uint32_t magic = 0;
|
||
+ uint32_t hint = 0;
|
||
+
|
||
+ assert(stm32_clock_is_enabled(BKPSRAM) &&
|
||
+ stm32_clock_is_enabled(RTCAPB));
|
||
+
|
||
+ if (suspend) {
|
||
+ magic = BOOT_API_A7_CORE0_MAGIC_NUMBER;
|
||
+ mailbox->magic = STANDBY_CONTEXT_MAGIC;
|
||
+
|
||
+ hint = virt_to_phys(&get_retram_resume_ctx()->resume_sequence);
|
||
+ } else {
|
||
+ mailbox->magic = 0;
|
||
+ }
|
||
+
|
||
+ io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER), magic);
|
||
+ io_write32(stm32mp_bkpreg(BCKR_CORE1_BRANCH_ADDRESS), hint);
|
||
+
|
||
+ mailbox->core0_resume_ep = hint;
|
||
+}
|
||
+
|
||
+static void gate_pm_context_clocks(bool enable)
|
||
+{
|
||
+ static bool clocks_enabled;
|
||
+
|
||
+ if (enable) {
|
||
+ assert(!clocks_enabled);
|
||
+ stm32_clock_enable(BKPSRAM);
|
||
+ stm32_clock_enable(RTCAPB);
|
||
+ stm32_clock_enable(CRYP1);
|
||
+ clocks_enabled = true;
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ /* Suspended TEE RAM state left the clocks enabled */
|
||
+ if (clocks_enabled) {
|
||
+ stm32_clock_disable(BKPSRAM);
|
||
+ stm32_clock_disable(RTCAPB);
|
||
+ stm32_clock_disable(CRYP1);
|
||
+ clocks_enabled = false;
|
||
+ }
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Context (TEE RAM content + peripherals) must be restored
|
||
+ * only if system may reach STANDBY state.
|
||
+ */
|
||
+TEE_Result stm32mp_pm_save_context(unsigned int soc_mode)
|
||
+{
|
||
+ TEE_Result res = TEE_ERROR_GENERIC;
|
||
+
|
||
+ save_time();
|
||
+
|
||
+ if (!need_to_backup_cpu_context(soc_mode)) {
|
||
+ if (need_to_backup_stop_context(soc_mode))
|
||
+ stm32mp1_clk_save_context_for_stop();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+ }
|
||
+
|
||
+ gate_pm_context_clocks(true);
|
||
+ load_earlyboot_pm_mailbox();
|
||
+ res = pm_change_state(PM_OP_SUSPEND, 0);
|
||
+ if (res)
|
||
+ return res;
|
||
+
|
||
+ save_teeram_in_ddr();
|
||
+ enable_pm_mailbox(1);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+
|
||
+void stm32mp_pm_restore_context(unsigned int soc_mode)
|
||
+{
|
||
+ if (need_to_backup_cpu_context(soc_mode)) {
|
||
+ if (pm_change_state(PM_OP_RESUME, 0))
|
||
+ panic();
|
||
+
|
||
+ gate_pm_context_clocks(false);
|
||
+ } else if (need_to_backup_stop_context(soc_mode)) {
|
||
+ stm32mp1_clk_restore_context_for_stop();
|
||
+ }
|
||
+
|
||
+ restore_time();
|
||
+}
|
||
+
|
||
+void stm32mp_pm_shutdown_context(void)
|
||
+{
|
||
+ gate_pm_context_clocks(true);
|
||
+ load_earlyboot_pm_mailbox();
|
||
+ enable_pm_mailbox(0);
|
||
+ gate_pm_context_clocks(false);
|
||
+}
|
||
+
|
||
+static TEE_Result init_pm_support(void)
|
||
+{
|
||
+ init_retram_resume_resources();
|
||
+
|
||
+ stm32mp_pm_wipe_context();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+driver_init(init_pm_support);
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/context.h b/core/arch/arm/plat-stm32mp1/pm/context.h
|
||
new file mode 100644
|
||
index 0000000..a806d68
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/context.h
|
||
@@ -0,0 +1,102 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#ifndef __STM32MP_PM_CONTEXT_H__
|
||
+#define __STM32MP_PM_CONTEXT_H__
|
||
+
|
||
+#ifndef __ASSEMBLER__
|
||
+#include <compiler.h>
|
||
+#include <stdbool.h>
|
||
+#include <stdint.h>
|
||
+#include <stddef.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <tee_api_types.h>
|
||
+#endif
|
||
+
|
||
+#define PM_CTX_CCM_KEY_SIZE 32
|
||
+#define PM_CTX_CCM_CTR1_SIZE 16
|
||
+#define PM_CTX_CCM_B0_SIZE 16
|
||
+#define PM_CTX_CCM_CTR0_SIZE 16
|
||
+#define PM_CTX_CCM_TAG_SIZE 16
|
||
+
|
||
+#ifndef __ASSEMBLER__
|
||
+/*
|
||
+ * All materials for the CCM sequence using CRYP support are preloaded
|
||
+ * in this specific structure. Note that the sequence does not use AAD.
|
||
+ *
|
||
+ * @key: AES key material buffer
|
||
+ * @ctr1: Preformatted 128bit CTR1 block
|
||
+ * @ctr1: Preformatted 128bit B0 block
|
||
+ * @ctr1: Preformatted 128bit CTR0 block
|
||
+ * @tag: Buffer where the generated CCM tag is stored
|
||
+ */
|
||
+struct ccm_unpg_ctx {
|
||
+ uint32_t key[PM_CTX_CCM_KEY_SIZE / sizeof(uint32_t)];
|
||
+ uint32_t ctr1[PM_CTX_CCM_CTR1_SIZE / sizeof(uint32_t)];
|
||
+ uint32_t b0[PM_CTX_CCM_B0_SIZE / sizeof(uint32_t)];
|
||
+ uint32_t ctr0[PM_CTX_CCM_CTR0_SIZE / sizeof(uint32_t)];
|
||
+ uint32_t tag[PM_CTX_CCM_TAG_SIZE / sizeof(uint32_t)];
|
||
+};
|
||
+
|
||
+/*
|
||
+ * This structure is used by pm_helpers.S at early resume from retention RAM.
|
||
+ * It is defined here and used by context_asm_defines.c to generate offset
|
||
+ * macros for the assembly implementation in pm_helpers.S.
|
||
+ *
|
||
+ * To lower the memory footprint of suspend sequence, The same function is
|
||
+ * used for encryption (executed from TEE RAM with MMU enabled) and for
|
||
+ * decryption (executed from BKPSRAM with MMU disabled). Therefore some
|
||
+ * required addresses are provided by the caller through this structure
|
||
+ * especially some SoC interface registers that are likely to have different
|
||
+ * physical and virtual addresses.
|
||
+ *
|
||
+ * @resume_pa: OP-TEE resume physical entry in TEE RAM (once restored)
|
||
+ * @teeram_bkp_pa: Physical base address in TEE RAM backup in DDR
|
||
+ * @cryp1_base: Base address of the CRYP1 registers (physical or virtual)
|
||
+ * @rcc_base: Base address of the RCC registers (physical or virtual)
|
||
+ * @stgen_base: Base address of the STGEN registers (physical or virtual)
|
||
+ * @stgen_cnt: STGEN cycle counter backup cell and measure of cycles spent
|
||
+ * @ccm_ref_tag: 128bit arrays storing tag generated during encryption
|
||
+ * @ccm_ctx: Structure storing CCM configuration and generated tag
|
||
+ * @resume_sequence: Code/data array for the BKPSRAM resume sequence
|
||
+ */
|
||
+struct retram_resume_ctx {
|
||
+ uint32_t resume_pa;
|
||
+ uint32_t teeram_bkp_pa;
|
||
+ uint32_t cryp1_base;
|
||
+ uint32_t rcc_base;
|
||
+ uint32_t stgen_base;
|
||
+ uint32_t stgen_cnt;
|
||
+ uint8_t ccm_ref_tag[PM_CTX_CCM_TAG_SIZE];
|
||
+ struct ccm_unpg_ctx ccm_ctx;
|
||
+ /* Last start the resume routine ARM (32bit) instructions sequence */
|
||
+ uint32_t resume_sequence[];
|
||
+};
|
||
+
|
||
+extern const uint8_t stm32mp_bkpsram_image_end[];
|
||
+void stm32mp_bkpsram_resume(void);
|
||
+void stm32mp_sysram_resume(void);
|
||
+
|
||
+void stm32mp_cpu_reset_state(void);
|
||
+
|
||
+TEE_Result stm32mp_pm_save_context(unsigned int soc_mode);
|
||
+void stm32mp_pm_restore_context(unsigned int soc_mode);
|
||
+void stm32mp_pm_shutdown_context(void);
|
||
+void stm32mp_pm_wipe_context(void);
|
||
+
|
||
+int stm32mp1_set_pm_domain_state(enum stm32mp1_pm_domain domain, bool status);
|
||
+
|
||
+uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode);
|
||
+int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode);
|
||
+
|
||
+uintptr_t stm32mp_pm_retram_resume_ep(void);
|
||
+
|
||
+int stm32mp_ccm_encrypt_teeram(struct retram_resume_ctx *ctx,
|
||
+ void *dst, void *src, size_t size);
|
||
+int stm32mp_ccm_decrypt_teeram(struct retram_resume_ctx *ctx,
|
||
+ void *dst, void *src, size_t size);
|
||
+#endif /*__ASSEMBLER__*/
|
||
+
|
||
+#endif /*__STM32MP_PM_CONTEXT_H__*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c b/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c
|
||
new file mode 100644
|
||
index 0000000..34c797f
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c
|
||
@@ -0,0 +1,28 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics
|
||
+ * Copyright (c) 2018, Linaro Limited
|
||
+ */
|
||
+
|
||
+#include <gen-asm-defines.h>
|
||
+
|
||
+#include "context.h"
|
||
+
|
||
+#define OFFSET_OF_CTX_STRUCT(_f) offsetof(struct retram_resume_ctx, _f)
|
||
+#define OFFSET_OF_CMM_CTX_STRUCT(_f) (OFFSET_OF_CTX_STRUCT(ccm_ctx) + \
|
||
+ offsetof(struct ccm_unpg_ctx, _f))
|
||
+DEFINES
|
||
+{
|
||
+ DEFINE(PM_CTX_RESUME_PA, OFFSET_OF_CTX_STRUCT(resume_pa));
|
||
+ DEFINE(PM_CTX_TEERAM_BKP_PA, OFFSET_OF_CTX_STRUCT(teeram_bkp_pa));
|
||
+ DEFINE(PM_CTX_CRYP1_BASE, OFFSET_OF_CTX_STRUCT(cryp1_base));
|
||
+ DEFINE(PM_CTX_RCC_BASE, OFFSET_OF_CTX_STRUCT(rcc_base));
|
||
+ DEFINE(PM_CTX_STGEN_BASE, OFFSET_OF_CTX_STRUCT(stgen_base));
|
||
+ DEFINE(PM_CTX_STGEN_CNT, OFFSET_OF_CTX_STRUCT(stgen_cnt));
|
||
+ DEFINE(PM_CTX_CCM_KEY, OFFSET_OF_CMM_CTX_STRUCT(key));
|
||
+ DEFINE(PM_CTX_CCM_CTR1, OFFSET_OF_CMM_CTX_STRUCT(ctr1));
|
||
+ DEFINE(PM_CTX_CCM_B0, OFFSET_OF_CMM_CTX_STRUCT(b0));
|
||
+ DEFINE(PM_CTX_CCM_CTR0, OFFSET_OF_CMM_CTX_STRUCT(ctr0));
|
||
+ DEFINE(PM_CTX_CCM_TAG, OFFSET_OF_CMM_CTX_STRUCT(tag));
|
||
+ DEFINE(PM_CTX_CCM_REF_TAG, OFFSET_OF_CTX_STRUCT(ccm_ref_tag));
|
||
+}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/low_power.c b/core/arch/arm/plat-stm32mp1/pm/low_power.c
|
||
new file mode 100644
|
||
index 0000000..0a9a166
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/low_power.c
|
||
@@ -0,0 +1,609 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
|
||
+ */
|
||
+
|
||
+#include <arm.h>
|
||
+#include <assert.h>
|
||
+#include <boot_api.h>
|
||
+#include <console.h>
|
||
+#include <drivers/gic.h>
|
||
+#include <drivers/stm32_etzpc.h>
|
||
+#include <drivers/stm32_iwdg.h>
|
||
+#include <drivers/stm32mp1_ddrc.h>
|
||
+#include <drivers/stm32mp1_pmic.h>
|
||
+#include <drivers/stm32mp1_pwr.h>
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <drivers/stpmic1.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+#include <dt-bindings/reset/stm32mp1-resets.h>
|
||
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
||
+#include <initcall.h>
|
||
+#include <io.h>
|
||
+#include <keep.h>
|
||
+#include <kernel/cache_helpers.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/misc.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <platform_config.h>
|
||
+#include <sm/psci.h>
|
||
+#include <stdbool.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <stm32_util.h>
|
||
+#include <trace.h>
|
||
+
|
||
+#include "context.h"
|
||
+#include "power.h"
|
||
+
|
||
+#define TIMEOUT_US_1MS 1000
|
||
+
|
||
+static uint8_t gicd_rcc_wakeup;
|
||
+static uint8_t gicc_pmr;
|
||
+
|
||
+struct pwr_lp_config {
|
||
+ uint32_t pwr_cr1;
|
||
+ uint32_t pwr_mpucr;
|
||
+ const char *regul_suspend_node_name;
|
||
+};
|
||
+
|
||
+#define PWR_CR1_MASK (PWR_CR1_LPDS | PWR_CR1_LPCFG | PWR_CR1_LVDS)
|
||
+#define PWR_MPUCR_MASK (PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | PWR_MPUCR_PDDS)
|
||
+
|
||
+static const struct pwr_lp_config config_pwr[STM32_PM_MAX_SOC_MODE] = {
|
||
+ [STM32_PM_CSLEEP_RUN] = {
|
||
+ .pwr_cr1 = 0U,
|
||
+ .pwr_mpucr = 0U,
|
||
+ .regul_suspend_node_name = NULL,
|
||
+ },
|
||
+ [STM32_PM_CSTOP_ALLOW_STOP] = {
|
||
+ .pwr_cr1 = 0U,
|
||
+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF,
|
||
+ .regul_suspend_node_name = NULL,
|
||
+ },
|
||
+ [STM32_PM_CSTOP_ALLOW_LP_STOP] = {
|
||
+ .pwr_cr1 = PWR_CR1_LPDS,
|
||
+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF,
|
||
+ .regul_suspend_node_name = "lp-stop",
|
||
+ },
|
||
+ [STM32_PM_CSTOP_ALLOW_LPLV_STOP] = {
|
||
+ .pwr_cr1 = PWR_CR1_LVDS | PWR_CR1_LPDS | PWR_CR1_LPCFG,
|
||
+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF,
|
||
+ .regul_suspend_node_name = "lplv-stop",
|
||
+ },
|
||
+ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR] = {
|
||
+ .pwr_cr1 = 0U,
|
||
+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF |
|
||
+ PWR_MPUCR_PDDS,
|
||
+ .regul_suspend_node_name = "standby-ddr-sr",
|
||
+ },
|
||
+ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF] = {
|
||
+ .pwr_cr1 = 0U,
|
||
+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF |
|
||
+ PWR_MPUCR_PDDS,
|
||
+ .regul_suspend_node_name = "standby-ddr-off",
|
||
+ },
|
||
+ [STM32_PM_SHUTDOWN] = {
|
||
+ .pwr_cr1 = 0U,
|
||
+ .pwr_mpucr = 0U,
|
||
+ .regul_suspend_node_name = "standby-ddr-off",
|
||
+ },
|
||
+};
|
||
+
|
||
+static void set_rcc_it_priority(uint8_t *it_prio, uint8_t *pmr)
|
||
+{
|
||
+ *it_prio = itr_set_ipriority(RCC_WAKEUP_IT, GIC_HIGHEST_SEC_PRIORITY);
|
||
+ *pmr = itr_set_pmr(STM32MP_GIC_PRIORITY_CSTOP);
|
||
+}
|
||
+
|
||
+static void restore_rcc_it_priority(uint8_t it_prio, uint8_t pmr)
|
||
+{
|
||
+ (void)itr_set_ipriority(RCC_WAKEUP_IT, it_prio);
|
||
+ (void)itr_set_pmr(pmr);
|
||
+}
|
||
+
|
||
+static void stm32_apply_pmic_suspend_config(uint32_t mode)
|
||
+{
|
||
+ const char *name = config_pwr[mode].regul_suspend_node_name;
|
||
+
|
||
+ assert(mode < ARRAY_SIZE(config_pwr));
|
||
+
|
||
+ if (stm32mp_with_pmic() && name) {
|
||
+ stm32mp_get_pmic();
|
||
+ stm32mp_pmic_apply_lp_config(name);
|
||
+ stm32mp_pmic_apply_boot_on_config();
|
||
+ stm32mp_put_pmic();
|
||
+ }
|
||
+}
|
||
+
|
||
+#define CONSOLE_FLUSH_DELAY_MS 10
|
||
+
|
||
+#if TRACE_LEVEL >= TRACE_DEBUG
|
||
+static void wait_console_flushed(void)
|
||
+{
|
||
+ console_flush();
|
||
+ mdelay(CONSOLE_FLUSH_DELAY_MS);
|
||
+}
|
||
+#else
|
||
+static void wait_console_flushed(void)
|
||
+{
|
||
+}
|
||
+#endif
|
||
+
|
||
+static void cpu_wfi(void)
|
||
+{
|
||
+ dsb();
|
||
+ isb();
|
||
+ wfi();
|
||
+}
|
||
+
|
||
+void stm32_pm_cpu_wfi(void)
|
||
+{
|
||
+ wait_console_flushed();
|
||
+ cpu_wfi();
|
||
+}
|
||
+
|
||
+/* If IWDG is not supported, provide a stubbed weak watchdog kicker */
|
||
+void __weak stm32_iwdg_refresh(uint32_t __unused instance)
|
||
+{
|
||
+}
|
||
+
|
||
+#define ARM_CNTXCTL_IMASK BIT(1)
|
||
+
|
||
+static void stm32mp_mask_timer(void)
|
||
+{
|
||
+ /* Mask timer interrupts */
|
||
+ write_cntp_ctl(read_cntp_ctl() | ARM_CNTXCTL_IMASK);
|
||
+ write_cntv_ctl(read_cntv_ctl() | ARM_CNTXCTL_IMASK);
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_enter_cstop - Prepare CSTOP mode
|
||
+ *
|
||
+ * @mode - Target low power mode
|
||
+ */
|
||
+void stm32_enter_cstop(uint32_t mode)
|
||
+{
|
||
+ uint32_t pwr_cr1 = config_pwr[mode].pwr_cr1;
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ stm32mp_syscfg_disable_io_compensation();
|
||
+
|
||
+ /* Save Self-Refresh (SR) mode and switch to Software SR mode */
|
||
+ ddr_save_sr_mode(DDR_SSR_MODE);
|
||
+
|
||
+ stm32_apply_pmic_suspend_config(mode);
|
||
+
|
||
+ if (stm32mp_with_pmic() && (mode == STM32_PM_CSTOP_ALLOW_LP_STOP))
|
||
+ pwr_cr1 |= PWR_CR1_LPCFG;
|
||
+
|
||
+ /* Workaround for non secure cache issue: this should not be needed */
|
||
+ dcache_op_all(DCACHE_OP_CLEAN_INV);
|
||
+
|
||
+ /* Clear RCC interrupt before enabling it */
|
||
+ io_setbits32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_WKUPF);
|
||
+
|
||
+ /* Enable RCC Wake-up */
|
||
+ io_setbits32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF);
|
||
+
|
||
+ /* Configure low power mode */
|
||
+ io_clrsetbits32(pwr_base + PWR_MPUCR_OFF, PWR_MPUCR_MASK,
|
||
+ config_pwr[mode].pwr_mpucr);
|
||
+ io_clrsetbits32(pwr_base + PWR_CR1_OFF, PWR_CR1_MASK, pwr_cr1);
|
||
+
|
||
+ /* Clear RCC pending interrupt flags */
|
||
+ io_write32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_MASK);
|
||
+
|
||
+ /* Request CSTOP mode to RCC */
|
||
+ io_setbits32(rcc_base + RCC_MP_SREQSETR,
|
||
+ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1);
|
||
+
|
||
+ stm32_iwdg_refresh(IWDG2_INST);
|
||
+
|
||
+ set_rcc_it_priority(&gicd_rcc_wakeup, &gicc_pmr);
|
||
+
|
||
+ if (ddr_standby_sr_entry() != 0)
|
||
+ panic();
|
||
+
|
||
+ if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) {
|
||
+ /* Keep retention and backup RAM content in standby */
|
||
+ io_setbits32(pwr_base + PWR_CR2_OFF, PWR_CR2_BREN |
|
||
+ PWR_CR2_RREN);
|
||
+
|
||
+ while ((io_read32(pwr_base + PWR_CR2_OFF) &
|
||
+ (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U)
|
||
+ ;
|
||
+ }
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_exit_cstop - Exit from CSTOP mode
|
||
+ */
|
||
+void stm32_exit_cstop(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ if (ddr_standby_sr_exit())
|
||
+ panic();
|
||
+
|
||
+ /* Restore Self-Refresh mode saved in stm32_enter_cstop() */
|
||
+ ddr_restore_sr_mode();
|
||
+
|
||
+ restore_rcc_it_priority(gicd_rcc_wakeup, gicc_pmr);
|
||
+
|
||
+ /* Disable STOP request */
|
||
+ io_setbits32(rcc_base + RCC_MP_SREQCLRR,
|
||
+ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1);
|
||
+
|
||
+ /* Disable RCC Wake-up */
|
||
+ io_clrbits32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF);
|
||
+
|
||
+ dsb();
|
||
+ isb();
|
||
+
|
||
+ /* Disable retention and backup RAM content after stop */
|
||
+ io_clrbits32(stm32_pwr_base() + PWR_CR2_OFF, PWR_CR2_BREN | PWR_CR2_RREN);
|
||
+
|
||
+ stm32mp_syscfg_enable_io_compensation();
|
||
+}
|
||
+
|
||
+/*
|
||
+ * GIC support required in low power sequences and reset sequences
|
||
+ */
|
||
+#define GICC_IAR 0x00C
|
||
+#define GICC_IT_ID_MASK 0x3ff
|
||
+#define GICC_EOIR 0x010
|
||
+#define GICC_HPPIR 0x018
|
||
+#define GICC_AHPPIR 0x028
|
||
+#define GIC_PENDING_G1_INTID 1022U
|
||
+#define GIC_SPURIOUS_INTERRUPT 1023U
|
||
+#define GIC_NUM_INTS_PER_REG 32
|
||
+#define GIC_MAX_SPI_ID 1020
|
||
+#define GICD_ICENABLER(n) (0x180 + (n) * 4)
|
||
+
|
||
+static void clear_pending_interrupts(void)
|
||
+{
|
||
+ uint32_t id = 0;
|
||
+ vaddr_t gicc_base = get_gicc_base();
|
||
+ vaddr_t gicd_base = get_gicd_base();
|
||
+
|
||
+ do {
|
||
+ id = io_read32(gicc_base + GICC_HPPIR) & GICC_IT_ID_MASK;
|
||
+
|
||
+ /*
|
||
+ * Find out which interrupt it is under the
|
||
+ * assumption that the GICC_CTLR.AckCtl bit is 0.
|
||
+ */
|
||
+ if (id == GIC_PENDING_G1_INTID)
|
||
+ id = io_read32(gicc_base + GICC_AHPPIR) & GICC_IT_ID_MASK;
|
||
+
|
||
+ if (id < GIC_MAX_SPI_ID) {
|
||
+ size_t idx = id / GIC_NUM_INTS_PER_REG;
|
||
+ uint32_t mask = 1 << (id % GIC_NUM_INTS_PER_REG);
|
||
+
|
||
+ io_write32(gicc_base + GICC_EOIR, id);
|
||
+
|
||
+ io_write32(gicd_base + GICD_ICENABLER(idx), mask);
|
||
+
|
||
+ dsb_ishst();
|
||
+ }
|
||
+ } while (id < GIC_MAX_SPI_ID);
|
||
+}
|
||
+
|
||
+void stm32mp_gic_set_end_of_interrupt(uint32_t it)
|
||
+{
|
||
+ vaddr_t gicc_base = get_gicc_base();
|
||
+
|
||
+ io_write32(gicc_base + GICC_EOIR, it);
|
||
+}
|
||
+
|
||
+static void __noreturn wait_cpu_reset(void)
|
||
+{
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ dcache_op_all(DCACHE_OP_CLEAN_INV);
|
||
+ write_sctlr(read_sctlr() & ~SCTLR_C);
|
||
+ dcache_op_all(DCACHE_OP_CLEAN_INV);
|
||
+ __asm__("clrex");
|
||
+
|
||
+ dsb();
|
||
+ isb();
|
||
+#else
|
||
+ psci_armv7_cpu_off();
|
||
+#endif
|
||
+
|
||
+ for ( ; ; ) {
|
||
+ clear_pending_interrupts();
|
||
+ wfi();
|
||
+ }
|
||
+}
|
||
+
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+/*
|
||
+ * tzc_source_ip contains the TZC transaction source IPs that need to be reset
|
||
+ * before a C-A7 subsystem is reset (i.e. independent reset):
|
||
+ * - C-A7 subsystem is reset separately later in the sequence,
|
||
+ * - C-M4 subsystem is not concerned here,
|
||
+ * - DAP is excluded for debug purpose,
|
||
+ * - IPs are stored with their ETZPC IDs (STM32MP1_ETZPC_MAX_ID if not
|
||
+ * applicable) because some of them need to be reset only if they are not
|
||
+ * configured in MCU isolation mode inside ETZPC device tree.
|
||
+ */
|
||
+struct tzc_source_ip {
|
||
+ uint16_t reset_id;
|
||
+ uint16_t clock_id;
|
||
+ uint32_t decprot_id;
|
||
+};
|
||
+
|
||
+#define _TZC_FIXED(res, clk) \
|
||
+ { \
|
||
+ .reset_id = (res), \
|
||
+ .clock_id = (clk), \
|
||
+ .decprot_id = STM32MP1_ETZPC_MAX_ID, \
|
||
+ }
|
||
+
|
||
+#define _TZC_COND(res, clk, decprot) \
|
||
+ { \
|
||
+ .reset_id = (res), \
|
||
+ .clock_id = (clk), \
|
||
+ .decprot_id = (decprot), \
|
||
+ }
|
||
+
|
||
+static const struct tzc_source_ip __maybe_unused tzc_source_ip[] = {
|
||
+ _TZC_FIXED(LTDC_R, LTDC_PX),
|
||
+ _TZC_FIXED(GPU_R, GPU),
|
||
+ _TZC_FIXED(USBH_R, USBH),
|
||
+ _TZC_FIXED(SDMMC1_R, SDMMC1_K),
|
||
+ _TZC_FIXED(SDMMC2_R, SDMMC2_K),
|
||
+ _TZC_FIXED(MDMA_R, MDMA),
|
||
+ _TZC_COND(USBO_R, USBO_K, STM32MP1_ETZPC_OTG_ID),
|
||
+ _TZC_COND(SDMMC3_R, SDMMC3_K, STM32MP1_ETZPC_SDMMC3_ID),
|
||
+ _TZC_COND(ETHMAC_R, ETHMAC, STM32MP1_ETZPC_ETH_ID),
|
||
+ _TZC_COND(DMA1_R, DMA1, STM32MP1_ETZPC_DMA1_ID),
|
||
+ _TZC_COND(DMA2_R, DMA2, STM32MP1_ETZPC_DMA2_ID),
|
||
+};
|
||
+
|
||
+static void reset_peripherals(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+ size_t __maybe_unused id = 0;
|
||
+
|
||
+ for (id = 0U; id < ARRAY_SIZE(tzc_source_ip); id++) {
|
||
+ const struct tzc_source_ip *tzc = &tzc_source_ip[id];
|
||
+
|
||
+ if (!stm32_clock_is_enabled(tzc->clock_id) ||
|
||
+ ((tzc->decprot_id != STM32MP1_ETZPC_MAX_ID) &&
|
||
+ (etzpc_get_decprot(tzc->decprot_id) ==
|
||
+ ETZPC_DECPROT_MCU_ISOLATION)))
|
||
+ continue;
|
||
+
|
||
+ if (tzc->reset_id != GPU_R) {
|
||
+ stm32_reset_assert(tzc->reset_id, TIMEOUT_US_1MS);
|
||
+ stm32_reset_deassert(tzc->reset_id, TIMEOUT_US_1MS);
|
||
+ } else {
|
||
+ /* GPU reset automatically cleared by hardware */
|
||
+ io_setbits32(rcc_base + RCC_AHB6RSTSETR,
|
||
+ RCC_AHB6RSTSETR_GPURST);
|
||
+ }
|
||
+ }
|
||
+}
|
||
+#endif /* STM32MP1_USE_MPU0_RESET */
|
||
+
|
||
+static void __noreturn reset_cores(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t reset_mask = RCC_MP_GRSTCSETR_MPUP0RST |
|
||
+ RCC_MP_GRSTCSETR_MPUP1RST;
|
||
+ uint32_t target_mask = 0;
|
||
+
|
||
+ /* Mask timer interrupts */
|
||
+ stm32mp_mask_timer();
|
||
+
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ reset_peripherals();
|
||
+#endif
|
||
+
|
||
+ if (get_core_pos() == 0)
|
||
+ target_mask = TARGET_CPU1_GIC_MASK;
|
||
+ else
|
||
+ target_mask = TARGET_CPU0_GIC_MASK;
|
||
+
|
||
+ itr_raise_sgi(GIC_SEC_SGI_1, target_mask);
|
||
+
|
||
+ clear_pending_interrupts();
|
||
+
|
||
+ io_write32(rcc_base + RCC_MP_GRSTCSETR, reset_mask);
|
||
+
|
||
+ wait_cpu_reset();
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_pm_cpus_reset - Reset only cpus
|
||
+ */
|
||
+void __noreturn stm32_cores_reset(void)
|
||
+{
|
||
+ reset_cores();
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_cores_reset);
|
||
+
|
||
+static __maybe_unused void reset_other_core(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t reset_mask = 0;
|
||
+ uint32_t target_mask = 0;
|
||
+
|
||
+ if (get_core_pos() == 0) {
|
||
+ reset_mask = RCC_MP_GRSTCSETR_MPUP1RST;
|
||
+ target_mask = TARGET_CPU1_GIC_MASK;
|
||
+ } else {
|
||
+ reset_mask = RCC_MP_GRSTCSETR_MPUP0RST;
|
||
+ target_mask = TARGET_CPU0_GIC_MASK;
|
||
+ }
|
||
+
|
||
+ itr_raise_sgi(GIC_SEC_SGI_1, target_mask);
|
||
+
|
||
+ io_write32(rcc_base + RCC_MP_GRSTCSETR, reset_mask);
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_enter_cstop_shutdown - Shutdown CPUs to target low power mode
|
||
+ * @mode - Target low power mode
|
||
+ */
|
||
+void __noreturn stm32_enter_cstop_shutdown(uint32_t mode)
|
||
+{
|
||
+ switch (mode) {
|
||
+ case STM32_PM_SHUTDOWN:
|
||
+ if (stm32mp_with_pmic()) {
|
||
+ wait_console_flushed();
|
||
+ stm32mp_get_pmic();
|
||
+ stpmic1_switch_off();
|
||
+ udelay(100);
|
||
+ }
|
||
+ break;
|
||
+ case STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR:
|
||
+ case STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF:
|
||
+#ifdef STM32MP1_USE_MPU0_RESET
|
||
+ stm32mp_pm_shutdown_context();
|
||
+ reset_other_core();
|
||
+ stm32_enter_cstop(mode);
|
||
+ dsb();
|
||
+ isb();
|
||
+ for ( ; ; )
|
||
+ wfi();
|
||
+#else
|
||
+ if (stm32mp_with_pmic()) {
|
||
+ wait_console_flushed();
|
||
+ stm32mp_get_pmic();
|
||
+ stpmic1_switch_off();
|
||
+ udelay(100);
|
||
+ }
|
||
+#endif
|
||
+ break;
|
||
+ default:
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ panic();
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_enter_cstop_reset - Reset CPUs to target low power mode
|
||
+ * @mode - Target low power mode
|
||
+ */
|
||
+void __noreturn stm32_enter_cstop_reset(uint32_t mode)
|
||
+{
|
||
+ vaddr_t rcc = stm32_rcc_base();
|
||
+
|
||
+ switch (mode) {
|
||
+ case STM32_PM_SHUTDOWN:
|
||
+ io_write32(rcc + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST);
|
||
+ udelay(100);
|
||
+ break;
|
||
+ default:
|
||
+ IMSG("Forced system reset");
|
||
+ wait_console_flushed();
|
||
+ io_write32(rcc + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST);
|
||
+ udelay(100);
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ panic();
|
||
+}
|
||
+
|
||
+/*
|
||
+ * stm32_enter_csleep - enter CSLEEP state while WFI and exit in CRUN
|
||
+ *
|
||
+ * Configure PWR for CSLEEP state. CPU shall execute a WFI and return
|
||
+ * once a interrupt is pending.
|
||
+ */
|
||
+void stm32_enter_csleep(void)
|
||
+{
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+
|
||
+ io_clrsetbits32(pwr_base + PWR_MPUCR_OFF, PWR_MPUCR_MASK,
|
||
+ config_pwr[STM32_PM_CSLEEP_RUN].pwr_mpucr);
|
||
+ io_clrsetbits32(pwr_base + PWR_CR1_OFF, PWR_CR1_MASK,
|
||
+ config_pwr[STM32_PM_CSLEEP_RUN].pwr_cr1);
|
||
+
|
||
+ stm32_pm_cpu_wfi();
|
||
+}
|
||
+
|
||
+/* RCC Wakeup interrupt is used to wake from suspeneded mode */
|
||
+static enum itr_return rcc_wakeup_it_handler(struct itr_handler *hdl __unused)
|
||
+{
|
||
+ /* This interrupt is not expected to be handled */
|
||
+ panic("RCC wakeup interrupt");
|
||
+ return ITRR_HANDLED;
|
||
+}
|
||
+
|
||
+static struct itr_handler rcc_wakeup_handler = {
|
||
+ .it = RCC_WAKEUP_IT,
|
||
+ .handler = rcc_wakeup_it_handler,
|
||
+};
|
||
+DECLARE_KEEP_PAGER(rcc_wakeup_handler);
|
||
+
|
||
+/* SGI9 (secure SGI 1) informs targeted CPU it shall reset */
|
||
+static enum itr_return sgi9_it_handler(struct itr_handler *handler)
|
||
+{
|
||
+ stm32mp_mask_timer();
|
||
+
|
||
+ stm32mp_gic_set_end_of_interrupt(handler->it);
|
||
+
|
||
+ clear_pending_interrupts();
|
||
+
|
||
+ wait_cpu_reset();
|
||
+
|
||
+ panic("Core reset");
|
||
+
|
||
+ return ITRR_HANDLED;
|
||
+}
|
||
+
|
||
+static struct itr_handler sgi9_reset_handler = {
|
||
+ .it = GIC_SEC_SGI_1,
|
||
+ .handler = sgi9_it_handler,
|
||
+};
|
||
+DECLARE_KEEP_PAGER(sgi9_reset_handler);
|
||
+
|
||
+static TEE_Result init_low_power(void)
|
||
+{
|
||
+ vaddr_t pwr_base = stm32_pwr_base();
|
||
+
|
||
+ itr_add(&rcc_wakeup_handler);
|
||
+ itr_enable(rcc_wakeup_handler.it);
|
||
+
|
||
+ itr_add(&sgi9_reset_handler);
|
||
+ itr_enable(sgi9_reset_handler.it);
|
||
+
|
||
+ /* Enable retention for BKPSRAM and BKPREG */
|
||
+ io_mask32(pwr_base + PWR_CR2_OFF,
|
||
+ PWR_CR2_BREN | PWR_CR2_RREN, PWR_CR2_BREN | PWR_CR2_RREN);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+service_init(init_low_power);
|
||
+
|
||
+/*
|
||
+ * CPU low power sequences
|
||
+ */
|
||
+void __noreturn stm32_pm_cpu_power_down_wfi(void)
|
||
+{
|
||
+ vaddr_t rcc_base = stm32_rcc_base();
|
||
+
|
||
+ if (get_core_pos() == 0) {
|
||
+ void (*reset_ep)(void) = stm32mp_sysram_resume;
|
||
+
|
||
+ stm32_pm_cpu_wfi();
|
||
+
|
||
+ /* STANDBY not reached: resume from retained SYSRAM */
|
||
+ stm32_exit_cstop();
|
||
+ stm32mp_cpu_reset_state();
|
||
+ reset_ep();
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ dcache_op_level1(DCACHE_OP_CLEAN);
|
||
+ io_write32(rcc_base + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPUP1RST);
|
||
+ cpu_wfi();
|
||
+ panic();
|
||
+}
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S b/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S
|
||
new file mode 100644
|
||
index 0000000..cd8e48c
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S
|
||
@@ -0,0 +1,740 @@
|
||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics
|
||
+ * Copyright (c) 2017 NXP
|
||
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#include <arm.h>
|
||
+#include <arm32_macros.S>
|
||
+#include <asm.S>
|
||
+#include <boot_api.h>
|
||
+#include <drivers/stm32mp1_rcc.h>
|
||
+#include <generated/context_asm_defines.h>
|
||
+#include <kernel/cache_helpers.h>
|
||
+#include <kernel/tz_proc_def.h>
|
||
+#include <kernel/tz_ssvce_def.h>
|
||
+#include <kernel/unwind.h>
|
||
+#include <platform_config.h>
|
||
+#include <mm/core_mmu.h>
|
||
+#include <util.h>
|
||
+
|
||
+#include "context.h"
|
||
+
|
||
+/*
|
||
+ * Right bit shift distance to reach timeout from a 1s STGEN freq count
|
||
+ * Value N relates to 1000ms / 2^N, i.e 7 relates to 7.8125ms=~8ms
|
||
+ */
|
||
+#define CCM_TIMEOUT_128MS 2
|
||
+#define CCM_TIMEOUT_8MS 7
|
||
+#define CCM_TIMEOUT_1MS 10
|
||
+#define CCM_TIMEOUT_16US 16
|
||
+#define CCM_TIMEOUT CCM_TIMEOUT_8MS
|
||
+
|
||
+/*
|
||
+ * CRYP interface register used for AES CCM
|
||
+ */
|
||
+#define CRYP_CR 0x000
|
||
+#define CRYP_SR 0x004
|
||
+#define CRYP_DIN 0x008
|
||
+#define CRYP_DOUT 0x00c
|
||
+#define CRYP_KEYR_BASE 0x020
|
||
+#define CRYP_IVR_BASE 0x040
|
||
+
|
||
+#define CRYP_CR_ALGODIR_DECRYPT BIT(2)
|
||
+#define CRYP_CR_ALGOMODE_MASK (BIT(19) | GENMASK_32(5, 3))
|
||
+#define CRYP_CR_ALGOMODE(m) (((m & BIT(3)) << 16) | (m & 0x7) << 3)
|
||
+#define ALGOMODE_AES_CCM 0x9
|
||
+#define CRYP_CR_DATATYPE_SHIFT 6
|
||
+#define CRYP_CR_DATATYPE_8BIT (2 << CRYP_CR_DATATYPE_SHIFT)
|
||
+#define CRYP_CR_KEYSIZE_SHIFT 8
|
||
+#define CRYP_CR_KEYSIZE_256BIT (2U << CRYP_CR_KEYSIZE_SHIFT)
|
||
+#define CRYP_CR_CRYPEN BIT(15)
|
||
+#define CRYP_CR_FFLUSH BIT(14)
|
||
+#define CRYP_CR_GCM_CCMPH_SHIFT 16
|
||
+#define CRYP_CR_PHASE_MASK (0x3 << CRYP_CR_GCM_CCMPH_SHIFT)
|
||
+#define CRYP_CR_INIT_PHASE (0 << CRYP_CR_GCM_CCMPH_SHIFT)
|
||
+#define CRYP_CR_HEADER_PHASE (1 << CRYP_CR_GCM_CCMPH_SHIFT)
|
||
+#define CRYP_CR_PAYLOAD_PHASE (2 << CRYP_CR_GCM_CCMPH_SHIFT)
|
||
+#define CRYP_CR_FINAL_PHASE (3 << CRYP_CR_GCM_CCMPH_SHIFT)
|
||
+
|
||
+#define CRYP_SR_BUSY BIT(4)
|
||
+#define CRYP_SR_OFFU BIT(3)
|
||
+#define CRYP_SR_OFNE BIT(2)
|
||
+#define CRYP_SR_IFNF BIT(1)
|
||
+#define CRYP_SR_IFEM BIT(0)
|
||
+
|
||
+/*
|
||
+ * Enable TRACE_SYSRAM_RESTORE to get some UART console traces
|
||
+ * at resume time.
|
||
+ */
|
||
+#if defined(TRACE_SYSRAM_RESTORE)
|
||
+
|
||
+#define UART_BASE UART4_BASE
|
||
+#define UART_ISR_OFF 0x1c
|
||
+#define UART_TDR_OFF 0x28
|
||
+#define USART_ISR_TXE_TXFNF (1<< 7)
|
||
+
|
||
+ .macro PRINT_CHAR _reg0, _reg1, _char
|
||
+ /* Trace only at resume when MMU is OFF */
|
||
+ read_sctlr \_reg0
|
||
+ ands \_reg0, #SCTLR_M
|
||
+ 101:
|
||
+ bne 102f
|
||
+ mov_imm \_reg0, UART4_BASE
|
||
+ ldr \_reg1, [\_reg0, #UART_ISR_OFF]
|
||
+ ands \_reg1, #USART_ISR_TXE_TXFNF
|
||
+ beq 101b
|
||
+ mov_imm \_reg1, (\_char)
|
||
+ str \_reg1, [\_reg0, #UART_TDR_OFF]
|
||
+ 102:
|
||
+ .endm
|
||
+#else
|
||
+ .macro PRINT_CHAR _reg0, _reg1, _char
|
||
+ .endm
|
||
+#endif
|
||
+
|
||
+ /* Bound of the binary image loaded in retained memory */
|
||
+ .global stm32mp_bkpsram_image_end
|
||
+
|
||
+/*
|
||
+ * stm32mp_bkpsram_resume - Restore TEE RAM from backup memory and resume into
|
||
+ *
|
||
+ * This function executes at early resume from suspend state. It is the
|
||
+ * entrypoint of the OP-TEE provided to early boot stage when SoC wakes.
|
||
+ * This code is located in a retained memory, MMU disabled. This function
|
||
+ * shall restore TEE RAM content for OP-TEE to resume execution. Once
|
||
+ * TEE RAM is restored, this function branches to the resident resume entry
|
||
+ * point in TEE_RAM. This function and its resources shall execute in place.
|
||
+ */
|
||
+FUNC stm32mp_bkpsram_resume , :
|
||
+UNWIND( .fnstart)
|
||
+UNWIND( .cantunwind)
|
||
+
|
||
+ PRINT_CHAR r0, r1, '0'
|
||
+
|
||
+ /*
|
||
+ * Almost all sequences here expect PM context structure base address
|
||
+ * from CPU register r11.
|
||
+ */
|
||
+ mov_imm r11, (BKPSRAM_BASE + BKPSRAM_PM_CONTEXT_OFFSET)
|
||
+
|
||
+ /* stm32mp_ccm_teeram needs some HW interface base addresss */
|
||
+ mov_imm r0, CRYP1_BASE
|
||
+ str r0, [r11, #PM_CTX_CRYP1_BASE]
|
||
+ mov_imm r0, RCC_BASE
|
||
+ str r0, [r11, #PM_CTX_RCC_BASE]
|
||
+ mov_imm r0, STGEN_BASE
|
||
+ str r0, [r11, #PM_CTX_STGEN_BASE]
|
||
+
|
||
+ bl _clear_early_mailbox
|
||
+ bl _prepare_time
|
||
+
|
||
+ mov_imm r0, TEE_RAM_START
|
||
+ ldr r1, [r11, #PM_CTX_TEERAM_BKP_PA]
|
||
+ mov_imm r2, TEE_RAM_PH_SIZE
|
||
+ mov_imm r3, 1
|
||
+ bl stm32mp_ccm_teeram
|
||
+ cmp r0, #0
|
||
+ bne _failed
|
||
+
|
||
+ PRINT_CHAR r0, r1, 'T'
|
||
+ PRINT_CHAR r0, r1, 'a'
|
||
+ PRINT_CHAR r0, r1, 'g'
|
||
+ PRINT_CHAR r0, r1, '\n'
|
||
+
|
||
+ /* Compare the generated and reference tags */
|
||
+ add r8, r11, #PM_CTX_CCM_TAG
|
||
+ add r9, r11, #PM_CTX_CCM_REF_TAG
|
||
+ ldm r8, {r2-r5}
|
||
+ ldm r9, {r6-r9}
|
||
+ mov r0, #0
|
||
+ cmp r2, r6
|
||
+ addeq r0, #1
|
||
+ cmp r3, r7
|
||
+ addeq r0, #1
|
||
+ cmp r4, r8
|
||
+ addeq r0, #1
|
||
+ cmp r5, r9
|
||
+ addeq r0, #1
|
||
+ cmp r0, #4
|
||
+ bne _failed
|
||
+ bl _save_resume_time
|
||
+
|
||
+ PRINT_CHAR r1, r2, 'O'
|
||
+ PRINT_CHAR r1, r2, 'k'
|
||
+ PRINT_CHAR r1, r2, '\n'
|
||
+
|
||
+ /* Resume into the restored TEE RAM */
|
||
+ ldr r1, [r11, #PM_CTX_RESUME_PA]
|
||
+ bx r1
|
||
+
|
||
+_failed:
|
||
+ PRINT_CHAR r0, r12, 'F'
|
||
+ PRINT_CHAR r0, r12, '\n'
|
||
+
|
||
+ /* Clear context including key and reference tag */
|
||
+ mov r0, #0xa5
|
||
+ mov_imm r12, BKPSRAM_PM_CONTEXT_SIZE
|
||
+ add r12, r11, r12
|
||
+1: str r0, [r11], #4
|
||
+ cmp r11, r12
|
||
+ blt 1b
|
||
+ b .
|
||
+
|
||
+ /*
|
||
+ * _clear_early_mailbox - Wipe mailbox in case of reset
|
||
+ *
|
||
+ * Sratches r0-r4.
|
||
+ * All other CPU registers are preserved.
|
||
+ */
|
||
+_clear_early_mailbox:
|
||
+ /* Clear the backup registers (first enable RTCAPB clock) */
|
||
+ mov_imm r0, (RCC_BASE + RCC_MP_APB5ENSETR)
|
||
+ mov_imm r2, RCC_MP_APB5ENSETR_RTCAPBEN
|
||
+ ldr r1, [r0]
|
||
+ ands r1, r1, r2
|
||
+ moveq r1, r2
|
||
+ movne r1, #0
|
||
+ str r2, [r0]
|
||
+ mov_imm r2, (TAMP_BASE + TAMP_BKP_REGISTER_OFF)
|
||
+ mov_imm r3, (BCKR_CORE1_MAGIC_NUMBER * 4)
|
||
+ mov_imm r4, BOOT_API_A7_RESET_MAGIC_NUMBER
|
||
+ str r4, [r2, r3]
|
||
+ mov_imm r3, (BCKR_CORE1_BRANCH_ADDRESS * 4)
|
||
+ mov r4, #0
|
||
+ str r4, [r2, r3]
|
||
+ /* Restore RTCAPB clock initial state */
|
||
+ str r1, [r0, #RCC_MP_ENCLRR_OFFSET]
|
||
+ bx lr
|
||
+
|
||
+ /*
|
||
+ * prepare_time - save/reset cycle counter to prevent later overflow
|
||
+ *
|
||
+ * Save current 32bit lower counter and reset to 0 so that later
|
||
+ * timeout test do not need to care about overflow.
|
||
+ *
|
||
+ * Expects r11 is context base and lr is return address.
|
||
+ * Scrathes r0-r2.
|
||
+ * All other CPU registers are preserved.
|
||
+ */
|
||
+_prepare_time:
|
||
+ ldr r2, [r11, #PM_CTX_STGEN_BASE]
|
||
+ /* Disable STGEN counter */
|
||
+ ldr r1, [r2, #CNTCR_OFFSET]
|
||
+ bic r1, r1, #CNTCR_EN
|
||
+ str r1, [r2, #CNTCR_OFFSET]
|
||
+1: ldr r1, [r2, #CNTSR_OFFSET]
|
||
+ tst r1, #CNTCR_EN
|
||
+ bne 1b
|
||
+ /* Save and reset STGEN counter */
|
||
+ ldr r0, [r2, #CNTCVL_OFFSET]
|
||
+ str r0, [r11, #PM_CTX_STGEN_CNT]
|
||
+ mov r0, #0
|
||
+ str r0, [r2, #CNTCVL_OFFSET]
|
||
+ ldr r0, [r2, #CNTCVU_OFFSET]
|
||
+ str r0, [r2, #CNTCVU_OFFSET]
|
||
+ /* Enable STGEN counter */
|
||
+ ldr r1, [r2, #CNTCR_OFFSET]
|
||
+ orr r1, r1, #CNTCR_EN
|
||
+ str r1, [r2, #CNTCR_OFFSET]
|
||
+ bx lr
|
||
+
|
||
+ /*
|
||
+ * save_resume_time - save time spent and restore STGEN cycle counter
|
||
+ *
|
||
+ * Restore STGEN counter to initial value incremented by the current
|
||
+ * count. Note 32bit upper may need to be incremented.
|
||
+ *
|
||
+ * Expects r11 is context base and lr is return address.
|
||
+ * Scrathes r0-r3.
|
||
+ * All other CPU registers are preserved.
|
||
+ */
|
||
+_save_resume_time:
|
||
+ /* Compute update STGEN counter 32bit LSB value */
|
||
+ ldr r2, [r11, #PM_CTX_STGEN_BASE]
|
||
+ ldr r0, [r11, #PM_CTX_STGEN_CNT]
|
||
+ ldr r3, [r2, #CNTCVL_OFFSET]
|
||
+ str r3, [r11, #PM_CTX_STGEN_CNT]
|
||
+ adds r0, r0, r3
|
||
+ /* Disable STGEN */
|
||
+ ldr r1, [r2, #CNTCR_OFFSET]
|
||
+ bic r1, r1, #CNTCR_EN
|
||
+ str r1, [r2, #CNTCR_OFFSET]
|
||
+1: ldr r1, [r2, #CNTSR_OFFSET]
|
||
+ tst r1, #CNTCR_EN
|
||
+ bne 1b
|
||
+ /* Update counter (increment 32bit MSB if requried) */
|
||
+ str r0, [r2, #CNTCVL_OFFSET]
|
||
+ ldr r0, [r2, #CNTCVU_OFFSET]
|
||
+ addcs r0, r0, #1
|
||
+ str r0, [r2, #CNTCVU_OFFSET] /* Write CNTCVU value ... */
|
||
+ ldr r0, [r2, #CNTCVU_OFFSET] /* ... and wait it is set */
|
||
+ /* Enable STGEN */
|
||
+ ldr r0, [r2, #CNTCR_OFFSET]
|
||
+ orr r0, r0, #CNTCR_EN
|
||
+ str r0, [r2, #CNTCR_OFFSET]
|
||
+ bx lr
|
||
+
|
||
+ /*
|
||
+ * _setup_cryp1 - Enable CRYP1 hardware: reset & clock
|
||
+ * _reset_cryp1 - Reset CRYP1 hardware
|
||
+ *
|
||
+ * Function call before and after CCM sequence. Note that the CRYP1
|
||
+ * clock remain enabled. It is disabled later by the resume sequence.
|
||
+ *
|
||
+ * Expects r11 is context base and lr is return address.
|
||
+ * Scratches r0-r3.
|
||
+ */
|
||
+_setup_cryp1:
|
||
+ ldr r1, [r11, #PM_CTX_RCC_BASE]
|
||
+ mov_imm r0, RCC_MP_AHB5ENSETR_CRYP1EN
|
||
+ str r0, [r1, #RCC_MP_AHB5ENSETR]
|
||
+ /* Intentionnally fall through reset_cryp1 */
|
||
+_reset_cryp1:
|
||
+ ldr r3, [r11, #PM_CTX_RCC_BASE]
|
||
+ mov_imm r0, RCC_AHB5RSTSETR_CRYP1RST
|
||
+ str r0, [r3, #RCC_AHB5RSTSETR]
|
||
+1: ldr r1, [r3, #RCC_AHB5RSTSETR]
|
||
+ ands r1, r1, r0
|
||
+ beq 1b
|
||
+ mov_imm r0, RCC_AHB5RSTSETR_CRYP1RST
|
||
+ str r0, [r3, #RCC_AHB5RSTCLRR]
|
||
+1: ldr r1, [r3, #RCC_AHB5RSTSETR]
|
||
+ ands r1, r1, r0
|
||
+ bne 1b
|
||
+ bx lr
|
||
+
|
||
+ /*
|
||
+ * _ccm_arm_8ms_timeout - Init 8ms threshold for _ccm_failed_on_timeout
|
||
+ * _ccm_fail_on_timeout - Check STGEN counter against timeout threshold
|
||
+ *
|
||
+ * These function are used by the macro wait_flag_timeout_8ms. The
|
||
+ * former loads the timeout in CPU register r0 while the later get the
|
||
+ * timeout counter threshold from CPU register r0.
|
||
+ *
|
||
+ * Expect r11 is context base and lr is return address.
|
||
+ * Scratch r0-r1.
|
||
+ * All other CPU registers are preserved.
|
||
+ */
|
||
+_ccm_arm_8ms_timeout:
|
||
+ ldr r1, [r11, #PM_CTX_STGEN_BASE]
|
||
+ ldr r0, [r1, #CNTFID_OFFSET]
|
||
+ lsrs r0, r0, #CCM_TIMEOUT
|
||
+ moveq r0, #1
|
||
+ ldr r1, [r1, #CNTCVL_OFFSET]
|
||
+ adds r0, r0, r1
|
||
+ bcs _ccm_failed_on_timeout
|
||
+ bx lr
|
||
+
|
||
+_ccm_fail_on_timeout:
|
||
+
|
||
+ ldr r1, [r11, #PM_CTX_STGEN_BASE]
|
||
+ ldr r1, [r1, #CNTCVL_OFFSET]
|
||
+ cmp r1, r0
|
||
+ bge _ccm_failed_on_timeout
|
||
+ bx lr
|
||
+
|
||
+_ccm_failed_on_timeout:
|
||
+ PRINT_CHAR r0, r1, 'T'
|
||
+ PRINT_CHAR r0, r1, 'o'
|
||
+ PRINT_CHAR r0, r1, '\n'
|
||
+ b _ccm_failed
|
||
+
|
||
+ /*
|
||
+ * Macro WAIT_FLAG_TIMEOUT compares timeout threshold (r0) with
|
||
+ * current time and branches the CCM failure entry on timeout.
|
||
+ * It is assumed the 32bit timestamps cannot overflow.
|
||
+ */
|
||
+ .macro WAIT_FLAG_TIMEOUT register_offset, bit_mask, awaited_mask
|
||
+ bl _ccm_arm_8ms_timeout
|
||
+ 1:
|
||
+ bl _ccm_fail_on_timeout
|
||
+ ldr r1, [r10, #(\register_offset)]
|
||
+ and r1, r1, #(\bit_mask)
|
||
+ cmp r1, #(\awaited_mask)
|
||
+ bne 1b
|
||
+ .endm
|
||
+
|
||
+/*
|
||
+ * stm32mp_ccm_teeram - Size optimzed unpaged CCM encryption/decryption
|
||
+ *
|
||
+ * This sequence encrypts or decrypts a input block using AES CCM with a
|
||
+ * 256bit key and no AAD and generates the CCM tag. The key, CTR0, CTR1
|
||
+ * and B0 block are read from PM context structure. The generated tag is
|
||
+ * stored in the PM context structure.
|
||
+ *
|
||
+ * This function is executed from TEE RAM during suspend sequence to generate
|
||
+ * the encrypted data and the tag. This function is also executed from BKPSRAM
|
||
+ * called with MMU disabled. Therefore this sequence shall be comply with
|
||
+ * position independent code constraints.
|
||
+ *
|
||
+ * Expects at entry:
|
||
+ * lr = caller return address
|
||
+ * r11 = retram_resume_ctx structure base address
|
||
+ * r0 = Destination buffer for the output data (ciphertext or plaintext)
|
||
+ * r1 = Source buffer for the input data (plaintext or ciphertext)
|
||
+ * r2 = Input (and output) data size in bytes
|
||
+ * r3 = 1 if decrypting, 0 if encrypting
|
||
+ */
|
||
+stm32mp_ccm_teeram:
|
||
+ /*
|
||
+ * Use of the CPU registers in the whole stm32mp_ccm_teeram sequence
|
||
+ *
|
||
+ * sp: preserved, not used
|
||
+ * lr: scratch register used to call subroutines.
|
||
+ * r12: saves the caller link register for final return
|
||
+ * r11: context from BKPSRAM
|
||
+ * r10: CRYP1 base address
|
||
+ * r9: destination buffer
|
||
+ * r8: source buffer to cipher
|
||
+ * r7: data byte counter
|
||
+ * r0-r6 are scratch registers
|
||
+ */
|
||
+ mov r12, lr
|
||
+ ldr r10, [r11, #PM_CTX_CRYP1_BASE]
|
||
+ mov r9, r0
|
||
+ mov r8, r1
|
||
+ mov r7, r2
|
||
+ mov r6, r3
|
||
+
|
||
+ PRINT_CHAR r0, r1, '1'
|
||
+
|
||
+ bl _setup_cryp1
|
||
+
|
||
+ PRINT_CHAR r0, r1, '2'
|
||
+
|
||
+ mov_imm r0, (CRYP_CR_ALGOMODE(ALGOMODE_AES_CCM) | \
|
||
+ CRYP_CR_DATATYPE_8BIT | CRYP_CR_FFLUSH | \
|
||
+ CRYP_CR_KEYSIZE_256BIT)
|
||
+ cmp r6, #0
|
||
+ orrne r0, r0, #CRYP_CR_ALGODIR_DECRYPT
|
||
+ str r0, [r10, #CRYP_CR]
|
||
+
|
||
+ PRINT_CHAR r0, r1, '3'
|
||
+
|
||
+ /* Check data alignment (addresses and size) */
|
||
+ ands r0, r7, #0x0F
|
||
+ bne _ccm_failed
|
||
+ ands r0, r8, #0x03
|
||
+ bne _ccm_failed
|
||
+ ands r0, r9, #0x03
|
||
+ bne _ccm_failed
|
||
+
|
||
+ PRINT_CHAR r0, r1, '4'
|
||
+
|
||
+ ldr r0, [r11, #PM_CTX_CCM_KEY]
|
||
+ str r0, [r10, #CRYP_KEYR_BASE]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 4)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 4)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 8)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 8)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 12)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 12)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 16)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 16)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 20)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 20)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 24)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 24)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_KEY + 28)]
|
||
+ str r0, [r10, #(CRYP_KEYR_BASE + 28)]
|
||
+
|
||
+ ldr r0, [r11, #PM_CTX_CCM_CTR1]
|
||
+ str r0, [r10, #CRYP_IVR_BASE]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR1 + 4)]
|
||
+ str r0, [r10, #(CRYP_IVR_BASE + 4)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR1 + 8)]
|
||
+ str r0, [r10, #(CRYP_IVR_BASE + 8)]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR1 + 12)]
|
||
+ str r0, [r10, #(CRYP_IVR_BASE + 12)]
|
||
+
|
||
+ /* Setup CRYP for the CCM Init Phase */
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+ orr r0, r0, #(CRYP_CR_CRYPEN | CRYP_CR_INIT_PHASE)
|
||
+ str r0, [r10, #CRYP_CR]
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+
|
||
+ ldr r0, [r11, #PM_CTX_CCM_B0]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_B0 + 4)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_B0 + 8)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_B0 + 12)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+
|
||
+ PRINT_CHAR r0, r1, '5'
|
||
+
|
||
+ WAIT_FLAG_TIMEOUT CRYP_CR, CRYP_CR_CRYPEN, 0
|
||
+
|
||
+ /* Setup CRYP for the CCM Payload phase */
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+ bic r0, r0, #CRYP_CR_PHASE_MASK
|
||
+ orr r0, r0, #CRYP_CR_PAYLOAD_PHASE
|
||
+ orr r0, r0, #CRYP_CR_CRYPEN
|
||
+ str r0, [r10, #CRYP_CR]
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+
|
||
+ PRINT_CHAR r0, r1, '\n'
|
||
+
|
||
+_next_block:
|
||
+ PRINT_CHAR r0, r1, 'b'
|
||
+
|
||
+ WAIT_FLAG_TIMEOUT CRYP_SR, CRYP_SR_IFEM, CRYP_SR_IFEM
|
||
+
|
||
+ /* Feed input data, r8 stores the current source buffer */
|
||
+ ldr r0, [r8], #4
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r8], #4
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r8], #4
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r8], #4
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+
|
||
+ WAIT_FLAG_TIMEOUT CRYP_SR, CRYP_SR_OFNE, CRYP_SR_OFNE
|
||
+
|
||
+ /* Store output data, r9 stores the current source buffer */
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r9], #4
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r9], #4
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r9], #4
|
||
+ /* Before last 32bit word, the output FIFO shall not be empty */
|
||
+ ldr r0, [r10, #CRYP_SR]
|
||
+ ands r0, r0, #CRYP_SR_OFNE
|
||
+ beq _ccm_failed
|
||
+ /* After last 32bit word for this 128block, FIFO shall be empty */
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r9], #4
|
||
+ ldr r0, [r10, #CRYP_SR]
|
||
+ ands r0, r0, #CRYP_SR_OFNE
|
||
+ bne _ccm_failed
|
||
+
|
||
+ /* Another round if remaining data */
|
||
+ subs r7, r7, #16
|
||
+ bne _next_block;
|
||
+
|
||
+ PRINT_CHAR r0, r1, '\n'
|
||
+ PRINT_CHAR r0, r1, '6'
|
||
+
|
||
+ WAIT_FLAG_TIMEOUT CRYP_SR, CRYP_SR_BUSY, 0
|
||
+
|
||
+ /*
|
||
+ * Data processing completed, now remains the tag generation.
|
||
+ * Here expect SR[IFNF]=SR[OFNE]=1 and all others bits are 0.
|
||
+ */
|
||
+ ldr r0, [r10, #CRYP_SR]
|
||
+ cmp r0, #(CRYP_SR_IFEM | CRYP_SR_IFNF)
|
||
+ bne _ccm_failed
|
||
+
|
||
+ PRINT_CHAR r0, r1, '7'
|
||
+
|
||
+ /* Setup CRYP1 for the CCM Final Phase */
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+ bic r0, r0, #CRYP_CR_CRYPEN
|
||
+ str r0, [r10, #CRYP_CR]
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+ bic r0, r0, #CRYP_CR_PHASE_MASK
|
||
+ bic r0, r0, #CRYP_CR_ALGODIR_DECRYPT
|
||
+ orr r0, r0, #CRYP_CR_FINAL_PHASE
|
||
+ orr r0, r0, #CRYP_CR_CRYPEN
|
||
+ str r0, [r10, #CRYP_CR]
|
||
+ ldr r0, [r10, #CRYP_CR]
|
||
+
|
||
+ /* Load CTR0 to generate the tag */
|
||
+ ldr r0, [r11, #PM_CTX_CCM_CTR0]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR0 + 4)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR0 + 8)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+ ldr r0, [r11, #(PM_CTX_CCM_CTR0 + 12)]
|
||
+ str r0, [r10, #CRYP_DIN]
|
||
+
|
||
+ PRINT_CHAR r0, r1, '8'
|
||
+
|
||
+ WAIT_FLAG_TIMEOUT CRYP_SR, CRYP_SR_OFNE, CRYP_SR_OFNE
|
||
+
|
||
+ /* Store generated tag in the PM_CTX structure */
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r11, #PM_CTX_CCM_TAG]
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r11, #(PM_CTX_CCM_TAG + 4)]
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r11, #(PM_CTX_CCM_TAG + 8)]
|
||
+ /* Before last 32bit word, the output FIFO shall not be empty */
|
||
+ ldr r0, [r10, #CRYP_SR]
|
||
+ ands r0, r0, #CRYP_SR_OFNE
|
||
+ beq _ccm_failed
|
||
+ /* After last 32bit word for this 128block, FIFO shall be empty */
|
||
+ ldr r0, [r10, #CRYP_DOUT]
|
||
+ str r0, [r11, #(PM_CTX_CCM_TAG + 12)]
|
||
+ ldr r0, [r10, #CRYP_SR]
|
||
+ ands r0, r0, #CRYP_SR_OFNE
|
||
+ bne _ccm_failed
|
||
+
|
||
+ PRINT_CHAR r0, r1, '9'
|
||
+
|
||
+ /* Successful return */
|
||
+ bl _reset_cryp1
|
||
+ mov r0, #0
|
||
+ bx r12
|
||
+
|
||
+_ccm_failed:
|
||
+
|
||
+ PRINT_CHAR r0, r1, 'K'
|
||
+ PRINT_CHAR r0, r1, 'O'
|
||
+
|
||
+ bl _reset_cryp1
|
||
+ mov r0, #1
|
||
+ bx r12
|
||
+
|
||
+/* End address of the PIC resume sequence copy in retained RAM */
|
||
+stm32mp_bkpsram_image_end:
|
||
+ nop
|
||
+
|
||
+UNWIND( .fnend)
|
||
+END_FUNC stm32mp_bkpsram_resume
|
||
+
|
||
+/*
|
||
+ * int stm32mp_ccm_encrypt_teeram(ctx, dst, src, len)
|
||
+ */
|
||
+FUNC stm32mp_ccm_encrypt_teeram , :
|
||
+UNWIND( .fnstart)
|
||
+ push {r4-r12, lr}
|
||
+UNWIND( .save {r4-r12, lr})
|
||
+ mov r11, r0
|
||
+ mov r0, r1
|
||
+ mov r1, r2
|
||
+ mov r2, r3
|
||
+ mov r3, #0
|
||
+ push {r0-r3}
|
||
+ bl _prepare_time
|
||
+ pop {r0-r3}
|
||
+ bl stm32mp_ccm_teeram
|
||
+ bl _save_resume_time
|
||
+ pop {r4-r12, pc}
|
||
+UNWIND( .fnend)
|
||
+END_FUNC stm32mp_ccm_encrypt_teeram
|
||
+
|
||
+/*
|
||
+ * int stm32mp_ccm_decrypt_teeram(ctx, cryp_base, dst, src)
|
||
+ */
|
||
+FUNC stm32mp_ccm_decrypt_teeram , :
|
||
+UNWIND( .fnstart)
|
||
+ push {r4-r12, lr}
|
||
+UNWIND( .save {r4-r12, lr})
|
||
+ mov r11, r0
|
||
+ mov r0, r1
|
||
+ mov r1, r2
|
||
+ mov r2, r3
|
||
+ mov r3, #1
|
||
+ push {r0-r3}
|
||
+ bl _prepare_time
|
||
+ pop {r0-r3}
|
||
+ bl stm32mp_ccm_teeram
|
||
+ bl _save_resume_time
|
||
+ pop {r4-r12, pc}
|
||
+UNWIND( .fnend)
|
||
+END_FUNC stm32mp_ccm_decrypt_teeram
|
||
+
|
||
+/*
|
||
+ * stm32mp_sysram_resume - Resume OP-TEE execution
|
||
+ *
|
||
+ * This function is the entry point of OP-TEE core resume sequence in the TEE
|
||
+ * RAM. When TEE RAM is lost during a power cycle, stm32mp_bkpsram_resume() is
|
||
+ * called to restore TEE RAM content and branch to this stm32mp_sysram_resume()
|
||
+ * routine.
|
||
+ *
|
||
+ * This function calls the OP-TEE core generic PM resume API
|
||
+ * sm_pm_cpu_resume().
|
||
+ */
|
||
+FUNC stm32mp_sysram_resume, :
|
||
+UNWIND( .fnstart)
|
||
+UNWIND( .cantunwind)
|
||
+ /* Invalidate the data cache */
|
||
+
|
||
+ read_clidr r2
|
||
+ ubfx r3, r2, #CLIDR_LOC_SHIFT, #CLIDR_FIELD_WIDTH
|
||
+ lsl r3, r3, #CSSELR_LEVEL_SHIFT
|
||
+ mov r1, #0
|
||
+
|
||
+loop1:
|
||
+ add r10, r1, r1, LSR #1 // Work out 3x current cache level
|
||
+ mov r12, r2, LSR r10 // extract cache type bits from clidr
|
||
+ and r12, r12, #7 // mask the bits for current cache only
|
||
+ cmp r12, #2 // see what cache we have at this level
|
||
+ blo level_done // no cache or only instruction cache at this level
|
||
+
|
||
+ write_csselr r1 // select current cache level in csselr
|
||
+ isb // isb to sych the new cssr&csidr
|
||
+ read_ccsidr r12 // read the new ccsidr
|
||
+ and r10, r12, #7 // extract the length of the cache lines
|
||
+ add r10, r10, #4 // add 4 (r10 = line length offset)
|
||
+ ubfx r4, r12, #3, #10 // r4 = maximum way number (right aligned)
|
||
+ clz r5, r4 // r5 = the bit position of the way size increment
|
||
+ mov r9, r4 // r9 working copy of the aligned max way number
|
||
+
|
||
+loop2:
|
||
+ ubfx r7, r12, #13, #15 // r7 = max set number (right aligned)
|
||
+
|
||
+loop3:
|
||
+ orr r0, r1, r9, LSL r5 // factor in the way number and cache level into r0
|
||
+ orr r0, r0, r7, LSL r10 // factor in the set number
|
||
+
|
||
+ write_dcisw r0
|
||
+
|
||
+ subs r7, r7, #1 // decrement the set number
|
||
+ bhs loop3
|
||
+ subs r9, r9, #1 // decrement the way number
|
||
+ bhs loop2
|
||
+level_done:
|
||
+ add r1, r1, #2 // increment the cache number
|
||
+ cmp r3, r1
|
||
+ dsb sy // ensure completion of previous cache maintenance instruction
|
||
+ bhi loop1
|
||
+
|
||
+ mov r6, #0
|
||
+ write_csselr r6 //select cache level 0 in csselr
|
||
+ dsb sy
|
||
+ isb
|
||
+
|
||
+ /* Resume sequence executes in Monitor mode */
|
||
+ cps #CPSR_MODE_MON
|
||
+
|
||
+ blx plat_cpu_reset_early
|
||
+ b sm_pm_cpu_resume
|
||
+UNWIND( .fnend)
|
||
+END_FUNC stm32mp_sysram_resume
|
||
+
|
||
+/*
|
||
+ * stm32mp_cpu_reset_state - set CPU in a reset like state
|
||
+ *
|
||
+ * Disable CPU env (interrupts, cache, SMP, MMU) and return.
|
||
+ * Preserve the execution mode in CPSR.
|
||
+ */
|
||
+FUNC stm32mp_cpu_reset_state, :
|
||
+UNWIND( .fnstart)
|
||
+ push {r12, lr}
|
||
+UNWIND( .save {r12, lr})
|
||
+
|
||
+ cpsid aif
|
||
+
|
||
+ bl psci_armv7_cpu_off
|
||
+
|
||
+ write_bpiall
|
||
+ dsb
|
||
+ isb
|
||
+ read_sctlr r0
|
||
+ bic r0, r0, #SCTLR_M
|
||
+ bic r0, r0, #SCTLR_I
|
||
+ write_sctlr r0
|
||
+ dsb sy
|
||
+ isb
|
||
+
|
||
+ pop {r12, pc}
|
||
+UNWIND( .fnend)
|
||
+END_FUNC stm32mp_cpu_reset_state
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/power.h b/core/arch/arm/plat-stm32mp1/pm/power.h
|
||
new file mode 100644
|
||
index 0000000..4a5578c
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/power.h
|
||
@@ -0,0 +1,27 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#ifndef __STM32MP_PM_POWER_H__
|
||
+#define __STM32MP_PM_POWER_H__
|
||
+
|
||
+#include <compiler.h>
|
||
+#include <stdint.h>
|
||
+#include <stddef.h>
|
||
+
|
||
+bool need_to_backup_cpu_context(unsigned int soc_mode);
|
||
+bool need_to_backup_stop_context(unsigned int soc_mode);
|
||
+
|
||
+void stm32_enter_csleep(void);
|
||
+
|
||
+void stm32_enter_cstop(uint32_t mode);
|
||
+void stm32_exit_cstop(void);
|
||
+
|
||
+void stm32_enter_cstop_shutdown(uint32_t mode) __noreturn;
|
||
+void stm32_enter_cstop_reset(uint32_t mode) __noreturn;
|
||
+
|
||
+void stm32_pm_cpu_power_down_wfi(void) __noreturn;
|
||
+void stm32_pm_cpu_wfi(void);
|
||
+
|
||
+#endif /*__STM32MP_PM_POWER_H__*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/power_config.c b/core/arch/arm/plat-stm32mp1/pm/power_config.c
|
||
new file mode 100644
|
||
index 0000000..246c92e
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/power_config.c
|
||
@@ -0,0 +1,252 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
|
||
+ */
|
||
+
|
||
+#include <assert.h>
|
||
+#include <config.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <libfdt.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <trace.h>
|
||
+#include <util.h>
|
||
+
|
||
+#include "context.h"
|
||
+#include "power.h"
|
||
+
|
||
+#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg"
|
||
+#define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes"
|
||
+#define SYSTEM_OFF_MODE "system_off_soc_mode"
|
||
+
|
||
+static uint32_t deepest_suspend_mode;
|
||
+static uint32_t system_off_mode;
|
||
+static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE];
|
||
+
|
||
+/* Boot with all domains ON */
|
||
+static bool stm32mp1_pm_dom[STM32MP1_PD_MAX_PM_DOMAIN] = {
|
||
+ [STM32MP1_PD_VSW] = false,
|
||
+ [STM32MP1_PD_CORE_RET] = false,
|
||
+ [STM32MP1_PD_CORE] = false
|
||
+};
|
||
+
|
||
+bool need_to_backup_cpu_context(unsigned int soc_mode)
|
||
+{
|
||
+ switch (soc_mode) {
|
||
+ case STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR:
|
||
+ return true;
|
||
+ case STM32_PM_CSLEEP_RUN:
|
||
+ case STM32_PM_CSTOP_ALLOW_STOP:
|
||
+ case STM32_PM_CSTOP_ALLOW_LP_STOP:
|
||
+ case STM32_PM_CSTOP_ALLOW_LPLV_STOP:
|
||
+ case STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF:
|
||
+ case STM32_PM_SHUTDOWN:
|
||
+ return false;
|
||
+ default:
|
||
+ EMSG("Invalid mode 0x%x", soc_mode);
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+bool need_to_backup_stop_context(unsigned int soc_mode)
|
||
+{
|
||
+ switch (soc_mode) {
|
||
+ case STM32_PM_CSTOP_ALLOW_STOP:
|
||
+ case STM32_PM_CSTOP_ALLOW_LP_STOP:
|
||
+ case STM32_PM_CSTOP_ALLOW_LPLV_STOP:
|
||
+ return true;
|
||
+ default:
|
||
+ return false;
|
||
+ }
|
||
+}
|
||
+
|
||
+static bool get_pm_domain_state(uint8_t mode)
|
||
+{
|
||
+ bool res = true;
|
||
+ enum stm32mp1_pm_domain id = STM32MP1_PD_MAX_PM_DOMAIN;
|
||
+
|
||
+ while (res && (id > mode)) {
|
||
+ id--;
|
||
+ res &= stm32mp1_pm_dom[id];
|
||
+ }
|
||
+
|
||
+ return res;
|
||
+}
|
||
+
|
||
+int stm32mp1_set_pm_domain_state(enum stm32mp1_pm_domain domain, bool status)
|
||
+{
|
||
+ if (domain >= STM32MP1_PD_MAX_PM_DOMAIN)
|
||
+ return -1;
|
||
+
|
||
+ stm32mp1_pm_dom[domain] = status;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+#ifdef CFG_DT
|
||
+static int fdt_read_uint32_array(void *fdt, int node, const char *prop_name,
|
||
+ uint32_t *array, uint32_t count)
|
||
+{
|
||
+ const fdt32_t *cuint = NULL;
|
||
+ int len = 0;
|
||
+ uint32_t i = 0;
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, prop_name, &len);
|
||
+ if (!cuint)
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+
|
||
+ if ((uint32_t)len != (count * sizeof(uint32_t)))
|
||
+ return -FDT_ERR_BADLAYOUT;
|
||
+
|
||
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
|
||
+ *array = fdt32_to_cpu(*cuint);
|
||
+ array++;
|
||
+ cuint++;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static void save_supported_mode(void *fdt, int pwr_node)
|
||
+{
|
||
+ int len = 0;
|
||
+ uint32_t count = 0;
|
||
+ unsigned int i = 0;
|
||
+ uint32_t supported[ARRAY_SIZE(stm32mp1_supported_soc_modes)] = { };
|
||
+ const void *prop = 0;
|
||
+
|
||
+ prop = fdt_getprop(fdt, pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, &len);
|
||
+ if (!prop)
|
||
+ panic();
|
||
+
|
||
+ count = (uint32_t)len / sizeof(uint32_t);
|
||
+ if (count > STM32_PM_MAX_SOC_MODE)
|
||
+ panic();
|
||
+
|
||
+ if (fdt_read_uint32_array(fdt, pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES,
|
||
+ &supported[0], count) < 0)
|
||
+ panic("PWR DT");
|
||
+
|
||
+ for (i = 0; i < count; i++) {
|
||
+ if (supported[i] >= STM32_PM_MAX_SOC_MODE)
|
||
+ panic("Invalid mode");
|
||
+
|
||
+ stm32mp1_supported_soc_modes[supported[i]] = true;
|
||
+ }
|
||
+}
|
||
+#endif
|
||
+
|
||
+static bool is_supported_mode(uint32_t soc_mode)
|
||
+{
|
||
+ assert(soc_mode < ARRAY_SIZE(stm32mp1_supported_soc_modes));
|
||
+ return stm32mp1_supported_soc_modes[soc_mode] == 1;
|
||
+}
|
||
+
|
||
+uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode)
|
||
+{
|
||
+ uint32_t mode = 0;
|
||
+
|
||
+ if (psci_mode == PSCI_MODE_SYSTEM_OFF)
|
||
+ return system_off_mode;
|
||
+
|
||
+ mode = deepest_suspend_mode;
|
||
+
|
||
+ if ((mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) &&
|
||
+ (!get_pm_domain_state(STM32MP1_PD_CORE_RET) ||
|
||
+ !is_supported_mode(mode)))
|
||
+ mode = STM32_PM_CSTOP_ALLOW_LPLV_STOP;
|
||
+
|
||
+ if ((mode == STM32_PM_CSTOP_ALLOW_LPLV_STOP) &&
|
||
+ (!get_pm_domain_state(STM32MP1_PD_CORE) ||
|
||
+ !is_supported_mode(mode)))
|
||
+ mode = STM32_PM_CSTOP_ALLOW_LP_STOP;
|
||
+
|
||
+ if ((mode == STM32_PM_CSTOP_ALLOW_LP_STOP) &&
|
||
+ !is_supported_mode(mode))
|
||
+ mode = STM32_PM_CSTOP_ALLOW_STOP;
|
||
+
|
||
+ if ((mode == STM32_PM_CSTOP_ALLOW_STOP) &&
|
||
+ !is_supported_mode(mode))
|
||
+ mode = STM32_PM_CSLEEP_RUN;
|
||
+
|
||
+ return mode;
|
||
+}
|
||
+
|
||
+int stm32mp1_set_lp_deepest_soc_mode(uint32_t psci_mode, uint32_t soc_mode)
|
||
+{
|
||
+ if (soc_mode >= STM32_PM_MAX_SOC_MODE)
|
||
+ return -1;
|
||
+
|
||
+ if (psci_mode == PSCI_MODE_SYSTEM_SUSPEND) {
|
||
+ deepest_suspend_mode = soc_mode;
|
||
+
|
||
+ if (!IS_ENABLED(CFG_STM32_CRYP) &&
|
||
+ deepest_suspend_mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR)
|
||
+ deepest_suspend_mode = STM32_PM_CSTOP_ALLOW_LPLV_STOP;
|
||
+ }
|
||
+
|
||
+ if (psci_mode == PSCI_MODE_SYSTEM_OFF)
|
||
+ system_off_mode = soc_mode;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+#ifdef CFG_DT
|
||
+static int dt_get_pwr_node(void *fdt)
|
||
+{
|
||
+ return fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT);
|
||
+}
|
||
+
|
||
+static TEE_Result stm32mp1_init_lp_states(void)
|
||
+{
|
||
+ void *fdt = NULL;
|
||
+ int pwr_node = -1;
|
||
+ const fdt32_t *cuint = NULL;
|
||
+
|
||
+ fdt = get_embedded_dt();
|
||
+ if (fdt)
|
||
+ pwr_node = dt_get_pwr_node(fdt);
|
||
+
|
||
+ if (pwr_node >= 0)
|
||
+ cuint = fdt_getprop(fdt, pwr_node, SYSTEM_OFF_MODE, NULL);
|
||
+
|
||
+ if (!fdt || (pwr_node < 0) || !cuint) {
|
||
+ IMSG("No power configuration found in DT");
|
||
+ return TEE_SUCCESS;
|
||
+ }
|
||
+
|
||
+ system_off_mode = fdt32_to_cpu(*cuint);
|
||
+
|
||
+ /* Initialize suspend support to the deepest possible mode */
|
||
+ if (IS_ENABLED(CFG_STM32_CRYP))
|
||
+ deepest_suspend_mode = STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR;
|
||
+ else
|
||
+ deepest_suspend_mode = STM32_PM_CSTOP_ALLOW_LPLV_STOP;
|
||
+
|
||
+ save_supported_mode(fdt, pwr_node);
|
||
+
|
||
+ DMSG("Power configuration: shutdown to %u, suspend to %u",
|
||
+ stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF),
|
||
+ stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_SUSPEND));
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+#else
|
||
+static TEE_Result stm32mp1_init_lp_states(void)
|
||
+{
|
||
+ if (IS_ENABLED(CFG_STM32_CRYP))
|
||
+ deepest_suspend_mode = STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR;
|
||
+ else
|
||
+ deepest_suspend_mode = STM32_PM_CSTOP_ALLOW_LPLV_STOP;
|
||
+
|
||
+ system_off_mode = STM32_PM_SHUTDOWN;
|
||
+
|
||
+ DMSG("Power configuration: shutdown to %u, suspend to %u",
|
||
+ stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF),
|
||
+ stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_SUSPEND));
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+#endif
|
||
+service_init(stm32mp1_init_lp_states);
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/psci.c b/core/arch/arm/plat-stm32mp1/pm/psci.c
|
||
index 740b13b..ff7b966 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/pm/psci.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/psci.c
|
||
@@ -5,11 +5,18 @@
|
||
|
||
#include <arm.h>
|
||
#include <boot_api.h>
|
||
+#include <config.h>
|
||
#include <console.h>
|
||
+#include <drivers/stm32_etzpc.h>
|
||
+#include <drivers/stm32_rng.h>
|
||
#include <drivers/stm32mp1_pmic.h>
|
||
#include <drivers/stm32mp1_rcc.h>
|
||
#include <drivers/stpmic1.h>
|
||
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
+#include <dt-bindings/power/stm32mp1-power.h>
|
||
+#include <initcall.h>
|
||
#include <io.h>
|
||
+#include <keep.h>
|
||
#include <kernel/cache_helpers.h>
|
||
#include <kernel/delay.h>
|
||
#include <kernel/generic_boot.h>
|
||
@@ -19,10 +26,17 @@
|
||
#include <kernel/spinlock.h>
|
||
#include <mm/core_memprot.h>
|
||
#include <platform_config.h>
|
||
+#include <sm/pm.h>
|
||
#include <sm/psci.h>
|
||
#include <sm/std_smc.h>
|
||
#include <stm32_util.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <string.h>
|
||
#include <trace.h>
|
||
+#include <util.h>
|
||
+
|
||
+#include "context.h"
|
||
+#include "power.h"
|
||
|
||
#define CONSOLE_FLUSH_DELAY_MS 10
|
||
|
||
@@ -56,10 +70,9 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level)
|
||
|
||
DMSG("core %zu, state %u", pos, core_state[pos]);
|
||
|
||
- if ((pos >= CFG_TEE_CORE_NB_CORE) ||
|
||
- (lowest_affinity_level > PSCI_AFFINITY_LEVEL_ON)) {
|
||
+ if (pos >= CFG_TEE_CORE_NB_CORE ||
|
||
+ lowest_affinity_level > PSCI_AFFINITY_LEVEL_ON)
|
||
return PSCI_RET_INVALID_PARAMETERS;
|
||
- }
|
||
|
||
switch (core_state[pos]) {
|
||
case CORE_OFF:
|
||
@@ -81,35 +94,24 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level)
|
||
*/
|
||
void stm32mp_register_online_cpu(void)
|
||
{
|
||
- assert(core_state[0] == CORE_OFF);
|
||
+ assert(core_state[0] == CORE_OFF || core_state[0] == CORE_RET);
|
||
core_state[0] = CORE_ON;
|
||
}
|
||
#else
|
||
-static void __noreturn stm32_pm_cpu_power_down_wfi(void)
|
||
-{
|
||
- dcache_op_level1(DCACHE_OP_CLEAN);
|
||
-
|
||
- io_write32(stm32_rcc_base() + RCC_MP_GRSTCSETR,
|
||
- RCC_MP_GRSTCSETR_MPUP1RST);
|
||
-
|
||
- dsb();
|
||
- isb();
|
||
- wfi();
|
||
- panic();
|
||
-}
|
||
-
|
||
void stm32mp_register_online_cpu(void)
|
||
{
|
||
size_t pos = get_core_pos();
|
||
uint32_t exceptions = lock_state_access();
|
||
|
||
if (pos == 0) {
|
||
- assert(core_state[pos] == CORE_OFF);
|
||
+ assert((core_state[pos] == CORE_OFF) ||
|
||
+ (core_state[pos] == CORE_RET));
|
||
} else {
|
||
if (core_state[pos] != CORE_AWAKE) {
|
||
core_state[pos] = CORE_OFF;
|
||
unlock_state_access(exceptions);
|
||
- stm32_pm_cpu_power_down_wfi();
|
||
+ if (IS_ENABLED(CFG_PM))
|
||
+ stm32_pm_cpu_power_down_wfi();
|
||
panic();
|
||
}
|
||
}
|
||
@@ -132,11 +134,15 @@ static void release_secondary_early_hpen(size_t __unused pos)
|
||
raise_sgi0_as_secure();
|
||
udelay(20);
|
||
|
||
+ stm32_clock_enable(RTCAPB);
|
||
+
|
||
io_write32(stm32mp_bkpreg(BCKR_CORE1_BRANCH_ADDRESS),
|
||
TEE_LOAD_ADDR);
|
||
io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER),
|
||
BOOT_API_A7_CORE1_MAGIC_NUMBER);
|
||
|
||
+ stm32_clock_disable(RTCAPB);
|
||
+
|
||
dsb_ishst();
|
||
itr_raise_sgi(GIC_SEC_SGI_0, TARGET_CPU1_GIC_MASK);
|
||
}
|
||
@@ -204,42 +210,189 @@ int psci_cpu_off(void)
|
||
|
||
unlock_state_access(exceptions);
|
||
|
||
+ /* Enable BKPREG access for the disabled CPU */
|
||
+ stm32_clock_enable(RTCAPB);
|
||
+
|
||
thread_mask_exceptions(THREAD_EXCP_ALL);
|
||
- stm32_pm_cpu_power_down_wfi();
|
||
+ if (IS_ENABLED(CFG_PM))
|
||
+ stm32_pm_cpu_power_down_wfi();
|
||
panic();
|
||
}
|
||
#endif
|
||
|
||
-/* Override default psci_system_off() with platform specific sequence */
|
||
-void __noreturn psci_system_off(void)
|
||
+#ifdef CFG_PM
|
||
+static int enter_cstop_suspend(unsigned int soc_mode)
|
||
{
|
||
- DMSG("core %u", get_core_pos());
|
||
+ int rc = 1;
|
||
+
|
||
+ if (read_isr())
|
||
+ return rc;
|
||
+
|
||
+ stm32_enter_cstop(soc_mode);
|
||
+
|
||
+ if (need_to_backup_cpu_context(soc_mode)) {
|
||
+ stm32_pm_cpu_power_down_wfi();
|
||
+ } else {
|
||
+ stm32_pm_cpu_wfi();
|
||
+ rc = 0;
|
||
+ }
|
||
+
|
||
+ stm32_exit_cstop();
|
||
+
|
||
+ return rc;
|
||
+}
|
||
+
|
||
+static int plat_suspend(uint32_t arg)
|
||
+{
|
||
+ unsigned int soc_mode = arg;
|
||
+ size_t pos = get_core_pos();
|
||
+ int rc = 1;
|
||
+
|
||
+ if (read_isr())
|
||
+ return rc;
|
||
+
|
||
+ /* No need to lock state access as CPU is alone when here */
|
||
+ assert(core_state[pos] == CORE_ON);
|
||
+ core_state[pos] = CORE_RET;
|
||
+
|
||
+ if (stm32mp_pm_save_context(soc_mode) == TEE_SUCCESS)
|
||
+ rc = enter_cstop_suspend(soc_mode);
|
||
+
|
||
+ stm32mp_pm_restore_context(soc_mode);
|
||
+ stm32mp_pm_wipe_context();
|
||
+
|
||
+ assert(core_state[pos] == CORE_RET);
|
||
+ core_state[pos] = CORE_ON;
|
||
+
|
||
+ return rc;
|
||
+}
|
||
+
|
||
+static void plat_resume(uint32_t arg)
|
||
+{
|
||
+ unsigned int soc_mode = arg;
|
||
+
|
||
+ stm32mp_register_online_cpu();
|
||
+
|
||
+ assert(core_state[get_core_pos()] == CORE_ON);
|
||
+
|
||
+ stm32mp_pm_restore_context(soc_mode);
|
||
+}
|
||
+
|
||
+static bool plat_can_suspend(void)
|
||
+{
|
||
+ size_t pos = get_core_pos();
|
||
+ size_t n = 0;
|
||
+ uint32_t exceptions = 0;
|
||
+ bool rc = true;
|
||
|
||
- if (TRACE_LEVEL >= TRACE_DEBUG) {
|
||
- console_flush();
|
||
- mdelay(CONSOLE_FLUSH_DELAY_MS);
|
||
+ if (!IS_ENABLED(CFG_STM32_RNG))
|
||
+ return false;
|
||
+
|
||
+ if (CFG_TEE_CORE_NB_CORE == 1)
|
||
+ return true;
|
||
+
|
||
+ exceptions = lock_state_access();
|
||
+
|
||
+ for (n = 0; n < ARRAY_SIZE(core_state); n++) {
|
||
+ if (n == pos)
|
||
+ continue;
|
||
+
|
||
+ if (core_state[n] == CORE_AWAKE) {
|
||
+ /* State core as lost and proceed suspend */
|
||
+ core_state[n] = CORE_OFF;
|
||
+ }
|
||
+
|
||
+ if (core_state[n] != CORE_OFF)
|
||
+ rc = false;
|
||
}
|
||
|
||
- if (stm32mp_with_pmic()) {
|
||
- stm32mp_get_pmic();
|
||
- stpmic1_switch_off();
|
||
- udelay(100);
|
||
+ unlock_state_access(exceptions);
|
||
+
|
||
+ return rc;
|
||
+}
|
||
+
|
||
+/* Override default psci_system_suspend() with platform specific sequence */
|
||
+int psci_system_suspend(uintptr_t entry, uint32_t context_id __unused,
|
||
+ struct sm_nsec_ctx *nsec)
|
||
+{
|
||
+ int ret = PSCI_RET_INVALID_PARAMETERS;
|
||
+ uint32_t soc_mode = 0;
|
||
+ int __maybe_unused pos = get_core_pos();
|
||
+
|
||
+ DMSG("core %u", pos);
|
||
+
|
||
+ if (!plat_can_suspend())
|
||
+ return PSCI_RET_DENIED;
|
||
+
|
||
+ soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_SUSPEND);
|
||
+
|
||
+ switch (soc_mode) {
|
||
+ case STM32_PM_CSLEEP_RUN:
|
||
+ stm32_enter_csleep();
|
||
+ nsec->mon_lr = (uint32_t)entry;
|
||
+ return PSCI_RET_SUCCESS;
|
||
+ case STM32_PM_SHUTDOWN:
|
||
+ stm32_enter_cstop_shutdown(soc_mode);
|
||
+ panic();
|
||
+ default:
|
||
+ /* Others are suspended mode: at least some context to backup */
|
||
+ break;
|
||
}
|
||
|
||
- panic();
|
||
+ assert(cpu_mmu_enabled() && core_state[pos] == CORE_ON);
|
||
+
|
||
+ if (need_to_backup_cpu_context(soc_mode)) {
|
||
+ if (!IS_ENABLED(CFG_STM32_CRYP))
|
||
+ return PSCI_RET_DENIED;
|
||
+
|
||
+ sm_save_unbanked_regs(&nsec->ub_regs);
|
||
+ /*
|
||
+ * sm_pm_cpu_suspend(arg, func) saves the CPU core context in TEE RAM
|
||
+ * then calls func(arg) to run the platform lower power sequence.
|
||
+ *
|
||
+ * If platform fails to suspend, sm_pm_cpu_suspend() returns with a
|
||
+ * non null return code. When sm_pm_cpu_suspend() returns 0 platform
|
||
+ * context must be restored.
|
||
+ */
|
||
+ ret = sm_pm_cpu_suspend((uint32_t)soc_mode, plat_suspend);
|
||
+ if (ret == 0) {
|
||
+ plat_resume((uint32_t)soc_mode);
|
||
+ sm_restore_unbanked_regs(&nsec->ub_regs);
|
||
+ }
|
||
+ } else {
|
||
+ ret = plat_suspend((uint32_t)soc_mode);
|
||
+ }
|
||
+
|
||
+ if (ret == 0) {
|
||
+ nsec->mon_lr = (uint32_t)entry;
|
||
+ IMSG("Resumed");
|
||
+ return PSCI_RET_SUCCESS;
|
||
+ }
|
||
+
|
||
+ return PSCI_RET_INTERNAL_FAILURE;
|
||
+}
|
||
+
|
||
+/* Override default psci_system_off() with platform specific sequence */
|
||
+void __noreturn psci_system_off(void)
|
||
+{
|
||
+ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF);
|
||
+
|
||
+ DMSG("core %u", get_core_pos());
|
||
+
|
||
+ stm32_enter_cstop_shutdown(soc_mode);
|
||
}
|
||
|
||
/* Override default psci_system_reset() with platform specific sequence */
|
||
void __noreturn psci_system_reset(void)
|
||
{
|
||
- vaddr_t rcc_base = stm32_rcc_base();
|
||
+ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF);
|
||
|
||
DMSG("core %u", get_core_pos());
|
||
|
||
- io_write32(rcc_base + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST);
|
||
- udelay(100);
|
||
- panic();
|
||
+ stm32_enter_cstop_reset(soc_mode);
|
||
}
|
||
+#endif /*CFG_PM*/
|
||
+
|
||
|
||
/* Override default psci_cpu_on() with platform supported features */
|
||
int psci_features(uint32_t psci_fid)
|
||
@@ -256,6 +409,7 @@ int psci_features(uint32_t psci_fid)
|
||
return PSCI_RET_SUCCESS;
|
||
return PSCI_RET_NOT_SUPPORTED;
|
||
case PSCI_SYSTEM_OFF:
|
||
+ case PSCI_SYSTEM_SUSPEND:
|
||
if (stm32mp_with_pmic())
|
||
return PSCI_RET_SUCCESS;
|
||
return PSCI_RET_NOT_SUPPORTED;
|
||
diff --git a/core/arch/arm/plat-stm32mp1/pm/sub.mk b/core/arch/arm/plat-stm32mp1/pm/sub.mk
|
||
index c8ae8f9..d652958 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/pm/sub.mk
|
||
+++ b/core/arch/arm/plat-stm32mp1/pm/sub.mk
|
||
@@ -1 +1,7 @@
|
||
+asm-defines-y += context_asm_defines.c
|
||
+
|
||
+srcs-$(CFG_PM) += context.c
|
||
+srcs-$(CFG_PM) += low_power.c
|
||
+srcs-$(CFG_PM) += pm_helpers.S
|
||
+srcs-$(CFG_PM) += power_config.c
|
||
srcs-$(CFG_PSCI_ARM32) += psci.c
|
||
diff --git a/core/arch/arm/plat-stm32mp1/reset.S b/core/arch/arm/plat-stm32mp1/reset.S
|
||
index 69ab151..6a8ac06 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/reset.S
|
||
+++ b/core/arch/arm/plat-stm32mp1/reset.S
|
||
@@ -3,7 +3,7 @@
|
||
* Copyright (c) 2018, STMicroelectronics
|
||
*/
|
||
|
||
-#include <arm32.h>
|
||
+#include <arm.h>
|
||
#include <arm32_macros.S>
|
||
#include <asm.S>
|
||
#include <kernel/unwind.h>
|
||
@@ -23,8 +23,34 @@ UNWIND( .fnstart)
|
||
mov_imm r1, STM32MP1_NSACR_PRESERVE_MASK
|
||
and r0, r0, r1
|
||
write_nsacr r0
|
||
+ isb
|
||
+
|
||
+ read_actlr r0
|
||
+ orr r0, r0, #ACTLR_SMP
|
||
+ write_actlr r0
|
||
+
|
||
+ /*
|
||
+ * Always reset CNTVOFF for the dear non secure world.
|
||
+ * This operation requires being in Monitor mode and
|
||
+ * non secure state.
|
||
+ */
|
||
+ mrs r1, cpsr
|
||
+ cps #CPSR_MODE_MON
|
||
+ isb
|
||
+
|
||
+ read_scr r2
|
||
+ orr r0, r2, #SCR_NS
|
||
+ write_scr r0
|
||
+ isb
|
||
+
|
||
+ mov r0, #0
|
||
+ write_cntvoff r0, r0
|
||
|
||
+ write_scr r2
|
||
isb
|
||
- bx lr
|
||
+ msr cpsr, r1
|
||
+ isb
|
||
+
|
||
+ bx lr
|
||
UNWIND( .fnend)
|
||
END_FUNC plat_cpu_reset_early
|
||
diff --git a/core/arch/arm/plat-stm32mp1/scmi_server.c b/core/arch/arm/plat-stm32mp1/scmi_server.c
|
||
index ddc19ca..5116b89 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/scmi_server.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/scmi_server.c
|
||
@@ -9,6 +9,7 @@
|
||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||
#include <dt-bindings/reset/stm32mp1-resets.h>
|
||
#include <initcall.h>
|
||
+#include <kernel/pm.h>
|
||
#include <mm/core_memprot.h>
|
||
#include <mm/core_mmu.h>
|
||
#include <platform_config.h>
|
||
@@ -276,8 +277,21 @@ const char *plat_scmi_clock_get_name(unsigned int agent_id,
|
||
return clock->name;
|
||
}
|
||
|
||
-int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
|
||
- unsigned long *array, size_t *nb_elts)
|
||
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused,
|
||
+ unsigned int scmi_id __unused,
|
||
+ unsigned long *array __unused,
|
||
+ size_t *nb_elts __unused)
|
||
+{
|
||
+ /*
|
||
+ * Explicitly do not expose clock rates by array since not
|
||
+ * fully supported by Linux kernel as of v5.4.24.
|
||
+ */
|
||
+ return SCMI_NOT_SUPPORTED;
|
||
+}
|
||
+
|
||
+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id,
|
||
+ unsigned int scmi_id,
|
||
+ unsigned long *array)
|
||
{
|
||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||
|
||
@@ -287,12 +301,48 @@ int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
|
||
if (!stm32mp_nsec_can_access_clock(clock->clock_id))
|
||
return SCMI_DENIED;
|
||
|
||
- if (!array)
|
||
- *nb_elts = 1;
|
||
- else if (*nb_elts == 1)
|
||
- *array = stm32_clock_get_rate(clock->clock_id);
|
||
- else
|
||
- return SCMI_GENERIC_ERROR;
|
||
+ switch (scmi_id) {
|
||
+ case CK_SCMI0_MPU:
|
||
+ /*
|
||
+ * Pretend we support all rates for MPU clock,
|
||
+ * CLOCK_RATE_SET will reject unsupported rates.
|
||
+ */
|
||
+ array[0] = 0U;
|
||
+ array[1] = UINT32_MAX;
|
||
+ array[2] = 1U;
|
||
+ break;
|
||
+ default:
|
||
+ array[0] = stm32_clock_get_rate(clock->clock_id);
|
||
+ array[1] = array[0];
|
||
+ array[2] = 0U;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ return SCMI_SUCCESS;
|
||
+}
|
||
+
|
||
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
|
||
+ unsigned long rate)
|
||
+{
|
||
+ struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||
+ int ret = SCMI_DENIED;
|
||
+
|
||
+ if (!clock)
|
||
+ return SCMI_NOT_FOUND;
|
||
+ if (!stm32mp_nsec_can_access_clock(clock->clock_id))
|
||
+ return SCMI_DENIED;
|
||
+
|
||
+ switch (scmi_id) {
|
||
+ case CK_SCMI0_MPU:
|
||
+ ret = stm32mp1_set_opp_khz(rate / 1000);
|
||
+ if (ret)
|
||
+ return SCMI_INVALID_PARAMETERS;
|
||
+ break;
|
||
+ default:
|
||
+ if (rate != stm32_clock_get_rate(clock->clock_id))
|
||
+ return SCMI_INVALID_PARAMETERS;
|
||
+ break;
|
||
+ }
|
||
|
||
return SCMI_SUCCESS;
|
||
}
|
||
@@ -432,6 +482,19 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id,
|
||
return SCMI_SUCCESS;
|
||
}
|
||
|
||
+static TEE_Result stm32_scmi_pm(enum pm_op op, unsigned int pm_hint __unused,
|
||
+ const struct pm_callback_handle *hdl __unused)
|
||
+{
|
||
+ size_t i = 0;
|
||
+
|
||
+ if (op == PM_OP_RESUME)
|
||
+ for (i = 0; i < ARRAY_SIZE(scmi_channel); i++)
|
||
+ scmi_smt_init_agent_channel(&scmi_channel[i]);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_scmi_pm);
|
||
+
|
||
/*
|
||
* Initialize platform SCMI resources
|
||
*/
|
||
@@ -440,6 +503,8 @@ static TEE_Result stm32mp1_init_scmi_server(void)
|
||
size_t i = 0;
|
||
size_t j = 0;
|
||
|
||
+ register_pm_driver_cb(stm32_scmi_pm, NULL);
|
||
+
|
||
for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) {
|
||
struct scmi_msg_channel *chan = &scmi_channel[i];
|
||
|
||
diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c
|
||
index e321ec8..08aa9a3 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/shared_resources.c
|
||
+++ b/core/arch/arm/plat-stm32mp1/shared_resources.c
|
||
@@ -650,27 +650,36 @@ static void check_rcc_secure_configuration(void)
|
||
{
|
||
bool secure = stm32_rcc_is_secure();
|
||
bool mckprot = stm32_rcc_is_mckprot();
|
||
+ bool need_secure = false;
|
||
+ bool need_mckprot = false;
|
||
enum stm32mp_shres id = STM32MP1_SHRES_COUNT;
|
||
- bool have_error = false;
|
||
|
||
- if (stm32mp_is_closed_device() && !secure)
|
||
- panic();
|
||
+ if (stm32mp_is_closed_device() && !secure) {
|
||
+ DMSG("stm32mp1: closed device mandates OP-TEE to secure RCC");
|
||
+ need_secure = true;
|
||
+ }
|
||
|
||
for (id = 0; id < STM32MP1_SHRES_COUNT; id++) {
|
||
if (shres_state[id] != SHRES_SECURE)
|
||
continue;
|
||
|
||
- if ((mckprot_resource(id) && !mckprot) || !secure) {
|
||
- EMSG("RCC %s MCKPROT %s and %s (%u) secure",
|
||
- secure ? "secure" : "non-secure",
|
||
- mckprot ? "set" : "not set",
|
||
- shres2str_id(id), id);
|
||
- have_error = true;
|
||
- }
|
||
+ need_secure = true;
|
||
+ if (mckprot_resource(id))
|
||
+ need_mckprot = true;
|
||
+
|
||
+ if ((mckprot_resource(id) && !mckprot) || !secure)
|
||
+ EMSG("Error: RCC TZEN=%u MCKPROT=%u while %s is secure",
|
||
+ secure, mckprot, shres2str_id(id));
|
||
}
|
||
|
||
- if (have_error)
|
||
+ DMSG("RCC/PWR secure hardening: TZEN %sable, MCKPROT %sable",
|
||
+ secure ? "en" : "dis", mckprot ? "en" : "dis");
|
||
+
|
||
+ if (need_secure && !secure)
|
||
panic();
|
||
+
|
||
+ if (need_mckprot)
|
||
+ io_setbits32(stm32_rcc_base() + RCC_TZCR, RCC_TZCR_MCKPROT);
|
||
}
|
||
|
||
static void set_gpio_secure_configuration(void)
|
||
diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h
|
||
index 5572dae..9c86cd2 100644
|
||
--- a/core/arch/arm/plat-stm32mp1/stm32_util.h
|
||
+++ b/core/arch/arm/plat-stm32mp1/stm32_util.h
|
||
@@ -9,11 +9,23 @@
|
||
#include <assert.h>
|
||
#include <drivers/stm32_bsec.h>
|
||
#include <kernel/panic.h>
|
||
+#include <stdbool.h>
|
||
#include <stdint.h>
|
||
#include <types_ext.h>
|
||
|
||
+/* SoC versioning and device ID */
|
||
+TEE_Result stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version);
|
||
+TEE_Result stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id);
|
||
+
|
||
+/* OPP service */
|
||
+bool stm32mp_supports_cpu_opp(uint32_t opp_id);
|
||
+
|
||
/* Backup registers and RAM utils */
|
||
vaddr_t stm32mp_bkpreg(unsigned int idx);
|
||
+vaddr_t stm32mp_bkpsram_base(void);
|
||
+
|
||
+/* Platform util for the STGEN driver */
|
||
+vaddr_t stm32mp_stgen_base(void);
|
||
|
||
/*
|
||
* SYSCFG IO compensation.
|
||
@@ -25,6 +37,7 @@ void stm32mp_syscfg_disable_io_compensation(void);
|
||
/* Platform util for the GIC */
|
||
vaddr_t get_gicc_base(void);
|
||
vaddr_t get_gicd_base(void);
|
||
+void stm32mp_gic_set_end_of_interrupt(uint32_t it);
|
||
|
||
/*
|
||
* Platform util functions for the GPIO driver
|
||
@@ -43,6 +56,18 @@ vaddr_t stm32_get_gpio_bank_base(unsigned int bank);
|
||
unsigned int stm32_get_gpio_bank_offset(unsigned int bank);
|
||
unsigned int stm32_get_gpio_bank_clock(unsigned int bank);
|
||
|
||
+/*
|
||
+ * Platform util for the IWDG driver
|
||
+ */
|
||
+
|
||
+/* Get IWDG_* enable flags mask from watchdog configuration read from fuses */
|
||
+unsigned long stm32_get_iwdg_otp_config(vaddr_t pbase);
|
||
+
|
||
+/* Conversion between IWDG instance IDs and hardware resources */
|
||
+size_t stm32mp_iwdg_instance2irq(unsigned int instance);
|
||
+unsigned int stm32mp_iwdg_irq2instance(size_t irq);
|
||
+unsigned int stm32mp_iwdg_iomem2instance(vaddr_t pbase);
|
||
+
|
||
/* Platform util for PMIC support */
|
||
bool stm32mp_with_pmic(void);
|
||
|
||
@@ -74,6 +99,19 @@ bool stm32_clock_is_enabled(unsigned long id);
|
||
/* Return true if @clock_id is shared by secure and non-secure worlds */
|
||
bool stm32mp_nsec_can_access_clock(unsigned long clock_id);
|
||
|
||
+/* PM sequences specific to SoC STOP mode support */
|
||
+void stm32mp1_clk_save_context_for_stop(void);
|
||
+void stm32mp1_clk_restore_context_for_stop(void);
|
||
+
|
||
+/*
|
||
+ * Util for PLL1 settings management based on DT OPP table content.
|
||
+ */
|
||
+int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage);
|
||
+void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data, size_t size);
|
||
+bool stm32mp1_clk_pll1_settings_are_valid(void);
|
||
+int stm32mp1_set_opp_khz(uint32_t freq_khz);
|
||
+int stm32mp1_round_opp_khz(uint32_t *freq_khz);
|
||
+
|
||
/*
|
||
* Util for reset signal assertion/desassertion for stm32 and platform drivers
|
||
* @id: Target peripheral ID, ID used in reset DT bindings
|
||
@@ -110,6 +148,22 @@ struct stm32_bsec_static_cfg {
|
||
|
||
void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg);
|
||
|
||
+/* Reset function for early watchdog management */
|
||
+void stm32mp_platform_reset(int cpu);
|
||
+
|
||
+/* Clock calibration. Returns 0 on success */
|
||
+#ifdef CFG_STM32_CLKCALIB
|
||
+int stm32mp_start_clock_calib(unsigned int clock_id);
|
||
+#else
|
||
+static inline int stm32mp_start_clock_calib(unsigned int clock_id __unused)
|
||
+{
|
||
+ return 1;
|
||
+}
|
||
+#endif
|
||
+
|
||
+/* Platform util for the RTC driver */
|
||
+bool stm32_rtc_get_read_twice(void);
|
||
+
|
||
/*
|
||
* Return true if platform is in closed_device mode
|
||
*/
|
||
diff --git a/core/arch/arm/plat-stm32mp1/stm32mp_pm.h b/core/arch/arm/plat-stm32mp1/stm32mp_pm.h
|
||
new file mode 100644
|
||
index 0000000..4265db9
|
||
--- /dev/null
|
||
+++ b/core/arch/arm/plat-stm32mp1/stm32mp_pm.h
|
||
@@ -0,0 +1,21 @@
|
||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics
|
||
+ */
|
||
+#ifndef __STM32MP_PM_H__
|
||
+#define __STM32MP_PM_H__
|
||
+
|
||
+#define PSCI_MODE_SYSTEM_SUSPEND 0
|
||
+#define PSCI_MODE_SYSTEM_OFF 1
|
||
+
|
||
+enum stm32mp1_pm_domain {
|
||
+ STM32MP1_PD_VSW,
|
||
+ STM32MP1_PD_CORE_RET,
|
||
+ STM32MP1_PD_CORE,
|
||
+ STM32MP1_PD_MAX_PM_DOMAIN
|
||
+};
|
||
+
|
||
+void __noreturn stm32_cores_reset(void);
|
||
+
|
||
+#endif /*__STM32MP_PM_H__*/
|
||
+
|
||
diff --git a/core/arch/arm/sm/pm_a32.S b/core/arch/arm/sm/pm_a32.S
|
||
index 9421b2d..8a59cd2 100644
|
||
--- a/core/arch/arm/sm/pm_a32.S
|
||
+++ b/core/arch/arm/sm/pm_a32.S
|
||
@@ -69,25 +69,30 @@ a9_suspend:
|
||
a7_suspend:
|
||
read_fcseidr r4
|
||
read_tpidruro r5
|
||
- stmia r0!, {r4 - r5}
|
||
- read_dacr r4
|
||
+ read_dacr r6
|
||
+ stmia r0!, {r4 - r6}
|
||
#ifdef CFG_WITH_LPAE
|
||
-#error "Not supported"
|
||
+ read_ttbr0_64bit r4, r5
|
||
+ read_ttbr1_64bit r6, r7
|
||
+ read_mair0 r8
|
||
+ read_mair1 r9
|
||
+ stmia r0!, {r4 - r9}
|
||
#else
|
||
- read_ttbr0 r5
|
||
- read_ttbr1 r6
|
||
- read_ttbcr r7
|
||
+ read_ttbr0 r4
|
||
+ read_ttbr1 r5
|
||
+ read_prrr r6
|
||
+ read_nmrr r7
|
||
+ stmia r0!, {r4 - r7}
|
||
#endif
|
||
- read_sctlr r8
|
||
- read_actlr r9
|
||
- read_cpacr r10
|
||
- read_mvbar r11
|
||
- stmia r0!, {r4 - r11}
|
||
- read_prrr r4
|
||
- read_nmrr r5
|
||
- read_vbar r6
|
||
- read_nsacr r7
|
||
- stmia r0, {r4 - r7}
|
||
+ read_ttbcr r4
|
||
+ read_actlr r5
|
||
+ read_cpacr r6
|
||
+ read_mvbar r7
|
||
+ read_vbar r8
|
||
+ read_nsacr r9
|
||
+ read_sctlr r10
|
||
+ stmia r0, {r4 - r10}
|
||
+
|
||
pop {r4 - r11}
|
||
bx lr
|
||
UNWIND( .fnend)
|
||
@@ -154,50 +159,50 @@ UNWIND( .cantunwind)
|
||
cmp r5, r4
|
||
beq a7_resume
|
||
|
||
- /*
|
||
- * A9 needs PCR/DIAG
|
||
- */
|
||
+ /* A9 needs PCR/DIAG */
|
||
ldmia r0!, {r4 - r5}
|
||
write_pcr r4
|
||
write_diag r5
|
||
-
|
||
a7_resume:
|
||
- /* v7 resume */
|
||
+ /* Armv7 generic resume */
|
||
mov ip, #0
|
||
/* Invalidate icache to PoU */
|
||
write_iciallu
|
||
/* set reserved context */
|
||
write_contextidr ip
|
||
- ldmia r0!, {r4 - r5}
|
||
+ ldmia r0!, {r4 - r6}
|
||
write_fcseidr r4
|
||
write_tpidruro r5
|
||
- ldmia r0!, {r4 - r11}
|
||
/* Invalidate entire TLB */
|
||
write_tlbiall
|
||
- write_dacr r4
|
||
+ write_dacr r6
|
||
#ifdef CFG_WITH_LPAE
|
||
-#error "Not supported -"
|
||
+ ldmia r0!, {r4 - r9}
|
||
+ write_ttbr0_64bit r4, r5
|
||
+ write_ttbr1_64bit r6, r7
|
||
+ write_mair0 r8
|
||
+ write_mair1 r9
|
||
#else
|
||
- write_ttbr0 r5
|
||
- write_ttbr1 r6
|
||
- write_ttbcr r7
|
||
+ ldmia r0!, {r4 - r7}
|
||
+ write_ttbr0 r4
|
||
+ write_ttbr1 r5
|
||
+ write_prrr r6
|
||
+ write_nmrr r7
|
||
#endif
|
||
-
|
||
- ldmia r0, {r4 - r7}
|
||
- write_prrr r4
|
||
- write_nmrr r5
|
||
- write_vbar r6
|
||
- write_nsacr r7
|
||
-
|
||
- write_actlr r9
|
||
- write_cpacr r10
|
||
- write_mvbar r11
|
||
+ ldmia r0!, {r4 - r10}
|
||
+ write_ttbcr r4
|
||
+ write_actlr r5
|
||
+ write_cpacr r6
|
||
+ write_mvbar r7
|
||
+ write_vbar r8
|
||
+ write_nsacr r9
|
||
write_bpiall
|
||
isb
|
||
dsb
|
||
/* MMU will be enabled here */
|
||
- write_sctlr r8
|
||
+ write_sctlr r10
|
||
isb
|
||
+
|
||
mov r0, #0
|
||
b suspend_return
|
||
UNWIND( .fnend)
|
||
diff --git a/core/arch/arm/tee/entry_std.c b/core/arch/arm/tee/entry_std.c
|
||
index 5c1e8c2..60aed6c 100644
|
||
--- a/core/arch/arm/tee/entry_std.c
|
||
+++ b/core/arch/arm/tee/entry_std.c
|
||
@@ -535,4 +535,4 @@ static TEE_Result default_mobj_init(void)
|
||
return TEE_SUCCESS;
|
||
}
|
||
|
||
-driver_init_late(default_mobj_init);
|
||
+service_init(default_mobj_init);
|
||
diff --git a/core/drivers/gic.c b/core/drivers/gic.c
|
||
index 0bad974..3f1a606 100644
|
||
--- a/core/drivers/gic.c
|
||
+++ b/core/drivers/gic.c
|
||
@@ -7,12 +7,15 @@
|
||
#include <arm.h>
|
||
#include <assert.h>
|
||
#include <drivers/gic.h>
|
||
+#include <io.h>
|
||
#include <keep.h>
|
||
#include <kernel/interrupt.h>
|
||
#include <kernel/panic.h>
|
||
+#include <kernel/pm.h>
|
||
+#include <malloc.h>
|
||
#include <util.h>
|
||
-#include <io.h>
|
||
#include <trace.h>
|
||
+#include <string.h>
|
||
|
||
/* Offsets from gic.gicc_base */
|
||
#define GICC_CTLR (0x000)
|
||
@@ -33,9 +36,11 @@
|
||
#define GICD_ICENABLER(n) (0x180 + (n) * 4)
|
||
#define GICD_ISPENDR(n) (0x200 + (n) * 4)
|
||
#define GICD_ICPENDR(n) (0x280 + (n) * 4)
|
||
+#define GICD_ISACTIVER(n) (0x300 + (n) * 4)
|
||
#define GICD_IPRIORITYR(n) (0x400 + (n) * 4)
|
||
#define GICD_ITARGETSR(n) (0x800 + (n) * 4)
|
||
#define GICD_IGROUPMODR(n) (0xd00 + (n) * 4)
|
||
+#define GICD_ICFGR(n) (0xc00 + (n) * 4)
|
||
#define GICD_SGIR (0xF00)
|
||
|
||
#define GICD_CTLR_ENABLEGRP0 (1 << 0)
|
||
@@ -76,6 +81,25 @@ static void gic_op_raise_sgi(struct itr_chip *chip, size_t it,
|
||
static void gic_op_set_affinity(struct itr_chip *chip, size_t it,
|
||
uint8_t cpu_mask);
|
||
|
||
+#if defined(CFG_ARM_GIC_PM)
|
||
+static void gic_pm_add_it(struct gic_data *gd, unsigned int it);
|
||
+static void gic_pm_register(struct gic_data *gd);
|
||
+#else
|
||
+static void gic_pm_add_it(struct gic_data *gd __unused,
|
||
+ unsigned int it __unused)
|
||
+{
|
||
+}
|
||
+static void gic_pm_register(struct gic_data *gd __unused)
|
||
+{
|
||
+}
|
||
+#endif
|
||
+
|
||
+#if !defined(CFG_ARM_GICV3)
|
||
+static uint8_t gic_op_set_pmr(struct itr_chip *chip, uint8_t mask);
|
||
+static uint8_t gic_op_set_ipriority(struct itr_chip *chip, size_t it,
|
||
+ uint8_t mask);
|
||
+#endif
|
||
+
|
||
static const struct itr_ops gic_ops = {
|
||
.add = gic_op_add,
|
||
.enable = gic_op_enable,
|
||
@@ -83,6 +107,10 @@ static const struct itr_ops gic_ops = {
|
||
.raise_pi = gic_op_raise_pi,
|
||
.raise_sgi = gic_op_raise_sgi,
|
||
.set_affinity = gic_op_set_affinity,
|
||
+#if !defined(CFG_ARM_GICV3)
|
||
+ .set_pmr = gic_op_set_pmr,
|
||
+ .set_ipriority = gic_op_set_ipriority,
|
||
+#endif
|
||
};
|
||
DECLARE_KEEP_PAGER(gic_ops);
|
||
|
||
@@ -148,10 +176,10 @@ void gic_cpu_init(struct gic_data *gd)
|
||
* allow the Non-secure world to adjust the priority mask itself
|
||
*/
|
||
#if defined(CFG_ARM_GICV3)
|
||
- write_icc_pmr(0x80);
|
||
+ write_icc_pmr(GIC_HIGHEST_NS_PRIORITY);
|
||
write_icc_igrpen1(1);
|
||
#else
|
||
- io_write32(gd->gicc_base + GICC_PMR, 0x80);
|
||
+ io_write32(gd->gicc_base + GICC_PMR, GIC_HIGHEST_NS_PRIORITY);
|
||
|
||
/* Enable GIC */
|
||
io_write32(gd->gicc_base + GICC_CTLR,
|
||
@@ -160,13 +188,10 @@ void gic_cpu_init(struct gic_data *gd)
|
||
#endif
|
||
}
|
||
|
||
-void gic_init(struct gic_data *gd, vaddr_t gicc_base __maybe_unused,
|
||
- vaddr_t gicd_base)
|
||
+void gic_init_setup(struct gic_data *gd)
|
||
{
|
||
size_t n;
|
||
|
||
- gic_init_base_addr(gd, gicc_base, gicd_base);
|
||
-
|
||
for (n = 0; n <= gd->max_it / NUM_INTS_PER_REG; n++) {
|
||
/* Disable interrupts */
|
||
io_write32(gd->gicd_base + GICD_ICENABLER(n), 0xffffffff);
|
||
@@ -191,11 +216,11 @@ void gic_init(struct gic_data *gd, vaddr_t gicc_base __maybe_unused,
|
||
* allow the Non-secure world to adjust the priority mask itself
|
||
*/
|
||
#if defined(CFG_ARM_GICV3)
|
||
- write_icc_pmr(0x80);
|
||
+ write_icc_pmr(GIC_HIGHEST_NS_PRIORITY);
|
||
write_icc_igrpen1(1);
|
||
io_setbits32(gd->gicd_base + GICD_CTLR, GICD_CTLR_ENABLEGRP1S);
|
||
#else
|
||
- io_write32(gd->gicc_base + GICC_PMR, 0x80);
|
||
+ io_write32(gd->gicc_base + GICC_PMR, GIC_HIGHEST_NS_PRIORITY);
|
||
|
||
/* Enable GIC */
|
||
io_write32(gd->gicc_base + GICC_CTLR, GICC_CTLR_FIQEN |
|
||
@@ -212,6 +237,14 @@ void gic_init_base_addr(struct gic_data *gd, vaddr_t gicc_base __maybe_unused,
|
||
gd->gicd_base = gicd_base;
|
||
gd->max_it = probe_max_it(gicc_base, gicd_base);
|
||
gd->chip.ops = &gic_ops;
|
||
+
|
||
+ gic_pm_register(gd);
|
||
+}
|
||
+
|
||
+void gic_init(struct gic_data *gd, vaddr_t gicc_base, vaddr_t gicd_base)
|
||
+{
|
||
+ gic_init_base_addr(gd, gicc_base, gicd_base);
|
||
+ gic_init_setup(gd);
|
||
}
|
||
|
||
static void gic_it_add(struct gic_data *gd, size_t it)
|
||
@@ -236,7 +269,8 @@ static void gic_it_set_cpu_mask(struct gic_data *gd, size_t it,
|
||
{
|
||
size_t idx __maybe_unused = it / NUM_INTS_PER_REG;
|
||
uint32_t mask __maybe_unused = 1 << (it % NUM_INTS_PER_REG);
|
||
- uint32_t target, target_shift;
|
||
+ uint32_t target = 0;
|
||
+ uint32_t target_shift = 0;
|
||
vaddr_t itargetsr = gd->gicd_base +
|
||
GICD_ITARGETSR(it / NUM_TARGETS_PER_REG);
|
||
|
||
@@ -258,15 +292,39 @@ static void gic_it_set_prio(struct gic_data *gd, size_t it, uint8_t prio)
|
||
size_t idx __maybe_unused = it / NUM_INTS_PER_REG;
|
||
uint32_t mask __maybe_unused = 1 << (it % NUM_INTS_PER_REG);
|
||
|
||
- /* Assigned to group0 */
|
||
- assert(!(io_read32(gd->gicd_base + GICD_IGROUPR(idx)) & mask));
|
||
-
|
||
/* Set prio it to selected CPUs */
|
||
DMSG("prio: writing 0x%x to 0x%" PRIxVA,
|
||
prio, gd->gicd_base + GICD_IPRIORITYR(0) + it);
|
||
io_write8(gd->gicd_base + GICD_IPRIORITYR(0) + it, prio);
|
||
}
|
||
|
||
+static uint8_t gic_op_set_pmr(struct itr_chip *chip, uint8_t mask)
|
||
+{
|
||
+ struct gic_data *gd = container_of(chip, struct gic_data, chip);
|
||
+ uint32_t pmr = io_read32(gd->gicc_base + GICC_PMR);
|
||
+
|
||
+ /*
|
||
+ * Order memory updates w.r.t. PMR write, and ensure they're visible
|
||
+ * before potential out of band interrupt trigger because of PMR update.
|
||
+ */
|
||
+ dsb_ishst();
|
||
+ io_write32(gd->gicc_base + GICC_PMR, mask);
|
||
+ dsb_ishst();
|
||
+
|
||
+ return (uint8_t)pmr;
|
||
+}
|
||
+
|
||
+static uint8_t gic_op_set_ipriority(struct itr_chip *chip, size_t it,
|
||
+ uint8_t mask)
|
||
+{
|
||
+ struct gic_data *gd = container_of(chip, struct gic_data, chip);
|
||
+ uint8_t prio = io_read8(gd->gicd_base + GICD_IPRIORITYR(0) + it);
|
||
+
|
||
+ gic_it_set_prio(gd, it, mask);
|
||
+
|
||
+ return prio;
|
||
+}
|
||
+
|
||
static void gic_it_enable(struct gic_data *gd, size_t it)
|
||
{
|
||
size_t idx = it / NUM_INTS_PER_REG;
|
||
@@ -391,8 +449,8 @@ void gic_dump_state(struct gic_data *gd)
|
||
|
||
void gic_it_handle(struct gic_data *gd)
|
||
{
|
||
- uint32_t iar;
|
||
- uint32_t id;
|
||
+ uint32_t iar = 0;
|
||
+ uint32_t id = 0;
|
||
|
||
iar = gic_read_iar(gd);
|
||
id = iar & GICC_IAR_IT_ID_MASK;
|
||
@@ -417,6 +475,8 @@ static void gic_op_add(struct itr_chip *chip, size_t it,
|
||
/* Set the CPU mask to deliver interrupts to any online core */
|
||
gic_it_set_cpu_mask(gd, it, 0xff);
|
||
gic_it_set_prio(gd, it, 0x1);
|
||
+
|
||
+ gic_pm_add_it(gd, it);
|
||
}
|
||
|
||
static void gic_op_enable(struct itr_chip *chip, size_t it)
|
||
@@ -462,6 +522,7 @@ static void gic_op_raise_sgi(struct itr_chip *chip, size_t it,
|
||
else
|
||
gic_it_raise_sgi(gd, it, cpu_mask, 0);
|
||
}
|
||
+
|
||
static void gic_op_set_affinity(struct itr_chip *chip, size_t it,
|
||
uint8_t cpu_mask)
|
||
{
|
||
@@ -472,3 +533,137 @@ static void gic_op_set_affinity(struct itr_chip *chip, size_t it,
|
||
|
||
gic_it_set_cpu_mask(gd, it, cpu_mask);
|
||
}
|
||
+
|
||
+#if defined(CFG_ARM_GIC_PM)
|
||
+/*
|
||
+ * Save/restore interrupts registered from the gic_op_add_it() handler
|
||
+ */
|
||
+#define IT_PM_GPOUP1_BIT BIT(0)
|
||
+#define IT_PM_ENABLE_BIT BIT(1)
|
||
+#define IT_PM_PENDING_BIT BIT(2)
|
||
+#define IT_PM_ACTIVE_BIT BIT(3)
|
||
+#define IT_PM_CONFIG_MASK GENMASK_32(1, 0)
|
||
+
|
||
+/*
|
||
+ * @it - interrupt ID/number
|
||
+ * @flags - bitflag IT_PM_*_BIT
|
||
+ * @iprio - 8bit prio from IPRIORITYR
|
||
+ * @itarget - 8bit target from ITARGETR
|
||
+ * @icfg - 2bit configuration from ICFGR and IT_PM_CONFIG_MASK
|
||
+ */
|
||
+struct gic_it_pm {
|
||
+ uint16_t it;
|
||
+ uint8_t flags;
|
||
+ uint8_t iprio;
|
||
+ uint8_t itarget;
|
||
+ uint8_t icfg;
|
||
+};
|
||
+
|
||
+static void gic_pm_add_it(struct gic_data *gd, unsigned int it)
|
||
+{
|
||
+ struct gic_pm *pm = &gd->pm;
|
||
+
|
||
+ pm->count++;
|
||
+ pm->pm_cfg = realloc(pm->pm_cfg, pm->count * sizeof(*pm->pm_cfg));
|
||
+ if (!pm->pm_cfg)
|
||
+ panic();
|
||
+
|
||
+ pm->pm_cfg[pm->count - 1] = (struct gic_it_pm){ .it = it };
|
||
+}
|
||
+
|
||
+static void gic_save_it(struct gic_data *gd, struct gic_it_pm *pm)
|
||
+{
|
||
+ unsigned int it = pm->it;
|
||
+ size_t idx = 0;
|
||
+ uint32_t bit_mask = BIT(it % NUM_INTS_PER_REG);
|
||
+ uint32_t shift2 = it % (NUM_INTS_PER_REG / 2);
|
||
+ uint32_t shift8 = it % (NUM_INTS_PER_REG / 8);
|
||
+ uint32_t data32 = 0;
|
||
+
|
||
+ pm->flags = 0;
|
||
+ idx = it / NUM_INTS_PER_REG;
|
||
+
|
||
+ if (io_read32(gd->gicd_base + GICD_IGROUPR(idx)) & bit_mask)
|
||
+ pm->flags |= IT_PM_GPOUP1_BIT;
|
||
+ if (io_read32(gd->gicd_base + GICD_ISENABLER(idx)) & bit_mask)
|
||
+ pm->flags |= IT_PM_ENABLE_BIT;
|
||
+ if (io_read32(gd->gicd_base + GICD_ISPENDR(idx)) & bit_mask)
|
||
+ pm->flags |= IT_PM_PENDING_BIT;
|
||
+ if (io_read32(gd->gicd_base + GICD_ISACTIVER(idx)) & bit_mask)
|
||
+ pm->flags |= IT_PM_ACTIVE_BIT;
|
||
+
|
||
+ idx = (8 * it) / NUM_INTS_PER_REG;
|
||
+
|
||
+ data32 = io_read32(gd->gicd_base + GICD_IPRIORITYR(idx)) >> shift8;
|
||
+ pm->iprio = (uint8_t)data32;
|
||
+
|
||
+ data32 = io_read32(gd->gicd_base + GICD_ITARGETSR(idx)) >> shift8;
|
||
+ pm->itarget = (uint8_t)data32;
|
||
+
|
||
+ /* Note: ICFGR is RAO for SPIs and PPIs */
|
||
+ idx = (2 * it) / NUM_INTS_PER_REG;
|
||
+ data32 = io_read32(gd->gicd_base + GICD_ICFGR(idx)) >> shift2;
|
||
+ pm->icfg = (uint8_t)data32 & IT_PM_CONFIG_MASK;
|
||
+}
|
||
+
|
||
+static void gic_restore_it(struct gic_data *gd, struct gic_it_pm *pm)
|
||
+{
|
||
+ unsigned int it = pm->it;
|
||
+ size_t idx = it / NUM_INTS_PER_REG;
|
||
+ uint32_t mask = BIT(it % NUM_INTS_PER_REG);
|
||
+ uint32_t shift2 = it % (NUM_INTS_PER_REG / 2);
|
||
+ uint32_t shift8 = it % (NUM_INTS_PER_REG / 8);
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_IGROUPR(idx),
|
||
+ (pm->flags & IT_PM_GPOUP1_BIT) ? mask : 0, mask);
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_ISENABLER(idx),
|
||
+ (pm->flags & IT_PM_ENABLE_BIT) ? mask : 0, mask);
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_ISPENDR(idx),
|
||
+ (pm->flags & IT_PM_PENDING_BIT) ? mask : 0, mask);
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_ISACTIVER(idx),
|
||
+ (pm->flags & IT_PM_ACTIVE_BIT) ? mask : 0, mask);
|
||
+
|
||
+ idx = (8 * it) / NUM_INTS_PER_REG;
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_IPRIORITYR(idx),
|
||
+ (uint32_t)pm->iprio << shift8, UINT8_MAX << shift8);
|
||
+
|
||
+ io_mask32(gd->gicd_base + GICD_ITARGETSR(idx),
|
||
+ (uint32_t)pm->itarget << shift8, UINT8_MAX << shift8);
|
||
+
|
||
+ /* Note: ICFGR is WI for SPIs and PPIs */
|
||
+ idx = (2 * it) / NUM_INTS_PER_REG;
|
||
+ io_mask32(gd->gicd_base + GICD_ICFGR(idx),
|
||
+ (uint32_t)pm->icfg << shift2, IT_PM_CONFIG_MASK << shift2);
|
||
+}
|
||
+
|
||
+static TEE_Result gic_pm(enum pm_op op, unsigned int pm_hint __unused,
|
||
+ const struct pm_callback_handle *handle)
|
||
+{
|
||
+ void (*sequence)(struct gic_data *gd, struct gic_it_pm *pm) = NULL;
|
||
+ struct gic_it_pm *cfg = NULL;
|
||
+ unsigned int n = 0;
|
||
+ struct gic_data *gd = (struct gic_data *)PM_CALLBACK_GET_HANDLE(handle);
|
||
+ struct gic_pm *pm = &gd->pm;
|
||
+
|
||
+ if (op == PM_OP_SUSPEND) {
|
||
+ sequence = gic_save_it;
|
||
+ } else {
|
||
+ gic_init_setup(gd);
|
||
+ sequence = gic_restore_it;
|
||
+ }
|
||
+ for (n = 0, cfg = pm->pm_cfg; n < pm->count; n++, cfg++)
|
||
+ sequence(gd, cfg);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(gic_pm);
|
||
+
|
||
+static void gic_pm_register(struct gic_data *gd)
|
||
+{
|
||
+ register_pm_core_service_cb(gic_pm, gd);
|
||
+}
|
||
+#endif /*CFG_ARM_GIC_PM*/
|
||
diff --git a/core/drivers/stm32_bsec.c b/core/drivers/stm32_bsec.c
|
||
index 546ba91..a563f79 100644
|
||
--- a/core/drivers/stm32_bsec.c
|
||
+++ b/core/drivers/stm32_bsec.c
|
||
@@ -91,10 +91,6 @@
|
||
#define BSEC_MODE_BIST2_LOCK_MASK BIT(7)
|
||
|
||
/* BSEC_DEBUG */
|
||
-#define BSEC_HDPEN BIT(4)
|
||
-#define BSEC_SPIDEN BIT(5)
|
||
-#define BSEC_SPINDEN BIT(6)
|
||
-#define BSEC_DBGSWGEN BIT(10)
|
||
#define BSEC_DEN_ALL_MSK GENMASK_32(10, 0)
|
||
|
||
/*
|
||
@@ -138,6 +134,11 @@ static uint32_t otp_max_id(void)
|
||
return bsec_dev.max_id;
|
||
}
|
||
|
||
+static uint32_t otp_upper_base(void)
|
||
+{
|
||
+ return bsec_dev.upper_base;
|
||
+}
|
||
+
|
||
static uint32_t otp_bank_offset(uint32_t otp_id)
|
||
{
|
||
assert(otp_id <= otp_max_id());
|
||
@@ -363,12 +364,12 @@ TEE_Result stm32_bsec_permanent_lock_otp(uint32_t otp_id)
|
||
uint32_t addr = 0;
|
||
uint32_t exceptions = 0;
|
||
vaddr_t base = bsec_base();
|
||
- uint64_t timeout_ref;
|
||
+ uint64_t timeout_ref = 0;
|
||
|
||
if (otp_id > otp_max_id())
|
||
return TEE_ERROR_BAD_PARAMETERS;
|
||
|
||
- if (otp_id < bsec_dev.upper_base) {
|
||
+ if (otp_id < otp_upper_base()) {
|
||
addr = otp_id >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
|
||
data = DATA_LOWER_OTP_PERLOCK_BIT <<
|
||
((otp_id & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
|
||
@@ -521,7 +522,7 @@ TEE_Result stm32_bsec_otp_lock(uint32_t service)
|
||
|
||
static size_t nsec_access_array_size(void)
|
||
{
|
||
- size_t upper_count = otp_max_id() - bsec_dev.upper_base + 1;
|
||
+ size_t upper_count = otp_max_id() - otp_upper_base() + 1;
|
||
|
||
return ROUNDUP(upper_count, BITS_PER_WORD) / BITS_PER_WORD;
|
||
}
|
||
@@ -537,16 +538,50 @@ static bool nsec_access_granted(unsigned int index)
|
||
|
||
bool stm32_bsec_nsec_can_access_otp(uint32_t otp_id)
|
||
{
|
||
- return otp_id < bsec_dev.upper_base ||
|
||
- nsec_access_granted(otp_id - bsec_dev.upper_base);
|
||
+ return otp_id < otp_upper_base() ||
|
||
+ nsec_access_granted(otp_id - otp_upper_base());
|
||
+}
|
||
+
|
||
+struct nvmem_layout {
|
||
+ char *name;
|
||
+ uint32_t otp_id;
|
||
+ size_t bit_len;
|
||
+};
|
||
+
|
||
+static struct nvmem_layout *nvmem_layout;
|
||
+static size_t nvmem_layout_count;
|
||
+
|
||
+TEE_Result stm32_bsec_find_otp_in_nvmem_layout(const char *name,
|
||
+ uint32_t *otp_id,
|
||
+ size_t *otp_bit_len)
|
||
+{
|
||
+ size_t i = 0;
|
||
+
|
||
+ if (!name)
|
||
+ return TEE_ERROR_BAD_PARAMETERS;
|
||
+
|
||
+ for (i = 0; i < nvmem_layout_count; i++) {
|
||
+ if (!nvmem_layout[i].name || strcmp(name, nvmem_layout[i].name))
|
||
+ continue;
|
||
+
|
||
+ if (otp_id)
|
||
+ *otp_id = nvmem_layout[i].otp_id;
|
||
+
|
||
+ if (otp_bit_len)
|
||
+ *otp_bit_len = nvmem_layout[i].bit_len;
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+ }
|
||
+
|
||
+ return TEE_ERROR_ITEM_NOT_FOUND;
|
||
}
|
||
|
||
#ifdef CFG_DT
|
||
static void enable_nsec_access(unsigned int otp_id)
|
||
{
|
||
- unsigned int idx = (otp_id - bsec_dev.upper_base) / BITS_PER_WORD;
|
||
+ unsigned int idx = (otp_id - otp_upper_base()) / BITS_PER_WORD;
|
||
|
||
- if (otp_id < bsec_dev.upper_base)
|
||
+ if (otp_id < otp_upper_base())
|
||
return;
|
||
|
||
if (otp_id > otp_max_id() || stm32_bsec_shadow_register(otp_id))
|
||
@@ -619,6 +654,77 @@ static void bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
|
||
}
|
||
}
|
||
|
||
+static void save_dt_nvmem_layout(void *fdt)
|
||
+{
|
||
+ const fdt32_t *cells = NULL;
|
||
+ int i = 0;
|
||
+ int cell_nb = 0;
|
||
+ int nvmem_node = 0;
|
||
+
|
||
+ nvmem_node = fdt_node_offset_by_compatible(fdt, -1,
|
||
+ "st,stm32-nvmem-layout");
|
||
+ if (nvmem_node < 0)
|
||
+ return;
|
||
+
|
||
+ cells = fdt_getprop(fdt, nvmem_node, "nvmem-cells", &cell_nb);
|
||
+ if (!cells)
|
||
+ cell_nb = 0;
|
||
+
|
||
+ cell_nb /= sizeof(uint32_t);
|
||
+
|
||
+ i = fdt_stringlist_count(fdt, nvmem_node, "nvmem-cell-names");
|
||
+ if (i < 0)
|
||
+ i = 0;
|
||
+
|
||
+ if (cell_nb != i)
|
||
+ panic("Inconsistent NVMEM layout");
|
||
+
|
||
+ nvmem_layout = calloc(cell_nb, sizeof(*nvmem_layout));
|
||
+ if (!nvmem_layout)
|
||
+ panic();
|
||
+
|
||
+ nvmem_layout_count = (size_t)cell_nb;
|
||
+
|
||
+ for (i = 0; i < cell_nb; i++) {
|
||
+ const fdt32_t *cuint = NULL;
|
||
+ const char *string = NULL;
|
||
+ int len = 0;
|
||
+ int node = 0;
|
||
+ struct nvmem_layout *layout_cell = &nvmem_layout[i];
|
||
+
|
||
+ node = fdt_node_offset_by_phandle(fdt,
|
||
+ fdt32_to_cpu(*(cells + i)));
|
||
+ if (node < 0) {
|
||
+ IMSG("Malformed nvmem_layout node: ignored");
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, "reg", &len);
|
||
+ if (!cuint || (len != (2 * (int)sizeof(uint32_t)))) {
|
||
+ IMSG("Malformed nvmem_layout node: ignored");
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ if (fdt32_to_cpu(*cuint) % sizeof(uint32_t)) {
|
||
+ IMSG("Misaligned nvmem_layout element: ignored");
|
||
+ continue;
|
||
+ }
|
||
+ layout_cell->otp_id = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
|
||
+ layout_cell->bit_len = fdt32_to_cpu(*(cuint + 1)) * CHAR_BIT;
|
||
+
|
||
+ string = fdt_stringlist_get(fdt, nvmem_node, "nvmem-cell-names",
|
||
+ i, &len);
|
||
+ if (!string || !len)
|
||
+ continue;
|
||
+
|
||
+ layout_cell->name = calloc(1, len + 1);
|
||
+ if (!layout_cell->name)
|
||
+ panic();
|
||
+
|
||
+ memcpy(layout_cell->name, string, len);
|
||
+ }
|
||
+}
|
||
+
|
||
static void initialize_bsec_from_dt(void)
|
||
{
|
||
void *fdt = NULL;
|
||
@@ -637,6 +743,8 @@ static void initialize_bsec_from_dt(void)
|
||
panic();
|
||
|
||
bsec_dt_otp_nsec_access(fdt, node);
|
||
+
|
||
+ save_dt_nvmem_layout(fdt);
|
||
}
|
||
#else
|
||
static void initialize_bsec_from_dt(void)
|
||
diff --git a/core/drivers/stm32_iwdg.c b/core/drivers/stm32_iwdg.c
|
||
new file mode 100644
|
||
index 0000000..5073663
|
||
--- /dev/null
|
||
+++ b/core/drivers/stm32_iwdg.c
|
||
@@ -0,0 +1,313 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
|
||
+ */
|
||
+
|
||
+#include <assert.h>
|
||
+#include <drivers/stm32_iwdg.h>
|
||
+#include <io.h>
|
||
+#include <keep.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/dt.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/interrupt.h>
|
||
+#include <kernel/misc.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <kernel/pm.h>
|
||
+#include <libfdt.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <stm32_util.h>
|
||
+#include <stm32mp_pm.h>
|
||
+#include <string.h>
|
||
+#include <trace.h>
|
||
+
|
||
+/* IWDG Compatibility */
|
||
+#define IWDG_COMPAT "st,stm32mp1-iwdg"
|
||
+#define IWDG_TIMEOUT_US 100000U
|
||
+
|
||
+/* IWDG registers offsets */
|
||
+#define IWDG_KR_OFFSET 0x00U
|
||
+#define IWDG_PR_OFFSET 0x04U
|
||
+#define IWDG_RLR_OFFSET 0x08U
|
||
+#define IWDG_SR_OFFSET 0x0CU
|
||
+#define IWDG_EWCR_OFFSET 0x14U
|
||
+
|
||
+/* Registers values */
|
||
+#define IWDG_KR_ACCESS_KEY 0x5555
|
||
+#define IWDG_KR_RELOAD_KEY 0xAAAA
|
||
+#define IWDG_KR_START_KEY 0xCCCC
|
||
+
|
||
+#define IWDG_PR_DIV_4 0x00
|
||
+#define IWDG_PR_DIV_256 0x06
|
||
+
|
||
+#define IWDG_RLR_MAX_VAL 0xFFF
|
||
+
|
||
+#define IWDG_SR_EWU BIT(3)
|
||
+
|
||
+#define IWDG_EWCR_EWIE BIT(15)
|
||
+#define IWDG_EWCR_EWIC BIT(14)
|
||
+#define IWDG_EWCR_EWIT_MASK GENMASK_32(11, 0)
|
||
+
|
||
+struct stm32_iwdg_instance {
|
||
+ struct io_pa_va base;
|
||
+ unsigned long clock;
|
||
+ uint8_t instance;
|
||
+ uint8_t flags;
|
||
+};
|
||
+
|
||
+static struct stm32_iwdg_instance *stm32_iwdg;
|
||
+static size_t stm32_iwdg_count;
|
||
+
|
||
+static vaddr_t get_base(struct stm32_iwdg_instance *iwdg)
|
||
+{
|
||
+ return io_pa_or_va(&iwdg->base);
|
||
+}
|
||
+
|
||
+static int stm32_iwdg_get_dt_node(void *fdt, struct dt_node_info *info,
|
||
+ int offset)
|
||
+{
|
||
+ int node = fdt_node_offset_by_compatible(fdt, offset, IWDG_COMPAT);
|
||
+
|
||
+ if (node < 0) {
|
||
+ if (offset == -1)
|
||
+ DMSG("No IDWG found");
|
||
+
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+ }
|
||
+
|
||
+ _fdt_fill_device_info(fdt, info, node);
|
||
+
|
||
+ return node;
|
||
+}
|
||
+
|
||
+static struct stm32_iwdg_instance *get_iwdg(unsigned int instance)
|
||
+{
|
||
+ size_t i = 0;
|
||
+
|
||
+ assert(instance <= UINT8_MAX);
|
||
+ for (i = 0; i < stm32_iwdg_count; i++)
|
||
+ if (stm32_iwdg[i].instance == instance)
|
||
+ return &stm32_iwdg[i];
|
||
+
|
||
+ return NULL;
|
||
+}
|
||
+
|
||
+static enum itr_return stm32_iwdg_it_handler(struct itr_handler *handler)
|
||
+{
|
||
+ unsigned int __maybe_unused cpu = get_core_pos();
|
||
+ unsigned int instance = stm32mp_iwdg_irq2instance(handler->it);
|
||
+ struct stm32_iwdg_instance *iwdg = get_iwdg(instance);
|
||
+ vaddr_t iwdg_base = get_base(iwdg);
|
||
+
|
||
+ DMSG("CPU %u IT Watchdog %d\n", cpu, instance + 1);
|
||
+
|
||
+ stm32_iwdg_refresh(instance);
|
||
+
|
||
+ stm32_clock_enable(iwdg->clock);
|
||
+
|
||
+ io_setbits32(iwdg_base + IWDG_EWCR_OFFSET, IWDG_EWCR_EWIC);
|
||
+
|
||
+ stm32_clock_disable(iwdg->clock);
|
||
+
|
||
+#ifdef CFG_PM
|
||
+ /*
|
||
+ * Ack interrupt as we do not return from next call.
|
||
+ * And interrupt is no more considered as pending here.
|
||
+ */
|
||
+ stm32mp_gic_set_end_of_interrupt(handler->it);
|
||
+
|
||
+ stm32_cores_reset();
|
||
+#else
|
||
+ panic("Watchdog");
|
||
+#endif
|
||
+
|
||
+ return ITRR_HANDLED;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_iwdg_it_handler);
|
||
+
|
||
+static int stm32_iwdg_get_secure_timeout(void *fdt, int node)
|
||
+{
|
||
+ const fdt32_t *cuint = NULL;
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, "secure-timeout-sec", NULL);
|
||
+ if (!cuint)
|
||
+ return -1;
|
||
+
|
||
+ return (int)fdt32_to_cpu(*cuint);
|
||
+}
|
||
+
|
||
+static int fdt_get_clock_id_by_name(void *fdt, int node, const char *name)
|
||
+{
|
||
+ const fdt32_t *cuint = NULL;
|
||
+ int index = 0;
|
||
+ int len = 0;
|
||
+
|
||
+ index = fdt_stringlist_search(fdt, node, "clock-names", name);
|
||
+ if (index < 0)
|
||
+ return index;
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, "clocks", &len);
|
||
+ if (!cuint)
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+
|
||
+ if ((index * (int)sizeof(uint32_t)) > len)
|
||
+ return -FDT_ERR_BADVALUE;
|
||
+
|
||
+ cuint += (index << 1) + 1;
|
||
+ return (int)fdt32_to_cpu(*cuint);
|
||
+}
|
||
+
|
||
+static TEE_Result stm32_iwdg_conf_etimeout(void *fdt, int node,
|
||
+ struct stm32_iwdg_instance *iwdg)
|
||
+{
|
||
+ int id_lsi = 0;
|
||
+ int dt_secure_timeout = stm32_iwdg_get_secure_timeout(fdt, node);
|
||
+ uint32_t reload = 0;
|
||
+ uint32_t status = 0;
|
||
+ uint64_t timeout_ref = 0;
|
||
+ unsigned long long reload_ll = 0;
|
||
+ vaddr_t iwdg_base = get_base(iwdg);
|
||
+ struct itr_handler *itr = NULL;
|
||
+
|
||
+ if (dt_secure_timeout < 0)
|
||
+ return TEE_SUCCESS;
|
||
+
|
||
+ if (dt_secure_timeout == 0)
|
||
+ return TEE_ERROR_GENERIC;
|
||
+
|
||
+ id_lsi = fdt_get_clock_id_by_name(fdt, node, "lsi");
|
||
+ if (id_lsi < 0)
|
||
+ return TEE_ERROR_GENERIC;
|
||
+
|
||
+ /* Prescaler fix to 256 */
|
||
+ reload_ll = (unsigned long long)dt_secure_timeout *
|
||
+ stm32_clock_get_rate(id_lsi);
|
||
+ reload = ((uint32_t)(reload_ll >> 8) - 1) & IWDG_EWCR_EWIT_MASK;
|
||
+
|
||
+ stm32_clock_enable(iwdg->clock);
|
||
+
|
||
+ io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_START_KEY);
|
||
+ io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY);
|
||
+ io_write32(iwdg_base + IWDG_PR_OFFSET, IWDG_PR_DIV_256);
|
||
+ io_write32(iwdg_base + IWDG_EWCR_OFFSET, reload | IWDG_EWCR_EWIE);
|
||
+
|
||
+ timeout_ref = timeout_init_us(IWDG_TIMEOUT_US);
|
||
+ while (!timeout_elapsed(timeout_ref))
|
||
+ if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_EWU))
|
||
+ break;
|
||
+
|
||
+ status = io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_EWU;
|
||
+ stm32_clock_disable(iwdg->clock);
|
||
+ if (status)
|
||
+ return TEE_ERROR_GENERIC;
|
||
+
|
||
+ itr = calloc(1, sizeof(*itr));
|
||
+ if (!itr)
|
||
+ panic("out of memory");
|
||
+
|
||
+ itr->it = stm32mp_iwdg_instance2irq(iwdg->instance);
|
||
+ itr->handler = stm32_iwdg_it_handler;
|
||
+ itr_add(itr);
|
||
+ itr_enable(itr->it);
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+
|
||
+void stm32_iwdg_refresh(unsigned int instance)
|
||
+{
|
||
+ struct stm32_iwdg_instance *iwdg = get_iwdg(instance);
|
||
+
|
||
+ if (!iwdg)
|
||
+ return;
|
||
+
|
||
+ stm32_clock_enable(iwdg->clock);
|
||
+
|
||
+ io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY);
|
||
+
|
||
+ stm32_clock_disable(iwdg->clock);
|
||
+}
|
||
+
|
||
+static TEE_Result iwdg_init(void)
|
||
+{
|
||
+ int node = -1;
|
||
+ TEE_Result res = TEE_ERROR_GENERIC;
|
||
+ struct dt_node_info dt_info = { };
|
||
+ void *fdt = NULL;
|
||
+ size_t count = 0;
|
||
+
|
||
+ fdt = get_embedded_dt();
|
||
+ if (!fdt)
|
||
+ panic();
|
||
+
|
||
+ assert(!stm32_iwdg && !stm32_iwdg_count);
|
||
+
|
||
+ for (node = stm32_iwdg_get_dt_node(fdt, &dt_info, node);
|
||
+ node != -FDT_ERR_NOTFOUND;
|
||
+ node = stm32_iwdg_get_dt_node(fdt, &dt_info, node)) {
|
||
+ struct stm32_iwdg_instance iwdg = { };
|
||
+ enum teecore_memtypes memtype = MEM_AREA_MAXTYPE;
|
||
+ uint32_t hw_init = 0;
|
||
+
|
||
+ iwdg.base.pa = dt_info.reg;
|
||
+ iwdg.clock = (unsigned long)dt_info.clock;
|
||
+ iwdg.instance = stm32mp_iwdg_iomem2instance(iwdg.base.pa);
|
||
+
|
||
+ memtype = ((dt_info.status & DT_STATUS_OK_NSEC) != 0) ?
|
||
+ MEM_AREA_IO_NSEC : MEM_AREA_IO_SEC;
|
||
+ iwdg.base.va = (vaddr_t)phys_to_virt(iwdg.base.pa, memtype);
|
||
+
|
||
+ /* DT can specify low power cases */
|
||
+ if (!fdt_getprop(fdt, node, "stm32,enable-on-stop", NULL))
|
||
+ iwdg.flags |= IWDG_DISABLE_ON_STOP;
|
||
+
|
||
+ if (!fdt_getprop(fdt, node, "stm32,enable-on-standby", NULL))
|
||
+ iwdg.flags |= IWDG_DISABLE_ON_STANDBY;
|
||
+
|
||
+ hw_init = stm32_get_iwdg_otp_config(iwdg.base.pa);
|
||
+
|
||
+ if (hw_init & IWDG_HW_ENABLED) {
|
||
+ if (dt_info.status == DT_STATUS_DISABLED)
|
||
+ panic("IWDG HW enabled");
|
||
+
|
||
+ iwdg.flags |= IWDG_HW_ENABLED;
|
||
+ }
|
||
+
|
||
+ if (hw_init & IWDG_DISABLE_ON_STOP)
|
||
+ iwdg.flags |= IWDG_DISABLE_ON_STOP;
|
||
+
|
||
+ if (hw_init & IWDG_DISABLE_ON_STANDBY)
|
||
+ iwdg.flags |= IWDG_DISABLE_ON_STANDBY;
|
||
+
|
||
+ if (dt_info.status == DT_STATUS_DISABLED)
|
||
+ continue;
|
||
+
|
||
+ DMSG("IWDG%u found, %ssecure", iwdg.instance + 1,
|
||
+ (dt_info.status & DT_STATUS_OK_NSEC) ? "non-" : "");
|
||
+
|
||
+ if (dt_info.status & DT_STATUS_OK_NSEC)
|
||
+ stm32mp_register_non_secure_periph_iomem(iwdg.base.pa);
|
||
+ else
|
||
+ stm32mp_register_secure_periph_iomem(iwdg.base.pa);
|
||
+
|
||
+ res = stm32_iwdg_conf_etimeout(fdt, node, &iwdg);
|
||
+ if (res) {
|
||
+ EMSG("IWDG%x early timeout config failed (%d)\n",
|
||
+ iwdg.instance + 1, res);
|
||
+ panic();
|
||
+ }
|
||
+
|
||
+ stm32_iwdg = realloc(stm32_iwdg, (count + 1) * sizeof(iwdg));
|
||
+ if (!stm32_iwdg)
|
||
+ panic("out of memory");
|
||
+
|
||
+ memcpy(&stm32_iwdg[count], &iwdg, sizeof(iwdg));
|
||
+ count++;
|
||
+ }
|
||
+
|
||
+ stm32_iwdg_count = count;
|
||
+
|
||
+ DMSG("%u IWDG instance%s found", count, count > 1 ? "s" : "");
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+driver_init(iwdg_init);
|
||
diff --git a/core/drivers/stm32_rtc.c b/core/drivers/stm32_rtc.c
|
||
new file mode 100644
|
||
index 0000000..1abeaab
|
||
--- /dev/null
|
||
+++ b/core/drivers/stm32_rtc.c
|
||
@@ -0,0 +1,445 @@
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
|
||
+ *
|
||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||
+ */
|
||
+
|
||
+#include <arm32.h>
|
||
+#include <drivers/stm32_rtc.h>
|
||
+#include <initcall.h>
|
||
+#include <io.h>
|
||
+#include <kernel/dt.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <libfdt.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <stm32_util.h>
|
||
+
|
||
+#define RTC_COMPAT "st,stm32mp1-rtc"
|
||
+
|
||
+#define RTC_TR 0x00
|
||
+#define RTC_DR 0x04
|
||
+#define RTC_SSR 0x08
|
||
+#define RTC_ICSR 0x0C
|
||
+#define RTC_PRER 0x10
|
||
+#define RTC_WUTR 0x14
|
||
+#define RTC_CR 0x18
|
||
+#define RTC_SMCR 0x20
|
||
+#define RTC_WPR 0x24
|
||
+#define RTC_CALR 0x28
|
||
+#define RTC_SHIFTR 0x2C
|
||
+#define RTC_TSTR 0x30
|
||
+#define RTC_TSDR 0x34
|
||
+#define RTC_TSSSR 0x38
|
||
+#define RTC_ALRMAR 0x40
|
||
+#define RTC_ALRMASSR 0x44
|
||
+#define RTC_ALRMBR 0x48
|
||
+#define RTC_ALRMBSSR 0x4C
|
||
+#define RTC_SR 0x50
|
||
+#define RTC_SCR 0x5C
|
||
+#define RTC_OR 0x60
|
||
+
|
||
+#define RTC_TR_SU_MASK GENMASK_32(3, 0)
|
||
+#define RTC_TR_ST_MASK GENMASK_32(6, 4)
|
||
+#define RTC_TR_ST_SHIFT 4
|
||
+#define RTC_TR_MNU_MASK GENMASK_32(11, 8)
|
||
+#define RTC_TR_MNU_SHIFT 8
|
||
+#define RTC_TR_MNT_MASK GENMASK_32(14, 12)
|
||
+#define RTC_TR_MNT_SHIFT 12
|
||
+#define RTC_TR_HU_MASK GENMASK_32(19, 16)
|
||
+#define RTC_TR_HU_SHIFT 16
|
||
+#define RTC_TR_HT_MASK GENMASK_32(21, 20)
|
||
+#define RTC_TR_HT_SHIFT 20
|
||
+#define RTC_TR_PM BIT(22)
|
||
+
|
||
+#define RTC_DR_DU_MASK GENMASK_32(3, 0)
|
||
+#define RTC_DR_DT_MASK GENMASK_32(5, 4)
|
||
+#define RTC_DR_DT_SHIFT 4
|
||
+#define RTC_DR_MU_MASK GENMASK_32(11, 8)
|
||
+#define RTC_DR_MU_SHIFT 8
|
||
+#define RTC_DR_MT BIT(12)
|
||
+#define RTC_DR_MT_SHIFT 12
|
||
+#define RTC_DR_WDU_MASK GENMASK_32(15, 13)
|
||
+#define RTC_DR_WDU_SHIFT 13
|
||
+#define RTC_DR_YU_MASK GENMASK_32(19, 16)
|
||
+#define RTC_DR_YU_SHIFT 16
|
||
+#define RTC_DR_YT_MASK GENMASK_32(23, 20)
|
||
+#define RTC_DR_YT_SHIFT 20
|
||
+
|
||
+#define RTC_SSR_SS_MASK GENMASK_32(15, 0)
|
||
+
|
||
+#define RTC_ICSR_RSF BIT(5)
|
||
+
|
||
+#define RTC_PRER_PREDIV_S_MASK GENMASK_32(15, 0)
|
||
+
|
||
+#define RTC_CR_BYPSHAD BIT(5)
|
||
+#define RTC_CR_BYPSHAD_SHIFT 5
|
||
+#define RTC_CR_TAMPTS BIT(25)
|
||
+
|
||
+#define RTC_SMCR_TS_DPROT BIT(3)
|
||
+#define RTC_SR_TSF BIT(3)
|
||
+#define RTC_SCR_CTSF BIT(3)
|
||
+#define RTC_SR_TSOVF BIT(4)
|
||
+#define RTC_SCR_CTSOVF BIT(4)
|
||
+
|
||
+#define RTC_TSDR_MU_MASK GENMASK_32(11, 8)
|
||
+#define RTC_TSDR_MU_SHIFT 8
|
||
+#define RTC_TSDR_DT_MASK GENMASK_32(5, 4)
|
||
+#define RTC_TSDR_DT_SHIFT 4
|
||
+#define RTC_TSDR_DU_MASK GENMASK_32(3, 0)
|
||
+#define RTC_TSDR_DU_SHIFT 0
|
||
+
|
||
+#define RTC_WPR_KEY1 0xCA
|
||
+#define RTC_WPR_KEY2 0x53
|
||
+#define RTC_WPR_KEY_LOCK 0xFF
|
||
+
|
||
+#define RTC_FLAGS_READ_TWICE BIT(0)
|
||
+#define RTC_FLAGS_SECURE BIT(1)
|
||
+
|
||
+struct rtc_device {
|
||
+ struct io_pa_va base;
|
||
+ uint16_t clock;
|
||
+ uint8_t flags;
|
||
+};
|
||
+
|
||
+/* Expect a single RTC instance */
|
||
+struct rtc_device rtc_dev;
|
||
+
|
||
+static vaddr_t get_base(void)
|
||
+{
|
||
+ assert(rtc_dev.base.pa);
|
||
+ return io_pa_or_va(&rtc_dev.base);
|
||
+}
|
||
+
|
||
+static void stm32_rtc_write_unprotect(void)
|
||
+{
|
||
+ vaddr_t rtc_base = get_base();
|
||
+
|
||
+ io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY1);
|
||
+ io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY2);
|
||
+}
|
||
+
|
||
+static void stm32_rtc_write_protect(void)
|
||
+{
|
||
+ vaddr_t rtc_base = get_base();
|
||
+
|
||
+ io_write32(rtc_base + RTC_WPR, RTC_WPR_KEY_LOCK);
|
||
+}
|
||
+
|
||
+static bool stm32_rtc_get_bypshad(void)
|
||
+{
|
||
+ return io_read32(get_base() + RTC_CR) & RTC_CR_BYPSHAD;
|
||
+}
|
||
+
|
||
+/* Get calendar data from RTC devicecalendar valueregister values */
|
||
+static void stm32_rtc_read_calendar(struct stm32_rtc_calendar *calendar)
|
||
+{
|
||
+ vaddr_t rtc_base = get_base();
|
||
+ bool bypshad = stm32_rtc_get_bypshad();
|
||
+
|
||
+ if (!bypshad) {
|
||
+ /* Shadow RTC registers */
|
||
+ io_clrbits32(rtc_base + RTC_ICSR, RTC_ICSR_RSF);
|
||
+ while (!(io_read32(rtc_base + RTC_ICSR) & RTC_ICSR_RSF))
|
||
+ ;
|
||
+ }
|
||
+
|
||
+ calendar->ssr = io_read32(rtc_base + RTC_SSR);
|
||
+ calendar->tr = io_read32(rtc_base + RTC_TR);
|
||
+ calendar->dr = io_read32(rtc_base + RTC_DR);
|
||
+}
|
||
+
|
||
+/* Fill the RTC timestamp structure from a given RTC time-in-day value */
|
||
+static void stm32_rtc_get_time(struct stm32_rtc_calendar *cal,
|
||
+ struct stm32_rtc_time *tm)
|
||
+{
|
||
+ tm->hour = (((cal->tr & RTC_TR_HT_MASK) >> RTC_TR_HT_SHIFT) * 10) +
|
||
+ ((cal->tr & RTC_TR_HU_MASK) >> RTC_TR_HU_SHIFT);
|
||
+
|
||
+ if (cal->tr & RTC_TR_PM)
|
||
+ tm->hour += 12;
|
||
+
|
||
+ tm->min = (((cal->tr & RTC_TR_MNT_MASK) >> RTC_TR_MNT_SHIFT) * 10) +
|
||
+ ((cal->tr & RTC_TR_MNU_MASK) >> RTC_TR_MNU_SHIFT);
|
||
+ tm->sec = (((cal->tr & RTC_TR_ST_MASK) >> RTC_TR_ST_SHIFT) * 10) +
|
||
+ (cal->tr & RTC_TR_SU_MASK);
|
||
+}
|
||
+
|
||
+/* Fill the RTC timestamp structure from a given RTC date value */
|
||
+static void stm32_rtc_get_date(struct stm32_rtc_calendar *cal,
|
||
+ struct stm32_rtc_time *tm)
|
||
+{
|
||
+ tm->wday = (((cal->dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT));
|
||
+
|
||
+ tm->day = (((cal->dr & RTC_DR_DT_MASK) >> RTC_DR_DT_SHIFT) * 10) +
|
||
+ (cal->dr & RTC_DR_DU_MASK);
|
||
+
|
||
+ tm->month = (((cal->dr & RTC_DR_MT) >> RTC_DR_MT_SHIFT) * 10) +
|
||
+ ((cal->dr & RTC_DR_MU_MASK) >> RTC_DR_MU_SHIFT);
|
||
+
|
||
+ tm->year = (((cal->dr & RTC_DR_YT_MASK) >> RTC_DR_YT_SHIFT) * 10) +
|
||
+ ((cal->dr & RTC_DR_YU_MASK) >> RTC_DR_YU_SHIFT) + 2000;
|
||
+}
|
||
+
|
||
+/* Update time value with RTC timestamp */
|
||
+static void stm32_rtc_read_timestamp(struct stm32_rtc_time *time)
|
||
+{
|
||
+ struct stm32_rtc_calendar cal_tamp = { };
|
||
+ vaddr_t rtc_base = get_base();
|
||
+
|
||
+ cal_tamp.tr = io_read32(rtc_base + RTC_TSTR);
|
||
+ cal_tamp.dr = io_read32(rtc_base + RTC_TSDR);
|
||
+ stm32_rtc_get_time(&cal_tamp, time);
|
||
+ stm32_rtc_get_date(&cal_tamp, time);
|
||
+}
|
||
+
|
||
+void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar)
|
||
+{
|
||
+ stm32_clock_enable(rtc_dev.clock);
|
||
+
|
||
+ stm32_rtc_read_calendar(calendar);
|
||
+
|
||
+ /* RTC may need to be read twice, depending of clocks configuration */
|
||
+ if (rtc_dev.flags & RTC_FLAGS_READ_TWICE) {
|
||
+ uint32_t tr_save = calendar->tr;
|
||
+
|
||
+ stm32_rtc_read_calendar(calendar);
|
||
+
|
||
+ if (calendar->tr != tr_save)
|
||
+ stm32_rtc_read_calendar(calendar);
|
||
+ }
|
||
+
|
||
+ stm32_clock_disable(rtc_dev.clock);
|
||
+}
|
||
+
|
||
+/* Return difference in milliseconds on second fraction */
|
||
+static uint32_t stm32_rtc_get_second_fraction(struct stm32_rtc_calendar *cal)
|
||
+{
|
||
+ uint32_t prediv_s = io_read32(get_base() + RTC_PRER) &
|
||
+ RTC_PRER_PREDIV_S_MASK;
|
||
+ uint32_t ss = cal->ssr & RTC_SSR_SS_MASK;
|
||
+
|
||
+ return ((prediv_s - ss) * 1000) / (prediv_s + 1);
|
||
+}
|
||
+
|
||
+/* Return absolute difference in milliseconds on second fraction */
|
||
+static signed long long stm32_rtc_diff_frac(struct stm32_rtc_calendar *cur,
|
||
+ struct stm32_rtc_calendar *ref)
|
||
+{
|
||
+ return (signed long long)stm32_rtc_get_second_fraction(cur) -
|
||
+ (signed long long)stm32_rtc_get_second_fraction(ref);
|
||
+}
|
||
+
|
||
+/* Return absolute difference in milliseconds on seconds-in-day fraction */
|
||
+static signed long long stm32_rtc_diff_time(struct stm32_rtc_time *current,
|
||
+ struct stm32_rtc_time *ref)
|
||
+{
|
||
+ signed long long curr_s = 0;
|
||
+ signed long long ref_s = 0;
|
||
+
|
||
+ curr_s = (signed long long)current->sec +
|
||
+ (((signed long long)current->min +
|
||
+ (((signed long long)current->hour * 60))) * 60);
|
||
+
|
||
+ ref_s = (signed long long)ref->sec +
|
||
+ (((signed long long)ref->min +
|
||
+ (((signed long long)ref->hour * 60))) * 60);
|
||
+
|
||
+ return (curr_s - ref_s) * 1000U;
|
||
+}
|
||
+
|
||
+static bool stm32_is_a_leap_year(uint32_t year)
|
||
+{
|
||
+ return ((year % 4) == 0) &&
|
||
+ (((year % 100) != 0) || ((year % 400) == 0));
|
||
+}
|
||
+
|
||
+/* Return absolute difference in milliseconds on day-in-year fraction */
|
||
+static signed long long stm32_rtc_diff_date(struct stm32_rtc_time *current,
|
||
+ struct stm32_rtc_time *ref)
|
||
+{
|
||
+ uint32_t diff_in_days = 0;
|
||
+ uint32_t m = 0;
|
||
+ const uint8_t month_len[NB_MONTHS] = {
|
||
+ 31, 28, 31, 30, 31, 30,
|
||
+ 31, 31, 30, 31, 30, 31
|
||
+ };
|
||
+
|
||
+ /* Get the number of non-entire month days */
|
||
+ if (current->day >= ref->day)
|
||
+ diff_in_days += current->day - ref->day;
|
||
+ else
|
||
+ diff_in_days += month_len[ref->month - 1] -
|
||
+ ref->day + current->day;
|
||
+
|
||
+ /* Get the number of entire months, and compute the related days */
|
||
+ if (current->month > (ref->month + 1))
|
||
+ for (m = ref->month + 1; m < current->month && m < 12; m++)
|
||
+ diff_in_days += month_len[m - 1];
|
||
+
|
||
+ if (current->month < (ref->month - 1)) {
|
||
+ for (m = 1; m < current->month && m < 12; m++)
|
||
+ diff_in_days += month_len[m - 1];
|
||
+
|
||
+ for (m = ref->month + 1; m < 12; m++)
|
||
+ diff_in_days += month_len[m - 1];
|
||
+ }
|
||
+
|
||
+ /* Get complete years */
|
||
+ if (current->year > (ref->year + 1))
|
||
+ diff_in_days += (current->year - ref->year - 1) * 365;
|
||
+
|
||
+ /* Particular cases: leap years (one day more) */
|
||
+ if (diff_in_days > 0) {
|
||
+ if (current->year == ref->year) {
|
||
+ if (stm32_is_a_leap_year(current->year) &&
|
||
+ ref->month <= 2 &&
|
||
+ current->month >= 3 && current->day <= 28)
|
||
+ diff_in_days++;
|
||
+ } else {
|
||
+ uint32_t y = 0;
|
||
+
|
||
+ /* Ref year is leap */
|
||
+ if (stm32_is_a_leap_year(ref->year) &&
|
||
+ ref->month <= 2 && ref->day <= 28)
|
||
+ diff_in_days++;
|
||
+
|
||
+ /* Current year is leap */
|
||
+ if (stm32_is_a_leap_year(current->year) &&
|
||
+ current->month >= 3)
|
||
+ diff_in_days++;
|
||
+
|
||
+ /* Interleaved years are leap */
|
||
+ for (y = ref->year + 1; y < current->year; y++)
|
||
+ if (stm32_is_a_leap_year(y))
|
||
+ diff_in_days++;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return (24 * 60 * 60 * 1000) * (signed long long)diff_in_days;
|
||
+}
|
||
+
|
||
+unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *cur,
|
||
+ struct stm32_rtc_calendar *ref)
|
||
+{
|
||
+ signed long long diff_in_ms = 0;
|
||
+ struct stm32_rtc_time curr_t = { };
|
||
+ struct stm32_rtc_time ref_t = { };
|
||
+
|
||
+ stm32_rtc_get_date(cur, &curr_t);
|
||
+ stm32_rtc_get_date(ref, &ref_t);
|
||
+ stm32_rtc_get_time(cur, &curr_t);
|
||
+ stm32_rtc_get_time(ref, &ref_t);
|
||
+
|
||
+ diff_in_ms += stm32_rtc_diff_frac(cur, ref);
|
||
+ diff_in_ms += stm32_rtc_diff_time(&curr_t, &ref_t);
|
||
+ diff_in_ms += stm32_rtc_diff_date(&curr_t, &ref_t);
|
||
+
|
||
+ return (unsigned long long)diff_in_ms;
|
||
+}
|
||
+
|
||
+void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts)
|
||
+{
|
||
+ vaddr_t rtc_base = get_base();
|
||
+
|
||
+ stm32_clock_enable(rtc_dev.clock);
|
||
+
|
||
+ if (io_read32(rtc_base + RTC_SR) & RTC_SR_TSF) {
|
||
+ /* Timestamp for tamper event */
|
||
+ stm32_rtc_read_timestamp(tamp_ts);
|
||
+ io_setbits32(rtc_base + RTC_SCR, RTC_SCR_CTSF);
|
||
+
|
||
+ /* Overflow detection */
|
||
+ if (io_read32(rtc_base + RTC_SR) & RTC_SR_TSOVF)
|
||
+ io_setbits32(rtc_base + RTC_SCR, RTC_SCR_CTSOVF);
|
||
+ }
|
||
+
|
||
+ stm32_clock_disable(rtc_dev.clock);
|
||
+}
|
||
+
|
||
+void stm32_rtc_set_tamper_timestamp(void)
|
||
+{
|
||
+ vaddr_t rtc_base = get_base();
|
||
+
|
||
+ stm32_clock_enable(rtc_dev.clock);
|
||
+
|
||
+ stm32_rtc_write_unprotect();
|
||
+
|
||
+ /* Enable tamper timestamper */
|
||
+ io_setbits32(rtc_base + RTC_CR, RTC_CR_TAMPTS);
|
||
+
|
||
+ /* Secure Timestamp bit */
|
||
+ io_clrbits32(rtc_base + RTC_SMCR, RTC_SMCR_TS_DPROT);
|
||
+
|
||
+ stm32_rtc_write_protect();
|
||
+
|
||
+ stm32_clock_disable(rtc_dev.clock);
|
||
+}
|
||
+
|
||
+bool stm32_rtc_is_timestamp_enable(void)
|
||
+{
|
||
+ bool ret = false;
|
||
+
|
||
+ stm32_clock_enable(rtc_dev.clock);
|
||
+
|
||
+ ret = io_read32(get_base() + RTC_CR) & RTC_CR_TAMPTS;
|
||
+
|
||
+ stm32_clock_disable(rtc_dev.clock);
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
+#ifdef CFG_DT
|
||
+static unsigned int get_second_clock(void *fdt, int offs)
|
||
+{
|
||
+ const fdt32_t *cuint = NULL;
|
||
+ int len = 0;
|
||
+
|
||
+ cuint = fdt_getprop(fdt, offs, "clocks", &len);
|
||
+ if (len == 3) {
|
||
+ EMSG("RTC expects 2 clocks, %d found", len);
|
||
+ return DT_INFO_INVALID_CLOCK;
|
||
+ }
|
||
+
|
||
+ return fdt32_to_cpu(*(cuint + 3));
|
||
+}
|
||
+
|
||
+static TEE_Result stm32_rtc_init(void)
|
||
+{
|
||
+ int node = 0;
|
||
+ struct dt_node_info dt_info = { };
|
||
+ void *fdt = get_embedded_dt();
|
||
+
|
||
+ if (!fdt)
|
||
+ panic();
|
||
+
|
||
+ node = fdt_node_offset_by_compatible(fdt, -1, RTC_COMPAT);
|
||
+ if (node < 0)
|
||
+ return TEE_SUCCESS;
|
||
+
|
||
+ _fdt_fill_device_info(fdt, &dt_info, node);
|
||
+
|
||
+ rtc_dev.base.pa = dt_info.reg;
|
||
+
|
||
+ if (dt_info.status == DT_STATUS_OK_SEC) {
|
||
+ rtc_dev.flags |= RTC_FLAGS_SECURE;
|
||
+ stm32mp_register_secure_periph_iomem(rtc_dev.base.pa);
|
||
+ rtc_dev.base.va = (vaddr_t)phys_to_virt(rtc_dev.base.pa,
|
||
+ MEM_AREA_IO_SEC);
|
||
+ /* Unbalanced clock enable: keep RTC running */
|
||
+ stm32_clock_enable(get_second_clock(fdt, node));
|
||
+ } else {
|
||
+ stm32mp_register_non_secure_periph_iomem(rtc_dev.base.pa);
|
||
+ rtc_dev.base.va = (vaddr_t)phys_to_virt(rtc_dev.base.pa,
|
||
+ MEM_AREA_IO_NSEC);
|
||
+ }
|
||
+
|
||
+ rtc_dev.clock = (unsigned long)dt_info.clock;
|
||
+
|
||
+ if (stm32_rtc_get_read_twice())
|
||
+ rtc_dev.flags |= RTC_FLAGS_READ_TWICE;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+driver_init(stm32_rtc_init);
|
||
+#endif
|
||
diff --git a/core/drivers/stm32_tim.c b/core/drivers/stm32_tim.c
|
||
new file mode 100644
|
||
index 0000000..612fbbc
|
||
--- /dev/null
|
||
+++ b/core/drivers/stm32_tim.c
|
||
@@ -0,0 +1,286 @@
|
||
+// SPDX-License-Identifier: BSD-3-Clause
|
||
+/*
|
||
+ * Copyright (c) 2018, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#include <arm.h>
|
||
+#include <drivers/serial.h>
|
||
+#include <drivers/stm32_tim.h>
|
||
+#include <initcall.h>
|
||
+#include <io.h>
|
||
+#include <keep.h>
|
||
+#include <kernel/delay.h>
|
||
+#include <kernel/dt.h>
|
||
+#include <kernel/generic_boot.h>
|
||
+#include <kernel/panic.h>
|
||
+#include <libfdt.h>
|
||
+#include <mm/core_memprot.h>
|
||
+#include <stm32_util.h>
|
||
+
|
||
+#define TIM_CR1 0x00 /* Control Register 1 */
|
||
+#define TIM_CR2 0x04 /* Control Register 2 */
|
||
+#define TIM_SMCR 0x08 /* Slave mode control reg */
|
||
+#define TIM_DIER 0x0C /* DMA/interrupt register */
|
||
+#define TIM_SR 0x10 /* Status register */
|
||
+#define TIM_EGR 0x14 /* Event Generation Reg */
|
||
+#define TIM_CCMR1 0x18 /* Capt/Comp 1 Mode Reg */
|
||
+#define TIM_CCMR2 0x1C /* Capt/Comp 2 Mode Reg */
|
||
+#define TIM_CCER 0x20 /* Capt/Comp Enable Reg */
|
||
+#define TIM_CNT 0x24 /* Counter */
|
||
+#define TIM_PSC 0x28 /* Prescaler */
|
||
+#define TIM_ARR 0x2C /* Auto-Reload Register */
|
||
+#define TIM_CCR1 0x34 /* Capt/Comp Register 1 */
|
||
+#define TIM_CCR2 0x38 /* Capt/Comp Register 2 */
|
||
+#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */
|
||
+#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */
|
||
+#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */
|
||
+#define TIM_DCR 0x48 /* DMA control register */
|
||
+#define TIM_DMAR 0x4C /* DMA transfer register */
|
||
+#define TIM_AF1 0x60 /* Alt Function Reg 1 */
|
||
+#define TIM_AF2 0x64 /* Alt Function Reg 2 */
|
||
+#define TIM_TISEL 0x68 /* Input Selection */
|
||
+
|
||
+#define TIM_CR1_CEN BIT(0)
|
||
+#define TIM_SMCR_SMS GENMASK_32(2, 0) /* Slave mode selection */
|
||
+#define TIM_SMCR_TS GENMASK_32(6, 4) /* Trigger selection */
|
||
+#define TIM_CCMR_CC1S_TI1 BIT(0) /* IC1/IC3 selects TI1/TI3 */
|
||
+#define TIM_CCMR_CC1S_TI2 BIT(1) /* IC1/IC3 selects TI2/TI4 */
|
||
+#define TIM_CCMR_CC2S_TI2 BIT(8) /* IC2/IC4 selects TI2/TI4 */
|
||
+#define TIM_CCMR_CC2S_TI1 BIT(9) /* IC2/IC4 selects TI1/TI3 */
|
||
+#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */
|
||
+#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */
|
||
+#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */
|
||
+#define TIM_SR_UIF BIT(0) /* UIF interrupt flag */
|
||
+#define TIM_SR_CC1IF BIT(1) /* CC1 interrupt flag */
|
||
+#define TIM_TISEL_TI1SEL_MASK GENMASK_32(3, 0)
|
||
+#define TIM_SMCR_SMS_RESET BIT(2)
|
||
+#define TIM_SMCR_TS_SHIFT 4
|
||
+#define TIM_SMCR_TS_TI1FP1 0x5
|
||
+
|
||
+#define TIM_COMPAT "st,stm32-timers"
|
||
+#define TIM_TIMEOUT_US 100000
|
||
+#define TIM_TIMEOUT_STEP_US 10
|
||
+#define TIM_PRESCAL_HSI 10
|
||
+#define TIM_PRESCAL_CSI 7
|
||
+#define TIM_MIN_FREQ_CALIB 50000000U
|
||
+
|
||
+struct stm32_tim_instance {
|
||
+ struct io_pa_va base;
|
||
+ unsigned long clk;
|
||
+ unsigned long freq;
|
||
+ uint8_t cal_input;
|
||
+};
|
||
+
|
||
+static vaddr_t timer_base(struct stm32_tim_instance *timer)
|
||
+{
|
||
+ return io_pa_or_va(&timer->base);
|
||
+}
|
||
+
|
||
+/* Currently support HSI and CSI calibratrion */
|
||
+#define TIM_MAX_INSTANCE 2
|
||
+static struct stm32_tim_instance stm32_tim[TIM_MAX_INSTANCE];
|
||
+
|
||
+static int timer_get_dt_node(void *fdt, struct dt_node_info *info, int offset)
|
||
+{
|
||
+ int node = fdt_node_offset_by_compatible(fdt, offset, TIM_COMPAT);
|
||
+
|
||
+ if (node < 0)
|
||
+ return -FDT_ERR_NOTFOUND;
|
||
+
|
||
+ _fdt_fill_device_info(fdt, info, node);
|
||
+
|
||
+ return node;
|
||
+}
|
||
+
|
||
+static int timer_config(struct stm32_tim_instance *timer)
|
||
+{
|
||
+ vaddr_t base = timer_base(timer);
|
||
+
|
||
+ stm32_clock_enable(timer->clk);
|
||
+
|
||
+ timer->freq = stm32_clock_get_rate(timer->clk);
|
||
+ if (timer->freq < TIM_MIN_FREQ_CALIB) {
|
||
+ EMSG("Calibration: timer not accurate enough");
|
||
+ stm32_clock_disable(timer->clk);
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
+ if ((io_read32(base + TIM_TISEL) & TIM_TISEL_TI1SEL_MASK) !=
|
||
+ timer->cal_input) {
|
||
+ io_clrsetbits32(base + TIM_CCMR1,
|
||
+ TIM_CCMR_CC1S_TI1 | TIM_CCMR_CC1S_TI2,
|
||
+ TIM_CCMR_CC1S_TI1);
|
||
+
|
||
+ io_clrbits32(base + TIM_CCER,
|
||
+ TIM_CCER_CC1P | TIM_CCER_CC1NP);
|
||
+
|
||
+ io_clrsetbits32(base + TIM_SMCR,
|
||
+ TIM_SMCR_TS | TIM_SMCR_SMS,
|
||
+ (TIM_SMCR_TS_TI1FP1 << TIM_SMCR_TS_SHIFT) |
|
||
+ TIM_SMCR_SMS_RESET);
|
||
+
|
||
+ io_write32(base + TIM_TISEL, timer->cal_input);
|
||
+ io_setbits32(base + TIM_CR1, TIM_CR1_CEN);
|
||
+ io_setbits32(base + TIM_CCER, TIM_CCER_CC1E);
|
||
+ }
|
||
+
|
||
+ stm32_clock_disable(timer->clk);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static uint32_t timer_start_capture(struct stm32_tim_instance *timer)
|
||
+{
|
||
+ uint64_t timeout_ref = 0;
|
||
+ uint32_t counter = 0;
|
||
+ uint32_t old_counter = 0;
|
||
+ int twice = 0;
|
||
+ vaddr_t base = timer_base(timer);
|
||
+
|
||
+ if (timer_config(timer))
|
||
+ return 0;
|
||
+
|
||
+ stm32_clock_enable(timer->clk);
|
||
+
|
||
+ io_write32(base + TIM_SR, 0);
|
||
+
|
||
+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US);
|
||
+
|
||
+ while (!timeout_elapsed(timeout_ref))
|
||
+ if (io_read32(base + TIM_SR) & TIM_SR_UIF)
|
||
+ break;
|
||
+ if (!(io_read32(base + TIM_SR) & TIM_SR_UIF))
|
||
+ goto bail;
|
||
+
|
||
+ io_write32(base + TIM_SR, 0);
|
||
+
|
||
+ for (twice = 0; (twice < 2) || (counter != old_counter); twice++) {
|
||
+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US);
|
||
+ while (!timeout_elapsed(timeout_ref))
|
||
+ if (io_read32(base + TIM_SR) & TIM_SR_CC1IF)
|
||
+ break;
|
||
+ if (!(io_read32(base + TIM_SR) & TIM_SR_CC1IF)) {
|
||
+ counter = 0;
|
||
+ goto bail;
|
||
+ }
|
||
+
|
||
+ old_counter = counter;
|
||
+ counter = io_read32(base + TIM_CCR1);
|
||
+ }
|
||
+
|
||
+bail:
|
||
+ stm32_clock_disable(timer->clk);
|
||
+
|
||
+ return counter;
|
||
+}
|
||
+
|
||
+unsigned long stm32_tim_hsi_freq(void)
|
||
+{
|
||
+ struct stm32_tim_instance *timer = &stm32_tim[HSI_CAL];
|
||
+ uint32_t counter = 0;
|
||
+
|
||
+ if (timer->base.pa)
|
||
+ counter = timer_start_capture(timer);
|
||
+
|
||
+ if (!counter)
|
||
+ return 0;
|
||
+
|
||
+ return (timer->freq / counter) << TIM_PRESCAL_HSI;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_tim_hsi_freq);
|
||
+
|
||
+unsigned long stm32_tim_csi_freq(void)
|
||
+{
|
||
+ struct stm32_tim_instance *timer = &stm32_tim[CSI_CAL];
|
||
+ uint32_t counter = 0;
|
||
+
|
||
+ if (timer->base.pa)
|
||
+ counter = timer_start_capture(timer);
|
||
+
|
||
+ if (!counter)
|
||
+ return 0;
|
||
+
|
||
+ return (timer->freq / counter) << TIM_PRESCAL_CSI;
|
||
+}
|
||
+DECLARE_KEEP_PAGER(stm32_tim_csi_freq);
|
||
+
|
||
+static void _init_stm32_tim(void)
|
||
+{
|
||
+ void *fdt = get_embedded_dt();
|
||
+ struct dt_node_info dt_timer = { };
|
||
+ int node = -1;
|
||
+ static bool inited;
|
||
+
|
||
+ if (inited)
|
||
+ return;
|
||
+ inited = true;
|
||
+
|
||
+ if (!fdt)
|
||
+ panic();
|
||
+
|
||
+ for (node = timer_get_dt_node(fdt, &dt_timer, node);
|
||
+ node != -FDT_ERR_NOTFOUND;
|
||
+ node = timer_get_dt_node(fdt, &dt_timer, node)) {
|
||
+ struct stm32_tim_instance *timer = NULL;
|
||
+ const uint32_t *cuint = NULL;
|
||
+
|
||
+ if (!(dt_timer.status & DT_STATUS_OK_SEC))
|
||
+ continue;
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, "st,hsi-cal-input", NULL);
|
||
+ if (cuint) {
|
||
+ timer = &stm32_tim[HSI_CAL];
|
||
+ timer->base.pa = dt_timer.reg;
|
||
+ timer->clk = dt_timer.clock;
|
||
+ timer->freq = stm32_clock_get_rate(timer->clk);
|
||
+ timer->cal_input = fdt32_to_cpu(*cuint);
|
||
+ if (timer_config(timer)) {
|
||
+ timer->base.pa = 0;
|
||
+ continue;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ cuint = fdt_getprop(fdt, node, "st,csi-cal-input", NULL);
|
||
+ if (cuint) {
|
||
+ timer = &stm32_tim[CSI_CAL];
|
||
+ timer->base.pa = dt_timer.reg;
|
||
+ timer->clk = dt_timer.clock;
|
||
+ timer->freq = stm32_clock_get_rate(timer->clk);
|
||
+ timer->cal_input = fdt32_to_cpu(*cuint);
|
||
+ if (timer_config(timer)) {
|
||
+ timer->base.pa = 0;
|
||
+ continue;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+void stm32_tim_freq_func(unsigned long (**timer_freq_cb)(void),
|
||
+ enum stm32_tim_cal type)
|
||
+{
|
||
+ _init_stm32_tim();
|
||
+
|
||
+ *timer_freq_cb = NULL;
|
||
+
|
||
+ switch (type) {
|
||
+ case HSI_CAL:
|
||
+ if (stm32_tim[HSI_CAL].base.pa)
|
||
+ *timer_freq_cb = stm32_tim_hsi_freq;
|
||
+ break;
|
||
+
|
||
+ case CSI_CAL:
|
||
+ if (stm32_tim[CSI_CAL].base.pa)
|
||
+ *timer_freq_cb = stm32_tim_csi_freq;
|
||
+ break;
|
||
+ default:
|
||
+ panic();
|
||
+ }
|
||
+}
|
||
+
|
||
+static TEE_Result init_stm32_tim(void)
|
||
+{
|
||
+ _init_stm32_tim();
|
||
+
|
||
+ return TEE_SUCCESS;
|
||
+}
|
||
+driver_init(init_stm32_tim);
|
||
diff --git a/core/drivers/sub.mk b/core/drivers/sub.mk
|
||
index f9e03b5..2216b63 100644
|
||
--- a/core/drivers/sub.mk
|
||
+++ b/core/drivers/sub.mk
|
||
@@ -25,7 +25,10 @@ srcs-$(CFG_STM32_BSEC) += stm32_bsec.c
|
||
srcs-$(CFG_STM32_ETZPC) += stm32_etzpc.c
|
||
srcs-$(CFG_STM32_GPIO) += stm32_gpio.c
|
||
srcs-$(CFG_STM32_I2C) += stm32_i2c.c
|
||
+srcs-$(CFG_STM32_IWDG) += stm32_iwdg.c
|
||
srcs-$(CFG_STM32_RNG) += stm32_rng.c
|
||
+srcs-$(CFG_STM32_RTC) += stm32_rtc.c
|
||
+srcs-$(CFG_STM32_TIM) += stm32_tim.c
|
||
srcs-$(CFG_STM32_UART) += stm32_uart.c
|
||
srcs-$(CFG_STPMIC1) += stpmic1.c
|
||
srcs-$(CFG_BCM_HWRNG) += bcm_hwrng.c
|
||
diff --git a/core/include/drivers/gic.h b/core/include/drivers/gic.h
|
||
index f9bb28e..c8da6d8 100644
|
||
--- a/core/include/drivers/gic.h
|
||
+++ b/core/include/drivers/gic.h
|
||
@@ -9,17 +9,38 @@
|
||
#include <types_ext.h>
|
||
#include <kernel/interrupt.h>
|
||
|
||
+/* Constants to categorize priorities */
|
||
+#define GIC_HIGHEST_SEC_PRIORITY 0x0U
|
||
+#define GIC_LOWEST_SEC_PRIORITY 0x7fU
|
||
+#define GIC_HIGHEST_NS_PRIORITY 0x80U
|
||
+#define GIC_LOWEST_NS_PRIORITY 0xfeU
|
||
+/* 0xff would disable all interrupts */
|
||
+
|
||
#define GIC_DIST_REG_SIZE 0x10000
|
||
#define GIC_CPU_REG_SIZE 0x10000
|
||
#define GIC_SGI(x) (x)
|
||
#define GIC_PPI(x) ((x) + 16)
|
||
#define GIC_SPI(x) ((x) + 32)
|
||
|
||
+/*
|
||
+ * Save and restore some interrupts configuration during low power sequences.
|
||
+ * This is used on platforms using OP-TEE secure monitor.
|
||
+ */
|
||
+struct gic_it_pm;
|
||
+
|
||
+struct gic_pm {
|
||
+ struct gic_it_pm *pm_cfg;
|
||
+ size_t count;
|
||
+};
|
||
+
|
||
struct gic_data {
|
||
vaddr_t gicc_base;
|
||
vaddr_t gicd_base;
|
||
size_t max_it;
|
||
struct itr_chip chip;
|
||
+#if defined(CFG_ARM_GIC_PM)
|
||
+ struct gic_pm pm;
|
||
+#endif
|
||
};
|
||
|
||
/*
|
||
@@ -31,6 +52,9 @@ void gic_init(struct gic_data *gd, vaddr_t gicc_base, vaddr_t gicd_base);
|
||
/* initial base address only */
|
||
void gic_init_base_addr(struct gic_data *gd, vaddr_t gicc_base,
|
||
vaddr_t gicd_base);
|
||
+/* Setup GIC default configuration */
|
||
+void gic_init_setup(struct gic_data *gd);
|
||
+
|
||
/* initial cpu if only, mainly use for secondary cpu setup cpu interface */
|
||
void gic_cpu_init(struct gic_data *gd);
|
||
|
||
diff --git a/core/include/drivers/stm32_bsec.h b/core/include/drivers/stm32_bsec.h
|
||
index dfb0d47..d284eea 100644
|
||
--- a/core/include/drivers/stm32_bsec.h
|
||
+++ b/core/include/drivers/stm32_bsec.h
|
||
@@ -10,6 +10,12 @@
|
||
#include <stdint.h>
|
||
#include <tee_api.h>
|
||
|
||
+/* BSEC_DEBUG */
|
||
+#define BSEC_HDPEN BIT(4)
|
||
+#define BSEC_SPIDEN BIT(5)
|
||
+#define BSEC_SPINDEN BIT(6)
|
||
+#define BSEC_DBGSWGEN BIT(10)
|
||
+
|
||
/*
|
||
* Load OTP from SAFMEM and provide its value
|
||
* @value: Output read value
|
||
@@ -155,4 +161,14 @@ TEE_Result stm32_bsec_otp_lock(uint32_t service);
|
||
*/
|
||
bool stm32_bsec_nsec_can_access_otp(uint32_t otp_id);
|
||
|
||
+/*
|
||
+ * Find and get OTP location from its name.
|
||
+ * @name: sub-node name to look up.
|
||
+ * @otp_id: pointer to read OTP number or NULL.
|
||
+ * @otp_bit_len: pointer to read OTP length in bits or NULL.
|
||
+ * Return a TEE_Result compliant status
|
||
+ */
|
||
+TEE_Result stm32_bsec_find_otp_in_nvmem_layout(const char *name,
|
||
+ uint32_t *otp_id,
|
||
+ size_t *otp_bit_len);
|
||
#endif /*__STM32_BSEC_H*/
|
||
diff --git a/core/include/drivers/stm32_iwdg.h b/core/include/drivers/stm32_iwdg.h
|
||
new file mode 100644
|
||
index 0000000..f063258
|
||
--- /dev/null
|
||
+++ b/core/include/drivers/stm32_iwdg.h
|
||
@@ -0,0 +1,17 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
|
||
+ */
|
||
+
|
||
+#ifndef __STM32_IWDG_H__
|
||
+#define __STM32_IWDG_H__
|
||
+
|
||
+#include <stdint.h>
|
||
+
|
||
+#define IWDG_HW_ENABLED BIT(0)
|
||
+#define IWDG_DISABLE_ON_STOP BIT(1)
|
||
+#define IWDG_DISABLE_ON_STANDBY BIT(2)
|
||
+
|
||
+void stm32_iwdg_refresh(unsigned int instance);
|
||
+
|
||
+#endif /*__STM32_IWDG_H__*/
|
||
diff --git a/core/include/drivers/stm32_rtc.h b/core/include/drivers/stm32_rtc.h
|
||
new file mode 100644
|
||
index 0000000..b0f4ef8
|
||
--- /dev/null
|
||
+++ b/core/include/drivers/stm32_rtc.h
|
||
@@ -0,0 +1,60 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
|
||
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||
+ */
|
||
+
|
||
+#ifndef __PLAT_RTC_H__
|
||
+#define __PLAT_RTC_H__
|
||
+
|
||
+#include <stdbool.h>
|
||
+
|
||
+struct stm32_rtc_calendar {
|
||
+ uint32_t ssr;
|
||
+ uint32_t tr;
|
||
+ uint32_t dr;
|
||
+};
|
||
+
|
||
+enum months {
|
||
+ JANUARY = 1,
|
||
+ FEBRUARY,
|
||
+ MARCH,
|
||
+ APRIL,
|
||
+ MAY,
|
||
+ JUNE,
|
||
+ JULY,
|
||
+ AUGUST,
|
||
+ SEPTEMBER,
|
||
+ OCTOBER,
|
||
+ NOVEMBER,
|
||
+ DECEMBER,
|
||
+ NB_MONTHS = 12
|
||
+};
|
||
+
|
||
+struct stm32_rtc_time {
|
||
+ uint32_t hour;
|
||
+ uint32_t min;
|
||
+ uint32_t sec;
|
||
+ uint32_t wday;
|
||
+ uint32_t day;
|
||
+ enum months month;
|
||
+ uint32_t year;
|
||
+};
|
||
+
|
||
+/* Get calendar formated time from RTC device */
|
||
+void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar);
|
||
+
|
||
+/* Return time diff in milliseconds between current and reference time */
|
||
+unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *cur,
|
||
+ struct stm32_rtc_calendar *ref);
|
||
+
|
||
+/* Enable tamper and secure timestamp access in RTC */
|
||
+void stm32_rtc_set_tamper_timestamp(void);
|
||
+
|
||
+/* Retrun true if and only if RTC timestamp is enable */
|
||
+bool stm32_rtc_is_timestamp_enable(void);
|
||
+
|
||
+/* Get RTC timestamp for current time */
|
||
+void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts);
|
||
+
|
||
+#endif /* __PLAT_RTC_H__ */
|
||
diff --git a/core/include/drivers/stm32_tim.h b/core/include/drivers/stm32_tim.h
|
||
new file mode 100644
|
||
index 0000000..2373561
|
||
--- /dev/null
|
||
+++ b/core/include/drivers/stm32_tim.h
|
||
@@ -0,0 +1,25 @@
|
||
+/* SPDX-License-Identifier: BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (c) 2018-2019, STMicroelectronics
|
||
+ */
|
||
+
|
||
+#ifndef STM32_TIM_H
|
||
+#define STM32_TIM_H
|
||
+
|
||
+enum stm32_tim_cal {
|
||
+ HSI_CAL = 0,
|
||
+ CSI_CAL
|
||
+};
|
||
+
|
||
+unsigned long stm32_tim_hsi_freq(void);
|
||
+unsigned long stm32_tim_csi_freq(void);
|
||
+
|
||
+/*
|
||
+ * Get the timer frequence callback function for a target clock calibration
|
||
+ * @timer_freq_cb - Output callback function
|
||
+ * @type - Target clock calibration ID
|
||
+ */
|
||
+void stm32_tim_freq_func(unsigned long (**timer_freq_cb)(void),
|
||
+ enum stm32_tim_cal type);
|
||
+
|
||
+#endif /* STM32_TIM_H */
|
||
diff --git a/core/include/dt-bindings/clock/stm32mp1-clksrc.h b/core/include/dt-bindings/clock/stm32mp1-clksrc.h
|
||
new file mode 100644
|
||
index 0000000..de7d160
|
||
--- /dev/null
|
||
+++ b/core/include/dt-bindings/clock/stm32mp1-clksrc.h
|
||
@@ -0,0 +1,284 @@
|
||
+/*
|
||
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||
+ *
|
||
+ * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause
|
||
+ */
|
||
+
|
||
+#ifndef _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
|
||
+#define _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
|
||
+
|
||
+/* PLL output is enable when x=1, with x=p,q or r */
|
||
+#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
|
||
+
|
||
+/* st,clksrc: mandatory clock source */
|
||
+
|
||
+#define CLK_MPU_HSI 0x00000200
|
||
+#define CLK_MPU_HSE 0x00000201
|
||
+#define CLK_MPU_PLL1P 0x00000202
|
||
+#define CLK_MPU_PLL1P_DIV 0x00000203
|
||
+
|
||
+#define CLK_AXI_HSI 0x00000240
|
||
+#define CLK_AXI_HSE 0x00000241
|
||
+#define CLK_AXI_PLL2P 0x00000242
|
||
+
|
||
+#define CLK_MCU_HSI 0x00000480
|
||
+#define CLK_MCU_HSE 0x00000481
|
||
+#define CLK_MCU_CSI 0x00000482
|
||
+#define CLK_MCU_PLL3P 0x00000483
|
||
+
|
||
+#define CLK_PLL12_HSI 0x00000280
|
||
+#define CLK_PLL12_HSE 0x00000281
|
||
+
|
||
+#define CLK_PLL3_HSI 0x00008200
|
||
+#define CLK_PLL3_HSE 0x00008201
|
||
+#define CLK_PLL3_CSI 0x00008202
|
||
+
|
||
+#define CLK_PLL4_HSI 0x00008240
|
||
+#define CLK_PLL4_HSE 0x00008241
|
||
+#define CLK_PLL4_CSI 0x00008242
|
||
+#define CLK_PLL4_I2SCKIN 0x00008243
|
||
+
|
||
+#define CLK_RTC_DISABLED 0x00001400
|
||
+#define CLK_RTC_LSE 0x00001401
|
||
+#define CLK_RTC_LSI 0x00001402
|
||
+#define CLK_RTC_HSE 0x00001403
|
||
+
|
||
+#define CLK_MCO1_HSI 0x00008000
|
||
+#define CLK_MCO1_HSE 0x00008001
|
||
+#define CLK_MCO1_CSI 0x00008002
|
||
+#define CLK_MCO1_LSI 0x00008003
|
||
+#define CLK_MCO1_LSE 0x00008004
|
||
+#define CLK_MCO1_DISABLED 0x0000800F
|
||
+
|
||
+#define CLK_MCO2_MPU 0x00008040
|
||
+#define CLK_MCO2_AXI 0x00008041
|
||
+#define CLK_MCO2_MCU 0x00008042
|
||
+#define CLK_MCO2_PLL4P 0x00008043
|
||
+#define CLK_MCO2_HSE 0x00008044
|
||
+#define CLK_MCO2_HSI 0x00008045
|
||
+#define CLK_MCO2_DISABLED 0x0000804F
|
||
+
|
||
+/* st,pkcs: peripheral kernel clock source */
|
||
+
|
||
+#define CLK_I2C12_PCLK1 0x00008C00
|
||
+#define CLK_I2C12_PLL4R 0x00008C01
|
||
+#define CLK_I2C12_HSI 0x00008C02
|
||
+#define CLK_I2C12_CSI 0x00008C03
|
||
+#define CLK_I2C12_DISABLED 0x00008C07
|
||
+
|
||
+#define CLK_I2C35_PCLK1 0x00008C40
|
||
+#define CLK_I2C35_PLL4R 0x00008C41
|
||
+#define CLK_I2C35_HSI 0x00008C42
|
||
+#define CLK_I2C35_CSI 0x00008C43
|
||
+#define CLK_I2C35_DISABLED 0x00008C47
|
||
+
|
||
+#define CLK_I2C46_PCLK5 0x00000C00
|
||
+#define CLK_I2C46_PLL3Q 0x00000C01
|
||
+#define CLK_I2C46_HSI 0x00000C02
|
||
+#define CLK_I2C46_CSI 0x00000C03
|
||
+#define CLK_I2C46_DISABLED 0x00000C07
|
||
+
|
||
+#define CLK_SAI1_PLL4Q 0x00008C80
|
||
+#define CLK_SAI1_PLL3Q 0x00008C81
|
||
+#define CLK_SAI1_I2SCKIN 0x00008C82
|
||
+#define CLK_SAI1_CKPER 0x00008C83
|
||
+#define CLK_SAI1_PLL3R 0x00008C84
|
||
+#define CLK_SAI1_DISABLED 0x00008C87
|
||
+
|
||
+#define CLK_SAI2_PLL4Q 0x00008CC0
|
||
+#define CLK_SAI2_PLL3Q 0x00008CC1
|
||
+#define CLK_SAI2_I2SCKIN 0x00008CC2
|
||
+#define CLK_SAI2_CKPER 0x00008CC3
|
||
+#define CLK_SAI2_SPDIF 0x00008CC4
|
||
+#define CLK_SAI2_PLL3R 0x00008CC5
|
||
+#define CLK_SAI2_DISABLED 0x00008CC7
|
||
+
|
||
+#define CLK_SAI3_PLL4Q 0x00008D00
|
||
+#define CLK_SAI3_PLL3Q 0x00008D01
|
||
+#define CLK_SAI3_I2SCKIN 0x00008D02
|
||
+#define CLK_SAI3_CKPER 0x00008D03
|
||
+#define CLK_SAI3_PLL3R 0x00008D04
|
||
+#define CLK_SAI3_DISABLED 0x00008D07
|
||
+
|
||
+#define CLK_SAI4_PLL4Q 0x00008D40
|
||
+#define CLK_SAI4_PLL3Q 0x00008D41
|
||
+#define CLK_SAI4_I2SCKIN 0x00008D42
|
||
+#define CLK_SAI4_CKPER 0x00008D43
|
||
+#define CLK_SAI4_PLL3R 0x00008D44
|
||
+#define CLK_SAI4_DISABLED 0x00008D47
|
||
+
|
||
+#define CLK_SPI2S1_PLL4P 0x00008D80
|
||
+#define CLK_SPI2S1_PLL3Q 0x00008D81
|
||
+#define CLK_SPI2S1_I2SCKIN 0x00008D82
|
||
+#define CLK_SPI2S1_CKPER 0x00008D83
|
||
+#define CLK_SPI2S1_PLL3R 0x00008D84
|
||
+#define CLK_SPI2S1_DISABLED 0x00008D87
|
||
+
|
||
+#define CLK_SPI2S23_PLL4P 0x00008DC0
|
||
+#define CLK_SPI2S23_PLL3Q 0x00008DC1
|
||
+#define CLK_SPI2S23_I2SCKIN 0x00008DC2
|
||
+#define CLK_SPI2S23_CKPER 0x00008DC3
|
||
+#define CLK_SPI2S23_PLL3R 0x00008DC4
|
||
+#define CLK_SPI2S23_DISABLED 0x00008DC7
|
||
+
|
||
+#define CLK_SPI45_PCLK2 0x00008E00
|
||
+#define CLK_SPI45_PLL4Q 0x00008E01
|
||
+#define CLK_SPI45_HSI 0x00008E02
|
||
+#define CLK_SPI45_CSI 0x00008E03
|
||
+#define CLK_SPI45_HSE 0x00008E04
|
||
+#define CLK_SPI45_DISABLED 0x00008E07
|
||
+
|
||
+#define CLK_SPI6_PCLK5 0x00000C40
|
||
+#define CLK_SPI6_PLL4Q 0x00000C41
|
||
+#define CLK_SPI6_HSI 0x00000C42
|
||
+#define CLK_SPI6_CSI 0x00000C43
|
||
+#define CLK_SPI6_HSE 0x00000C44
|
||
+#define CLK_SPI6_PLL3Q 0x00000C45
|
||
+#define CLK_SPI6_DISABLED 0x00000C47
|
||
+
|
||
+#define CLK_UART6_PCLK2 0x00008E40
|
||
+#define CLK_UART6_PLL4Q 0x00008E41
|
||
+#define CLK_UART6_HSI 0x00008E42
|
||
+#define CLK_UART6_CSI 0x00008E43
|
||
+#define CLK_UART6_HSE 0x00008E44
|
||
+#define CLK_UART6_DISABLED 0x00008E47
|
||
+
|
||
+#define CLK_UART24_PCLK1 0x00008E80
|
||
+#define CLK_UART24_PLL4Q 0x00008E81
|
||
+#define CLK_UART24_HSI 0x00008E82
|
||
+#define CLK_UART24_CSI 0x00008E83
|
||
+#define CLK_UART24_HSE 0x00008E84
|
||
+#define CLK_UART24_DISABLED 0x00008E87
|
||
+
|
||
+#define CLK_UART35_PCLK1 0x00008EC0
|
||
+#define CLK_UART35_PLL4Q 0x00008EC1
|
||
+#define CLK_UART35_HSI 0x00008EC2
|
||
+#define CLK_UART35_CSI 0x00008EC3
|
||
+#define CLK_UART35_HSE 0x00008EC4
|
||
+#define CLK_UART35_DISABLED 0x00008EC7
|
||
+
|
||
+#define CLK_UART78_PCLK1 0x00008F00
|
||
+#define CLK_UART78_PLL4Q 0x00008F01
|
||
+#define CLK_UART78_HSI 0x00008F02
|
||
+#define CLK_UART78_CSI 0x00008F03
|
||
+#define CLK_UART78_HSE 0x00008F04
|
||
+#define CLK_UART78_DISABLED 0x00008F07
|
||
+
|
||
+#define CLK_UART1_PCLK5 0x00000C80
|
||
+#define CLK_UART1_PLL3Q 0x00000C81
|
||
+#define CLK_UART1_HSI 0x00000C82
|
||
+#define CLK_UART1_CSI 0x00000C83
|
||
+#define CLK_UART1_PLL4Q 0x00000C84
|
||
+#define CLK_UART1_HSE 0x00000C85
|
||
+#define CLK_UART1_DISABLED 0x00000C87
|
||
+
|
||
+#define CLK_SDMMC12_HCLK6 0x00008F40
|
||
+#define CLK_SDMMC12_PLL3R 0x00008F41
|
||
+#define CLK_SDMMC12_PLL4P 0x00008F42
|
||
+#define CLK_SDMMC12_HSI 0x00008F43
|
||
+#define CLK_SDMMC12_DISABLED 0x00008F47
|
||
+
|
||
+#define CLK_SDMMC3_HCLK2 0x00008F80
|
||
+#define CLK_SDMMC3_PLL3R 0x00008F81
|
||
+#define CLK_SDMMC3_PLL4P 0x00008F82
|
||
+#define CLK_SDMMC3_HSI 0x00008F83
|
||
+#define CLK_SDMMC3_DISABLED 0x00008F87
|
||
+
|
||
+#define CLK_ETH_PLL4P 0x00008FC0
|
||
+#define CLK_ETH_PLL3Q 0x00008FC1
|
||
+#define CLK_ETH_DISABLED 0x00008FC3
|
||
+
|
||
+#define CLK_QSPI_ACLK 0x00009000
|
||
+#define CLK_QSPI_PLL3R 0x00009001
|
||
+#define CLK_QSPI_PLL4P 0x00009002
|
||
+#define CLK_QSPI_CKPER 0x00009003
|
||
+
|
||
+#define CLK_FMC_ACLK 0x00009040
|
||
+#define CLK_FMC_PLL3R 0x00009041
|
||
+#define CLK_FMC_PLL4P 0x00009042
|
||
+#define CLK_FMC_CKPER 0x00009043
|
||
+
|
||
+#define CLK_FDCAN_HSE 0x000090C0
|
||
+#define CLK_FDCAN_PLL3Q 0x000090C1
|
||
+#define CLK_FDCAN_PLL4Q 0x000090C2
|
||
+#define CLK_FDCAN_PLL4R 0x000090C3
|
||
+
|
||
+#define CLK_SPDIF_PLL4P 0x00009140
|
||
+#define CLK_SPDIF_PLL3Q 0x00009141
|
||
+#define CLK_SPDIF_HSI 0x00009142
|
||
+#define CLK_SPDIF_DISABLED 0x00009143
|
||
+
|
||
+#define CLK_CEC_LSE 0x00009180
|
||
+#define CLK_CEC_LSI 0x00009181
|
||
+#define CLK_CEC_CSI_DIV122 0x00009182
|
||
+#define CLK_CEC_DISABLED 0x00009183
|
||
+
|
||
+#define CLK_USBPHY_HSE 0x000091C0
|
||
+#define CLK_USBPHY_PLL4R 0x000091C1
|
||
+#define CLK_USBPHY_HSE_DIV2 0x000091C2
|
||
+#define CLK_USBPHY_DISABLED 0x000091C3
|
||
+
|
||
+#define CLK_USBO_PLL4R 0x800091C0
|
||
+#define CLK_USBO_USBPHY 0x800091C1
|
||
+
|
||
+#define CLK_RNG1_CSI 0x00000CC0
|
||
+#define CLK_RNG1_PLL4R 0x00000CC1
|
||
+#define CLK_RNG1_LSE 0x00000CC2
|
||
+#define CLK_RNG1_LSI 0x00000CC3
|
||
+
|
||
+#define CLK_RNG2_CSI 0x00009200
|
||
+#define CLK_RNG2_PLL4R 0x00009201
|
||
+#define CLK_RNG2_LSE 0x00009202
|
||
+#define CLK_RNG2_LSI 0x00009203
|
||
+
|
||
+#define CLK_CKPER_HSI 0x00000D00
|
||
+#define CLK_CKPER_CSI 0x00000D01
|
||
+#define CLK_CKPER_HSE 0x00000D02
|
||
+#define CLK_CKPER_DISABLED 0x00000D03
|
||
+
|
||
+#define CLK_STGEN_HSI 0x00000D40
|
||
+#define CLK_STGEN_HSE 0x00000D41
|
||
+#define CLK_STGEN_DISABLED 0x00000D43
|
||
+
|
||
+#define CLK_DSI_DSIPLL 0x00009240
|
||
+#define CLK_DSI_PLL4P 0x00009241
|
||
+
|
||
+#define CLK_ADC_PLL4R 0x00009280
|
||
+#define CLK_ADC_CKPER 0x00009281
|
||
+#define CLK_ADC_PLL3Q 0x00009282
|
||
+#define CLK_ADC_DISABLED 0x00009283
|
||
+
|
||
+#define CLK_LPTIM45_PCLK3 0x000092C0
|
||
+#define CLK_LPTIM45_PLL4P 0x000092C1
|
||
+#define CLK_LPTIM45_PLL3Q 0x000092C2
|
||
+#define CLK_LPTIM45_LSE 0x000092C3
|
||
+#define CLK_LPTIM45_LSI 0x000092C4
|
||
+#define CLK_LPTIM45_CKPER 0x000092C5
|
||
+#define CLK_LPTIM45_DISABLED 0x000092C7
|
||
+
|
||
+#define CLK_LPTIM23_PCLK3 0x00009300
|
||
+#define CLK_LPTIM23_PLL4Q 0x00009301
|
||
+#define CLK_LPTIM23_CKPER 0x00009302
|
||
+#define CLK_LPTIM23_LSE 0x00009303
|
||
+#define CLK_LPTIM23_LSI 0x00009304
|
||
+#define CLK_LPTIM23_DISABLED 0x00009307
|
||
+
|
||
+#define CLK_LPTIM1_PCLK1 0x00009340
|
||
+#define CLK_LPTIM1_PLL4P 0x00009341
|
||
+#define CLK_LPTIM1_PLL3Q 0x00009342
|
||
+#define CLK_LPTIM1_LSE 0x00009343
|
||
+#define CLK_LPTIM1_LSI 0x00009344
|
||
+#define CLK_LPTIM1_CKPER 0x00009345
|
||
+#define CLK_LPTIM1_DISABLED 0x00009347
|
||
+
|
||
+/* define for st,pll /csg */
|
||
+#define SSCG_MODE_CENTER_SPREAD 0
|
||
+#define SSCG_MODE_DOWN_SPREAD 1
|
||
+
|
||
+/* define for st,drive */
|
||
+#define LSEDRV_LOWEST 0
|
||
+#define LSEDRV_MEDIUM_LOW 1
|
||
+#define LSEDRV_MEDIUM_HIGH 2
|
||
+#define LSEDRV_HIGHEST 3
|
||
+
|
||
+#endif
|
||
diff --git a/core/include/dt-bindings/power/stm32mp1-power.h b/core/include/dt-bindings/power/stm32mp1-power.h
|
||
new file mode 100644
|
||
index 0000000..bfb7f78
|
||
--- /dev/null
|
||
+++ b/core/include/dt-bindings/power/stm32mp1-power.h
|
||
@@ -0,0 +1,19 @@
|
||
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
|
||
+/*
|
||
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
||
+ * Author: Yann Gautier <yann.gautier@st.com> for STMicroelectronics.
|
||
+ */
|
||
+
|
||
+#ifndef DT_BINDINGS_STM32MP1_POWER_H
|
||
+#define DT_BINDINGS_STM32MP1_POWER_H
|
||
+
|
||
+#define STM32_PM_CSLEEP_RUN 0
|
||
+#define STM32_PM_CSTOP_ALLOW_STOP 1
|
||
+#define STM32_PM_CSTOP_ALLOW_LP_STOP 2
|
||
+#define STM32_PM_CSTOP_ALLOW_LPLV_STOP 3
|
||
+#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR 4
|
||
+#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF 5
|
||
+#define STM32_PM_SHUTDOWN 6
|
||
+#define STM32_PM_MAX_SOC_MODE 7
|
||
+
|
||
+#endif /* DT_BINDINGS_STM32MP1_POWER_H */
|
||
diff --git a/core/include/dt-bindings/soc/st,stm32-etzpc.h b/core/include/dt-bindings/soc/st,stm32-etzpc.h
|
||
new file mode 100644
|
||
index 0000000..6678b8e
|
||
--- /dev/null
|
||
+++ b/core/include/dt-bindings/soc/st,stm32-etzpc.h
|
||
@@ -0,0 +1,107 @@
|
||
+/*
|
||
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||
+ *
|
||
+ * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause
|
||
+ */
|
||
+
|
||
+#ifndef _DT_BINDINGS_STM32_ETZPC_H
|
||
+#define _DT_BINDINGS_STM32_ETZPC_H
|
||
+
|
||
+/* define DECPROT modes */
|
||
+#define DECPROT_S_RW 0x0
|
||
+#define DECPROT_NS_R_S_W 0x1
|
||
+#define DECPROT_MCU_ISOLATION 0x2
|
||
+#define DECPROT_NS_RW 0x3
|
||
+
|
||
+/* define DECPROT lock */
|
||
+#define DECPROT_UNLOCK 0x0
|
||
+#define DECPROT_LOCK 0x1
|
||
+
|
||
+/* define ETZPC ID */
|
||
+#define STM32MP1_ETZPC_STGENC_ID 0
|
||
+#define STM32MP1_ETZPC_BKPSRAM_ID 1
|
||
+#define STM32MP1_ETZPC_IWDG1_ID 2
|
||
+#define STM32MP1_ETZPC_USART1_ID 3
|
||
+#define STM32MP1_ETZPC_SPI6_ID 4
|
||
+#define STM32MP1_ETZPC_I2C4_ID 5
|
||
+#define STM32MP1_ETZPC_RNG1_ID 7
|
||
+#define STM32MP1_ETZPC_HASH1_ID 8
|
||
+#define STM32MP1_ETZPC_CRYP1_ID 9
|
||
+#define STM32MP1_ETZPC_DDRCTRL_ID 10
|
||
+#define STM32MP1_ETZPC_DDRPHYC_ID 11
|
||
+#define STM32MP1_ETZPC_I2C6_ID 12
|
||
+#define STM32MP1_ETZPC_TIM2_ID 16
|
||
+#define STM32MP1_ETZPC_TIM3_ID 17
|
||
+#define STM32MP1_ETZPC_TIM4_ID 18
|
||
+#define STM32MP1_ETZPC_TIM5_ID 19
|
||
+#define STM32MP1_ETZPC_TIM6_ID 20
|
||
+#define STM32MP1_ETZPC_TIM7_ID 21
|
||
+#define STM32MP1_ETZPC_TIM12_ID 22
|
||
+#define STM32MP1_ETZPC_TIM13_ID 23
|
||
+#define STM32MP1_ETZPC_TIM14_ID 24
|
||
+#define STM32MP1_ETZPC_LPTIM1_ID 25
|
||
+#define STM32MP1_ETZPC_WWDG1_ID 26
|
||
+#define STM32MP1_ETZPC_SPI2_ID 27
|
||
+#define STM32MP1_ETZPC_SPI3_ID 28
|
||
+#define STM32MP1_ETZPC_SPDIFRX_ID 29
|
||
+#define STM32MP1_ETZPC_USART2_ID 30
|
||
+#define STM32MP1_ETZPC_USART3_ID 31
|
||
+#define STM32MP1_ETZPC_UART4_ID 32
|
||
+#define STM32MP1_ETZPC_UART5_ID 33
|
||
+#define STM32MP1_ETZPC_I2C1_ID 34
|
||
+#define STM32MP1_ETZPC_I2C2_ID 35
|
||
+#define STM32MP1_ETZPC_I2C3_ID 36
|
||
+#define STM32MP1_ETZPC_I2C5_ID 37
|
||
+#define STM32MP1_ETZPC_CEC_ID 38
|
||
+#define STM32MP1_ETZPC_DAC_ID 39
|
||
+#define STM32MP1_ETZPC_UART7_ID 40
|
||
+#define STM32MP1_ETZPC_UART8_ID 41
|
||
+#define STM32MP1_ETZPC_MDIOS_ID 44
|
||
+#define STM32MP1_ETZPC_TIM1_ID 48
|
||
+#define STM32MP1_ETZPC_TIM8_ID 49
|
||
+#define STM32MP1_ETZPC_USART6_ID 51
|
||
+#define STM32MP1_ETZPC_SPI1_ID 52
|
||
+#define STM32MP1_ETZPC_SPI4_ID 53
|
||
+#define STM32MP1_ETZPC_TIM15_ID 54
|
||
+#define STM32MP1_ETZPC_TIM16_ID 55
|
||
+#define STM32MP1_ETZPC_TIM17_ID 56
|
||
+#define STM32MP1_ETZPC_SPI5_ID 57
|
||
+#define STM32MP1_ETZPC_SAI1_ID 58
|
||
+#define STM32MP1_ETZPC_SAI2_ID 59
|
||
+#define STM32MP1_ETZPC_SAI3_ID 60
|
||
+#define STM32MP1_ETZPC_DFSDM_ID 61
|
||
+#define STM32MP1_ETZPC_TT_FDCAN_ID 62
|
||
+#define STM32MP1_ETZPC_LPTIM2_ID 64
|
||
+#define STM32MP1_ETZPC_LPTIM3_ID 65
|
||
+#define STM32MP1_ETZPC_LPTIM4_ID 66
|
||
+#define STM32MP1_ETZPC_LPTIM5_ID 67
|
||
+#define STM32MP1_ETZPC_SAI4_ID 68
|
||
+#define STM32MP1_ETZPC_VREFBUF_ID 69
|
||
+#define STM32MP1_ETZPC_DCMI_ID 70
|
||
+#define STM32MP1_ETZPC_CRC2_ID 71
|
||
+#define STM32MP1_ETZPC_ADC_ID 72
|
||
+#define STM32MP1_ETZPC_HASH2_ID 73
|
||
+#define STM32MP1_ETZPC_RNG2_ID 74
|
||
+#define STM32MP1_ETZPC_CRYP2_ID 75
|
||
+#define STM32MP1_ETZPC_SRAM1_ID 80
|
||
+#define STM32MP1_ETZPC_SRAM2_ID 81
|
||
+#define STM32MP1_ETZPC_SRAM3_ID 82
|
||
+#define STM32MP1_ETZPC_SRAM4_ID 83
|
||
+#define STM32MP1_ETZPC_RETRAM_ID 84
|
||
+#define STM32MP1_ETZPC_OTG_ID 85
|
||
+#define STM32MP1_ETZPC_SDMMC3_ID 86
|
||
+#define STM32MP1_ETZPC_DLYBSD3_ID 87
|
||
+#define STM32MP1_ETZPC_DMA1_ID 88
|
||
+#define STM32MP1_ETZPC_DMA2_ID 89
|
||
+#define STM32MP1_ETZPC_DMAMUX_ID 90
|
||
+#define STM32MP1_ETZPC_FMC_ID 91
|
||
+#define STM32MP1_ETZPC_QSPI_ID 92
|
||
+#define STM32MP1_ETZPC_DLYBQ_ID 93
|
||
+#define STM32MP1_ETZPC_ETH_ID 94
|
||
+
|
||
+#define STM32MP1_ETZPC_MAX_ID 96
|
||
+
|
||
+#define DECPROT(id, mode, lock) (((id) << 16) | ((mode) << 8) | (lock))
|
||
+
|
||
+#endif /* _DT_BINDINGS_STM32_ETZPC_H */
|
||
+
|
||
diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h
|
||
index 849e987..796eded 100644
|
||
--- a/core/include/kernel/interrupt.h
|
||
+++ b/core/include/kernel/interrupt.h
|
||
@@ -25,6 +25,11 @@ struct itr_ops {
|
||
uint8_t cpu_mask);
|
||
void (*set_affinity)(struct itr_chip *chip, size_t it,
|
||
uint8_t cpu_mask);
|
||
+#if !defined(CFG_ARM_GICV3)
|
||
+ uint8_t (*set_pmr)(struct itr_chip *chip, uint8_t mask);
|
||
+ uint8_t (*set_ipriority)(struct itr_chip *chip, size_t it,
|
||
+ uint8_t mask);
|
||
+#endif
|
||
};
|
||
|
||
enum itr_return {
|
||
@@ -66,4 +71,14 @@ void itr_set_affinity(size_t it, uint8_t cpu_mask);
|
||
*/
|
||
void itr_core_handler(void);
|
||
|
||
+/*
|
||
+ * Set the Priority Mask Regarding and return its previous value
|
||
+ */
|
||
+uint8_t itr_set_pmr(uint8_t mask);
|
||
+
|
||
+/*
|
||
+ * Set the targe tinterrupt priority mask and return its previous value
|
||
+ */
|
||
+uint8_t itr_set_ipriority(size_t it, uint8_t mask);
|
||
+
|
||
#endif /*__KERNEL_INTERRUPT_H*/
|
||
diff --git a/core/include/kernel/panic.h b/core/include/kernel/panic.h
|
||
index b9a56dc..0f0d079 100644
|
||
--- a/core/include/kernel/panic.h
|
||
+++ b/core/include/kernel/panic.h
|
||
@@ -8,6 +8,12 @@
|
||
|
||
#include <compiler.h>
|
||
|
||
+/*
|
||
+ * Platform can define a panic sequence to trap cpu/reset core or system
|
||
+ * after eventual debug trace.
|
||
+ */
|
||
+void plat_panic(void);
|
||
+
|
||
/* debug disabled => __FILE__, ... and panic message are not built. */
|
||
#if defined(CFG_TEE_CORE_DEBUG)
|
||
#define __panic(str) __do_panic(__FILE__, __LINE__, __func__, str)
|
||
diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c
|
||
index 961ce6b..3760125 100644
|
||
--- a/core/kernel/interrupt.c
|
||
+++ b/core/kernel/interrupt.c
|
||
@@ -88,3 +88,13 @@ void __weak __noreturn itr_core_handler(void)
|
||
{
|
||
panic("Secure interrupt handler not defined");
|
||
}
|
||
+
|
||
+uint8_t itr_set_pmr(uint8_t mask)
|
||
+{
|
||
+ return itr_chip->ops->set_pmr(itr_chip, mask);
|
||
+}
|
||
+
|
||
+uint8_t itr_set_ipriority(size_t it, uint8_t mask)
|
||
+{
|
||
+ return itr_chip->ops->set_ipriority(itr_chip, it, mask);
|
||
+}
|
||
diff --git a/core/kernel/panic.c b/core/kernel/panic.c
|
||
index 37e30a8..460ef90 100644
|
||
--- a/core/kernel/panic.c
|
||
+++ b/core/kernel/panic.c
|
||
@@ -6,8 +6,21 @@
|
||
|
||
#include <kernel/panic.h>
|
||
#include <kernel/thread.h>
|
||
+#include <stdbool.h>
|
||
#include <trace.h>
|
||
|
||
+static void __noreturn stall_cpu(void)
|
||
+{
|
||
+ while (true)
|
||
+ ;
|
||
+}
|
||
+
|
||
+void __weak __noreturn plat_panic(void)
|
||
+{
|
||
+ /* abort current execution */
|
||
+ stall_cpu();
|
||
+}
|
||
+
|
||
void __do_panic(const char *file __maybe_unused,
|
||
const int line __maybe_unused,
|
||
const char *func __maybe_unused,
|
||
@@ -16,8 +29,6 @@ void __do_panic(const char *file __maybe_unused,
|
||
/* disable prehemption */
|
||
(void)thread_mask_exceptions(THREAD_EXCP_ALL);
|
||
|
||
- /* TODO: notify other cores */
|
||
-
|
||
/* trace: Panic ['panic-string-message' ]at FILE:LINE [<FUNCTION>]" */
|
||
if (!file && !func && !msg)
|
||
EMSG_RAW("Panic");
|
||
@@ -28,7 +39,9 @@ void __do_panic(const char *file __maybe_unused,
|
||
func ? "<" : "", func ? func : "", func ? ">" : "");
|
||
|
||
EPRINT_STACK();
|
||
- /* abort current execution */
|
||
- while (1)
|
||
- ;
|
||
+
|
||
+ plat_panic();
|
||
+
|
||
+ EMSG("platform failed to abord execution");
|
||
+ stall_cpu();
|
||
}
|
||
diff --git a/mk/config.mk b/mk/config.mk
|
||
index c00a146..bc49f83 100644
|
||
--- a/mk/config.mk
|
||
+++ b/mk/config.mk
|
||
@@ -116,7 +116,7 @@ endif
|
||
# with limited depth not including any tag, so there is really no guarantee
|
||
# that TEE_IMPL_VERSION contains the major and minor revision numbers.
|
||
CFG_OPTEE_REVISION_MAJOR ?= 3
|
||
-CFG_OPTEE_REVISION_MINOR ?= 8
|
||
+CFG_OPTEE_REVISION_MINOR ?= 9
|
||
|
||
# Trusted OS implementation manufacturer name
|
||
CFG_TEE_MANUFACTURER ?= LINARO
|
||
--
|
||
2.7.4
|
||
|