From patchwork Mon May 25 10:19:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246488 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:41 +0200 Subject: [PATCH v2 1/9] arm: stm32mp: spl: add bsec driver in SPL In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-2-patrick.delaunay@st.com> Add the bsec driver in SPL, as it is needed by SOC part number detection to found the supported OPP. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- Changes in v2: None arch/arm/dts/stm32mp15-u-boot.dtsi | 2 +- arch/arm/mach-stm32mp/Makefile | 2 +- arch/arm/mach-stm32mp/bsec.c | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi index 1279589a56..a0d971ad88 100644 --- a/arch/arm/dts/stm32mp15-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi @@ -65,7 +65,7 @@ }; &bsec { - u-boot,dm-pre-proper; + u-boot,dm-pre-reloc; }; &clk_csi { diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile index 66bb8cf92f..c8aa24d489 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -6,12 +6,12 @@ obj-y += cpu.o obj-y += dram_init.o obj-y += syscon.o +obj-y += bsec.o ifdef CONFIG_SPL_BUILD obj-y += spl.o else obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ -obj-y += bsec.o obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o obj-$(CONFIG_ARMV7_PSCI) += psci.o obj-$(CONFIG_TFABOOT) += boot_params.o diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 0d5850b4a9..98a950c640 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -473,20 +473,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev) return 0; } -#ifndef CONFIG_TFABOOT static int stm32mp_bsec_probe(struct udevice *dev) { +#if !defined(CONFIG_TFABOOT) && !defined(CONFIG_SPL_BUILD) int otp; struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); - /* update unlocked shadow for OTP cleared by the rom code */ + /* + * update unlocked shadow for OTP cleared by the rom code + * only executed in U-Boot proper when TF-A is not used + */ for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++) if (!bsec_read_SR_lock(plat->base, otp)) bsec_shadow_register(plat->base, otp); +#endif return 0; } -#endif static const struct udevice_id stm32mp_bsec_ids[] = { { .compatible = "st,stm32mp15-bsec" }, @@ -500,7 +503,5 @@ U_BOOT_DRIVER(stm32mp_bsec) = { .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata), .ops = &stm32mp_bsec_ops, -#ifndef CONFIG_TFABOOT .probe = stm32mp_bsec_probe, -#endif }; From patchwork Mon May 25 10:19:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246490 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:42 +0200 Subject: [PATCH v2 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-3-patrick.delaunay@st.com> This commit adds cpufreq support on stm32mp15x SOC. STM32 cpufreq uses operating points V2 bindings (no legacy). Nvmem cells have to be used to know the chip version and then which OPPs are available. Note that STM32 cpufreq driver is mainly based on "cpufreq-dt" driver. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- Changes in v2: None arch/arm/dts/stm32mp151.dtsi | 21 +++++++++++++++++++++ arch/arm/dts/stm32mp157c-ed1.dts | 8 ++++++++ arch/arm/dts/stm32mp15xx-dkx.dtsi | 8 ++++++++ 3 files changed, 37 insertions(+) diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi index 75d2c0d296..d5216a1831 100644 --- a/arch/arm/dts/stm32mp151.dtsi +++ b/arch/arm/dts/stm32mp151.dtsi @@ -20,6 +20,24 @@ clock-frequency = <650000000>; device_type = "cpu"; reg = <0>; + 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; + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + opp-microvolt = <1200000>; + opp-supported-hw = <0x1>; + }; + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1350000>; + opp-supported-hw = <0x2>; }; }; @@ -1522,6 +1540,9 @@ reg = <0x5c005000 0x400>; #address-cells = <1>; #size-cells = <1>; + part_number_otp: part_number_otp at 4 { + reg = <0x4 0x1>; + }; ts_cal1: calib at 5c { reg = <0x5c 0x2>; }; diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts index 4fb71100f5..9996704b59 100644 --- a/arch/arm/dts/stm32mp157c-ed1.dts +++ b/arch/arm/dts/stm32mp157c-ed1.dts @@ -112,6 +112,14 @@ }; }; +&cpu0{ + cpu-supply = <&vddcore>; +}; + +&cpu1{ + cpu-supply = <&vddcore>; +}; + &dac { pinctrl-names = "default"; pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi index 812e370ee4..906bd4282c 100644 --- a/arch/arm/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi @@ -121,6 +121,14 @@ status = "okay"; }; +&cpu0{ + cpu-supply = <&vddcore>; +}; + +&cpu1{ + cpu-supply = <&vddcore>; +}; + ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; From patchwork Mon May 25 10:19:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246492 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:43 +0200 Subject: [PATCH v2 3/9] board: st: create common file stpmic1.c In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-4-patrick.delaunay@st.com> Move function board_ddr_power_init() in a new file stpmic1 in board/st/common to avoid duplicated code in each board using stpmic1 Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- Changes in v2: None board/dhelectronics/dh_stm32mp1/Makefile | 2 +- board/st/common/Makefile | 1 + board/st/common/stpmic1.c | 162 +++++++++++++++++++++++ board/st/stm32mp1/board.c | 158 ---------------------- 4 files changed, 164 insertions(+), 159 deletions(-) create mode 100644 board/st/common/stpmic1.c diff --git a/board/dhelectronics/dh_stm32mp1/Makefile b/board/dhelectronics/dh_stm32mp1/Makefile index e8f218da08..5758d9816b 100644 --- a/board/dhelectronics/dh_stm32mp1/Makefile +++ b/board/dhelectronics/dh_stm32mp1/Makefile @@ -7,7 +7,7 @@ ifdef CONFIG_SPL_BUILD obj-y += ../../st/stm32mp1/spl.o endif -obj-y += ../../st/stm32mp1/board.o board.o +obj-y += ../../st/common/stpmic1.o board.o obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += ../../st/common/stm32mp_mtdparts.o obj-$(CONFIG_SET_DFU_ALT_INFO) += ../../st/common/stm32mp_dfu.o diff --git a/board/st/common/Makefile b/board/st/common/Makefile index aa030bacd8..012bfbbe8e 100644 --- a/board/st/common/Makefile +++ b/board/st/common/Makefile @@ -4,6 +4,7 @@ # obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o +obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o ifeq ($(CONFIG_ARCH_STM32MP),y) obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += stm32mp_mtdparts.o diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c new file mode 100644 index 0000000000..ca10a2246b --- /dev/null +++ b/board/st/common/stpmic1.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include +#include +#include +#include +#include + +int board_ddr_power_init(enum ddr_type ddr_type) +{ + struct udevice *dev; + bool buck3_at_1800000v = false; + int ret; + u32 buck2; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_stpmic1), &dev); + if (ret) + /* No PMIC on board */ + return 0; + + switch (ddr_type) { + case STM32MP_DDR3: + /* VTT = Set LDO3 to sync mode */ + ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); + if (ret < 0) + return ret; + + ret &= ~STPMIC1_LDO3_MODE; + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL); + + ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + ret); + if (ret < 0) + return ret; + + /* VDD_DDR = Set BUCK2 to 1.35V */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, + STPMIC1_BUCK2_1350000V); + if (ret < 0) + return ret; + + /* Enable VDD_DDR = BUCK2 */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VREF */ + ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VTT = LDO3 */ + ret = pmic_clrsetbits(dev, + STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + break; + + case STM32MP_LPDDR2_16: + case STM32MP_LPDDR2_32: + case STM32MP_LPDDR3_16: + case STM32MP_LPDDR3_32: + /* + * configure VDD_DDR1 = LDO3 + * Set LDO3 to 1.8V + * + bypass mode if BUCK3 = 1.8V + * + normal mode if BUCK3 != 1.8V + */ + ret = pmic_reg_read(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3)); + if (ret < 0) + return ret; + + if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V) + buck3_at_1800000v = true; + + ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); + if (ret < 0) + return ret; + + ret &= ~STPMIC1_LDO3_MODE; + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO3_1800000; + if (buck3_at_1800000v) + ret |= STPMIC1_LDO3_MODE; + + ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + ret); + if (ret < 0) + return ret; + + /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/ + switch (ddr_type) { + case STM32MP_LPDDR2_32: + case STM32MP_LPDDR3_32: + buck2 = STPMIC1_BUCK2_1250000V; + break; + default: + case STM32MP_LPDDR2_16: + case STM32MP_LPDDR3_16: + buck2 = STPMIC1_BUCK2_1200000V; + break; + } + + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, + buck2); + if (ret < 0) + return ret; + + /* Enable VDD_DDR1 = LDO3 */ + ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VDD_DDR2 =BUCK2 */ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + /* Enable VREF */ + ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); + if (ret < 0) + return ret; + + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); + + break; + + default: + break; + }; + + return 0; +} diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c index 4e35d36c76..1887941e57 100644 --- a/board/st/stm32mp1/board.c +++ b/board/st/stm32mp1/board.c @@ -4,11 +4,7 @@ */ #include -#include #include -#include -#include -#include #ifdef CONFIG_DEBUG_UART_BOARD_INIT void board_debug_uart_init(void) @@ -36,157 +32,3 @@ void board_debug_uart_init(void) #endif } #endif - -#ifdef CONFIG_PMIC_STPMIC1 -int board_ddr_power_init(enum ddr_type ddr_type) -{ - struct udevice *dev; - bool buck3_at_1800000v = false; - int ret; - u32 buck2; - - ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmic1), &dev); - if (ret) - /* No PMIC on board */ - return 0; - - switch (ddr_type) { - case STM32MP_DDR3: - /* VTT = Set LDO3 to sync mode */ - ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); - if (ret < 0) - return ret; - - ret &= ~STPMIC1_LDO3_MODE; - ret &= ~STPMIC1_LDO12356_VOUT_MASK; - ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL); - - ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), - ret); - if (ret < 0) - return ret; - - /* VDD_DDR = Set BUCK2 to 1.35V */ - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_VOUT_MASK, - STPMIC1_BUCK2_1350000V); - if (ret < 0) - return ret; - - /* Enable VDD_DDR = BUCK2 */ - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - /* Enable VREF */ - ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, - STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - /* Enable VTT = LDO3 */ - ret = pmic_clrsetbits(dev, - STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), - STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - break; - - case STM32MP_LPDDR2_16: - case STM32MP_LPDDR2_32: - case STM32MP_LPDDR3_16: - case STM32MP_LPDDR3_32: - /* - * configure VDD_DDR1 = LDO3 - * Set LDO3 to 1.8V - * + bypass mode if BUCK3 = 1.8V - * + normal mode if BUCK3 != 1.8V - */ - ret = pmic_reg_read(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3)); - if (ret < 0) - return ret; - - if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V) - buck3_at_1800000v = true; - - ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); - if (ret < 0) - return ret; - - ret &= ~STPMIC1_LDO3_MODE; - ret &= ~STPMIC1_LDO12356_VOUT_MASK; - ret |= STPMIC1_LDO3_1800000; - if (buck3_at_1800000v) - ret |= STPMIC1_LDO3_MODE; - - ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), - ret); - if (ret < 0) - return ret; - - /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/ - switch (ddr_type) { - case STM32MP_LPDDR2_32: - case STM32MP_LPDDR3_32: - buck2 = STPMIC1_BUCK2_1250000V; - break; - default: - case STM32MP_LPDDR2_16: - case STM32MP_LPDDR3_16: - buck2 = STPMIC1_BUCK2_1200000V; - break; - } - - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_VOUT_MASK, - buck2); - if (ret < 0) - return ret; - - /* Enable VDD_DDR1 = LDO3 */ - ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), - STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - /* Enable VDD_DDR2 =BUCK2 */ - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - /* Enable VREF */ - ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, - STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); - if (ret < 0) - return ret; - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - - break; - - default: - break; - }; - - return 0; -} -#endif From patchwork Mon May 25 10:19:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246494 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:44 +0200 Subject: [PATCH v2 4/9] stm32mp1: clk: configure pll1 with OPP In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-5-patrick.delaunay@st.com> The PLL1 node (st,pll1) is optional in device tree, the max supported frequency define in OPP node is used when the node is absent. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- Changes in v2: None .../clock/st,stm32mp1.txt | 4 + drivers/clk/clk_stm32mp1.c | 290 ++++++++++++++++-- 2 files changed, 266 insertions(+), 28 deletions(-) diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt index a3d427911d..4d4136d2fc 100644 --- a/doc/device-tree-bindings/clock/st,stm32mp1.txt +++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt @@ -87,6 +87,10 @@ Optional Properties: are listed with associated reg 0 to 3. PLLx is off when the associated node is absent or deactivated. + For PLL1, when the node is absent, the frequency of the OPP node is used + to compute the PLL setting (see compatible "operating-points-v2" in + opp/opp.txt for details). + Here are the available properties for each PLL node: - compatible: should be "st,stm32mp1-pll" diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index 0d0ea43fd2..b48c835bc3 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -641,8 +642,18 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { }; #ifdef STM32MP1_CLOCK_TREE_INIT + /* define characteristic of PLL according type */ +#define DIVM_MIN 0 +#define DIVM_MAX 63 #define DIVN_MIN 24 +#define DIVP_MIN 0 +#define DIVP_MAX 127 +#define FRAC_MAX 8192 + +#define PLL1600_VCO_MIN 800000000 +#define PLL1600_VCO_MAX 1600000000 + static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { [PLL_800] = { .refclk_min = 4, @@ -1187,6 +1198,208 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk) } #ifdef STM32MP1_CLOCK_TREE_INIT + +bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type) +{ + unsigned int id; + + switch (opp_id) { + case 1: + case 2: + id = opp_id; + break; + default: + id = 1; /* default value */ + break; + } + + switch (cpu_type) { + case CPU_STM32MP157Fxx: + case CPU_STM32MP157Dxx: + case CPU_STM32MP153Fxx: + case CPU_STM32MP153Dxx: + case CPU_STM32MP151Fxx: + case CPU_STM32MP151Dxx: + return true; + default: + return id == 1; + } +} + +/* + * gets OPP parameters (frequency in KHz and voltage in mV) from + * an OPP table subnode. Platform HW support capabilities are also checked. + * Returns 0 on success and a negative FDT error code on failure. + */ +static int stm32mp1_get_opp(u32 cpu_type, ofnode subnode, + u32 *freq_khz, u32 *voltage_mv) +{ + u32 opp_hw; + u64 read_freq_64; + u32 read_voltage_32; + + *freq_khz = 0; + *voltage_mv = 0; + + opp_hw = ofnode_read_u32_default(subnode, "opp-supported-hw", 0); + if (opp_hw) + if (!stm32mp1_supports_opp(opp_hw, cpu_type)) + return -FDT_ERR_BADVALUE; + + read_freq_64 = ofnode_read_u64_default(subnode, "opp-hz", 0) / + 1000ULL; + read_voltage_32 = ofnode_read_u32_default(subnode, "opp-microvolt", 0) / + 1000U; + + if (!read_voltage_32 || !read_freq_64) + return -FDT_ERR_NOTFOUND; + + /* Frequency value expressed in KHz must fit on 32 bits */ + if (read_freq_64 > U32_MAX) + return -FDT_ERR_BADVALUE; + + /* Millivolt value must fit on 16 bits */ + if (read_voltage_32 > U16_MAX) + return -FDT_ERR_BADVALUE; + + *freq_khz = (u32)read_freq_64; + *voltage_mv = read_voltage_32; + + return 0; +} + +/* + * parses OPP table in DT and finds the parameters for the + * highest frequency supported by the HW platform. + * Returns 0 on success and a negative FDT error code on failure. + */ +int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz) +{ + ofnode node, subnode; + int ret; + u32 freq = 0U, voltage = 0U; + u32 cpu_type = get_cpu_type(); + + node = ofnode_by_compatible(ofnode_null(), "operating-points-v2"); + if (!ofnode_valid(node)) + return -FDT_ERR_NOTFOUND; + + ofnode_for_each_subnode(subnode, node) { + unsigned int read_freq; + unsigned int read_voltage; + + ret = stm32mp1_get_opp(cpu_type, subnode, + &read_freq, &read_voltage); + if (ret) + continue; + + if (read_freq > freq) { + freq = read_freq; + voltage = read_voltage; + } + } + + if (!freq || !voltage) + return -FDT_ERR_NOTFOUND; + + *freq_hz = (u64)1000U * freq; + + return 0; +} + +static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc, + u32 *pllcfg, u32 *fracv) +{ + u32 post_divm; + u32 input_freq; + u64 output_freq; + u64 freq; + u64 vco; + u32 divm, divn, divp, frac; + int i, ret; + u32 diff; + u32 best_diff = U32_MAX; + + /* PLL1 is 1600 */ + const u32 DIVN_MAX = stm32mp1_pll[PLL_1600].divn_max; + const u32 POST_DIVM_MIN = stm32mp1_pll[PLL_1600].refclk_min * 1000000U; + const u32 POST_DIVM_MAX = stm32mp1_pll[PLL_1600].refclk_max * 1000000U; + + ret = stm32mp1_get_max_opp_freq(priv, &output_freq); + if (ret) { + debug("PLL1 OPP configuration not found (%d).\n", ret); + return ret; + } + + switch (clksrc) { + case CLK_PLL12_HSI: + input_freq = stm32mp1_clk_get_fixed(priv, _HSI); + break; + case CLK_PLL12_HSE: + input_freq = stm32mp1_clk_get_fixed(priv, _HSE); + break; + default: + return -EINTR; + } + + /* Following parameters have always the same value */ + pllcfg[PLLCFG_Q] = 0; + pllcfg[PLLCFG_R] = 0; + pllcfg[PLLCFG_O] = PQR(1, 0, 0); + + for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) { + post_divm = (u32)(input_freq / (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 = (u32)((freq / input_freq) - 1); + if (divn < DIVN_MIN || divn > DIVN_MAX) + continue; + + frac = (u32)(((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 * (u64)frac) / + FRAC_MAX); + if (vco < (PLL1600_VCO_MIN / 2) || + vco > (PLL1600_VCO_MAX / 2)) { + frac++; + continue; + } + freq = vco / (divp + 1); + if (output_freq < freq) + diff = (u32)(freq - output_freq); + else + diff = (u32)(output_freq - freq); + if (diff < best_diff) { + pllcfg[PLLCFG_M] = divm; + pllcfg[PLLCFG_N] = divn; + pllcfg[PLLCFG_P] = divp; + *fracv = frac; + + if (diff == 0) + return 0; + + best_diff = diff; + } + frac++; + } + } + } + + if (best_diff == U32_MAX) + return -1; + + return 0; +} + static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset, u32 mask_on) { @@ -1658,9 +1871,12 @@ static int stm32mp1_clktree(struct udevice *dev) unsigned int clksrc[CLKSRC_NB]; unsigned int clkdiv[CLKDIV_NB]; unsigned int pllcfg[_PLL_NB][PLLCFG_NB]; - ofnode plloff[_PLL_NB]; - int ret, len; - uint i; + unsigned int pllfracv[_PLL_NB]; + unsigned int pllcsg[_PLL_NB][PLLCSG_NB]; + bool pllcfg_valid[_PLL_NB]; + bool pllcsg_set[_PLL_NB]; + int ret; + int i, len; int lse_css = 0; const u32 *pkcs_cell; @@ -1680,16 +1896,43 @@ static int stm32mp1_clktree(struct udevice *dev) /* check mandatory field in each pll */ for (i = 0; i < _PLL_NB; i++) { char name[12]; + ofnode node; sprintf(name, "st,pll@%d", i); - plloff[i] = dev_read_subnode(dev, name); - if (!ofnode_valid(plloff[i])) - continue; - ret = ofnode_read_u32_array(plloff[i], "cfg", - pllcfg[i], PLLCFG_NB); - if (ret < 0) { - debug("field cfg invalid: error %d\n", ret); - return -FDT_ERR_NOTFOUND; + node = dev_read_subnode(dev, name); + pllcfg_valid[i] = ofnode_valid(node); + pllcsg_set[i] = false; + if (pllcfg_valid[i]) { + debug("DT for PLL %d @ %s\n", i, name); + ret = ofnode_read_u32_array(node, "cfg", + pllcfg[i], PLLCFG_NB); + if (ret < 0) { + debug("field cfg invalid: error %d\n", ret); + return -FDT_ERR_NOTFOUND; + } + pllfracv[i] = ofnode_read_u32_default(node, "frac", 0); + + ret = ofnode_read_u32_array(node, "csg", pllcsg[i], + PLLCSG_NB); + if (!ret) { + pllcsg_set[i] = true; + } else if (ret != -FDT_ERR_NOTFOUND) { + debug("invalid csg node for pll@%d res=%d\n", + i, ret); + return ret; + } + } else if (i == _PLL1) { + /* use OPP for PLL1 for A7 CPU */ + debug("DT for PLL %d with OPP\n", i); + ret = stm32mp1_pll1_opp(priv, + clksrc[CLKSRC_PLL12], + pllcfg[i], + &pllfracv[i]); + if (ret) { + debug("PLL %d with OPP error = %d\n", i, ret); + return ret; + } + pllcfg_valid[i] = true; } } @@ -1775,29 +2018,18 @@ static int stm32mp1_clktree(struct udevice *dev) /* configure and start PLLs */ debug("configure PLLs\n"); for (i = 0; i < _PLL_NB; i++) { - u32 fracv; - u32 csg[PLLCSG_NB]; - - debug("configure PLL %d @ %d\n", i, - ofnode_to_offset(plloff[i])); - if (!ofnode_valid(plloff[i])) + if (!pllcfg_valid[i]) continue; - - fracv = ofnode_read_u32_default(plloff[i], "frac", 0); - pll_config(priv, i, pllcfg[i], fracv); - ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB); - if (!ret) { - pll_csg(priv, i, csg); - } else if (ret != -FDT_ERR_NOTFOUND) { - debug("invalid csg node for pll@%d res=%d\n", i, ret); - return ret; - } + debug("configure PLL %d\n", i); + pll_config(priv, i, pllcfg[i], pllfracv[i]); + if (pllcsg_set[i]) + pll_csg(priv, i, pllcsg[i]); pll_start(priv, i); } /* wait and start PLLs ouptut when ready */ for (i = 0; i < _PLL_NB; i++) { - if (!ofnode_valid(plloff[i])) + if (!pllcfg_valid[i]) continue; debug("output PLL %d\n", i); pll_output(priv, i, pllcfg[i][PLLCFG_O]); @@ -2047,6 +2279,8 @@ static int stm32mp1_clk_probe(struct udevice *dev) /* clock tree init is done only one time, before relocation */ if (!(gd->flags & GD_FLG_RELOC)) result = stm32mp1_clktree(dev); + if (result) + printf("clock tree initialization failed (%d)\n", result); #endif #ifndef CONFIG_SPL_BUILD From patchwork Mon May 25 10:19:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246489 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:45 +0200 Subject: [PATCH v2 5/9] arm: stm32mp: add weak function to save vddcore In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-6-patrick.delaunay@st.com> Add a weak functions to save the vddcore voltage value provided in the OPP node when the clock tree is initialized. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- Changes in v2: None arch/arm/mach-stm32mp/include/mach/sys_proto.h | 3 +++ drivers/clk/clk_stm32mp1.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h index 4b6c7b8bdd..4149d3a133 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h @@ -48,3 +48,6 @@ void get_soc_name(char name[SOC_NAME_SIZE]); u32 get_bootmode(void); int setup_mac_address(void); + +/* board power management : configure vddcore according OPP */ +void board_vddcore_init(u32 voltage_mv); diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index b48c835bc3..d1177fc3af 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -1226,6 +1226,10 @@ bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type) } } +__weak void board_vddcore_init(u32 voltage_mv) +{ +} + /* * gets OPP parameters (frequency in KHz and voltage in mV) from * an OPP table subnode. Platform HW support capabilities are also checked. @@ -1303,6 +1307,7 @@ int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz) return -FDT_ERR_NOTFOUND; *freq_hz = (u64)1000U * freq; + board_vddcore_init(voltage); return 0; } From patchwork Mon May 25 10:19:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246493 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:46 +0200 Subject: [PATCH v2 6/9] board: st: stpmic1: add function stpmic1_init In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-7-patrick.delaunay@st.com> Add a function stmpic_init to early initialize the PMIC STPMIC1 - keep vdd on during the reset cycle (to avoid issue when backup battery is absent) - Check if debug is enabled to program PMIC according to the bit This patch allows to remove the compilation of spl.c file from stm32mp1 board in dh_stm32mp1. CONFIG_SPL_BOARD_INIT is removed as the new function is called earlier in SPL, in the function board_early_init_f. Signed-off-by: Patrick Delaunay --- Changes in v2: - add stpmic1_init function, called in board_early_init_f for dh_stm32mp1 board support (and no more use spl.c from stm32mp1) - remove CONFIG_SPL_BOARD_INIT arch/arm/mach-stm32mp/Kconfig | 1 - board/dhelectronics/dh_stm32mp1/Makefile | 4 --- board/dhelectronics/dh_stm32mp1/board.c | 3 ++ board/st/common/stpmic1.c | 31 +++++++++++++++++++ board/st/common/stpmic1.h | 6 ++++ board/st/stm32mp1/spl.c | 39 +++--------------------- board/st/stm32mp1/stm32mp1.c | 6 ++++ configs/stm32mp15_basic_defconfig | 1 + 8 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 board/st/common/stpmic1.h diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 6c995ed8d8..ea7d57477b 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -1,7 +1,6 @@ if ARCH_STM32MP config SPL - select SPL_BOARD_INIT select SPL_CLK select SPL_DM select SPL_DM_SEQ_ALIAS diff --git a/board/dhelectronics/dh_stm32mp1/Makefile b/board/dhelectronics/dh_stm32mp1/Makefile index 5758d9816b..b368b396a4 100644 --- a/board/dhelectronics/dh_stm32mp1/Makefile +++ b/board/dhelectronics/dh_stm32mp1/Makefile @@ -3,10 +3,6 @@ # Copyright (C) 2018, STMicroelectronics - All Rights Reserved # -ifdef CONFIG_SPL_BUILD -obj-y += ../../st/stm32mp1/spl.o -endif - obj-y += ../../st/common/stpmic1.o board.o obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += ../../st/common/stm32mp_mtdparts.o diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index 85d56f6082..df0810dbda 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -37,6 +37,7 @@ #include #include #include +#include "../../st/common/stpmic1.h" /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 @@ -194,6 +195,8 @@ int board_stm32mp1_ddr_config_name_match(struct udevice *dev, int board_early_init_f(void) { + if (IS_ENABLED(CONFIG_SPL_BUILD)) + stpmic1_init(); board_get_coding_straps(); return 0; diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c index ca10a2246b..64f24f1f6f 100644 --- a/board/st/common/stpmic1.c +++ b/board/st/common/stpmic1.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -160,3 +161,33 @@ int board_ddr_power_init(enum ddr_type ddr_type) return 0; } + +/* early init of PMIC */ +void stpmic1_init(void) +{ + struct udevice *dev; + + if (uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_stpmic1), &dev)) + return; + + /* Keep vdd on during the reset cycle */ + pmic_clrsetbits(dev, + STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK(STPMIC1_BUCK3), + STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); + + /* Check if debug is enabled to program PMIC according to the bit */ + if (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) { + printf("Keep debug unit ON\n"); + + pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK_DEBUG, + STPMIC1_MRST_BUCK_DEBUG); + + if (STPMIC1_MRST_LDO_DEBUG) + pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR, + STPMIC1_MRST_LDO_DEBUG, + STPMIC1_MRST_LDO_DEBUG); + } +} diff --git a/board/st/common/stpmic1.h b/board/st/common/stpmic1.h new file mode 100644 index 0000000000..ecc3276697 --- /dev/null +++ b/board/st/common/stpmic1.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +void stpmic1_init(void); diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c index e65ff288ea..28efc5c0ae 100644 --- a/board/st/stm32mp1/spl.c +++ b/board/st/stm32mp1/spl.c @@ -5,41 +5,12 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include "../common/stpmic1.h" -void spl_board_init(void) +int board_early_init_f(void) { - /* Keep vdd on during the reset cycle */ -#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT) - struct udevice *dev; - int ret; + if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT)) + stpmic1_init(); - ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmic1), &dev); - if (!ret) - pmic_clrsetbits(dev, - STPMIC1_BUCKS_MRST_CR, - STPMIC1_MRST_BUCK(STPMIC1_BUCK3), - STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); - - /* Check if debug is enabled to program PMIC according to the bit */ - if ((readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) && !ret) { - printf("Keep debug unit ON\n"); - - pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, - STPMIC1_MRST_BUCK_DEBUG, - STPMIC1_MRST_BUCK_DEBUG); - - if (STPMIC1_MRST_LDO_DEBUG) - pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR, - STPMIC1_MRST_LDO_DEBUG, - STPMIC1_MRST_LDO_DEBUG); - } -#endif + return 0; } diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 33cb7f6c4d..22ad2dba9a 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -79,6 +79,12 @@ DECLARE_GLOBAL_DATA_PTR; #define USB_START_LOW_THRESHOLD_UV 1230000 #define USB_START_HIGH_THRESHOLD_UV 2150000 +int board_early_init_f(void) +{ + /* nothing to do, only used in SPL */ + return 0; +} + int checkboard(void) { int ret; diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index c7dd2926c9..628cde6cda 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -16,6 +16,7 @@ CONFIG_SPL_TEXT_BASE=0x2FFC2500 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" +CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 CONFIG_SPL_I2C_SUPPORT=y From patchwork Mon May 25 10:19:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246496 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:47 +0200 Subject: [PATCH v2 7/9] board: stm32mp1: update vddcore in SPL In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-8-patrick.delaunay@st.com> For board using STPMIC1, the vddcore is provided by BUCK1 of STPMIC1 and need to be updated for 800MHz support and only after the clock tree initialization. The VDDCORE voltage value is provided by clock driver, saved in global variable opp_voltage_mv and udpated in SPL board_early_init_f(), just after clock tree initialization. Signed-off-by: Patrick Delaunay --- Changes in v2: - stmpic_buck1_set is a static function called in stpmic1_init (with new parameter for vddcore value) - update also dh_stm32mp1 board board/dhelectronics/dh_stm32mp1/board.c | 9 ++++++++- board/st/common/stpmic1.c | 23 ++++++++++++++++++++++- board/st/common/stpmic1.h | 2 +- board/st/stm32mp1/spl.c | 11 ++++++++++- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index df0810dbda..2ae97f677b 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -136,6 +136,7 @@ int checkboard(void) static u8 brdcode __section("data"); static u8 ddr3code __section("data"); static u8 somcode __section("data"); +static u32 opp_voltage_mv __section(".data"); static void board_get_coding_straps(void) { @@ -193,10 +194,16 @@ int board_stm32mp1_ddr_config_name_match(struct udevice *dev, return -EINVAL; } +void board_vddcore_init(u32 voltage_mv) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD)) + opp_voltage_mv = voltage_mv; +} + int board_early_init_f(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) - stpmic1_init(); + stpmic1_init(opp_voltage_mv); board_get_coding_straps(); return 0; diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c index 64f24f1f6f..47f9d95c29 100644 --- a/board/st/common/stpmic1.c +++ b/board/st/common/stpmic1.c @@ -162,8 +162,25 @@ int board_ddr_power_init(enum ddr_type ddr_type) return 0; } +static int stmpic_buck1_set(struct udevice *dev, u32 voltage_mv) +{ + u32 value; + + /* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */ + value = ((voltage_mv - 725) / 25) + 5; + if (value < 5) + value = 5; + if (value > 36) + value = 36; + + return pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1), + STPMIC1_BUCK_VOUT_MASK, + STPMIC1_BUCK_VOUT(value)); +} + /* early init of PMIC */ -void stpmic1_init(void) +void stpmic1_init(u32 voltage_mv) { struct udevice *dev; @@ -171,6 +188,10 @@ void stpmic1_init(void) DM_GET_DRIVER(pmic_stpmic1), &dev)) return; + /* update VDDCORE = BUCK1 */ + if (voltage_mv) + stmpic_buck1_set(dev, voltage_mv); + /* Keep vdd on during the reset cycle */ pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, diff --git a/board/st/common/stpmic1.h b/board/st/common/stpmic1.h index ecc3276697..b17d6f1633 100644 --- a/board/st/common/stpmic1.h +++ b/board/st/common/stpmic1.h @@ -3,4 +3,4 @@ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved */ -void stpmic1_init(void); +void stpmic1_init(u32 voltage_mv); diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c index 28efc5c0ae..96ab671169 100644 --- a/board/st/stm32mp1/spl.c +++ b/board/st/stm32mp1/spl.c @@ -7,10 +7,19 @@ #include #include "../common/stpmic1.h" +/* board early initialisation in board_f: need to use global variable */ +static u32 opp_voltage_mv __section(".data"); + +void board_vddcore_init(u32 voltage_mv) +{ + if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT)) + opp_voltage_mv = voltage_mv; +} + int board_early_init_f(void) { if (IS_ENABLED(CONFIG_PMIC_STPMIC1) && CONFIG_IS_ENABLED(POWER_SUPPORT)) - stpmic1_init(); + stpmic1_init(opp_voltage_mv); return 0; } From patchwork Mon May 25 10:19:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246497 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:48 +0200 Subject: [PATCH v2 8/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings in SPL In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-9-patrick.delaunay@st.com> This patch allows to switch the CPU frequency to 800MHz on the ST Microelectronics board (DK1/DK2 and EV1) or dh electronics SOM using the STM32MP15x SOC and when it is supported by the HW (for STM32MP15xD and STM32MP15xF). Signed-off-by: Patrick Delaunay --- Changes in v2: - update stm32mp15xx-dhcor and dhcom device tree arch/arm/dts/stm32mp15-u-boot.dtsi | 10 ++++++++++ arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 9 --------- arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 9 --------- arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi | 9 --------- arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi | 9 --------- 5 files changed, 10 insertions(+), 36 deletions(-) diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi index a0d971ad88..66be7df9ae 100644 --- a/arch/arm/dts/stm32mp15-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi @@ -88,6 +88,16 @@ u-boot,dm-pre-reloc; }; +&cpu0_opp_table { + u-boot,dm-spl; + opp-650000000 { + u-boot,dm-spl; + }; + opp-800000000 { + u-boot,dm-spl; + }; +}; + &gpioa { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index c52abeb1e7..69cdae6685 100644 --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi @@ -118,15 +118,6 @@ CLK_LPTIM45_LSE >; - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll at 0 { - compatible = "st,stm32mp1-pll"; - reg = <0>; - cfg = < 2 80 0 0 0 PQR(1,0,0) >; - frac = < 0x800 >; - u-boot,dm-pre-reloc; - }; - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ pll2: st,pll at 1 { compatible = "st,stm32mp1-pll"; diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi index 84af7fa47b..3f716306be 100644 --- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi @@ -115,15 +115,6 @@ CLK_LPTIM45_LSE >; - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll at 0 { - compatible = "st,stm32mp1-pll"; - reg = <0>; - cfg = < 2 80 0 0 0 PQR(1,0,0) >; - frac = < 0x800 >; - u-boot,dm-pre-reloc; - }; - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ pll2: st,pll at 1 { compatible = "st,stm32mp1-pll"; diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi index 75d75266e8..f96de9e7a3 100644 --- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi @@ -235,15 +235,6 @@ CLK_LPTIM45_LSE >; - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll at 0 { - compatible = "st,stm32mp1-pll"; - reg = <0>; - cfg = < 2 80 0 0 0 PQR(1,0,0) >; - frac = < 0x800 >; - u-boot,dm-pre-reloc; - }; - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ pll2: st,pll at 1 { compatible = "st,stm32mp1-pll"; diff --git a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi index ef730a8322..4059dabf1d 100644 --- a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi @@ -105,15 +105,6 @@ CLK_LPTIM45_LSE >; - /* VCO = 1300.0 MHz => P = 650 (CPU) */ - pll1: st,pll at 0 { - compatible = "st,stm32mp1-pll"; - reg = <0>; - cfg = < 2 80 0 0 0 PQR(1,0,0) >; - frac = < 0x800 >; - u-boot,dm-pre-reloc; - }; - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ pll2: st,pll at 1 { compatible = "st,stm32mp1-pll"; From patchwork Mon May 25 10:19:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 246495 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 25 May 2020 12:19:49 +0200 Subject: [PATCH v2 9/9] board: stm32mp1: move the function board_debug_uart_init in spl.c In-Reply-To: <20200525101949.15944-1-patrick.delaunay@st.com> References: <20200525101949.15944-1-patrick.delaunay@st.com> Message-ID: <20200525101949.15944-10-patrick.delaunay@st.com> Move the debug function board_debug_uart_init in spl.c as the debug_uart_init() function is called in arch_cpu_init() only for SPL and remove the board.c file. For TFABOOT, the UART TX pin configuration is done in TF-A. Signed-off-by: Patrick Delaunay --- Changes in v2: - NEW: merge spl.c and board.c to avoid a file with only one function board/st/stm32mp1/Makefile | 2 -- board/st/stm32mp1/board.c | 34 ---------------------------------- board/st/stm32mp1/spl.c | 26 ++++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 36 deletions(-) delete mode 100644 board/st/stm32mp1/board.c diff --git a/board/st/stm32mp1/Makefile b/board/st/stm32mp1/Makefile index 8188075b1a..65560df290 100644 --- a/board/st/stm32mp1/Makefile +++ b/board/st/stm32mp1/Makefile @@ -8,5 +8,3 @@ obj-y += spl.o else obj-y += stm32mp1.o endif - -obj-y += board.o diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c deleted file mode 100644 index 1887941e57..0000000000 --- a/board/st/stm32mp1/board.c +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -/* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ - -#include -#include - -#ifdef CONFIG_DEBUG_UART_BOARD_INIT -void board_debug_uart_init(void) -{ -#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE) - -#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00) -#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28) - - /* UART4 clock enable */ - setbits_le32(RCC_MP_APB1ENSETR, BIT(16)); - -#define GPIOG_BASE 0x50008000 - /* GPIOG clock enable */ - writel(BIT(6), RCC_MP_AHB4ENSETR); - /* GPIO configuration for EVAL board - * => Uart4 TX = G11 - */ - writel(0xffbfffff, GPIOG_BASE + 0x00); - writel(0x00006000, GPIOG_BASE + 0x24); -#else - -#error("CONFIG_DEBUG_UART_BASE: not supported value") - -#endif -} -#endif diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c index 96ab671169..977703f58a 100644 --- a/board/st/stm32mp1/spl.c +++ b/board/st/stm32mp1/spl.c @@ -5,6 +5,7 @@ #include #include +#include #include "../common/stpmic1.h" /* board early initialisation in board_f: need to use global variable */ @@ -23,3 +24,28 @@ int board_early_init_f(void) return 0; } + +#ifdef CONFIG_DEBUG_UART_BOARD_INIT +void board_debug_uart_init(void) +{ +#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE) + +#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00) +#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28) + + /* UART4 clock enable */ + setbits_le32(RCC_MP_APB1ENSETR, BIT(16)); + +#define GPIOG_BASE 0x50008000 + /* GPIOG clock enable */ + writel(BIT(6), RCC_MP_AHB4ENSETR); + /* GPIO configuration for ST boards: Uart4 TX = G11 */ + writel(0xffbfffff, GPIOG_BASE + 0x00); + writel(0x00006000, GPIOG_BASE + 0x24); +#else + +#error("CONFIG_DEBUG_UART_BASE: not supported value") + +#endif +} +#endif