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

Such writing is needed to configure main voltages of PMIC.

Tested-by: Andreas Westman Dorcsak <hed...@yahoo.com> # ASUS TF T30
Tested-by: Robert Eckelmann <longnose...@gmail.com> # ASUS TF101 T20
Tested-by: Svyatoslav Ryhel <clamo...@gmail.com> # LG P895 T30
Signed-off-by: Svyatoslav Ryhel <clamo...@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

Reply via email to