aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorThara Gopinath <thara@ti.com>2010-12-10 12:45:16 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-12-22 17:31:45 -0500
commit7bc3ed9ae632b9c94d3721d555d3452e24ca8ee3 (patch)
tree2781b54bdc5434225d0005f854ab28d99d81c0fc /arch/arm
parent1482d8be5525eccdec6286677d40af29da03a30c (diff)
OMAP4: Register voltage PMIC parameters with the voltage layer
TWL6030 is the power IC used along with OMAP4 in OMAP4 SDPs, blaze boards and panda boards. This patch registers the OMAP4 PMIC specific information with the voltage layer. This also involves implementing a different formula for voltage to vsel and vsel to voltage calculations from TWL4030. Signed-off-by: Thara Gopinath <thara@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_twl.c166
-rw-r--r--arch/arm/mach-omap2/pm.c1
-rw-r--r--arch/arm/mach-omap2/pm.h5
3 files changed, 172 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index b8f08742a6f0..15f8c6c1bb0f 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -16,6 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/i2c/twl.h>
19 20
20#include <plat/voltage.h> 21#include <plat/voltage.h>
21 22
@@ -37,6 +38,28 @@
37#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18 38#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
38#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30 39#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
39 40
41#define OMAP4_SRI2C_SLAVE_ADDR 0x12
42#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
43#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
44#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
45
46#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
47#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
48#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
49#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
50
51#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
52#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
53#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
54#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
55#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
56#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
57
58static bool is_offset_valid;
59static u8 smps_offset;
60
61#define REG_SMPS_OFFSET 0xE0
62
40unsigned long twl4030_vsel_to_uv(const u8 vsel) 63unsigned long twl4030_vsel_to_uv(const u8 vsel)
41{ 64{
42 return (((vsel * 125) + 6000)) * 100; 65 return (((vsel * 125) + 6000)) * 100;
@@ -47,6 +70,70 @@ u8 twl4030_uv_to_vsel(unsigned long uv)
47 return DIV_ROUND_UP(uv - 600000, 12500); 70 return DIV_ROUND_UP(uv - 600000, 12500);
48} 71}
49 72
73unsigned long twl6030_vsel_to_uv(const u8 vsel)
74{
75 /*
76 * In TWL6030 depending on the value of SMPS_OFFSET
77 * efuse register the voltage range supported in
78 * standard mode can be either between 0.6V - 1.3V or
79 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
80 * is programmed to all 0's where as starting from
81 * TWL6030 ES1.1 the efuse is programmed to 1
82 */
83 if (!is_offset_valid) {
84 twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
85 REG_SMPS_OFFSET);
86 is_offset_valid = true;
87 }
88
89 /*
90 * There is no specific formula for voltage to vsel
91 * conversion above 1.3V. There are special hardcoded
92 * values for voltages above 1.3V. Currently we are
93 * hardcoding only for 1.35 V which is used for 1GH OPP for
94 * OMAP4430.
95 */
96 if (vsel == 0x3A)
97 return 1350000;
98
99 if (smps_offset & 0x8)
100 return ((((vsel - 1) * 125) + 7000)) * 100;
101 else
102 return ((((vsel - 1) * 125) + 6000)) * 100;
103}
104
105u8 twl6030_uv_to_vsel(unsigned long uv)
106{
107 /*
108 * In TWL6030 depending on the value of SMPS_OFFSET
109 * efuse register the voltage range supported in
110 * standard mode can be either between 0.6V - 1.3V or
111 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
112 * is programmed to all 0's where as starting from
113 * TWL6030 ES1.1 the efuse is programmed to 1
114 */
115 if (!is_offset_valid) {
116 twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
117 REG_SMPS_OFFSET);
118 is_offset_valid = true;
119 }
120
121 /*
122 * There is no specific formula for voltage to vsel
123 * conversion above 1.3V. There are special hardcoded
124 * values for voltages above 1.3V. Currently we are
125 * hardcoding only for 1.35 V which is used for 1GH OPP for
126 * OMAP4430.
127 */
128 if (uv == 1350000)
129 return 0x3A;
130
131 if (smps_offset & 0x8)
132 return DIV_ROUND_UP(uv - 700000, 12500) + 1;
133 else
134 return DIV_ROUND_UP(uv - 600000, 12500) + 1;
135}
136
50static struct omap_volt_pmic_info omap3_mpu_volt_info = { 137static struct omap_volt_pmic_info omap3_mpu_volt_info = {
51 .slew_rate = 4000, 138 .slew_rate = 4000,
52 .step_size = 12500, 139 .step_size = 12500,
@@ -87,6 +174,85 @@ static struct omap_volt_pmic_info omap3_core_volt_info = {
87 .uv_to_vsel = twl4030_uv_to_vsel, 174 .uv_to_vsel = twl4030_uv_to_vsel,
88}; 175};
89 176
177static struct omap_volt_pmic_info omap4_mpu_volt_info = {
178 .slew_rate = 4000,
179 .step_size = 12500,
180 .on_volt = 1350000,
181 .onlp_volt = 1350000,
182 .ret_volt = 837500,
183 .off_volt = 600000,
184 .volt_setup_time = 0,
185 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
186 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
187 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
188 .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
189 .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
190 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
191 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
192 .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
193 .vsel_to_uv = twl6030_vsel_to_uv,
194 .uv_to_vsel = twl6030_uv_to_vsel,
195};
196
197static struct omap_volt_pmic_info omap4_iva_volt_info = {
198 .slew_rate = 4000,
199 .step_size = 12500,
200 .on_volt = 1100000,
201 .onlp_volt = 1100000,
202 .ret_volt = 837500,
203 .off_volt = 600000,
204 .volt_setup_time = 0,
205 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
206 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
207 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
208 .vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
209 .vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
210 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
211 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
212 .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
213 .vsel_to_uv = twl6030_vsel_to_uv,
214 .uv_to_vsel = twl6030_uv_to_vsel,
215};
216
217static struct omap_volt_pmic_info omap4_core_volt_info = {
218 .slew_rate = 4000,
219 .step_size = 12500,
220 .on_volt = 1100000,
221 .onlp_volt = 1100000,
222 .ret_volt = 837500,
223 .off_volt = 600000,
224 .volt_setup_time = 0,
225 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
226 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
227 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
228 .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
229 .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
230 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
231 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
232 .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
233 .vsel_to_uv = twl6030_vsel_to_uv,
234 .uv_to_vsel = twl6030_uv_to_vsel,
235};
236
237int __init omap4_twl_init(void)
238{
239 struct voltagedomain *voltdm;
240
241 if (!cpu_is_omap44xx())
242 return -ENODEV;
243
244 voltdm = omap_voltage_domain_lookup("mpu");
245 omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
246
247 voltdm = omap_voltage_domain_lookup("iva");
248 omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
249
250 voltdm = omap_voltage_domain_lookup("core");
251 omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
252
253 return 0;
254}
255
90int __init omap3_twl_init(void) 256int __init omap3_twl_init(void)
91{ 257{
92 struct voltagedomain *voltdm; 258 struct voltagedomain *voltdm;
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d849e0071b94..aac9bacf1bd1 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -240,6 +240,7 @@ static int __init omap2_common_pm_late_init(void)
240{ 240{
241 /* Init the OMAP TWL parameters */ 241 /* Init the OMAP TWL parameters */
242 omap3_twl_init(); 242 omap3_twl_init();
243 omap4_twl_init();
243 244
244 /* Init the voltage layer */ 245 /* Init the voltage layer */
245 omap_voltage_late_init(); 246 omap_voltage_late_init();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index c975a79691b7..1c1b0ab5b978 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -126,11 +126,16 @@ static inline void omap_enable_smartreflex_on_init(void) {}
126 126
127#ifdef CONFIG_TWL4030_CORE 127#ifdef CONFIG_TWL4030_CORE
128extern int omap3_twl_init(void); 128extern int omap3_twl_init(void);
129extern int omap4_twl_init(void);
129#else 130#else
130static inline int omap3_twl_init(void) 131static inline int omap3_twl_init(void)
131{ 132{
132 return -EINVAL; 133 return -EINVAL;
133} 134}
135static inline int omap4_twl_init(void)
136{
137 return -EINVAL;
138}
134#endif 139#endif
135 140
136#endif 141#endif