aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_twl.c60
-rw-r--r--arch/arm/mach-omap2/pm.h1
2 files changed, 61 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 00e1d2b53683..b341c36a93f3 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -59,8 +59,15 @@
59 59
60static bool is_offset_valid; 60static bool is_offset_valid;
61static u8 smps_offset; 61static u8 smps_offset;
62/*
63 * Flag to ensure Smartreflex bit in TWL
64 * being cleared in board file is not overwritten.
65 */
66static bool __initdata twl_sr_enable_autoinit;
62 67
68#define TWL4030_DCDC_GLOBAL_CFG 0x06
63#define REG_SMPS_OFFSET 0xE0 69#define REG_SMPS_OFFSET 0xE0
70#define SMARTREFLEX_ENABLE BIT(3)
64 71
65static unsigned long twl4030_vsel_to_uv(const u8 vsel) 72static unsigned long twl4030_vsel_to_uv(const u8 vsel)
66{ 73{
@@ -269,6 +276,18 @@ int __init omap3_twl_init(void)
269 omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; 276 omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
270 } 277 }
271 278
279 /*
280 * The smartreflex bit on twl4030 specifies if the setting of voltage
281 * is done over the I2C_SR path. Since this setting is independent of
282 * the actual usage of smartreflex AVS module, we enable TWL SR bit
283 * by default irrespective of whether smartreflex AVS module is enabled
284 * on the OMAP side or not. This is because without this bit enabled,
285 * the voltage scaling through vp forceupdate/bypass mechanism of
286 * voltage scaling will not function on TWL over I2C_SR.
287 */
288 if (!twl_sr_enable_autoinit)
289 omap3_twl_set_sr_bit(true);
290
272 voltdm = omap_voltage_domain_lookup("mpu"); 291 voltdm = omap_voltage_domain_lookup("mpu");
273 omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info); 292 omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
274 293
@@ -277,3 +296,44 @@ int __init omap3_twl_init(void)
277 296
278 return 0; 297 return 0;
279} 298}
299
300/**
301 * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL
302 * @enable: enable SR mode in twl or not
303 *
304 * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure
305 * voltage scaling through OMAP SR works. Else, the smartreflex bit
306 * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but
307 * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct
308 * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages,
309 * in those scenarios this bit is to be cleared (enable = false).
310 *
311 * Returns 0 on sucess, error is returned if I2C read/write fails.
312 */
313int __init omap3_twl_set_sr_bit(bool enable)
314{
315 u8 temp;
316 int ret;
317 if (twl_sr_enable_autoinit)
318 pr_warning("%s: unexpected multiple calls\n", __func__);
319
320 ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp,
321 TWL4030_DCDC_GLOBAL_CFG);
322 if (ret)
323 goto err;
324
325 if (enable)
326 temp |= SMARTREFLEX_ENABLE;
327 else
328 temp &= ~SMARTREFLEX_ENABLE;
329
330 ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp,
331 TWL4030_DCDC_GLOBAL_CFG);
332 if (!ret) {
333 twl_sr_enable_autoinit = true;
334 return 0;
335 }
336err:
337 pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret);
338 return ret;
339}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 1c1b0ab5b978..f4a5f716422b 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -127,6 +127,7 @@ static inline void omap_enable_smartreflex_on_init(void) {}
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); 129extern int omap4_twl_init(void);
130extern int omap3_twl_set_sr_bit(bool enable);
130#else 131#else
131static inline int omap3_twl_init(void) 132static inline int omap3_twl_init(void)
132{ 133{