[PATCH v4 10/16] ARM: tegra: create common pre-dm i2c write

Svyatoslav Ryhel clamor95 at gmail.com
Tue Feb 14 18:35:32 CET 2023


This implementation allows pwr i2c writing on early SPL
stages when DM is not yet setup.

Such writing is needed to configure main voltages of PMIC
on early SPL for bootloader to boot properly.

Tested-by: Andreas Westman Dorcsak <hedmoo at yahoo.com> # ASUS TF T30
Tested-by: Robert Eckelmann <longnoserob at gmail.com> # ASUS TF101 T20
Tested-by: Svyatoslav Ryhel <clamor95 at gmail.com> # LG P895 T30
Tested-by: Thierry Reding <treding at nvidia.com> # T30 and T124
Signed-off-by: Svyatoslav Ryhel <clamor95 at gmail.com>
---
 arch/arm/include/asm/arch-tegra/tegra_i2c.h | 17 ++++++++++
 arch/arm/mach-tegra/cpu.h                   |  1 -
 arch/arm/mach-tegra/tegra124/cpu.c          |  4 +++
 arch/arm/mach-tegra/tegra30/cpu.c           | 37 +++++++--------------
 4 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/arch/arm/include/asm/arch-tegra/tegra_i2c.h b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
index c49f43251d..afec6bbdda 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_i2c.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
@@ -8,6 +8,7 @@
 #ifndef _TEGRA_I2C_H_
 #define _TEGRA_I2C_H_
 
+#include <asm/io.h>
 #include <asm/types.h>
 
 struct udevice;
@@ -154,4 +155,20 @@ struct i2c_ctlr {
  */
 int tegra_i2c_get_dvc_bus(struct udevice **busp);
 
+/* Pre-dm section used for initial setup of PMIC */
+#define I2C_SEND_2_BYTES		0x0A02
+
+static inline void tegra_i2c_ll_write(uint addr, uint data)
+{
+	struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
+
+	writel(addr, &reg->cmd_addr0);
+	writel(0x2, &reg->cnfg);
+
+	writel(data, &reg->cmd_data1);
+	writel(I2C_SEND_2_BYTES, &reg->cnfg);
+}
+
+void pmic_enable_cpu_vdd(void);
+
 #endif	/* _TEGRA_I2C_H_ */
diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h
index d541825441..006aae3d07 100644
--- a/arch/arm/mach-tegra/cpu.h
+++ b/arch/arm/mach-tegra/cpu.h
@@ -74,4 +74,3 @@ int tegra_get_chip(void);
 int tegra_get_sku_info(void);
 int tegra_get_chip_sku(void);
 void adjust_pllp_out_freqs(void);
-void pmic_enable_cpu_vdd(void);
diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c
index d5f2683b26..b1bfe8fb5e 100644
--- a/arch/arm/mach-tegra/tegra124/cpu.c
+++ b/arch/arm/mach-tegra/tegra124/cpu.c
@@ -14,10 +14,14 @@
 #include <asm/arch/tegra.h>
 #include <asm/arch-tegra/clk_rst.h>
 #include <asm/arch-tegra/pmc.h>
+#include <asm/arch-tegra/tegra_i2c.h>
 #include <asm/arch-tegra/ap.h>
 #include <linux/delay.h>
 #include "../cpu.h"
 
+/* In case this function is not defined */
+__weak void pmic_enable_cpu_vdd(void) {}
+
 /* Tegra124-specific CPU init code */
 
 static void enable_cpu_power_rail(void)
diff --git a/arch/arm/mach-tegra/tegra30/cpu.c b/arch/arm/mach-tegra/tegra30/cpu.c
index 651edd27ee..6ac45af51a 100644
--- a/arch/arm/mach-tegra/tegra30/cpu.c
+++ b/arch/arm/mach-tegra/tegra30/cpu.c
@@ -15,23 +15,6 @@
 #include <linux/delay.h>
 #include "../cpu.h"
 
-/* Tegra30-specific CPU init code */
-void tegra_i2c_ll_write_addr(uint addr, uint config)
-{
-	struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
-
-	writel(addr, &reg->cmd_addr0);
-	writel(config, &reg->cnfg);
-}
-
-void tegra_i2c_ll_write_data(uint data, uint config)
-{
-	struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
-
-	writel(data, &reg->cmd_data1);
-	writel(config, &reg->cnfg);
-}
-
 #define TPS62366A_I2C_ADDR		0xC0
 #define TPS62366A_SET1_REG		0x01
 #define TPS62366A_SET1_DATA		(0x4600 | TPS62366A_SET1_REG)
@@ -45,7 +28,9 @@ void tegra_i2c_ll_write_data(uint data, uint config)
 #define TPS65911_VDDCTRL_SR_REG		0x27
 #define TPS65911_VDDCTRL_OP_DATA	(0x2400 | TPS65911_VDDCTRL_OP_REG)
 #define TPS65911_VDDCTRL_SR_DATA	(0x0100 | TPS65911_VDDCTRL_SR_REG)
-#define I2C_SEND_2_BYTES		0x0A02
+
+/* In case this function is not defined */
+__weak void pmic_enable_cpu_vdd(void) {}
 
 static void enable_cpu_power_rail(void)
 {
@@ -59,12 +44,12 @@ static void enable_cpu_power_rail(void)
 
 	/* Set VDD_CORE to 1.200V. */
 #ifdef CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1
-	tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2);
-	tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES);
+	tegra_i2c_ll_write(TPS62366A_I2C_ADDR,
+			   TPS62366A_SET1_DATA);
 #endif
 #ifdef CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3
-	tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2);
-	tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES);
+	tegra_i2c_ll_write(TPS62361B_I2C_ADDR,
+			   TPS62361B_SET3_DATA);
 #endif
 	udelay(1000);
 
@@ -72,10 +57,11 @@ static void enable_cpu_power_rail(void)
 	 * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus.
 	 * First set VDD to 1.0125V, then enable the VDD regulator.
 	 */
-	tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2);
-	tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES);
+	tegra_i2c_ll_write(TPS65911_I2C_ADDR,
+			   TPS65911_VDDCTRL_OP_DATA);
 	udelay(1000);
-	tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES);
+	tegra_i2c_ll_write(TPS65911_I2C_ADDR,
+			   TPS65911_VDDCTRL_SR_DATA);
 	udelay(10 * 1000);
 }
 
@@ -142,6 +128,7 @@ void start_cpu(u32 reset_vector)
 
 	/* Enable VDD_CPU */
 	enable_cpu_power_rail();
+	pmic_enable_cpu_vdd();
 
 	set_cpu_running(0);
 
-- 
2.37.2



More information about the U-Boot mailing list