All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL
@ 2020-04-21 15:11 Patrick Delaunay
  2020-04-21 15:11 ` [PATCH 1/9] arm: stm32mp: spl: add bsec driver " Patrick Delaunay
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot


This serie allows to switch the CPU frequency to the max frequency
supported in OPP device tree nodes and supported by STM32MP SOC
(800MHz is supported by STM32MP15xD and STM32MP15xF).

Board also increases the VDDCore voltage to support this new
operation point.



Marek Vasut (1):
  ARM: stm32: Add board_early_init_f() to SPL

Patrick Delaunay (8):
  arm: stm32mp: spl: add bsec driver in SPL
  ARM: dts: stm32: add cpufreq support on stm32mp15x
  board: st: create common file stpmic1.c
  stm32mp1: clk: configure pll1 with OPP
  arm: stm32mp: add weak function to save vddcore
  board: st: stpmic1: add function stmpic_buck1_set
  board: stm32mp1: update vddcore in SPL
  ARM: dts: stm32mp1: use OPP information for PLL1 settings in SPL

 arch/arm/dts/stm32mp15-u-boot.dtsi            |  12 +-
 arch/arm/dts/stm32mp151.dtsi                  |  21 ++
 arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi      |   9 -
 arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi      |   9 -
 arch/arm/dts/stm32mp157c-ed1.dts              |   8 +
 arch/arm/dts/stm32mp15xx-dkx.dtsi             |   8 +
 arch/arm/mach-stm32mp/Makefile                |   2 +-
 arch/arm/mach-stm32mp/bsec.c                  |  11 +-
 .../arm/mach-stm32mp/include/mach/sys_proto.h |   3 +
 arch/arm/mach-stm32mp/spl.c                   |  11 +
 board/dhelectronics/dh_stm32mp1/Makefile      |   2 +-
 board/st/common/Makefile                      |   1 +
 board/st/common/stpmic1.c                     | 186 +++++++++++
 board/st/common/stpmic1.h                     |   6 +
 board/st/stm32mp1/board.c                     | 158 ----------
 board/st/stm32mp1/spl.c                       |  20 ++
 .../clock/st,stm32mp1.txt                     |   4 +
 drivers/clk/clk_stm32mp1.c                    | 295 ++++++++++++++++--
 18 files changed, 554 insertions(+), 212 deletions(-)
 create mode 100644 board/st/common/stpmic1.c
 create mode 100644 board/st/common/stpmic1.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/9] arm: stm32mp: spl: add bsec driver in SPL
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:48   ` Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x Patrick Delaunay
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

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 <patrick.delaunay@st.com>
---

I already sent in unrelated serie

http://patchwork.ozlabs.org/patch/1264829/

Patrick


 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 8f9535a4db..e0b1223de8 100644
--- a/arch/arm/dts/stm32mp15-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15-u-boot.dtsi
@@ -40,7 +40,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 eee39c27c3..f29d6f795f 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -6,11 +6,11 @@
 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-y += bsec.o
 obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
 obj-$(CONFIG_ARMV7_PSCI) += psci.o
 endif
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
 };
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
  2020-04-21 15:11 ` [PATCH 1/9] arm: stm32mp: spl: add bsec driver " Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:49   ` [Uboot-stm32] " Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 3/9] board: st: create common file stpmic1.c Patrick Delaunay
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

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 <patrick.delaunay@st.com>
---

 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 f185639a46..1d465c3064 100644
--- a/arch/arm/dts/stm32mp151.dtsi
+++ b/arch/arm/dts/stm32mp151.dtsi
@@ -19,6 +19,24 @@
 			compatible = "arm,cortex-a7";
 			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>;
 		};
 	};
 
@@ -1512,6 +1530,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 54af7c97b3..7215eb4768 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -107,6 +107,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 42d3f0cb2d..861280afe8 100644
--- a/arch/arm/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi
@@ -116,6 +116,14 @@
 	status = "okay";
 };
 
+&cpu0{
+	cpu-supply = <&vddcore>;
+};
+
+&cpu1{
+	cpu-supply = <&vddcore>;
+};
+
 &ethernet0 {
 	status = "okay";
 	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/9] board: st: create common file stpmic1.c
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
  2020-04-21 15:11 ` [PATCH 1/9] arm: stm32mp: spl: add bsec driver " Patrick Delaunay
  2020-04-21 15:11 ` [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:49   ` [Uboot-stm32] " Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP Patrick Delaunay
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

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 <patrick.delaunay@st.com>
---

 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 b42c4e4c04..04586c0a28 100644
--- a/board/dhelectronics/dh_stm32mp1/Makefile
+++ b/board/dhelectronics/dh_stm32mp1/Makefile
@@ -7,4 +7,4 @@ 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
diff --git a/board/st/common/Makefile b/board/st/common/Makefile
index 8553606b90..78bc0307f7 100644
--- a/board/st/common/Makefile
+++ b/board/st/common/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o
+obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.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 <common.h>
+#include <dm.h>
+#include <asm/arch/ddr.h>
+#include <power/pmic.h>
+#include <power/stpmic1.h>
+
+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 <common.h>
-#include <dm.h>
 #include <asm/io.h>
-#include <asm/arch/ddr.h>
-#include <power/pmic.h>
-#include <power/stpmic1.h>
 
 #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
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (2 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 3/9] board: st: create common file stpmic1.c Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:51   ` Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL Patrick Delaunay
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

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 <patrick.delaunay@st.com>
---

 .../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 50df8425bf..baacc1abb5 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -14,6 +14,7 @@
 #include <vsprintf.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <asm/arch/sys_proto.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
 
@@ -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,
@@ -1186,6 +1197,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)
 {
@@ -1657,9 +1870,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;
 
@@ -1679,16 +1895,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;
 		}
 	}
 
@@ -1774,29 +2017,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]);
@@ -2046,6 +2278,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
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (3 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:51   ` Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 6/9] arm: stm32mp: add weak function to save vddcore Patrick Delaunay
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

From: Marek Vasut <marex@denx.de>

Add weak implementation of board_early_init_f() hook into the
STM32MP1 SPL. This can be used to read out e.g. configuration
straps before initializing the DRAM.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Cc: Patrick Delaunay <patrick.delaunay@st.com>
Cc: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 arch/arm/mach-stm32mp/spl.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index ca4231cd0d..cd14d1065e 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -76,6 +76,11 @@ void spl_display_print(void)
 }
 #endif
 
+__weak int board_early_init_f(void)
+{
+	return 0;
+}
+
 void board_init_f(ulong dummy)
 {
 	struct udevice *dev;
@@ -110,6 +115,12 @@ void board_init_f(ulong dummy)
 	/* enable console uart printing */
 	preloader_console_init();
 
+	ret = board_early_init_f();
+	if (ret) {
+		debug("board_early_init_f() failed: %d\n", ret);
+		hang();
+	}
+
 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
 	if (ret) {
 		printf("DRAM init failed: %d\n", ret);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/9] arm: stm32mp: add weak function to save vddcore
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (4 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:53   ` Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set Patrick Delaunay
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

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 <patrick.delaunay@st.com>
---

 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 1617126bea..55193b5c2d 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -43,3 +43,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 baacc1abb5..5fccc03ba7 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -1225,6 +1225,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.
@@ -1302,6 +1306,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;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (5 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 6/9] arm: stm32mp: add weak function to save vddcore Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:54   ` [Uboot-stm32] " Patrice CHOTARD
  2020-04-21 15:11 ` [PATCH 8/9] board: stm32mp1: update vddcore in SPL Patrick Delaunay
  2020-04-21 15:11 ` [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings " Patrick Delaunay
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

Add a function stmpic_buck1_set to configure buck1 voltage
in SPL as regulator framework is not available.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 board/st/common/stpmic1.c | 24 ++++++++++++++++++++++++
 board/st/common/stpmic1.h |  6 ++++++
 2 files changed, 30 insertions(+)
 create mode 100644 board/st/common/stpmic1.h

diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c
index ca10a2246b..a912242ad9 100644
--- a/board/st/common/stpmic1.c
+++ b/board/st/common/stpmic1.c
@@ -9,6 +9,30 @@
 #include <power/pmic.h>
 #include <power/stpmic1.h>
 
+int stmpic_buck1_set(u32 voltage_mv)
+{
+	struct udevice *dev;
+	int ret;
+	u32 value;
+
+	ret = uclass_get_device_by_driver(UCLASS_PMIC,
+					  DM_GET_DRIVER(pmic_stpmic1), &dev);
+	if (ret)
+		return ret;
+
+	/* 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));
+}
+
 int board_ddr_power_init(enum ddr_type ddr_type)
 {
 	struct udevice *dev;
diff --git a/board/st/common/stpmic1.h b/board/st/common/stpmic1.h
new file mode 100644
index 0000000000..a020dddbe0
--- /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
+ */
+
+int stmpic_buck1_set(u32 voltage_mv);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 8/9] board: stm32mp1: update vddcore in SPL
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (6 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:54   ` [Uboot-stm32] " Patrice CHOTARD
  2020-05-13 16:32   ` Patrick DELAUNAY
  2020-04-21 15:11 ` [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings " Patrick Delaunay
  8 siblings, 2 replies; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

For board using STPMIC1, the vddcore is provided by BUCK1 of STMPIC1
and need to be updated for 800MHz support and only after the clock
tree initialization.

The VDDCORE voltage value in provide by clock driver, saved in global
variable  opp_voltage_mv and udpated SPL in board_early_init_f().

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 board/st/stm32mp1/spl.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c
index e65ff288ea..616fb1d6f2 100644
--- a/board/st/stm32mp1/spl.c
+++ b/board/st/stm32mp1/spl.c
@@ -12,6 +12,26 @@
 #include <power/pmic.h>
 #include <power/stpmic1.h>
 #include <asm/arch/ddr.h>
+#include "../common/stpmic1.h"
+
+/* board early initialisation in board_f: need to use global variable */
+#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
+static u32 opp_voltage_mv __section(".data");
+
+void board_vddcore_init(u32 voltage_mv)
+{
+	opp_voltage_mv = voltage_mv;
+}
+#endif
+
+int board_early_init_f(void)
+{
+#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
+	stmpic_buck1_set(opp_voltage_mv);
+#endif
+
+	return 0;
+}
 
 void spl_board_init(void)
 {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings in SPL
  2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
                   ` (7 preceding siblings ...)
  2020-04-21 15:11 ` [PATCH 8/9] board: stm32mp1: update vddcore in SPL Patrick Delaunay
@ 2020-04-21 15:11 ` Patrick Delaunay
  2020-05-11 13:55   ` [Uboot-stm32] " Patrice CHOTARD
  8 siblings, 1 reply; 20+ messages in thread
From: Patrick Delaunay @ 2020-04-21 15:11 UTC (permalink / raw)
  To: u-boot

This patch allows to switch the CPU frequency to 800MHz on the
ST Microelectronics board (DK1/DK2 and EV1) when it supported by the HW
(for STM32MP15xD and STM32MP15xF).

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 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 ---------
 3 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi
index e0b1223de8..497c1a01ec 100644
--- a/arch/arm/dts/stm32mp15-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15-u-boot.dtsi
@@ -63,6 +63,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 5844d41c53..97d5ea43c3 100644
--- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
@@ -122,15 +122,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 ed2f024be9..9f9aa4ac65 100644
--- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
@@ -119,15 +119,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";
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/9] arm: stm32mp: spl: add bsec driver in SPL
  2020-04-21 15:11 ` [PATCH 1/9] arm: stm32mp: spl: add bsec driver " Patrick Delaunay
@ 2020-05-11 13:48   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:48 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> 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 <patrick.delaunay@st.com>
> ---
>
> I already sent in unrelated serie
>
> http://patchwork.ozlabs.org/patch/1264829/
>
> Patrick
>
>
>  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 8f9535a4db..e0b1223de8 100644
> --- a/arch/arm/dts/stm32mp15-u-boot.dtsi
> +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi
> @@ -40,7 +40,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 eee39c27c3..f29d6f795f 100644
> --- a/arch/arm/mach-stm32mp/Makefile
> +++ b/arch/arm/mach-stm32mp/Makefile
> @@ -6,11 +6,11 @@
>  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-y += bsec.o
>  obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
>  obj-$(CONFIG_ARMV7_PSCI) += psci.o
>  endif
> 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
>  };

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Uboot-stm32] [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x
  2020-04-21 15:11 ` [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x Patrick Delaunay
@ 2020-05-11 13:49   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:49 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> 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 <patrick.delaunay@st.com>
> ---
>
>  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 f185639a46..1d465c3064 100644
> --- a/arch/arm/dts/stm32mp151.dtsi
> +++ b/arch/arm/dts/stm32mp151.dtsi
> @@ -19,6 +19,24 @@
>  			compatible = "arm,cortex-a7";
>  			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>;
>  		};
>  	};
>  
> @@ -1512,6 +1530,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 54af7c97b3..7215eb4768 100644
> --- a/arch/arm/dts/stm32mp157c-ed1.dts
> +++ b/arch/arm/dts/stm32mp157c-ed1.dts
> @@ -107,6 +107,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 42d3f0cb2d..861280afe8 100644
> --- a/arch/arm/dts/stm32mp15xx-dkx.dtsi
> +++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi
> @@ -116,6 +116,14 @@
>  	status = "okay";
>  };
>  
> +&cpu0{
> +	cpu-supply = <&vddcore>;
> +};
> +
> +&cpu1{
> +	cpu-supply = <&vddcore>;
> +};
> +
>  &ethernet0 {
>  	status = "okay";
>  	pinctrl-0 = <&ethernet0_rgmii_pins_a>;

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Uboot-stm32] [PATCH 3/9] board: st: create common file stpmic1.c
  2020-04-21 15:11 ` [PATCH 3/9] board: st: create common file stpmic1.c Patrick Delaunay
@ 2020-05-11 13:49   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:49 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> 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 <patrick.delaunay@st.com>
> ---
>
>  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 b42c4e4c04..04586c0a28 100644
> --- a/board/dhelectronics/dh_stm32mp1/Makefile
> +++ b/board/dhelectronics/dh_stm32mp1/Makefile
> @@ -7,4 +7,4 @@ 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
> diff --git a/board/st/common/Makefile b/board/st/common/Makefile
> index 8553606b90..78bc0307f7 100644
> --- a/board/st/common/Makefile
> +++ b/board/st/common/Makefile
> @@ -4,3 +4,4 @@
>  #
>  
>  obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o
> +obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.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 <common.h>
> +#include <dm.h>
> +#include <asm/arch/ddr.h>
> +#include <power/pmic.h>
> +#include <power/stpmic1.h>
> +
> +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 <common.h>
> -#include <dm.h>
>  #include <asm/io.h>
> -#include <asm/arch/ddr.h>
> -#include <power/pmic.h>
> -#include <power/stpmic1.h>
>  
>  #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


Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP
  2020-04-21 15:11 ` [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP Patrick Delaunay
@ 2020-05-11 13:51   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:51 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> 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 <patrick.delaunay@st.com>
> ---
>
>  .../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 50df8425bf..baacc1abb5 100644
> --- a/drivers/clk/clk_stm32mp1.c
> +++ b/drivers/clk/clk_stm32mp1.c
> @@ -14,6 +14,7 @@
>  #include <vsprintf.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> +#include <asm/arch/sys_proto.h>
>  #include <dt-bindings/clock/stm32mp1-clks.h>
>  #include <dt-bindings/clock/stm32mp1-clksrc.h>
>  
> @@ -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,
> @@ -1186,6 +1197,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)
>  {
> @@ -1657,9 +1870,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;
>  
> @@ -1679,16 +1895,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;
>  		}
>  	}
>  
> @@ -1774,29 +2017,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]);
> @@ -2046,6 +2278,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

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL
  2020-04-21 15:11 ` [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL Patrick Delaunay
@ 2020-05-11 13:51   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:51 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> From: Marek Vasut <marex@denx.de>
>
> Add weak implementation of board_early_init_f() hook into the
> STM32MP1 SPL. This can be used to read out e.g. configuration
> straps before initializing the DRAM.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Cc: Patrick Delaunay <patrick.delaunay@st.com>
> Cc: Patrice Chotard <patrice.chotard@st.com>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  arch/arm/mach-stm32mp/spl.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
> index ca4231cd0d..cd14d1065e 100644
> --- a/arch/arm/mach-stm32mp/spl.c
> +++ b/arch/arm/mach-stm32mp/spl.c
> @@ -76,6 +76,11 @@ void spl_display_print(void)
>  }
>  #endif
>  
> +__weak int board_early_init_f(void)
> +{
> +	return 0;
> +}
> +
>  void board_init_f(ulong dummy)
>  {
>  	struct udevice *dev;
> @@ -110,6 +115,12 @@ void board_init_f(ulong dummy)
>  	/* enable console uart printing */
>  	preloader_console_init();
>  
> +	ret = board_early_init_f();
> +	if (ret) {
> +		debug("board_early_init_f() failed: %d\n", ret);
> +		hang();
> +	}
> +
>  	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
>  	if (ret) {
>  		printf("DRAM init failed: %d\n", ret);

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 6/9] arm: stm32mp: add weak function to save vddcore
  2020-04-21 15:11 ` [PATCH 6/9] arm: stm32mp: add weak function to save vddcore Patrick Delaunay
@ 2020-05-11 13:53   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:53 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> 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 <patrick.delaunay@st.com>
> ---
>
>  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 1617126bea..55193b5c2d 100644
> --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
> +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
> @@ -43,3 +43,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 baacc1abb5..5fccc03ba7 100644
> --- a/drivers/clk/clk_stm32mp1.c
> +++ b/drivers/clk/clk_stm32mp1.c
> @@ -1225,6 +1225,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.
> @@ -1302,6 +1306,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;
>  }

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Uboot-stm32] [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set
  2020-04-21 15:11 ` [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set Patrick Delaunay
@ 2020-05-11 13:54   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:54 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> Add a function stmpic_buck1_set to configure buck1 voltage
> in SPL as regulator framework is not available.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  board/st/common/stpmic1.c | 24 ++++++++++++++++++++++++
>  board/st/common/stpmic1.h |  6 ++++++
>  2 files changed, 30 insertions(+)
>  create mode 100644 board/st/common/stpmic1.h
>
> diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c
> index ca10a2246b..a912242ad9 100644
> --- a/board/st/common/stpmic1.c
> +++ b/board/st/common/stpmic1.c
> @@ -9,6 +9,30 @@
>  #include <power/pmic.h>
>  #include <power/stpmic1.h>
>  
> +int stmpic_buck1_set(u32 voltage_mv)
> +{
> +	struct udevice *dev;
> +	int ret;
> +	u32 value;
> +
> +	ret = uclass_get_device_by_driver(UCLASS_PMIC,
> +					  DM_GET_DRIVER(pmic_stpmic1), &dev);
> +	if (ret)
> +		return ret;
> +
> +	/* 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));
> +}
> +
>  int board_ddr_power_init(enum ddr_type ddr_type)
>  {
>  	struct udevice *dev;
> diff --git a/board/st/common/stpmic1.h b/board/st/common/stpmic1.h
> new file mode 100644
> index 0000000000..a020dddbe0
> --- /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
> + */
> +
> +int stmpic_buck1_set(u32 voltage_mv);


Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Uboot-stm32] [PATCH 8/9] board: stm32mp1: update vddcore in SPL
  2020-04-21 15:11 ` [PATCH 8/9] board: stm32mp1: update vddcore in SPL Patrick Delaunay
@ 2020-05-11 13:54   ` Patrice CHOTARD
  2020-05-13 16:32   ` Patrick DELAUNAY
  1 sibling, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:54 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> For board using STPMIC1, the vddcore is provided by BUCK1 of STMPIC1
> and need to be updated for 800MHz support and only after the clock
> tree initialization.
>
> The VDDCORE voltage value in provide by clock driver, saved in global
> variable  opp_voltage_mv and udpated SPL in board_early_init_f().
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  board/st/stm32mp1/spl.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c
> index e65ff288ea..616fb1d6f2 100644
> --- a/board/st/stm32mp1/spl.c
> +++ b/board/st/stm32mp1/spl.c
> @@ -12,6 +12,26 @@
>  #include <power/pmic.h>
>  #include <power/stpmic1.h>
>  #include <asm/arch/ddr.h>
> +#include "../common/stpmic1.h"
> +
> +/* board early initialisation in board_f: need to use global variable */
> +#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
> +static u32 opp_voltage_mv __section(".data");
> +
> +void board_vddcore_init(u32 voltage_mv)
> +{
> +	opp_voltage_mv = voltage_mv;
> +}
> +#endif
> +
> +int board_early_init_f(void)
> +{
> +#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
> +	stmpic_buck1_set(opp_voltage_mv);
> +#endif
> +
> +	return 0;
> +}
>  
>  void spl_board_init(void)
>  {

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Uboot-stm32] [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings in SPL
  2020-04-21 15:11 ` [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings " Patrick Delaunay
@ 2020-05-11 13:55   ` Patrice CHOTARD
  0 siblings, 0 replies; 20+ messages in thread
From: Patrice CHOTARD @ 2020-05-11 13:55 UTC (permalink / raw)
  To: u-boot

Hi Patrick

On 4/21/20 5:11 PM, Patrick Delaunay wrote:
> This patch allows to switch the CPU frequency to 800MHz on the
> ST Microelectronics board (DK1/DK2 and EV1) when it supported by the HW
> (for STM32MP15xD and STM32MP15xF).
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  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 ---------
>  3 files changed, 10 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi
> index e0b1223de8..497c1a01ec 100644
> --- a/arch/arm/dts/stm32mp15-u-boot.dtsi
> +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi
> @@ -63,6 +63,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 5844d41c53..97d5ea43c3 100644
> --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
> +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
> @@ -122,15 +122,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 ed2f024be9..9f9aa4ac65 100644
> --- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
> +++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
> @@ -119,15 +119,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";

Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 8/9] board: stm32mp1: update vddcore in SPL
  2020-04-21 15:11 ` [PATCH 8/9] board: stm32mp1: update vddcore in SPL Patrick Delaunay
  2020-05-11 13:54   ` [Uboot-stm32] " Patrice CHOTARD
@ 2020-05-13 16:32   ` Patrick DELAUNAY
  1 sibling, 0 replies; 20+ messages in thread
From: Patrick DELAUNAY @ 2020-05-13 16:32 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: mardi 21 avril 2020 17:11
> 
> For board using STPMIC1, the vddcore is provided by BUCK1 of STMPIC1 and
> need to be updated for 800MHz support and only after the clock tree initialization.
> 
> The VDDCORE voltage value in provide by clock driver, saved in global variable
> opp_voltage_mv and udpated SPL in board_early_init_f().
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Ok for ST board boards but compilation failed for 
stm32mp15_dhcor_basic / stm32mp15_dhcom_basic

+arm-linux-gnueabi-ld.bfd: spl/board/dhelectronics/dh_stm32mp1/board.o: in function `board_early_init_f':
+board/dhelectronics/dh_stm32mp1/board.c:196: multiple definition of `board_early_init_f'; spl/board/dhelectronics/dh_stm32mp1/../../st/stm32mp1/spl.o:board/dhelectronics/dh_stm32mp1/../../st/stm32mp1/spl.c:28: first defined here

need V2
with rework for board/st/stm32mp1/spl.c
and better split for DHCOM SOM

regards

Patrick

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2020-05-13 16:32 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-21 15:11 [PATCH 0/9] stm32mp1: use OPP information for PLL1 settings in SPL Patrick Delaunay
2020-04-21 15:11 ` [PATCH 1/9] arm: stm32mp: spl: add bsec driver " Patrick Delaunay
2020-05-11 13:48   ` Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 2/9] ARM: dts: stm32: add cpufreq support on stm32mp15x Patrick Delaunay
2020-05-11 13:49   ` [Uboot-stm32] " Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 3/9] board: st: create common file stpmic1.c Patrick Delaunay
2020-05-11 13:49   ` [Uboot-stm32] " Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 4/9] stm32mp1: clk: configure pll1 with OPP Patrick Delaunay
2020-05-11 13:51   ` Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 5/9] ARM: stm32: Add board_early_init_f() to SPL Patrick Delaunay
2020-05-11 13:51   ` Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 6/9] arm: stm32mp: add weak function to save vddcore Patrick Delaunay
2020-05-11 13:53   ` Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 7/9] board: st: stpmic1: add function stmpic_buck1_set Patrick Delaunay
2020-05-11 13:54   ` [Uboot-stm32] " Patrice CHOTARD
2020-04-21 15:11 ` [PATCH 8/9] board: stm32mp1: update vddcore in SPL Patrick Delaunay
2020-05-11 13:54   ` [Uboot-stm32] " Patrice CHOTARD
2020-05-13 16:32   ` Patrick DELAUNAY
2020-04-21 15:11 ` [PATCH 9/9] ARM: dts: stm32mp1: use OPP information for PLL1 settings " Patrick Delaunay
2020-05-11 13:55   ` [Uboot-stm32] " Patrice CHOTARD

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.