* [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
@ 2011-02-18 17:08 Lesly A M
2011-02-18 17:08 ` [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence Lesly A M
` (13 more replies)
0 siblings, 14 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Patch series for TWL4030 power scripts and workaround for TWL errata 27.
Changes for implementing TWL4030 power scripts recommended by hardware team.
Introduced a new TWL4030 power script file, which can be used by different
OMAP3 board with the power companion chip TWL4030.
Updated the changes for TWL4030 errata 27 & 28, modified the
TWL4030 power script and voltage controller setuptime.
Workaround for TWL4030 errata 27 & 28 is required for
Si version less than or equal to TWL5030 ES1.1.
TWL4030 script changes rebased on Kevin's PM tree in pm branch.
Changes in v7:
changes to fix Nishanth Menon's comments
i) Added the TWL4030 Errata 27 fix
split the first patch in v6
i) fix for twl4030 script load
ii) correct the warning print during script loading
Added new patch files
i) pmic_info struct cleanup
ii) changing sys_off signal polarity
Updated the change logs
This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
Tested with suspend/resume script, which will test system suspend in a loop.
Tested for more than 1000 iterations.
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
Lesly A M (12):
omap3: pm: Fix for the TRITON sleep/wakeup sequence
omap3: pm: Correct the warning print during script loading
omap3: pm: cleanup pmic_info structure
omap3: pm: Using separate clk/volt setup_time for RET and OFF states
omap3630: pm: Adding voltage controller data
omap3: pm: Correcting the sys_offmode signal polarity
omap3: pm: Re-programing the setup time based on CORE target state
omap3: pm: TWL4030 power scripts for OMAP3 boards
omap3: pm: TWL5030 version checking
mfd: TWL4030: changes for TRITON Errata 27 workaround
omap3430: Updating the board file to use TWL4030 scripts
omap3630: Updating the board file to use TWL4030 scripts
arch/arm/mach-omap2/Makefile | 12 +-
arch/arm/mach-omap2/board-3430sdp.c | 3 +-
arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +
arch/arm/mach-omap2/omap_twl.c | 369 +++++++++++++++++++++++---
arch/arm/mach-omap2/pm34xx.c | 15 +-
arch/arm/mach-omap2/twl4030.c | 261 ++++++++++++++++++
arch/arm/mach-omap2/twl4030.h | 21 ++
arch/arm/mach-omap2/voltage.c | 167 +++++++++---
arch/arm/plat-omap/include/plat/voltage.h | 49 +++-
drivers/mfd/twl-core.c | 50 ++++
drivers/mfd/twl4030-power.c | 79 ++++++-
include/linux/i2c/twl.h | 45 +++-
12 files changed, 961 insertions(+), 112 deletions(-)
create mode 100644 arch/arm/mach-omap2/twl4030.c
create mode 100644 arch/arm/mach-omap2/twl4030.h
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 23:38 ` David Cohen
2011-02-18 17:08 ` [PATCH 02/12] omap3: pm: Correct the warning print during script loading Lesly A M
` (12 subsequent siblings)
13 siblings, 1 reply; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Since the function to populate the sleep script is getting called always
irrespective of the flag "TWL4030_SLEEP_SCRIPT", other scripts data
is getting over written by the sleep script.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/mfd/twl4030-power.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 16422de..2c0d4d1 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -447,12 +447,13 @@ static int __init load_twl4030_script(struct twl4030_script *tscript,
if (err)
goto out;
}
- if (tscript->flags & TWL4030_SLEEP_SCRIPT)
+ if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
if (order)
pr_warning("TWL4030: Bad order of scripts (sleep "\
"script before wakeup) Leads to boot"\
"failure on some boards\n");
err = twl4030_config_sleep_sequence(address);
+ }
out:
return err;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 02/12] omap3: pm: Correct the warning print during script loading
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
2011-02-18 17:08 ` [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 03/12] omap3: pm: cleanup pmic_info structure Lesly A M
` (11 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Correcting the if condition check for printing the warning,
if wakeup script is not updated before updating the sleep script.
Since the flag 'order' is set to '1' while updating the wakeup script for P1P2,
the condition checking for printing the warning should be if(!order)
(ie: print the warning if wakeup script is not updated before updating the sleep script)
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/mfd/twl4030-power.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 2c0d4d1..8373d79 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -448,7 +448,7 @@ static int __init load_twl4030_script(struct twl4030_script *tscript,
goto out;
}
if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
- if (order)
+ if (!order)
pr_warning("TWL4030: Bad order of scripts (sleep "\
"script before wakeup) Leads to boot"\
"failure on some boards\n");
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 03/12] omap3: pm: cleanup pmic_info structure
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
2011-02-18 17:08 ` [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence Lesly A M
2011-02-18 17:08 ` [PATCH 02/12] omap3: pm: Correct the warning print during script loading Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 04/12] omap3: pm: Using separate clk/volt setup_time for RET and OFF states Lesly A M
` (10 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Removing the hard coded values, rearranging the elements based on
OMAP, PMIC & board specific.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/omap_twl.c | 99 +++++++++++++++++++----------
arch/arm/plat-omap/include/plat/voltage.h | 8 ++-
2 files changed, 69 insertions(+), 38 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 00e1d2b..9510623 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -57,6 +57,35 @@
#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
+#define OMAP3430_VDD1_ON 1200000
+#define OMAP3430_VDD1_ONLP 1000000
+#define OMAP3430_VDD1_RET 975000
+#define OMAP3430_VDD1_OFF 600000
+
+#define OMAP3430_VDD2_ON 1200000
+#define OMAP3430_VDD2_ONLP 1000000
+#define OMAP3430_VDD2_RET 975000
+#define OMAP3430_VDD2_OFF 600000
+
+#define OMAP4430_VDD1_ON 1350000
+#define OMAP4430_VDD1_ONLP 1350000
+#define OMAP4430_VDD1_RET 837500
+#define OMAP4430_VDD1_OFF 600000
+
+#define OMAP4430_VDD2_ON 1100000
+#define OMAP4430_VDD2_ONLP 1100000
+#define OMAP4430_VDD2_RET 837500
+#define OMAP4430_VDD2_OFF 600000
+
+#define OMAP4430_VDD3_ON 1100000
+#define OMAP4430_VDD3_ONLP 1100000
+#define OMAP4430_VDD3_RET 837500
+#define OMAP4430_VDD3_OFF 600000
+
+#define OMAP_VOLTSETUP_TIME 0xff
+#define TWL4030_SMPS_SLEW_RATE 4000
+#define TWL4030_SMPS_STEP_SIZE 12500
+
static bool is_offset_valid;
static u8 smps_offset;
@@ -137,101 +166,101 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
}
static struct omap_volt_pmic_info omap3_mpu_volt_info = {
- .slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1200000,
- .onlp_volt = 1000000,
- .ret_volt = 975000,
- .off_volt = 600000,
- .volt_setup_time = 0xfff,
+ .on_volt = OMAP3430_VDD1_ON,
+ .onlp_volt = OMAP3430_VDD1_ONLP,
+ .ret_volt = OMAP3430_VDD1_RET,
+ .off_volt = OMAP3430_VDD1_OFF,
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
.vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .volt_setup_time = OMAP_VOLTSETUP_TIME,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
static struct omap_volt_pmic_info omap3_core_volt_info = {
- .slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1200000,
- .onlp_volt = 1000000,
- .ret_volt = 975000,
- .off_volt = 600000,
- .volt_setup_time = 0xfff,
+ .on_volt = OMAP3430_VDD2_ON,
+ .onlp_volt = OMAP3430_VDD2_ONLP,
+ .ret_volt = OMAP3430_VDD2_RET,
+ .off_volt = OMAP3430_VDD2_OFF,
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
.vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .volt_setup_time = OMAP_VOLTSETUP_TIME,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
static struct omap_volt_pmic_info omap4_mpu_volt_info = {
- .slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1350000,
- .onlp_volt = 1350000,
- .ret_volt = 837500,
- .off_volt = 600000,
- .volt_setup_time = 0,
+ .on_volt = OMAP4430_VDD1_ON,
+ .onlp_volt = OMAP4430_VDD1_ONLP,
+ .ret_volt = OMAP4430_VDD1_RET,
+ .off_volt = OMAP4430_VDD1_OFF,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .volt_setup_time = OMAP_VOLTSETUP_TIME,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
static struct omap_volt_pmic_info omap4_iva_volt_info = {
- .slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
- .volt_setup_time = 0,
+ .on_volt = OMAP4430_VDD2_ON,
+ .onlp_volt = OMAP4430_VDD2_ONLP,
+ .ret_volt = OMAP4430_VDD2_RET,
+ .off_volt = OMAP4430_VDD2_OFF,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .volt_setup_time = OMAP_VOLTSETUP_TIME,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
static struct omap_volt_pmic_info omap4_core_volt_info = {
- .slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
- .volt_setup_time = 0,
+ .on_volt = OMAP4430_VDD3_ON,
+ .onlp_volt = OMAP4430_VDD3_ONLP,
+ .ret_volt = OMAP4430_VDD3_RET,
+ .off_volt = OMAP4430_VDD3_OFF,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .volt_setup_time = OMAP_VOLTSETUP_TIME,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 5bd204e..7fcb788 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -94,21 +94,23 @@ struct omap_volt_data {
* @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
*/
struct omap_volt_pmic_info {
- int slew_rate;
- int step_size;
+ /* OMAP specific params: vc_cmd_values, vp_params */
u32 on_volt;
u32 onlp_volt;
u32 ret_volt;
u32 off_volt;
- u16 volt_setup_time;
u8 vp_erroroffset;
u8 vp_vstepmin;
u8 vp_vstepmax;
u8 vp_vddmin;
u8 vp_vddmax;
u8 vp_timeout_us;
+ /* PM IC specific params: voltsetup, pmic_config values */
+ u16 volt_setup_time;
u8 i2c_slave_addr;
u8 pmic_reg;
+ int slew_rate;
+ int step_size;
unsigned long (*vsel_to_uv) (const u8 vsel);
u8 (*uv_to_vsel) (unsigned long uV);
};
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 04/12] omap3: pm: Using separate clk/volt setup_time for RET and OFF states
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (2 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 03/12] omap3: pm: cleanup pmic_info structure Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 05/12] omap3630: pm: Adding voltage controller data Lesly A M
` (9 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Since the clocksetup & voltsetup time used for RET & OFF is different.
And Updating the VC setuptime struct during init based on the OMAP Si.
Clocksetup & voltsetup time values used are recommended by TI Soldel team,
which is tested on omap3 platform.
http://omapedia.org/wiki/TWL4030_power_scripts
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/omap_twl.c | 147 ++++++++++++++++++++++++++++-
arch/arm/mach-omap2/voltage.c | 16 +++-
arch/arm/plat-omap/include/plat/voltage.h | 39 ++++++--
3 files changed, 184 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 9510623..4b5a8e9 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -86,6 +86,86 @@
#define TWL4030_SMPS_SLEW_RATE 4000
#define TWL4030_SMPS_STEP_SIZE 12500
+/*
+ * Configuring setuptime when using i2c/sys_off signal for entering OFFMODE.
+ *
+ * 1. clock & volt setuptime for OMAP when using i2c for entering OFFMODE.
+ *
+ * <-----------clksetup----------->|
+ *
+ * |<----------voltsetup1-------->|
+ *
+ * |<-vdd2 setup->|
+ * |<-vdd1 setup->|
+ *
+ * voltsetup1 is total (VDD2 + VDD1) setup time
+ * when this sequence is managed by OMAP.
+ *
+ * voltsetup1 = voltsetup1[31:16] (VDD2 voltsetup time) +
+ * voltsetup1[15:0] (VDD1 voltsetup time).
+ *
+ * 2. clock & volt setuptime for OMAP when using sys_off signal
+ * for entering OFFMODE.
+ *
+ * <-------------------------clksetup---------------------------->|
+ *
+ * <----voltoffset---->|
+ * |<---------------voltsetup2--------------->|
+ *
+ * |<--vdd2 setup-->|
+ * |<--vdd1 setup-->|
+ *
+ * clksetup = voltoffset + voltsetup2.
+ *
+ * When exiting OFFMODE:
+ *
+ * clksetup is the rampup and stabilization time required
+ * for the X'stall or oscillator.
+ *
+ * voltoffset is the offset time to de-assert the sys_off signal,
+ * when this sequence is managed by the PM IC.
+ * And this will trigger the VDD1 & VDD2 voltage ramp on PM IC.
+ *
+ * voltsetup2 is the overall setup time of VDD1 and VDD2 regulators.
+ */
+
+/*
+ * VOLTSETUP1 for RET & OFF
+ * Setup time of the VDD1 and VDD2 regulators.
+ * Number of sys_clk cycles required for VDD regulator to stabilize is
+ * devide by 8 and programmed in the register field for VDD1/VDD2.
+ */
+#define OMAP3_VOLTSETUP_VDD1_RET 28 /* 28 uS */
+#define OMAP3_VOLTSETUP_VDD2_RET 26 /* 26 uS */
+
+#define OMAP3_VOLTSETUP_VDD1_OFF 55 /* 55 uS */
+#define OMAP3_VOLTSETUP_VDD2_OFF 49 /* 49 uS */
+
+/*
+ * VOLTOFFSET for RET & OFF
+ * Offset-time to de-assert sys_offmode signal while exiting the OFF mode
+ * and when the OFF sequence is supervised by the Power IC.
+ */
+#define OMAP3_VOLTOFFSET_RET 0
+#define OMAP3_VOLTOFFSET_OFF 8545 /* 8.545 mS */
+
+/*
+ * VOLTSETUP2 for RET & OFF
+ * Overall setup time of VDD1 and VDD2 regulators.
+ * Used when exiting OFF mode with the Power IC managing the
+ * sequencing of the voltages regulation steps.
+ */
+#define OMAP3_VOLTSETUP2_RET 0
+#define OMAP3_VOLTSETUP2_OFF 1526 /* 1.526 mS */
+
+/*
+ * OMAP3 CLKSETUP TIME for RET & OFF
+ * Setup time of the oscillator (sys_clk), based on number of
+ * 32 kHz clock cycles.
+ */
+#define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
+#define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
+
static bool is_offset_valid;
static u8 smps_offset;
@@ -176,13 +256,28 @@ static struct omap_volt_pmic_info omap3_mpu_volt_info = {
.vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
- .volt_setup_time = OMAP_VOLTSETUP_TIME,
+ .voltsetup_ret = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD1_RET,
+ .voltsetup2 = OMAP3_VOLTSETUP2_RET,
+ .voltoffset = OMAP3_VOLTOFFSET_RET,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD1_OFF,
+ .voltsetup2 = OMAP3_VOLTSETUP2_OFF,
+ .voltoffset = OMAP3_VOLTOFFSET_OFF,
+ },
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
.slew_rate = TWL4030_SMPS_SLEW_RATE,
.step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
+ .clksetup_ret = {
+ .clksetup = OMAP3_CLKSETUP_RET,
+ },
+ .clksetup_off = {
+ .clksetup = OMAP3_CLKSETUP_OFF,
+ },
};
static struct omap_volt_pmic_info omap3_core_volt_info = {
@@ -196,15 +291,34 @@ static struct omap_volt_pmic_info omap3_core_volt_info = {
.vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
- .volt_setup_time = OMAP_VOLTSETUP_TIME,
+ .voltsetup_ret = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD2_RET,
+ .voltsetup2 = OMAP3_VOLTSETUP2_RET,
+ .voltoffset = OMAP3_VOLTOFFSET_RET,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD2_OFF,
+ .voltsetup2 = OMAP3_VOLTSETUP2_OFF,
+ .voltoffset = OMAP3_VOLTOFFSET_OFF,
+ },
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
.slew_rate = TWL4030_SMPS_SLEW_RATE,
.step_size = TWL4030_SMPS_STEP_SIZE,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
+ .clksetup_ret = {
+ .clksetup = OMAP3_CLKSETUP_RET,
+ },
+ .clksetup_off = {
+ .clksetup = OMAP3_CLKSETUP_OFF,
+ },
};
+/*
+ * FIXME: voltsetup time values should be updated
+ * after profiling on OMAP4 board.
+ */
static struct omap_volt_pmic_info omap4_mpu_volt_info = {
.on_volt = OMAP4430_VDD1_ON,
.onlp_volt = OMAP4430_VDD1_ONLP,
@@ -216,7 +330,12 @@ static struct omap_volt_pmic_info omap4_mpu_volt_info = {
.vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
- .volt_setup_time = OMAP_VOLTSETUP_TIME,
+ .voltsetup_ret = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
.slew_rate = TWL4030_SMPS_SLEW_RATE,
@@ -225,6 +344,10 @@ static struct omap_volt_pmic_info omap4_mpu_volt_info = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
+/*
+ * FIXME: voltsetup time values should be updated
+ * after profiling on OMAP4 board.
+ */
static struct omap_volt_pmic_info omap4_iva_volt_info = {
.on_volt = OMAP4430_VDD2_ON,
.onlp_volt = OMAP4430_VDD2_ONLP,
@@ -236,7 +359,12 @@ static struct omap_volt_pmic_info omap4_iva_volt_info = {
.vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
- .volt_setup_time = OMAP_VOLTSETUP_TIME,
+ .voltsetup_ret = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
.slew_rate = TWL4030_SMPS_SLEW_RATE,
@@ -245,6 +373,10 @@ static struct omap_volt_pmic_info omap4_iva_volt_info = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
+/*
+ * FIXME: voltsetup time values should be updated
+ * after profiling on OMAP4 board.
+ */
static struct omap_volt_pmic_info omap4_core_volt_info = {
.on_volt = OMAP4430_VDD3_ON,
.onlp_volt = OMAP4430_VDD3_ONLP,
@@ -256,7 +388,12 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
.vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
- .volt_setup_time = OMAP_VOLTSETUP_TIME,
+ .voltsetup_ret = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP_VOLTSETUP_TIME,
+ },
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
.pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
.slew_rate = TWL4030_SMPS_SLEW_RATE,
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 12be525..1c58f8b 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -27,6 +27,7 @@
#include <plat/common.h>
#include <plat/voltage.h>
+#include <plat/clock.h>
#include "prm-regbits-34xx.h"
#include "prm-regbits-44xx.h"
@@ -95,6 +96,8 @@ struct vc_reg_info {
u8 bypass_val_reg;
u8 cmdval_reg;
u8 voltsetup_reg;
+ u8 voltsetup2_reg;
+ u8 voltoffset_reg;
/*VC_SMPS_SA*/
u8 smps_sa_shift;
u32 smps_sa_mask;
@@ -771,7 +774,7 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)
/*Configure the setup times */
vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
vc_val &= ~vdd->vc_reg.voltsetup_mask;
- vc_val |= vdd->pmic_info->volt_setup_time <<
+ vc_val |= vdd->pmic_info->voltsetup_ret.voltsetup <<
vdd->vc_reg.voltsetup_shift;
vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
@@ -794,9 +797,12 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)
OMAP3_PRM_VC_CH_CONF_OFFSET);
vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
OMAP3_PRM_VC_I2C_CFG_OFFSET);
- vdd->write_reg(OMAP3_CLKSETUP, mod, OMAP3_PRM_CLKSETUP_OFFSET);
- vdd->write_reg(OMAP3_VOLTOFFSET, mod, OMAP3_PRM_VOLTOFFSET_OFFSET);
- vdd->write_reg(OMAP3_VOLTSETUP2, mod, OMAP3_PRM_VOLTSETUP2_OFFSET);
+ vdd->write_reg(vdd->pmic_info->clksetup_ret.clksetup, mod,
+ OMAP3_PRM_CLKSETUP_OFFSET);
+ vdd->write_reg(vdd->pmic_info->voltsetup_ret.voltoffset, mod,
+ vdd->vc_reg.voltoffset_reg);
+ vdd->write_reg(vdd->pmic_info->voltsetup_ret.voltsetup2, mod,
+ vdd->vc_reg.voltsetup2_reg);
is_initialized = true;
}
@@ -877,6 +883,8 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->vc_reg.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
vdd->vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
vdd->vc_reg.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
+ vdd->vc_reg.voltsetup2_reg = OMAP3_PRM_VOLTSETUP2_OFFSET;
+ vdd->vc_reg.voltoffset_reg = OMAP3_PRM_VOLTOFFSET_OFFSET;
vdd->vc_reg.data_shift = OMAP3430_DATA_SHIFT;
vdd->vc_reg.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT;
vdd->vc_reg.regaddr_shift = OMAP3430_REGADDR_SHIFT;
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 7fcb788..c0373d0 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -19,14 +19,6 @@
#define VOLTSCALE_VPFORCEUPDATE 1
#define VOLTSCALE_VCBYPASS 2
-/*
- * OMAP3 GENERIC setup times. Revisit to see if these needs to be
- * passed from board or PMIC file
- */
-#define OMAP3_CLKSETUP 0xff
-#define OMAP3_VOLTOFFSET 0xff
-#define OMAP3_VOLTSETUP2 0xff
-
/* Voltage value defines */
#define OMAP3430_VDD_MPU_OPP1_UV 975000
#define OMAP3430_VDD_MPU_OPP2_UV 1075000
@@ -87,11 +79,36 @@ struct omap_volt_data {
};
/**
+ * struct volt_setuptime - voltage setup time values.
+ * @voltsetup: voltage setuptime for regulators (VDD1/VDD2),
+ * when the OMAP manages the sequencing of voltage regulation steps.
+ * @voltsetup2: overall setup time of regulators (VDD2 & VDD1),
+ * when the PMIC manages the sequencing of voltage regulation steps.
+ * @voltoffset: offset-time to de-assert sys_offmode signal,
+ * when the PMIC manages the sequencing of voltage regulation steps.
+ */
+struct volt_setuptime {
+ u16 voltsetup;
+ u16 voltsetup2;
+ u16 voltoffset;
+};
+
+/**
+ * struct clk_setuptime
+ * @clksetup: clksetup time (rampup + stabilization time)
+ */
+struct clk_setuptime {
+ u16 clksetup;
+};
+
+/**
* struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * @voltsetup_ret/off: voltetup values for CORE RET/OFF.
* @slew_rate: PMIC slew rate (in uv/us)
* @step_size: PMIC voltage step size (in uv)
* @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
* @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
+ * @clksetup_ret/off: clksetup values for CORE RET/OFF.
*/
struct omap_volt_pmic_info {
/* OMAP specific params: vc_cmd_values, vp_params */
@@ -106,13 +123,17 @@ struct omap_volt_pmic_info {
u8 vp_vddmax;
u8 vp_timeout_us;
/* PM IC specific params: voltsetup, pmic_config values */
- u16 volt_setup_time;
+ struct volt_setuptime voltsetup_ret;
+ struct volt_setuptime voltsetup_off;
u8 i2c_slave_addr;
u8 pmic_reg;
int slew_rate;
int step_size;
unsigned long (*vsel_to_uv) (const u8 vsel);
u8 (*uv_to_vsel) (unsigned long uV);
+ /* Board specific: clksetup_time */
+ struct clk_setuptime clksetup_ret;
+ struct clk_setuptime clksetup_off;
};
unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 05/12] omap3630: pm: Adding voltage controller data
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (3 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 04/12] omap3: pm: Using separate clk/volt setup_time for RET and OFF states Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 06/12] omap3: pm: Correcting the sys_offmode signal polarity Lesly A M
` (8 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Since voltage controller command values(ON/RET) for OMAP3630 Si is different.
Using the new voltage values specified in the Operating Condition Addendum
for OMAP3630.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/omap_twl.c | 98 ++++++++++++++++++++++++++++++++++++---
1 files changed, 90 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 4b5a8e9..f0feab9 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -67,6 +67,16 @@
#define OMAP3430_VDD2_RET 975000
#define OMAP3430_VDD2_OFF 600000
+#define OMAP3630_VDD1_ON 1100000
+#define OMAP3630_VDD1_ONLP 1000000
+#define OMAP3630_VDD1_RET 830000
+#define OMAP3630_VDD1_OFF 600000
+
+#define OMAP3630_VDD2_ON 1137500
+#define OMAP3630_VDD2_ONLP 1000000
+#define OMAP3630_VDD2_RET 830000
+#define OMAP3630_VDD2_OFF 600000
+
#define OMAP4430_VDD1_ON 1350000
#define OMAP4430_VDD1_ONLP 1350000
#define OMAP4430_VDD1_RET 837500
@@ -245,7 +255,7 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
return DIV_ROUND_UP(uv - 600000, 12500) + 1;
}
-static struct omap_volt_pmic_info omap3_mpu_volt_info = {
+static struct omap_volt_pmic_info omap3430_mpu_volt_info = {
.on_volt = OMAP3430_VDD1_ON,
.onlp_volt = OMAP3430_VDD1_ONLP,
.ret_volt = OMAP3430_VDD1_RET,
@@ -280,7 +290,7 @@ static struct omap_volt_pmic_info omap3_mpu_volt_info = {
},
};
-static struct omap_volt_pmic_info omap3_core_volt_info = {
+static struct omap_volt_pmic_info omap3430_core_volt_info = {
.on_volt = OMAP3430_VDD2_ON,
.onlp_volt = OMAP3430_VDD2_ONLP,
.ret_volt = OMAP3430_VDD2_RET,
@@ -315,6 +325,76 @@ static struct omap_volt_pmic_info omap3_core_volt_info = {
},
};
+static struct omap_volt_pmic_info omap3630_mpu_volt_info = {
+ .on_volt = OMAP3630_VDD1_ON,
+ .onlp_volt = OMAP3630_VDD1_ONLP,
+ .ret_volt = OMAP3630_VDD1_RET,
+ .off_volt = OMAP3630_VDD1_OFF,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .voltsetup_ret = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD1_RET,
+ .voltsetup2 = OMAP3_VOLTSETUP2_RET,
+ .voltoffset = OMAP3_VOLTOFFSET_RET,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD1_OFF,
+ .voltsetup2 = OMAP3_VOLTSETUP2_OFF,
+ .voltoffset = OMAP3_VOLTOFFSET_OFF,
+ },
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+ .clksetup_ret = {
+ .clksetup = OMAP3_CLKSETUP_RET,
+ },
+ .clksetup_off = {
+ .clksetup = OMAP3_CLKSETUP_OFF,
+ },
+};
+
+static struct omap_volt_pmic_info omap3630_core_volt_info = {
+ .on_volt = OMAP3630_VDD2_ON,
+ .onlp_volt = OMAP3630_VDD2_ONLP,
+ .ret_volt = OMAP3630_VDD2_RET,
+ .off_volt = OMAP3630_VDD2_OFF,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .voltsetup_ret = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD2_RET,
+ .voltsetup2 = OMAP3_VOLTSETUP2_RET,
+ .voltoffset = OMAP3_VOLTOFFSET_RET,
+ },
+ .voltsetup_off = {
+ .voltsetup = OMAP3_VOLTSETUP_VDD2_OFF,
+ .voltsetup2 = OMAP3_VOLTSETUP2_OFF,
+ .voltoffset = OMAP3_VOLTOFFSET_OFF,
+ },
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .slew_rate = TWL4030_SMPS_SLEW_RATE,
+ .step_size = TWL4030_SMPS_STEP_SIZE,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+ .clksetup_ret = {
+ .clksetup = OMAP3_CLKSETUP_RET,
+ },
+ .clksetup_off = {
+ .clksetup = OMAP3_CLKSETUP_OFF,
+ },
+};
+
/*
* FIXME: voltsetup time values should be updated
* after profiling on OMAP4 board.
@@ -424,22 +504,24 @@ int __init omap4_twl_init(void)
int __init omap3_twl_init(void)
{
struct voltagedomain *voltdm;
+ struct omap_volt_pmic_info *mpu_volt_info, *core_volt_info;
if (!cpu_is_omap34xx())
return -ENODEV;
if (cpu_is_omap3630()) {
- omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
- omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
- omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
- omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+ mpu_volt_info = &omap3630_mpu_volt_info;
+ core_volt_info = &omap3630_core_volt_info;
+ } else {
+ mpu_volt_info = &omap3430_mpu_volt_info;
+ core_volt_info = &omap3430_core_volt_info;
}
voltdm = omap_voltage_domain_lookup("mpu");
- omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
+ omap_voltage_register_pmic(voltdm, mpu_volt_info);
voltdm = omap_voltage_domain_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
+ omap_voltage_register_pmic(voltdm, core_volt_info);
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 06/12] omap3: pm: Correcting the sys_offmode signal polarity
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (4 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 05/12] omap3630: pm: Adding voltage controller data Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 07/12] omap3: pm: Re-programing the setup time based on CORE target state Lesly A M
` (7 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Changing the polarity of the sys_offmode signal to active low,
to get a High to Low transition on the NSLEEP1 of PM IC when OMAP is
entering offmode. Because on PM IC the power resources (LDO, DCDC regulators)
associated with P1 group which is controlled by NSLEEP1 are set to sleep,
when there is transition form High to Low.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/pm34xx.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index e46f4b5..8a7c756 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -1034,6 +1034,10 @@ static int __init omap3_pm_init(void)
printk(KERN_ERR "Power Management for TI OMAP3.\n");
+ /* Changing the polarity of the sys_offmode signal to active low */
+ omap2_prm_clear_mod_reg_bits(OMAP3430_OFFMODE_POL_MASK,
+ OMAP3430_GR_MOD, OMAP3_PRM_POLCTRL_OFFSET);
+
/* XXX prcm_setup_regs needs to be before enabling hw
* supervised mode for powerdomains */
prcm_setup_regs();
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 07/12] omap3: pm: Re-programing the setup time based on CORE target state
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (5 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 06/12] omap3: pm: Correcting the sys_offmode signal polarity Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 08/12] omap3: pm: TWL4030 power scripts for OMAP3 boards Lesly A M
` (6 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Since the setup time values are different for each CORE_DOMAIN target state
and VDD1(MPU voltage) can not be scaled separately. Because VDD1 has
dependency with VDD2(CORE voltage)
Adding a new function omap3_voltage_vc_update() to re-program the VC setuptime
data while entering low power mode.
Also added a flag to optimize the sleep latency. This flag is checked before
calling the vc_update, and is ignored if it is already configured for
the same target state.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/pm34xx.c | 11 ++-
arch/arm/mach-omap2/voltage.c | 165 ++++++++++++++++++++--------
arch/arm/plat-omap/include/plat/voltage.h | 2 +
3 files changed, 127 insertions(+), 51 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8a7c756..0d94dc1 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -40,6 +40,7 @@
#include <plat/gpmc.h>
#include <plat/dma.h>
#include <plat/usb.h>
+#include <plat/voltage.h>
#include <asm/tlbflush.h>
@@ -356,6 +357,7 @@ void omap_sram_idle(void)
int core_next_state = PWRDM_POWER_ON;
int per_going_off;
int core_prev_state, per_prev_state;
+ static int core_next_state_set = PWRDM_POWER_ON;
u32 sdrc_pwr = 0;
if (!_omap_sram_idle)
@@ -422,6 +424,11 @@ void omap_sram_idle(void)
omap3_core_save_context();
omap3_cm_save_context();
}
+ /* Update the voltsetup time for RET/OFF */
+ if (core_next_state != core_next_state_set) {
+ omap3_voltage_vc_update(core_next_state);
+ core_next_state_set = core_next_state;
+ }
}
omap3_intc_prepare_idle();
@@ -478,10 +485,6 @@ void omap_sram_idle(void)
}
omap_uart_resume_idle(0);
omap_uart_resume_idle(1);
- if (core_next_state == PWRDM_POWER_OFF)
- omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
- OMAP3430_GR_MOD,
- OMAP3_PRM_VOLTCTRL_OFFSET);
}
omap3_intc_resume_idle();
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 1c58f8b..43279a6 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -35,11 +35,18 @@
#include "prcm44xx.h"
#include "prminst44xx.h"
#include "control.h"
+#include "powerdomain.h"
#define VP_IDLE_TIMEOUT 200
#define VP_TRANXDONE_TIMEOUT 300
#define VOLTAGE_DIR_SIZE 16
+/* duration of one sys_32k clk cycle in uS */
+#define SYS_32K_CLK_CYCLE 31
+
+static u32 sys_clk_speed;
+static u32 sys_clk_cycle;
+
/* Voltage processor register offsets */
struct vp_reg_offs {
u8 vpconfig;
@@ -771,13 +778,6 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)
vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
- /*Configure the setup times */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
- vc_val &= ~vdd->vc_reg.voltsetup_mask;
- vc_val |= vdd->pmic_info->voltsetup_ret.voltsetup <<
- vdd->vc_reg.voltsetup_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
-
/* Set up the on, inactive, retention and off voltage */
on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
@@ -797,20 +797,14 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)
OMAP3_PRM_VC_CH_CONF_OFFSET);
vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
OMAP3_PRM_VC_I2C_CFG_OFFSET);
- vdd->write_reg(vdd->pmic_info->clksetup_ret.clksetup, mod,
- OMAP3_PRM_CLKSETUP_OFFSET);
- vdd->write_reg(vdd->pmic_info->voltsetup_ret.voltoffset, mod,
- vdd->vc_reg.voltoffset_reg);
- vdd->write_reg(vdd->pmic_info->voltsetup_ret.voltsetup2, mod,
- vdd->vc_reg.voltsetup2_reg);
+ omap3_voltage_vc_update(PWRDM_POWER_RET);
is_initialized = true;
}
/* Sets up all the VDD related info for OMAP3 */
static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
{
- struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
+ u32 timeout_val, waittime;
if (!vdd->pmic_info) {
pr_err("%s: PMIC info requried to configure vdd_%s not"
@@ -853,21 +847,6 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
return -EINVAL;
}
- /*
- * Sys clk rate is require to calculate vp timeout value and
- * smpswaittimemin and smpswaittimemax.
- */
- sys_ck = clk_get(NULL, "sys_ck");
- if (IS_ERR(sys_ck)) {
- pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
- return -EINVAL;
- }
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
-
/* Generic voltage parameters */
vdd->curr_volt = 1200000;
vdd->ocp_mod = OCP_MOD;
@@ -989,8 +968,7 @@ static void __init omap4_vc_init(struct omap_vdd_info *vdd)
/* Sets up all the VDD related info for OMAP4 */
static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
{
- struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
+ u32 timeout_val, waittime;
if (!vdd->pmic_info) {
pr_err("%s: PMIC info requried to configure vdd_%s not"
@@ -1046,21 +1024,6 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
return -EINVAL;
}
- /*
- * Sys clk rate is require to calculate vp timeout value and
- * smpswaittimemin and smpswaittimemax.
- */
- sys_ck = clk_get(NULL, "sys_clkin_ck");
- if (IS_ERR(sys_ck)) {
- pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
- return -EINVAL;
- }
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
-
/* Generic voltage parameters */
vdd->curr_volt = 1200000;
vdd->ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
@@ -1557,10 +1520,118 @@ int __init omap_voltage_late_init(void)
}
/**
+ * omap3_voltage_vc_update() - update the clk & vol setup time.
+ *
+ * @core_next_state: next target state for CORE DOMAIN.
+ *
+ * This API is to be called to update the clk & volt setup time
+ * depending on the CORE target state.
+ */
+void omap3_voltage_vc_update(int core_next_state)
+{
+ u32 voltsetup_time;
+ u16 mod;
+ struct voltagedomain *voltdm;
+ struct omap_vdd_info *vdd_mpu, *vdd_core;
+ u16 voltsetup_vdd1, voltsetup_vdd2;
+
+ if (!cpu_is_omap34xx())
+ return;
+
+ voltdm = omap_voltage_domain_lookup("mpu");
+ vdd_mpu = container_of(voltdm, struct omap_vdd_info, voltdm);
+ mod = vdd_mpu->vc_reg.prm_mod;
+ voltdm = omap_voltage_domain_lookup("core");
+ vdd_core = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ /* update voltsetup time */
+ if (core_next_state == PWRDM_POWER_OFF) {
+ vdd_mpu->write_reg(OMAP3430_SEL_OFF_MASK |
+ OMAP3430_AUTO_OFF_MASK,
+ mod, OMAP3_PRM_VOLTCTRL_OFFSET);
+
+ /* Calculating the values with sys_32k clk */
+ vdd_mpu->write_reg(vdd_mpu->pmic_info->clksetup_off.clksetup /
+ SYS_32K_CLK_CYCLE, mod, OMAP3_PRM_CLKSETUP_OFFSET);
+
+ /* Calculating the values with sys clk */
+ voltsetup_vdd1 =
+ ((vdd_mpu->pmic_info->voltsetup_off.voltsetup * 1000) /
+ sys_clk_cycle) >> 3;
+ voltsetup_vdd2 =
+ ((vdd_core->pmic_info->voltsetup_off.voltsetup * 1000) /
+ sys_clk_cycle) >> 3;
+
+ voltsetup_time = (voltsetup_vdd2 <<
+ vdd_core->vc_reg.voltsetup_shift) |
+ voltsetup_vdd1;
+ vdd_mpu->write_reg(voltsetup_time, mod,
+ vdd_mpu->vc_reg.voltsetup_reg);
+
+ /* Calculating the values with sys_32k clk */
+ vdd_mpu->write_reg(
+ vdd_mpu->pmic_info->voltsetup_off.voltsetup2 /
+ SYS_32K_CLK_CYCLE, mod, vdd_mpu->vc_reg.voltsetup2_reg);
+ vdd_mpu->write_reg(
+ vdd_mpu->pmic_info->voltsetup_off.voltoffset /
+ SYS_32K_CLK_CYCLE, mod, vdd_mpu->vc_reg.voltoffset_reg);
+
+ } else if (core_next_state == PWRDM_POWER_RET) {
+ vdd_mpu->write_reg(OMAP3430_AUTO_RET_MASK, mod,
+ OMAP3_PRM_VOLTCTRL_OFFSET);
+
+ /* Calculating the values with sys_32k clk */
+ vdd_mpu->write_reg(vdd_mpu->pmic_info->clksetup_ret.clksetup /
+ SYS_32K_CLK_CYCLE, mod, OMAP3_PRM_CLKSETUP_OFFSET);
+
+ /* Calculating the values with sys clk */
+ voltsetup_vdd1 =
+ ((vdd_mpu->pmic_info->voltsetup_ret.voltsetup * 1000) /
+ sys_clk_cycle) >> 3;
+ voltsetup_vdd2 =
+ ((vdd_core->pmic_info->voltsetup_ret.voltsetup * 1000) /
+ sys_clk_cycle) >> 3;
+
+ voltsetup_time = (voltsetup_vdd2 <<
+ vdd_core->vc_reg.voltsetup_shift) |
+ voltsetup_vdd1;
+ vdd_mpu->write_reg(voltsetup_time, mod,
+ vdd_mpu->vc_reg.voltsetup_reg);
+ /* clear voltsetup2_reg if sys_off not enabled */
+ vdd_mpu->write_reg(
+ vdd_mpu->pmic_info->voltsetup_ret.voltsetup2 /
+ SYS_32K_CLK_CYCLE, mod, vdd_mpu->vc_reg.voltsetup2_reg);
+ vdd_mpu->write_reg(
+ vdd_mpu->pmic_info->voltsetup_ret.voltoffset /
+ SYS_32K_CLK_CYCLE, mod, vdd_mpu->vc_reg.voltoffset_reg);
+ }
+}
+
+/**
* omap_voltage_early_init()- Volatage driver early init
*/
static int __init omap_voltage_early_init(void)
{
+ struct clk *sys_ck;
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, "sys_ck");
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys_clk frequency.\n",
+ __func__);
+ return -EINVAL;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+ /* Duration of one sys_clk cylce in nS */
+ sys_clk_cycle = 1000000 / sys_clk_speed;
+
if (cpu_is_omap34xx()) {
vdd_info = omap3_vdd_info;
nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index c0373d0..2d737b9 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -151,6 +151,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
#ifdef CONFIG_PM
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info);
+void omap3_voltage_vc_update(int core_next_state);
void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method);
/* API to get the voltagedomain pointer */
@@ -163,6 +164,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
{
return -EINVAL;
}
+void omap3_voltage_vc_update(int core_next_state) {}
static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method) {}
static inline int omap_voltage_late_init(void)
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 08/12] omap3: pm: TWL4030 power scripts for OMAP3 boards
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (6 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 07/12] omap3: pm: Re-programing the setup time based on CORE target state Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 09/12] omap3: pm: TWL5030 version checking Lesly A M
` (5 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Power bus message sequence for TWL4030 to enter sleep/wakeup/warm_reset.
TWL4030 power scripts which can be used by different OMAP3 boards
with the power companion chip (TWL4030 series).
The twl4030 generic script is exported and can be used by any other
boardfile to update the power data in twl4030_platform_data.
http://omapedia.org/wiki/TWL4030_power_scripts
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/twl4030.c | 146 +++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/twl4030.h | 21 ++++++
include/linux/i2c/twl.h | 33 +++++++++-
3 files changed, 197 insertions(+), 3 deletions(-)
create mode 100644 arch/arm/mach-omap2/twl4030.c
create mode 100644 arch/arm/mach-omap2/twl4030.h
diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
new file mode 100644
index 0000000..f3d05e5
--- /dev/null
+++ b/arch/arm/mach-omap2/twl4030.c
@@ -0,0 +1,146 @@
+/*
+ * OMAP power script for PMIC TWL4030
+ *
+ * Author: Lesly A M <leslyam@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Lesly A M <leslyam@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_TWL4030_POWER
+
+#include "twl4030.h"
+
+/*
+ * Sequence to control the TRITON Power resources,
+ * when the system goes into sleep.
+ * Executed upon P1_P2/P3 transition for sleep.
+ */
+static struct twl4030_ins __initdata sleep_on_seq[] = {
+ /* Broadcast message to put res to sleep */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
+ RES_STATE_SLEEP), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_SLEEP), 2},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+ .script = sleep_on_seq,
+ .size = ARRAY_SIZE(sleep_on_seq),
+ .flags = TWL4030_SLEEP_SCRIPT,
+};
+
+/*
+ * Sequence to control the TRITON Power resources,
+ * when the system wakeup from sleep.
+ * Executed upon P1_P2 transition for wakeup.
+ */
+static struct twl4030_ins wakeup_p12_seq[] __initdata = {
+ /* Broadcast message to put res to active */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
+ RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_p12_script __initdata = {
+ .script = wakeup_p12_seq,
+ .size = ARRAY_SIZE(wakeup_p12_seq),
+ .flags = TWL4030_WAKEUP12_SCRIPT,
+};
+
+/*
+ * Sequence to control the TRITON Power resources,
+ * when the system wakeup from sleep.
+ * Executed upon P3 transition for wakeup.
+ */
+static struct twl4030_ins wakeup_p3_seq[] __initdata = {
+ /* Broadcast message to put res to active */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_p3_script __initdata = {
+ .script = wakeup_p3_seq,
+ .size = ARRAY_SIZE(wakeup_p3_seq),
+ .flags = TWL4030_WAKEUP3_SCRIPT,
+};
+
+/*
+ * Sequence to reset the TRITON Power resources,
+ * when the system gets warm reset.
+ * Executed upon warm reset signal.
+ */
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset Main_Ref.
+ * Reset All type2_group2.
+ * Reset VUSB_3v1.
+ * Reset All type2_group1.
+ * Reset RC.
+ * Reenable twl4030.
+ */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_Main_Ref, RES_STATE_WRST), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_WRST), 2},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VUSB_3V1, RES_STATE_WRST), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
+ RES_STATE_WRST), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_WRST), 2},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wrst_script __initdata = {
+ .script = wrst_seq,
+ .size = ARRAY_SIZE(wrst_seq),
+ .flags = TWL4030_WRST_SCRIPT,
+};
+
+/* TRITON script for sleep, wakeup & warm_reset */
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+ &wakeup_p12_script,
+ &wakeup_p3_script,
+ &sleep_on_script,
+ &wrst_script,
+};
+
+static struct twl4030_resconfig twl4030_rconfig[] = {
+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1, .type = 3,
+ .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1,
+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1,
+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
+ .type = 0, .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { 0, 0},
+};
+
+struct twl4030_power_data twl4030_generic_script = {
+ .scripts = twl4030_scripts,
+ .num = ARRAY_SIZE(twl4030_scripts),
+ .resource_config = twl4030_rconfig,
+};
+EXPORT_SYMBOL(twl4030_generic_script);
+#endif
diff --git a/arch/arm/mach-omap2/twl4030.h b/arch/arm/mach-omap2/twl4030.h
new file mode 100644
index 0000000..e385340
--- /dev/null
+++ b/arch/arm/mach-omap2/twl4030.h
@@ -0,0 +1,21 @@
+/*
+ * OMAP TWL4030 power scripts header file
+ *
+ * Author: Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP3_TWL4030_SCRIPT_H
+#define __ARCH_ARM_MACH_OMAP3_TWL4030_SCRIPT_H
+
+#include <linux/i2c/twl.h>
+#include <plat/voltage.h>
+
+extern struct twl4030_power_data twl4030_generic_script;
+#endif
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 61b9609..f4bd475 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -436,9 +436,23 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
/* Power bus message definitions */
-/* The TWL4030/5030 splits its power-management resources (the various
- * regulators, clock and reset lines) into 3 processor groups - P1, P2 and
- * P3. These groups can then be configured to transition between sleep, wait-on
+/*
+ * The TWL4030/5030 splits its power-management resources (the various
+ * regulators, clock and reset lines) into 3 processor groups - P1, P2 and P3.
+ *
+ * Resources attached to device group P1 is managed depending on the state of
+ * NSLEEP1 pin of TRITON, which is connected to sys_off signal from OMAP
+ *
+ * Resources attached to device group P2 is managed depending on the state of
+ * NSLEEP2 pin of TRITON, which is can be connected to a modem or
+ * some other processor
+ *
+ * Resources attached to device group P3 is managed depending on the state of
+ * CLKREQ pin of TRITON, which is connected to clk request signal from OMAP
+ *
+ * If required these resources can be attached to combination of P1/P2/P3.
+ *
+ * These groups can then be configured to transition between sleep, wait-on
* and active states by sending messages to the power bus. See Section 5.4.2
* Power Resources of TWL4030 TRM
*/
@@ -448,7 +462,17 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
#define DEV_GRP_P1 0x1 /* P1: all OMAP devices */
#define DEV_GRP_P2 0x2 /* P2: all Modem devices */
#define DEV_GRP_P3 0x4 /* P3: all peripheral devices */
+#define DEV_GRP_ALL 0x7 /* P1/P2/P3: all devices */
+/*
+ * The 27 power resources in TRITON is again divided into
+ * analog resources:
+ * Power Providers - LDO regulators, dc-to-dc regulators
+ * Power Reference - analog reference
+ *
+ * and digital resources:
+ * Reset & Clock - reset and clock signals.
+ */
/* Resource groups */
#define RES_GRP_RES 0x0 /* Reserved */
#define RES_GRP_PP 0x1 /* Power providers */
@@ -460,7 +484,10 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)
#define RES_GRP_ALL 0x7 /* All resource groups */
#define RES_TYPE2_R0 0x0
+#define RES_TYPE2_R1 0x1
+#define RES_TYPE2_R2 0x2
+#define RES_TYPE_R0 0x0
#define RES_TYPE_ALL 0x7
/* Resource states */
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 09/12] omap3: pm: TWL5030 version checking
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (7 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 08/12] omap3: pm: TWL4030 power scripts for OMAP3 boards Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 23:51 ` David Cohen
2011-02-21 12:14 ` Krishnamoorthy, Balaji T
2011-02-18 17:08 ` [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround Lesly A M
` (4 subsequent siblings)
13 siblings, 2 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Added api to get the TWL5030 Si version from the IDCODE register.
It is used for enabling the workaround for TWL errata 27.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/mfd/twl-core.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/i2c/twl.h | 10 +++++++++
2 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index a35fa7d..211c2cc 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -487,6 +487,56 @@ EXPORT_SYMBOL(twl_i2c_read_u8);
/*----------------------------------------------------------------------*/
+/**
+ * twl_read_idcode_register - api to read the IDCODE register.
+ * @value: returns 32 bit IDCODE register value.
+ *
+ * Unlocks the IDCODE register and read the 32 bit value.
+ */
+int twl_read_idcode_register(u32 *value)
+{
+ int err = 0;
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK,
+ R_UNLOCK_TEST_REG);
+ if (err)
+ pr_err("TWL4030 Unable to unlock IDCODE registers\n");
+
+ err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(value),
+ 0x0, 4);
+ if (err)
+ pr_err("TWL4030: unable to read IDCODE-%d\n", err);
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, R_UNLOCK_TEST_REG);
+ if (err)
+ pr_err("TWL4030 Unable to relock IDCODE registers\n");
+
+ return err;
+}
+
+/**
+ * twl5030_get_si_ver - api to get TWL5030 Si version.
+ * @value: returns Si version from IDCODE.
+ *
+ * Api to get the TWL5030 Si version from IDCODE value.
+ */
+int twl5030_get_si_ver(u32 *value)
+{
+ int ret = 0;
+ static u32 twl_idcode;
+
+ if (twl_idcode == 0)
+ ret = twl_read_idcode_register(&twl_idcode);
+ if (ret)
+ pr_err("TWL4030 Unable to check Si version\n");
+
+ if (TWL_SIL_TYPE(twl_idcode) == TWL_SIL_5030)
+ *value = TWL_SIL_REV(twl_idcode);
+
+ return ret;
+}
+EXPORT_SYMBOL(twl5030_get_si_ver);
+
static struct device *
add_numbered_child(unsigned chip, const char *name, int num,
void *pdata, unsigned pdata_len,
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index f4bd475..5d3f2bf 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -150,7 +150,15 @@
#define MMC_PU (0x1 << 3)
#define MMC_PD (0x1 << 2)
+#define R_UNLOCK_TEST_REG 0x12
+#define TWL_EEPROM_R_UNLOCK 0x49
+#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
+#define TWL_SIL_REV(rev) ((rev) >> 24)
+#define TWL_SIL_5030 0x09002F
+#define TWL5030_REV_1_0 0x00
+#define TWL5030_REV_1_1 0x10
+#define TWL5030_REV_1_2 0x30
#define TWL4030_CLASS_ID 0x4030
#define TWL6030_CLASS_ID 0x6030
@@ -180,6 +188,8 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
+int twl5030_get_si_ver(u32 *value);
+
int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (8 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 09/12] omap3: pm: TWL5030 version checking Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 23:33 ` David Cohen
2011-02-18 17:08 ` [PATCH 11/12] omap3430: Updating the board file to use TWL4030 scripts Lesly A M
` (3 subsequent siblings)
13 siblings, 1 reply; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Workaround for TWL5030 Silicon Errata 27 & 28:
27 - VDD1, VDD2, may have glitches when their output value is updated.
28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
is switched from internal to external.
Errata 27:
If the DCDC regulators is running on their internal oscillator,
negative glitches may occur on VDD1, VDD2 output when voltage is changed.
The OMAP device may reboot if the VDD1 or VDD2 go below the
core minimum operating voltage.
WORKAROUND
Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
the internal oscillator.
Errata 28:
VDD1/VDD2 clock system may hang during switching the clock source from
internal oscillator to external. VDD1/VDD2 output voltages may collapse
if clock stops.
WORKAROUND
If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
setuptimes to make sure the switching will happen only when HFCLKIN is stable.
Also use the TWL5030 watchdog to safeguard the first switching from
internal oscillator to HFCLKIN during the TWL5030 init.
IMPACT
setup time and the power sequence is changed.
sleep/wakeup time values will be changed.
The workaround changes are called from twl4030_power_init(), since we have to
make some i2c_read calls to check the TRITON version & the i2c will not be
initialized in the early stage.
This workaround is required for TWL5030 Silicon version less than ES1.2
The power script & setup time changes are recommended by TI HW team.
http://omapedia.org/wiki/TWL4030_power_scripts
Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/voltage.h | 2 +
drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
include/linux/i2c/twl.h | 2 +
5 files changed, 228 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index f0feab9..d6984b8 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -176,6 +176,14 @@
#define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
#define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
+/*
+ * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
+ * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
+ */
+#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
+#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
+#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
+
static bool is_offset_valid;
static u8 smps_offset;
@@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
.uv_to_vsel = twl6030_uv_to_vsel,
};
+/**
+ * omap3_twl5030_errata27() - update the clk & volt setup time.
+ *
+ * Api to update the clk & volt setup time for TWL5030 errata 27.
+ */
+void omap3_twl5030_errata27(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ if (cpu_is_omap3630()) {
+ omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
+ VOLTSETUP2_TWL5030_ERRATA27;
+ omap3630_mpu_volt_info.voltsetup_off.voltoffset =
+ VOLTOFFSET_TWL5030_ERRATA27;
+ omap3630_mpu_volt_info.clksetup_off.clksetup =
+ CLKSETUP_TWL5030_ERRATA27;
+ } else {
+ omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
+ VOLTSETUP2_TWL5030_ERRATA27;
+ omap3430_mpu_volt_info.voltsetup_off.voltoffset =
+ VOLTOFFSET_TWL5030_ERRATA27;
+ omap3430_mpu_volt_info.clksetup_off.clksetup =
+ CLKSETUP_TWL5030_ERRATA27;
+ }
+}
+
int __init omap4_twl_init(void)
{
struct voltagedomain *voltdm;
diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
index f3d05e5..b5fb496 100644
--- a/arch/arm/mach-omap2/twl4030.c
+++ b/arch/arm/mach-omap2/twl4030.c
@@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
{ 0, 0},
};
+/*
+ * Active to Sleep sequence, which is executed upon P1/P2/P3
+ * transition for sleep.
+ *
+ * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
+ * HFCLKIN to internal oscillator when the HFCLKIN is stable.
+ */
+static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
+ /*
+ * Singular message to disable HCLKOUT.
+ * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
+ * HFCLKIN to internal oscillator before disabling HFCLKIN.
+ */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
+ /* Broadcast message to put res(TYPE2 = 1) to sleep */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
+ RES_STATE_SLEEP), 2},
+ /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_SLEEP), 2},
+};
+
+static struct twl4030_script sleep_on_script_errata27 __initdata = {
+ .script = sleep_on_seq_errata27,
+ .size = ARRAY_SIZE(sleep_on_seq_errata27),
+ .flags = TWL4030_SLEEP_SCRIPT,
+};
+
+/*
+ * Sleep to Active sequence, which is executed upon P1/P2/P3
+ * transition for wakeup.
+ *
+ * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
+ * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
+ */
+static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
+ /*
+ * Broadcast message to put res(TYPE2 = 2) to active.
+ * Wait for ~10 mS (rampup time for OSC on the board)
+ * after HFCLKIN is enabled
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_ACTIVE), 55},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_ACTIVE), 55},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_ACTIVE), 54},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
+ RES_STATE_ACTIVE), 1},
+ /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
+ /*
+ * Broadcast message to put res(TYPE2 = 1) to active.
+ * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
+ RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_script_errata27 __initdata = {
+ .script = wakeup_seq_errata27,
+ .size = ARRAY_SIZE(wakeup_seq_errata27),
+ .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
+};
+
+/* TRITON script for sleep, wakeup & warm_reset */
+static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
+ &sleep_on_script_errata27,
+ &wakeup_script_errata27,
+ &wrst_script,
+};
+
+/*
+ * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
+ * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
+ * only during OFFMODE.
+ * (*P2 is included if the platform uses it for modem/some other processor)
+ */
+static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
+ { 0, 0},
+};
+
+void twl5030_script_errata27(void)
+{
+ twl4030_generic_script.scripts = twl4030_scripts_errata27;
+ twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
+ twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
+}
+
struct twl4030_power_data twl4030_generic_script = {
.scripts = twl4030_scripts,
.num = ARRAY_SIZE(twl4030_scripts),
.resource_config = twl4030_rconfig,
+ .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
+ .twl5030_errata27wa_script = twl5030_script_errata27,
};
EXPORT_SYMBOL(twl4030_generic_script);
#endif
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 2d737b9..c9d899b 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info);
void omap3_voltage_vc_update(int core_next_state);
+void omap3_twl5030_errata27(void);
void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method);
/* API to get the voltagedomain pointer */
@@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
return -EINVAL;
}
void omap3_voltage_vc_update(int core_next_state) {}
+void omap3_twl5030_errata27(void) {}
static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method) {}
static inline int omap_voltage_late_init(void)
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 8373d79..cc8a137 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
#define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
#define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
+#define R_VDD1_OSC 0x5C
+#define R_VDD2_OSC 0x6A
+#define R_VIO_OSC 0x52
+#define EXT_FS_CLK_EN (0x1 << 6)
+
+#define R_WDT_CFG 0x03
+#define WDT_WRK_TIMEOUT 0x03
+
/* resource configuration registers
<RESOURCE>_DEV_GRP at address 'n+0'
<RESOURCE>_TYPE at address 'n+1'
@@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
return err;
}
+/**
+ * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
+ * 27 - VDD1, VDD2, may have glitches when their output value is updated.
+ * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
+ * switched from internal to external.
+ *
+ * Workaround requires the TWL DCDCs to use HFCLK instead of
+ * internal oscillator. Also enable TWL watchdog before switching the osc
+ * to recover if the VDD1/VDD2 stop working.
+ */
+static void __init twl_errata27_workaround(void)
+{
+ u8 val;
+ u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
+ u8 wdt_counter_val = 0;
+ int i;
+ int err;
+
+ /* Setup the twl wdt to take care of borderline failure case */
+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
+ R_WDT_CFG);
+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
+ R_WDT_CFG);
+
+ for (i = 0; i < sizeof(smps_osc_reg); i++) {
+ err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
+ smps_osc_reg[i]);
+ val |= EXT_FS_CLK_EN;
+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
+ smps_osc_reg[i]);
+ }
+
+ /* restore the original value */
+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
+ R_WDT_CFG);
+ if (err)
+ pr_warning("TWL4030: workaround setup failed!\n");
+}
+
+bool is_twl5030_errata27wa_required(void)
+{
+ u32 twl5030_si_ver;
+ int ret = 0;
+
+ ret = twl5030_get_si_ver(&twl5030_si_ver);
+ if (ret)
+ pr_warning("TWL4030: Unable to get the Si version\n");
+
+ if (twl5030_si_ver < TWL5030_REV_1_2)
+ return true;
+ else
+ return false;
+}
+
void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
@@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
if (err)
goto unlock;
+ /* Applying TWL5030 Errata 27 WA based on Si revision &
+ * flag updated from board file*/
+ if (is_twl5030_errata27wa_required()) {
+ pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
+ twl_errata27_workaround();
+ if (twl4030_scripts->twl5030_errata27wa_vcsetup)
+ twl4030_scripts->twl5030_errata27wa_vcsetup();
+
+ if (twl4030_scripts->twl5030_errata27wa_script)
+ twl4030_scripts->twl5030_errata27wa_script();
+ }
+
for (i = 0; i < twl4030_scripts->num; i++) {
err = load_twl4030_script(twl4030_scripts->scripts[i], address);
if (err)
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 5d3f2bf..26232f3 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -667,6 +667,8 @@ struct twl4030_power_data {
struct twl4030_script **scripts;
unsigned num;
struct twl4030_resconfig *resource_config;
+ void (*twl5030_errata27wa_vcsetup)(void);
+ void (*twl5030_errata27wa_script)(void);
#define TWL4030_RESCONFIG_UNDEF ((u8)-1)
};
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 11/12] omap3430: Updating the board file to use TWL4030 scripts
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (9 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:08 ` [PATCH 12/12] omap3630: " Lesly A M
` (2 subsequent siblings)
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Using TWL4030 power scripts to control the LDOs and DCDC regulators
while going to low power mode.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/Makefile | 3 ++-
arch/arm/mach-omap2/board-3430sdp.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 742ca67..bb11329 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -175,7 +175,8 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
hsmmc.o
obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
hsmmc.o \
- board-flash.o
+ board-flash.o \
+ twl4030.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
sdram-nokia.o \
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 813893b..c294f98 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -46,6 +46,7 @@
#include "mux.h"
#include "sdram-qimonda-hyb18m512160af-6.h"
#include "hsmmc.h"
+#include "twl4030.h"
#include "pm.h"
#include "control.h"
@@ -676,7 +677,7 @@ static struct twl4030_platform_data sdp3430_twldata = {
.power = &sdp3430_t2scripts_data,
.usb = &sdp3430_usb_data,
.codec = &sdp3430_codec,
-
+ .power = &twl4030_generic_script,
.vaux1 = &sdp3430_vaux1,
.vaux2 = &sdp3430_vaux2,
.vaux3 = &sdp3430_vaux3,
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 12/12] omap3630: Updating the board file to use TWL4030 scripts
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (10 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 11/12] omap3430: Updating the board file to use TWL4030 scripts Lesly A M
@ 2011-02-18 17:08 ` Lesly A M
2011-02-18 17:27 ` [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Jean Pihet
2011-03-01 22:24 ` Kevin Hilman
13 siblings, 0 replies; 30+ messages in thread
From: Lesly A M @ 2011-02-18 17:08 UTC (permalink / raw)
To: linux-omap; +Cc: Lesly A M, Nishanth Menon, David Derrick, Samuel Ortiz
Using TWL4030 power scripts to control the LDOs and DCDC regulators
while going to low power mode.
Signed-off-by: Lesly A M <leslyam@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: David Derrick <dderrick@ti.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
arch/arm/mach-omap2/Makefile | 9 ++++++---
arch/arm/mach-omap2/board-zoom-peripherals.c | 2 ++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bb11329..e6d5d27 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -191,18 +191,21 @@ obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
board-zoom-display.o \
board-flash.o \
hsmmc.o \
- board-zoom-debugboard.o
+ board-zoom-debugboard.o \
+ twl4030.o
obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
board-zoom-peripherals.o \
board-zoom-display.o \
board-flash.o \
hsmmc.o \
- board-zoom-debugboard.o
+ board-zoom-debugboard.o \
+ twl4030.o
obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
board-zoom-peripherals.o \
board-zoom-display.o \
board-flash.o \
- hsmmc.o
+ hsmmc.o \
+ twl4030.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \
hsmmc.o
obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index e0e040f..f978f73 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -31,6 +31,7 @@
#include "mux.h"
#include "hsmmc.h"
+#include "twl4030.h"
#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
@@ -341,6 +342,7 @@ static struct twl4030_platform_data zoom_twldata = {
.usb = &zoom_usb_data,
.gpio = &zoom_gpio_data,
.keypad = &zoom_kp_twl4030_data,
+ .power = &twl4030_generic_script,
.codec = &zoom_codec_data,
.vmmc1 = &zoom_vmmc1,
.vmmc2 = &zoom_vmmc2,
--
1.7.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (11 preceding siblings ...)
2011-02-18 17:08 ` [PATCH 12/12] omap3630: " Lesly A M
@ 2011-02-18 17:27 ` Jean Pihet
2011-02-21 6:55 ` Manuel, Lesly Arackal
2011-03-01 22:24 ` Kevin Hilman
13 siblings, 1 reply; 30+ messages in thread
From: Jean Pihet @ 2011-02-18 17:27 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Fri, Feb 18, 2011 at 6:08 PM, Lesly A M <leslyam@ti.com> wrote:
> Patch series for TWL4030 power scripts and workaround for TWL errata 27.
>
> Changes for implementing TWL4030 power scripts recommended by hardware team.
> Introduced a new TWL4030 power script file, which can be used by different
> OMAP3 board with the power companion chip TWL4030.
>
> Updated the changes for TWL4030 errata 27 & 28, modified the
> TWL4030 power script and voltage controller setuptime.
> Workaround for TWL4030 errata 27 & 28 is required for
> Si version less than or equal to TWL5030 ES1.1.
>
> TWL4030 script changes rebased on Kevin's PM tree in pm branch.
>
> Changes in v7:
> changes to fix Nishanth Menon's comments
> i) Added the TWL4030 Errata 27 fix
>
> split the first patch in v6
> i) fix for twl4030 script load
> ii) correct the warning print during script loading
>
> Added new patch files
> i) pmic_info struct cleanup
> ii) changing sys_off signal polarity
>
> Updated the change logs
>
> This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
> Tested with suspend/resume script, which will test system suspend in a loop.
> Tested for more than 1000 iterations.
Good to see the TWL scripts back in the mainline kernel!
Are the scripts compatible with the OMAP3 Beagleboard? I would like to
test the changes on that board.
Thanks,
Jean
>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: David Derrick <dderrick@ti.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> ---
> Lesly A M (12):
> omap3: pm: Fix for the TRITON sleep/wakeup sequence
> omap3: pm: Correct the warning print during script loading
> omap3: pm: cleanup pmic_info structure
> omap3: pm: Using separate clk/volt setup_time for RET and OFF states
> omap3630: pm: Adding voltage controller data
> omap3: pm: Correcting the sys_offmode signal polarity
> omap3: pm: Re-programing the setup time based on CORE target state
> omap3: pm: TWL4030 power scripts for OMAP3 boards
> omap3: pm: TWL5030 version checking
> mfd: TWL4030: changes for TRITON Errata 27 workaround
> omap3430: Updating the board file to use TWL4030 scripts
> omap3630: Updating the board file to use TWL4030 scripts
>
> arch/arm/mach-omap2/Makefile | 12 +-
> arch/arm/mach-omap2/board-3430sdp.c | 3 +-
> arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +
> arch/arm/mach-omap2/omap_twl.c | 369 +++++++++++++++++++++++---
> arch/arm/mach-omap2/pm34xx.c | 15 +-
> arch/arm/mach-omap2/twl4030.c | 261 ++++++++++++++++++
> arch/arm/mach-omap2/twl4030.h | 21 ++
> arch/arm/mach-omap2/voltage.c | 167 +++++++++---
> arch/arm/plat-omap/include/plat/voltage.h | 49 +++-
> drivers/mfd/twl-core.c | 50 ++++
> drivers/mfd/twl4030-power.c | 79 ++++++-
> include/linux/i2c/twl.h | 45 +++-
> 12 files changed, 961 insertions(+), 112 deletions(-)
> create mode 100644 arch/arm/mach-omap2/twl4030.c
> create mode 100644 arch/arm/mach-omap2/twl4030.h
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-18 17:08 ` [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround Lesly A M
@ 2011-02-18 23:33 ` David Cohen
2011-02-19 0:44 ` David Cohen
2011-02-21 11:23 ` Manuel, Lesly Arackal
0 siblings, 2 replies; 30+ messages in thread
From: David Cohen @ 2011-02-18 23:33 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi,
On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
> Workaround for TWL5030 Silicon Errata 27 & 28:
> 27 - VDD1, VDD2, may have glitches when their output value is updated.
> 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
> is switched from internal to external.
>
> Errata 27:
> If the DCDC regulators is running on their internal oscillator,
> negative glitches may occur on VDD1, VDD2 output when voltage is changed.
> The OMAP device may reboot if the VDD1 or VDD2 go below the
> core minimum operating voltage.
>
> WORKAROUND
> Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
> the internal oscillator.
>
> Errata 28:
> VDD1/VDD2 clock system may hang during switching the clock source from
> internal oscillator to external. VDD1/VDD2 output voltages may collapse
> if clock stops.
>
> WORKAROUND
> If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
> setuptimes to make sure the switching will happen only when HFCLKIN is stable.
> Also use the TWL5030 watchdog to safeguard the first switching from
> internal oscillator to HFCLKIN during the TWL5030 init.
>
> IMPACT
> setup time and the power sequence is changed.
> sleep/wakeup time values will be changed.
>
> The workaround changes are called from twl4030_power_init(), since we have to
> make some i2c_read calls to check the TRITON version & the i2c will not be
> initialized in the early stage.
>
> This workaround is required for TWL5030 Silicon version less than ES1.2
> The power script & setup time changes are recommended by TI HW team.
>
> http://omapedia.org/wiki/TWL4030_power_scripts
>
> Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
>
> Signed-off-by: Lesly A M <leslyam@ti.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: David Derrick <dderrick@ti.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> ---
> arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
> arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
> arch/arm/plat-omap/include/plat/voltage.h | 2 +
> drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
> include/linux/i2c/twl.h | 2 +
> 5 files changed, 228 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
> index f0feab9..d6984b8 100644
> --- a/arch/arm/mach-omap2/omap_twl.c
> +++ b/arch/arm/mach-omap2/omap_twl.c
> @@ -176,6 +176,14 @@
> #define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
> #define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
>
> +/*
> + * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
> + */
> +#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
> +#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
> +#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
> +
> static bool is_offset_valid;
> static u8 smps_offset;
>
> @@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
> .uv_to_vsel = twl6030_uv_to_vsel,
> };
>
> +/**
> + * omap3_twl5030_errata27() - update the clk & volt setup time.
> + *
> + * Api to update the clk & volt setup time for TWL5030 errata 27.
> + */
> +void omap3_twl5030_errata27(void)
> +{
> + if (!cpu_is_omap34xx())
> + return;
> +
> + if (cpu_is_omap3630()) {
> + omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
> + VOLTSETUP2_TWL5030_ERRATA27;
> + omap3630_mpu_volt_info.voltsetup_off.voltoffset =
> + VOLTOFFSET_TWL5030_ERRATA27;
> + omap3630_mpu_volt_info.clksetup_off.clksetup =
> + CLKSETUP_TWL5030_ERRATA27;
> + } else {
> + omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
> + VOLTSETUP2_TWL5030_ERRATA27;
> + omap3430_mpu_volt_info.voltsetup_off.voltoffset =
> + VOLTOFFSET_TWL5030_ERRATA27;
> + omap3430_mpu_volt_info.clksetup_off.clksetup =
> + CLKSETUP_TWL5030_ERRATA27;
> + }
> +}
> +
> int __init omap4_twl_init(void)
> {
> struct voltagedomain *voltdm;
> diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
> index f3d05e5..b5fb496 100644
> --- a/arch/arm/mach-omap2/twl4030.c
> +++ b/arch/arm/mach-omap2/twl4030.c
> @@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
> { 0, 0},
> };
>
> +/*
> + * Active to Sleep sequence, which is executed upon P1/P2/P3
> + * transition for sleep.
> + *
> + * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
> + * HFCLKIN to internal oscillator when the HFCLKIN is stable.
> + */
> +static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
> + /*
> + * Singular message to disable HCLKOUT.
> + * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
> + * HFCLKIN to internal oscillator before disabling HFCLKIN.
> + */
> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
> + /* Broadcast message to put res(TYPE2 = 1) to sleep */
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
> + RES_STATE_SLEEP), 2},
> + /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
> + RES_STATE_SLEEP), 2},
> +};
> +
> +static struct twl4030_script sleep_on_script_errata27 __initdata = {
> + .script = sleep_on_seq_errata27,
> + .size = ARRAY_SIZE(sleep_on_seq_errata27),
> + .flags = TWL4030_SLEEP_SCRIPT,
> +};
> +
> +/*
> + * Sleep to Active sequence, which is executed upon P1/P2/P3
> + * transition for wakeup.
> + *
> + * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
> + */
> +static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
> + /*
> + * Broadcast message to put res(TYPE2 = 2) to active.
> + * Wait for ~10 mS (rampup time for OSC on the board)
> + * after HFCLKIN is enabled
> + */
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
> + RES_STATE_ACTIVE), 55},
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
> + RES_STATE_ACTIVE), 55},
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
> + RES_STATE_ACTIVE), 54},
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
> + RES_STATE_ACTIVE), 1},
> + /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
> + /*
> + * Broadcast message to put res(TYPE2 = 1) to active.
> + * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
> + */
> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
> + RES_STATE_ACTIVE), 2},
> +};
> +
> +static struct twl4030_script wakeup_script_errata27 __initdata = {
> + .script = wakeup_seq_errata27,
> + .size = ARRAY_SIZE(wakeup_seq_errata27),
> + .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
> +};
> +
> +/* TRITON script for sleep, wakeup & warm_reset */
> +static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
> + &sleep_on_script_errata27,
> + &wakeup_script_errata27,
> + &wrst_script,
> +};
> +
> +/*
> + * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
> + * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
> + * only during OFFMODE.
> + * (*P2 is included if the platform uses it for modem/some other processor)
> + */
> +static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
> + { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
> + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
> + .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
> + { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
> + { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
> + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
> + .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
> + { 0, 0},
> +};
> +
> +void twl5030_script_errata27(void)
> +{
> + twl4030_generic_script.scripts = twl4030_scripts_errata27;
> + twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
> + twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
> +}
> +
> struct twl4030_power_data twl4030_generic_script = {
> .scripts = twl4030_scripts,
> .num = ARRAY_SIZE(twl4030_scripts),
> .resource_config = twl4030_rconfig,
> + .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
> + .twl5030_errata27wa_script = twl5030_script_errata27,
> };
> EXPORT_SYMBOL(twl4030_generic_script);
> #endif
> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
> index 2d737b9..c9d899b 100644
> --- a/arch/arm/plat-omap/include/plat/voltage.h
> +++ b/arch/arm/plat-omap/include/plat/voltage.h
> @@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
> int omap_voltage_register_pmic(struct voltagedomain *voltdm,
> struct omap_volt_pmic_info *pmic_info);
> void omap3_voltage_vc_update(int core_next_state);
> +void omap3_twl5030_errata27(void);
> void omap_change_voltscale_method(struct voltagedomain *voltdm,
> int voltscale_method);
> /* API to get the voltagedomain pointer */
> @@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
> return -EINVAL;
> }
> void omap3_voltage_vc_update(int core_next_state) {}
> +void omap3_twl5030_errata27(void) {}
> static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
> int voltscale_method) {}
> static inline int omap_voltage_late_init(void)
> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
> index 8373d79..cc8a137 100644
> --- a/drivers/mfd/twl4030-power.c
> +++ b/drivers/mfd/twl4030-power.c
> @@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
> #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
> #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
>
> +#define R_VDD1_OSC 0x5C
> +#define R_VDD2_OSC 0x6A
> +#define R_VIO_OSC 0x52
> +#define EXT_FS_CLK_EN (0x1 << 6)
> +
> +#define R_WDT_CFG 0x03
> +#define WDT_WRK_TIMEOUT 0x03
> +
> /* resource configuration registers
> <RESOURCE>_DEV_GRP at address 'n+0'
> <RESOURCE>_TYPE at address 'n+1'
> @@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
> return err;
> }
>
> +/**
> + * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
> + * 27 - VDD1, VDD2, may have glitches when their output value is updated.
> + * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
> + * switched from internal to external.
> + *
> + * Workaround requires the TWL DCDCs to use HFCLK instead of
> + * internal oscillator. Also enable TWL watchdog before switching the osc
> + * to recover if the VDD1/VDD2 stop working.
> + */
> +static void __init twl_errata27_workaround(void)
> +{
> + u8 val;
> + u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
> + u8 wdt_counter_val = 0;
> + int i;
> + int err;
> +
> + /* Setup the twl wdt to take care of borderline failure case */
> + err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
> + R_WDT_CFG);
> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
> + R_WDT_CFG);
> +
> + for (i = 0; i < sizeof(smps_osc_reg); i++) {
> + err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
> + smps_osc_reg[i]);
> + val |= EXT_FS_CLK_EN;
> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
> + smps_osc_reg[i]);
> + }
> +
> + /* restore the original value */
> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
> + R_WDT_CFG);
> + if (err)
> + pr_warning("TWL4030: workaround setup failed!\n");
> +}
> +
> +bool is_twl5030_errata27wa_required(void)
> +{
> + u32 twl5030_si_ver;
> + int ret = 0;
> +
> + ret = twl5030_get_si_ver(&twl5030_si_ver);
> + if (ret)
> + pr_warning("TWL4030: Unable to get the Si version\n");
You can get rid of 'ret'. What about:
if (twl5030_get_si_ver(&twl5030_si_ver))
pr_warning("TWL4030: Unable to get the Si version\n");
> +
> + if (twl5030_si_ver < TWL5030_REV_1_2)
> + return true;
> + else
> + return false;
No need to if...else here. You can:
return twl5030_si_ver < TWL5030_REV_1_2;
Regards,
David Cohen
> +}
> +
> void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
> {
> int err = 0;
> @@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
> if (err)
> goto unlock;
>
> + /* Applying TWL5030 Errata 27 WA based on Si revision &
> + * flag updated from board file*/
> + if (is_twl5030_errata27wa_required()) {
> + pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
> + twl_errata27_workaround();
> + if (twl4030_scripts->twl5030_errata27wa_vcsetup)
> + twl4030_scripts->twl5030_errata27wa_vcsetup();
> +
> + if (twl4030_scripts->twl5030_errata27wa_script)
> + twl4030_scripts->twl5030_errata27wa_script();
> + }
> +
> for (i = 0; i < twl4030_scripts->num; i++) {
> err = load_twl4030_script(twl4030_scripts->scripts[i], address);
> if (err)
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index 5d3f2bf..26232f3 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -667,6 +667,8 @@ struct twl4030_power_data {
> struct twl4030_script **scripts;
> unsigned num;
> struct twl4030_resconfig *resource_config;
> + void (*twl5030_errata27wa_vcsetup)(void);
> + void (*twl5030_errata27wa_script)(void);
> #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
> };
>
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence
2011-02-18 17:08 ` [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence Lesly A M
@ 2011-02-18 23:38 ` David Cohen
2011-02-21 9:39 ` Manuel, Lesly Arackal
0 siblings, 1 reply; 30+ messages in thread
From: David Cohen @ 2011-02-18 23:38 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi,
On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
> Since the function to populate the sleep script is getting called always
> irrespective of the flag "TWL4030_SLEEP_SCRIPT", other scripts data
> is getting over written by the sleep script.
Are you sure this is the correct patch description? For me it's something like:
Add missing brackets to if statement.
Br,
David Cohen
>
> Signed-off-by: Lesly A M <leslyam@ti.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: David Derrick <dderrick@ti.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> ---
> drivers/mfd/twl4030-power.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
> index 16422de..2c0d4d1 100644
> --- a/drivers/mfd/twl4030-power.c
> +++ b/drivers/mfd/twl4030-power.c
> @@ -447,12 +447,13 @@ static int __init load_twl4030_script(struct twl4030_script *tscript,
> if (err)
> goto out;
> }
> - if (tscript->flags & TWL4030_SLEEP_SCRIPT)
> + if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
> if (order)
> pr_warning("TWL4030: Bad order of scripts (sleep "\
> "script before wakeup) Leads to boot"\
> "failure on some boards\n");
> err = twl4030_config_sleep_sequence(address);
> + }
> out:
> return err;
> }
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] omap3: pm: TWL5030 version checking
2011-02-18 17:08 ` [PATCH 09/12] omap3: pm: TWL5030 version checking Lesly A M
@ 2011-02-18 23:51 ` David Cohen
2011-02-21 10:26 ` Manuel, Lesly Arackal
2011-02-21 12:14 ` Krishnamoorthy, Balaji T
1 sibling, 1 reply; 30+ messages in thread
From: David Cohen @ 2011-02-18 23:51 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi,
On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
> Added api to get the TWL5030 Si version from the IDCODE register.
> It is used for enabling the workaround for TWL errata 27.
>
> Signed-off-by: Lesly A M <leslyam@ti.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: David Derrick <dderrick@ti.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> ---
> drivers/mfd/twl-core.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/i2c/twl.h | 10 +++++++++
> 2 files changed, 60 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index a35fa7d..211c2cc 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -487,6 +487,56 @@ EXPORT_SYMBOL(twl_i2c_read_u8);
>
> /*----------------------------------------------------------------------*/
>
> +/**
> + * twl_read_idcode_register - api to read the IDCODE register.
> + * @value: returns 32 bit IDCODE register value.
> + *
> + * Unlocks the IDCODE register and read the 32 bit value.
> + */
> +int twl_read_idcode_register(u32 *value)
> +{
> + int err = 0;
No need to initialize 'ret'.
> +
> + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK,
> + R_UNLOCK_TEST_REG);
> + if (err)
> + pr_err("TWL4030 Unable to unlock IDCODE registers\n");
> +
> + err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(value),
> + 0x0, 4);
Variable 'err' is being overwritten here.
> + if (err)
> + pr_err("TWL4030: unable to read IDCODE-%d\n", err);
> +
> + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, R_UNLOCK_TEST_REG);
Here again.
> + if (err)
> + pr_err("TWL4030 Unable to relock IDCODE registers\n");
> +
> + return err;
And then you're returning 'err'. Unless you care only about the last
'err' assignment, something is wrong here, isn't it? :)
> +}
> +
> +/**
> + * twl5030_get_si_ver - api to get TWL5030 Si version.
> + * @value: returns Si version from IDCODE.
> + *
> + * Api to get the TWL5030 Si version from IDCODE value.
> + */
> +int twl5030_get_si_ver(u32 *value)
> +{
> + int ret = 0;
No need to initialize 'ret'.
> + static u32 twl_idcode;
> +
> + if (twl_idcode == 0)
> + ret = twl_read_idcode_register(&twl_idcode);
> + if (ret)
> + pr_err("TWL4030 Unable to check Si version\n");
Shouldn't you return error here?
> +
> + if (TWL_SIL_TYPE(twl_idcode) == TWL_SIL_5030)
> + *value = TWL_SIL_REV(twl_idcode);
Otherwise, what happens here if twl_read_idcode_register() fails?
> +
> + return ret;
return 0 if the code reaches this point.
Br,
David Cohen
> +}
> +EXPORT_SYMBOL(twl5030_get_si_ver);
> +
> static struct device *
> add_numbered_child(unsigned chip, const char *name, int num,
> void *pdata, unsigned pdata_len,
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index f4bd475..5d3f2bf 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -150,7 +150,15 @@
> #define MMC_PU (0x1 << 3)
> #define MMC_PD (0x1 << 2)
>
> +#define R_UNLOCK_TEST_REG 0x12
> +#define TWL_EEPROM_R_UNLOCK 0x49
>
> +#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
> +#define TWL_SIL_REV(rev) ((rev) >> 24)
> +#define TWL_SIL_5030 0x09002F
> +#define TWL5030_REV_1_0 0x00
> +#define TWL5030_REV_1_1 0x10
> +#define TWL5030_REV_1_2 0x30
>
> #define TWL4030_CLASS_ID 0x4030
> #define TWL6030_CLASS_ID 0x6030
> @@ -180,6 +188,8 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
> int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
> int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>
> +int twl5030_get_si_ver(u32 *value);
> +
> int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
> int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
>
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-18 23:33 ` David Cohen
@ 2011-02-19 0:44 ` David Cohen
2011-02-19 22:02 ` David Cohen
2011-02-21 11:23 ` Manuel, Lesly Arackal
1 sibling, 1 reply; 30+ messages in thread
From: David Cohen @ 2011-02-19 0:44 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Sat, Feb 19, 2011 at 1:33 AM, David Cohen <dacohen@gmail.com> wrote:
> Hi,
>
> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>> Workaround for TWL5030 Silicon Errata 27 & 28:
>> 27 - VDD1, VDD2, may have glitches when their output value is updated.
>> 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
>> is switched from internal to external.
>>
>> Errata 27:
>> If the DCDC regulators is running on their internal oscillator,
>> negative glitches may occur on VDD1, VDD2 output when voltage is changed.
>> The OMAP device may reboot if the VDD1 or VDD2 go below the
>> core minimum operating voltage.
>>
>> WORKAROUND
>> Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
>> the internal oscillator.
>>
>> Errata 28:
>> VDD1/VDD2 clock system may hang during switching the clock source from
>> internal oscillator to external. VDD1/VDD2 output voltages may collapse
>> if clock stops.
>>
>> WORKAROUND
>> If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
>> setuptimes to make sure the switching will happen only when HFCLKIN is stable.
>> Also use the TWL5030 watchdog to safeguard the first switching from
>> internal oscillator to HFCLKIN during the TWL5030 init.
>>
>> IMPACT
>> setup time and the power sequence is changed.
>> sleep/wakeup time values will be changed.
>>
>> The workaround changes are called from twl4030_power_init(), since we have to
>> make some i2c_read calls to check the TRITON version & the i2c will not be
>> initialized in the early stage.
>>
>> This workaround is required for TWL5030 Silicon version less than ES1.2
>> The power script & setup time changes are recommended by TI HW team.
>>
>> http://omapedia.org/wiki/TWL4030_power_scripts
>>
>> Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
>>
>> Signed-off-by: Lesly A M <leslyam@ti.com>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: David Derrick <dderrick@ti.com>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> ---
>> arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
>> arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
>> arch/arm/plat-omap/include/plat/voltage.h | 2 +
>> drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
>> include/linux/i2c/twl.h | 2 +
>> 5 files changed, 228 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
>> index f0feab9..d6984b8 100644
>> --- a/arch/arm/mach-omap2/omap_twl.c
>> +++ b/arch/arm/mach-omap2/omap_twl.c
>> @@ -176,6 +176,14 @@
>> #define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
>> #define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
>>
>> +/*
>> + * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
>> + */
>> +#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
>> +#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
>> +#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
>> +
>> static bool is_offset_valid;
>> static u8 smps_offset;
>>
>> @@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
>> .uv_to_vsel = twl6030_uv_to_vsel,
>> };
>>
>> +/**
>> + * omap3_twl5030_errata27() - update the clk & volt setup time.
>> + *
>> + * Api to update the clk & volt setup time for TWL5030 errata 27.
>> + */
>> +void omap3_twl5030_errata27(void)
>> +{
>> + if (!cpu_is_omap34xx())
>> + return;
>> +
>> + if (cpu_is_omap3630()) {
>> + omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
>> + VOLTSETUP2_TWL5030_ERRATA27;
>> + omap3630_mpu_volt_info.voltsetup_off.voltoffset =
>> + VOLTOFFSET_TWL5030_ERRATA27;
>> + omap3630_mpu_volt_info.clksetup_off.clksetup =
>> + CLKSETUP_TWL5030_ERRATA27;
>> + } else {
>> + omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
>> + VOLTSETUP2_TWL5030_ERRATA27;
>> + omap3430_mpu_volt_info.voltsetup_off.voltoffset =
>> + VOLTOFFSET_TWL5030_ERRATA27;
>> + omap3430_mpu_volt_info.clksetup_off.clksetup =
>> + CLKSETUP_TWL5030_ERRATA27;
>> + }
>> +}
>> +
>> int __init omap4_twl_init(void)
>> {
>> struct voltagedomain *voltdm;
>> diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
>> index f3d05e5..b5fb496 100644
>> --- a/arch/arm/mach-omap2/twl4030.c
>> +++ b/arch/arm/mach-omap2/twl4030.c
>> @@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
>> { 0, 0},
>> };
>>
>> +/*
>> + * Active to Sleep sequence, which is executed upon P1/P2/P3
>> + * transition for sleep.
>> + *
>> + * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
>> + * HFCLKIN to internal oscillator when the HFCLKIN is stable.
>> + */
>> +static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
>> + /*
>> + * Singular message to disable HCLKOUT.
>> + * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
>> + * HFCLKIN to internal oscillator before disabling HFCLKIN.
>> + */
>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
>> + /* Broadcast message to put res(TYPE2 = 1) to sleep */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>> + RES_STATE_SLEEP), 2},
>> + /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_SLEEP), 2},
>> +};
>> +
>> +static struct twl4030_script sleep_on_script_errata27 __initdata = {
>> + .script = sleep_on_seq_errata27,
>> + .size = ARRAY_SIZE(sleep_on_seq_errata27),
>> + .flags = TWL4030_SLEEP_SCRIPT,
>> +};
>> +
>> +/*
>> + * Sleep to Active sequence, which is executed upon P1/P2/P3
>> + * transition for wakeup.
>> + *
>> + * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
>> + */
>> +static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
>> + /*
>> + * Broadcast message to put res(TYPE2 = 2) to active.
>> + * Wait for ~10 mS (rampup time for OSC on the board)
>> + * after HFCLKIN is enabled
>> + */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 55},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 55},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 54},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 1},
>> + /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
>> + /*
>> + * Broadcast message to put res(TYPE2 = 1) to active.
>> + * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
>> + */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>> + RES_STATE_ACTIVE), 2},
>> +};
>> +
>> +static struct twl4030_script wakeup_script_errata27 __initdata = {
>> + .script = wakeup_seq_errata27,
>> + .size = ARRAY_SIZE(wakeup_seq_errata27),
>> + .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
>> +};
>> +
>> +/* TRITON script for sleep, wakeup & warm_reset */
>> +static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
>> + &sleep_on_script_errata27,
>> + &wakeup_script_errata27,
>> + &wrst_script,
>> +};
>> +
>> +/*
>> + * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
>> + * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
>> + * only during OFFMODE.
>> + * (*P2 is included if the platform uses it for modem/some other processor)
>> + */
>> +static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
>> + { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { 0, 0},
>> +};
>> +
>> +void twl5030_script_errata27(void)
>> +{
>> + twl4030_generic_script.scripts = twl4030_scripts_errata27;
>> + twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
>> + twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
>> +}
>> +
>> struct twl4030_power_data twl4030_generic_script = {
>> .scripts = twl4030_scripts,
>> .num = ARRAY_SIZE(twl4030_scripts),
>> .resource_config = twl4030_rconfig,
>> + .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
>> + .twl5030_errata27wa_script = twl5030_script_errata27,
>> };
>> EXPORT_SYMBOL(twl4030_generic_script);
>> #endif
>> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
>> index 2d737b9..c9d899b 100644
>> --- a/arch/arm/plat-omap/include/plat/voltage.h
>> +++ b/arch/arm/plat-omap/include/plat/voltage.h
>> @@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
>> int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>> struct omap_volt_pmic_info *pmic_info);
>> void omap3_voltage_vc_update(int core_next_state);
>> +void omap3_twl5030_errata27(void);
>> void omap_change_voltscale_method(struct voltagedomain *voltdm,
>> int voltscale_method);
>> /* API to get the voltagedomain pointer */
>> @@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>> return -EINVAL;
>> }
>> void omap3_voltage_vc_update(int core_next_state) {}
>> +void omap3_twl5030_errata27(void) {}
>> static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
>> int voltscale_method) {}
>> static inline int omap_voltage_late_init(void)
>> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
>> index 8373d79..cc8a137 100644
>> --- a/drivers/mfd/twl4030-power.c
>> +++ b/drivers/mfd/twl4030-power.c
>> @@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
>> #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
>> #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
>>
>> +#define R_VDD1_OSC 0x5C
>> +#define R_VDD2_OSC 0x6A
>> +#define R_VIO_OSC 0x52
>> +#define EXT_FS_CLK_EN (0x1 << 6)
>> +
>> +#define R_WDT_CFG 0x03
>> +#define WDT_WRK_TIMEOUT 0x03
>> +
>> /* resource configuration registers
>> <RESOURCE>_DEV_GRP at address 'n+0'
>> <RESOURCE>_TYPE at address 'n+1'
>> @@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
>> return err;
>> }
>>
>> +/**
>> + * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
>> + * 27 - VDD1, VDD2, may have glitches when their output value is updated.
>> + * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
>> + * switched from internal to external.
>> + *
>> + * Workaround requires the TWL DCDCs to use HFCLK instead of
>> + * internal oscillator. Also enable TWL watchdog before switching the osc
>> + * to recover if the VDD1/VDD2 stop working.
>> + */
>> +static void __init twl_errata27_workaround(void)
>> +{
>> + u8 val;
>> + u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
>> + u8 wdt_counter_val = 0;
>> + int i;
>> + int err;
>> +
>> + /* Setup the twl wdt to take care of borderline failure case */
>> + err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
>> + R_WDT_CFG);
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
>> + R_WDT_CFG);
>> +
>> + for (i = 0; i < sizeof(smps_osc_reg); i++) {
>> + err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
>> + smps_osc_reg[i]);
>> + val |= EXT_FS_CLK_EN;
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
>> + smps_osc_reg[i]);
>> + }
>> +
>> + /* restore the original value */
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
>> + R_WDT_CFG);
>> + if (err)
>> + pr_warning("TWL4030: workaround setup failed!\n");
>> +}
>> +
>> +bool is_twl5030_errata27wa_required(void)
>> +{
>> + u32 twl5030_si_ver;
>> + int ret = 0;
>> +
>> + ret = twl5030_get_si_ver(&twl5030_si_ver);
>> + if (ret)
>> + pr_warning("TWL4030: Unable to get the Si version\n");
>
> You can get rid of 'ret'. What about:
> if (twl5030_get_si_ver(&twl5030_si_ver))
> pr_warning("TWL4030: Unable to get the Si version\n");
And return error from here in case of !twl5030_get_si_ver()
Br,
David
>
>> +
>> + if (twl5030_si_ver < TWL5030_REV_1_2)
>> + return true;
>> + else
>> + return false;
>
> No need to if...else here. You can:
> return twl5030_si_ver < TWL5030_REV_1_2;
>
> Regards,
>
> David Cohen
>
>> +}
>> +
>> void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>> {
>> int err = 0;
>> @@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>> if (err)
>> goto unlock;
>>
>> + /* Applying TWL5030 Errata 27 WA based on Si revision &
>> + * flag updated from board file*/
>> + if (is_twl5030_errata27wa_required()) {
>> + pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
>> + twl_errata27_workaround();
>> + if (twl4030_scripts->twl5030_errata27wa_vcsetup)
>> + twl4030_scripts->twl5030_errata27wa_vcsetup();
>> +
>> + if (twl4030_scripts->twl5030_errata27wa_script)
>> + twl4030_scripts->twl5030_errata27wa_script();
>> + }
>> +
>> for (i = 0; i < twl4030_scripts->num; i++) {
>> err = load_twl4030_script(twl4030_scripts->scripts[i], address);
>> if (err)
>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>> index 5d3f2bf..26232f3 100644
>> --- a/include/linux/i2c/twl.h
>> +++ b/include/linux/i2c/twl.h
>> @@ -667,6 +667,8 @@ struct twl4030_power_data {
>> struct twl4030_script **scripts;
>> unsigned num;
>> struct twl4030_resconfig *resource_config;
>> + void (*twl5030_errata27wa_vcsetup)(void);
>> + void (*twl5030_errata27wa_script)(void);
>> #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
>> };
>>
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-19 0:44 ` David Cohen
@ 2011-02-19 22:02 ` David Cohen
2011-02-21 11:25 ` Manuel, Lesly Arackal
0 siblings, 1 reply; 30+ messages in thread
From: David Cohen @ 2011-02-19 22:02 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Sat, Feb 19, 2011 at 2:44 AM, David Cohen <dacohen@gmail.com> wrote:
> On Sat, Feb 19, 2011 at 1:33 AM, David Cohen <dacohen@gmail.com> wrote:
>> Hi,
>>
>> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>>> Workaround for TWL5030 Silicon Errata 27 & 28:
>>> 27 - VDD1, VDD2, may have glitches when their output value is updated.
>>> 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
>>> is switched from internal to external.
>>>
>>> Errata 27:
>>> If the DCDC regulators is running on their internal oscillator,
>>> negative glitches may occur on VDD1, VDD2 output when voltage is changed.
>>> The OMAP device may reboot if the VDD1 or VDD2 go below the
>>> core minimum operating voltage.
>>>
>>> WORKAROUND
>>> Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
>>> the internal oscillator.
>>>
>>> Errata 28:
>>> VDD1/VDD2 clock system may hang during switching the clock source from
>>> internal oscillator to external. VDD1/VDD2 output voltages may collapse
>>> if clock stops.
>>>
>>> WORKAROUND
>>> If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
>>> setuptimes to make sure the switching will happen only when HFCLKIN is stable.
>>> Also use the TWL5030 watchdog to safeguard the first switching from
>>> internal oscillator to HFCLKIN during the TWL5030 init.
>>>
>>> IMPACT
>>> setup time and the power sequence is changed.
>>> sleep/wakeup time values will be changed.
>>>
>>> The workaround changes are called from twl4030_power_init(), since we have to
>>> make some i2c_read calls to check the TRITON version & the i2c will not be
>>> initialized in the early stage.
>>>
>>> This workaround is required for TWL5030 Silicon version less than ES1.2
>>> The power script & setup time changes are recommended by TI HW team.
>>>
>>> http://omapedia.org/wiki/TWL4030_power_scripts
>>>
>>> Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
>>>
>>> Signed-off-by: Lesly A M <leslyam@ti.com>
>>> Cc: Nishanth Menon <nm@ti.com>
>>> Cc: David Derrick <dderrick@ti.com>
>>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>>> ---
>>> arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
>>> arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
>>> arch/arm/plat-omap/include/plat/voltage.h | 2 +
>>> drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
>>> include/linux/i2c/twl.h | 2 +
>>> 5 files changed, 228 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
>>> index f0feab9..d6984b8 100644
>>> --- a/arch/arm/mach-omap2/omap_twl.c
>>> +++ b/arch/arm/mach-omap2/omap_twl.c
>>> @@ -176,6 +176,14 @@
>>> #define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
>>> #define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
>>>
>>> +/*
>>> + * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
>>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
>>> + */
>>> +#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
>>> +#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
>>> +#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
>>> +
>>> static bool is_offset_valid;
>>> static u8 smps_offset;
>>>
>>> @@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
>>> .uv_to_vsel = twl6030_uv_to_vsel,
>>> };
>>>
>>> +/**
>>> + * omap3_twl5030_errata27() - update the clk & volt setup time.
>>> + *
>>> + * Api to update the clk & volt setup time for TWL5030 errata 27.
>>> + */
>>> +void omap3_twl5030_errata27(void)
>>> +{
>>> + if (!cpu_is_omap34xx())
>>> + return;
>>> +
>>> + if (cpu_is_omap3630()) {
>>> + omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
>>> + VOLTSETUP2_TWL5030_ERRATA27;
>>> + omap3630_mpu_volt_info.voltsetup_off.voltoffset =
>>> + VOLTOFFSET_TWL5030_ERRATA27;
>>> + omap3630_mpu_volt_info.clksetup_off.clksetup =
>>> + CLKSETUP_TWL5030_ERRATA27;
>>> + } else {
>>> + omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
>>> + VOLTSETUP2_TWL5030_ERRATA27;
>>> + omap3430_mpu_volt_info.voltsetup_off.voltoffset =
>>> + VOLTOFFSET_TWL5030_ERRATA27;
>>> + omap3430_mpu_volt_info.clksetup_off.clksetup =
>>> + CLKSETUP_TWL5030_ERRATA27;
>>> + }
>>> +}
>>> +
>>> int __init omap4_twl_init(void)
>>> {
>>> struct voltagedomain *voltdm;
>>> diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
>>> index f3d05e5..b5fb496 100644
>>> --- a/arch/arm/mach-omap2/twl4030.c
>>> +++ b/arch/arm/mach-omap2/twl4030.c
>>> @@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
>>> { 0, 0},
>>> };
>>>
>>> +/*
>>> + * Active to Sleep sequence, which is executed upon P1/P2/P3
>>> + * transition for sleep.
>>> + *
>>> + * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
>>> + * HFCLKIN to internal oscillator when the HFCLKIN is stable.
>>> + */
>>> +static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
>>> + /*
>>> + * Singular message to disable HCLKOUT.
>>> + * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
>>> + * HFCLKIN to internal oscillator before disabling HFCLKIN.
>>> + */
>>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
>>> + /* Broadcast message to put res(TYPE2 = 1) to sleep */
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>>> + RES_STATE_SLEEP), 2},
>>> + /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>> + RES_STATE_SLEEP), 2},
>>> +};
>>> +
>>> +static struct twl4030_script sleep_on_script_errata27 __initdata = {
>>> + .script = sleep_on_seq_errata27,
>>> + .size = ARRAY_SIZE(sleep_on_seq_errata27),
>>> + .flags = TWL4030_SLEEP_SCRIPT,
>>> +};
>>> +
>>> +/*
>>> + * Sleep to Active sequence, which is executed upon P1/P2/P3
>>> + * transition for wakeup.
>>> + *
>>> + * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
>>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
>>> + */
>>> +static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
>>> + /*
>>> + * Broadcast message to put res(TYPE2 = 2) to active.
>>> + * Wait for ~10 mS (rampup time for OSC on the board)
>>> + * after HFCLKIN is enabled
>>> + */
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>> + RES_STATE_ACTIVE), 55},
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>> + RES_STATE_ACTIVE), 55},
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>> + RES_STATE_ACTIVE), 54},
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>> + RES_STATE_ACTIVE), 1},
>>> + /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
>>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
>>> + /*
>>> + * Broadcast message to put res(TYPE2 = 1) to active.
>>> + * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
>>> + */
>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>>> + RES_STATE_ACTIVE), 2},
>>> +};
>>> +
>>> +static struct twl4030_script wakeup_script_errata27 __initdata = {
>>> + .script = wakeup_seq_errata27,
>>> + .size = ARRAY_SIZE(wakeup_seq_errata27),
>>> + .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
>>> +};
>>> +
>>> +/* TRITON script for sleep, wakeup & warm_reset */
>>> +static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
>>> + &sleep_on_script_errata27,
>>> + &wakeup_script_errata27,
>>> + &wrst_script,
>>> +};
>>> +
>>> +/*
>>> + * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
>>> + * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
>>> + * only during OFFMODE.
>>> + * (*P2 is included if the platform uses it for modem/some other processor)
>>> + */
>>> +static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
>>> + { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>> + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>> + .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>> + { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>> + { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>> + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>> + .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>> + { 0, 0},
>>> +};
>>> +
>>> +void twl5030_script_errata27(void)
>>> +{
>>> + twl4030_generic_script.scripts = twl4030_scripts_errata27;
>>> + twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
>>> + twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
>>> +}
>>> +
>>> struct twl4030_power_data twl4030_generic_script = {
>>> .scripts = twl4030_scripts,
>>> .num = ARRAY_SIZE(twl4030_scripts),
>>> .resource_config = twl4030_rconfig,
>>> + .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
>>> + .twl5030_errata27wa_script = twl5030_script_errata27,
>>> };
>>> EXPORT_SYMBOL(twl4030_generic_script);
>>> #endif
>>> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
>>> index 2d737b9..c9d899b 100644
>>> --- a/arch/arm/plat-omap/include/plat/voltage.h
>>> +++ b/arch/arm/plat-omap/include/plat/voltage.h
>>> @@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
>>> int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>>> struct omap_volt_pmic_info *pmic_info);
>>> void omap3_voltage_vc_update(int core_next_state);
>>> +void omap3_twl5030_errata27(void);
>>> void omap_change_voltscale_method(struct voltagedomain *voltdm,
>>> int voltscale_method);
>>> /* API to get the voltagedomain pointer */
>>> @@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>>> return -EINVAL;
>>> }
>>> void omap3_voltage_vc_update(int core_next_state) {}
>>> +void omap3_twl5030_errata27(void) {}
>>> static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
>>> int voltscale_method) {}
>>> static inline int omap_voltage_late_init(void)
>>> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
>>> index 8373d79..cc8a137 100644
>>> --- a/drivers/mfd/twl4030-power.c
>>> +++ b/drivers/mfd/twl4030-power.c
>>> @@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
>>> #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
>>> #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
>>>
>>> +#define R_VDD1_OSC 0x5C
>>> +#define R_VDD2_OSC 0x6A
>>> +#define R_VIO_OSC 0x52
>>> +#define EXT_FS_CLK_EN (0x1 << 6)
>>> +
>>> +#define R_WDT_CFG 0x03
>>> +#define WDT_WRK_TIMEOUT 0x03
>>> +
>>> /* resource configuration registers
>>> <RESOURCE>_DEV_GRP at address 'n+0'
>>> <RESOURCE>_TYPE at address 'n+1'
>>> @@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
>>> return err;
>>> }
>>>
>>> +/**
>>> + * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
>>> + * 27 - VDD1, VDD2, may have glitches when their output value is updated.
>>> + * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
>>> + * switched from internal to external.
>>> + *
>>> + * Workaround requires the TWL DCDCs to use HFCLK instead of
>>> + * internal oscillator. Also enable TWL watchdog before switching the osc
>>> + * to recover if the VDD1/VDD2 stop working.
>>> + */
>>> +static void __init twl_errata27_workaround(void)
>>> +{
>>> + u8 val;
>>> + u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
>>> + u8 wdt_counter_val = 0;
>>> + int i;
>>> + int err;
>>> +
>>> + /* Setup the twl wdt to take care of borderline failure case */
>>> + err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
>>> + R_WDT_CFG);
>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
>>> + R_WDT_CFG);
>>> +
>>> + for (i = 0; i < sizeof(smps_osc_reg); i++) {
>>> + err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
>>> + smps_osc_reg[i]);
>>> + val |= EXT_FS_CLK_EN;
>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
>>> + smps_osc_reg[i]);
>>> + }
>>> +
>>> + /* restore the original value */
>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
>>> + R_WDT_CFG);
>>> + if (err)
>>> + pr_warning("TWL4030: workaround setup failed!\n");
>>> +}
>>> +
>>> +bool is_twl5030_errata27wa_required(void)
>>> +{
>>> + u32 twl5030_si_ver;
>>> + int ret = 0;
>>> +
>>> + ret = twl5030_get_si_ver(&twl5030_si_ver);
>>> + if (ret)
>>> + pr_warning("TWL4030: Unable to get the Si version\n");
>>
>> You can get rid of 'ret'. What about:
>> if (twl5030_get_si_ver(&twl5030_si_ver))
>> pr_warning("TWL4030: Unable to get the Si version\n");
>
> And return error from here in case of !twl5030_get_si_ver()
s/!twl5030_get_si_ver()/twl5030_get_si_ver()/
Br,
David
>
> Br,
>
> David
>
>>
>>> +
>>> + if (twl5030_si_ver < TWL5030_REV_1_2)
>>> + return true;
>>> + else
>>> + return false;
>>
>> No need to if...else here. You can:
>> return twl5030_si_ver < TWL5030_REV_1_2;
>>
>> Regards,
>>
>> David Cohen
>>
>>> +}
>>> +
>>> void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>>> {
>>> int err = 0;
>>> @@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>>> if (err)
>>> goto unlock;
>>>
>>> + /* Applying TWL5030 Errata 27 WA based on Si revision &
>>> + * flag updated from board file*/
>>> + if (is_twl5030_errata27wa_required()) {
>>> + pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
>>> + twl_errata27_workaround();
>>> + if (twl4030_scripts->twl5030_errata27wa_vcsetup)
>>> + twl4030_scripts->twl5030_errata27wa_vcsetup();
>>> +
>>> + if (twl4030_scripts->twl5030_errata27wa_script)
>>> + twl4030_scripts->twl5030_errata27wa_script();
>>> + }
>>> +
>>> for (i = 0; i < twl4030_scripts->num; i++) {
>>> err = load_twl4030_script(twl4030_scripts->scripts[i], address);
>>> if (err)
>>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>>> index 5d3f2bf..26232f3 100644
>>> --- a/include/linux/i2c/twl.h
>>> +++ b/include/linux/i2c/twl.h
>>> @@ -667,6 +667,8 @@ struct twl4030_power_data {
>>> struct twl4030_script **scripts;
>>> unsigned num;
>>> struct twl4030_resconfig *resource_config;
>>> + void (*twl5030_errata27wa_vcsetup)(void);
>>> + void (*twl5030_errata27wa_script)(void);
>>> #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
>>> };
>>>
>>> --
>>> 1.7.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-02-18 17:27 ` [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Jean Pihet
@ 2011-02-21 6:55 ` Manuel, Lesly Arackal
2011-02-21 11:57 ` Peter 'p2' De Schrijver
0 siblings, 1 reply; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 6:55 UTC (permalink / raw)
To: Jean Pihet; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi Jean,
On Fri, Feb 18, 2011 at 10:57 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
> On Fri, Feb 18, 2011 at 6:08 PM, Lesly A M <leslyam@ti.com> wrote:
>> Patch series for TWL4030 power scripts and workaround for TWL errata 27.
>>
>> Changes for implementing TWL4030 power scripts recommended by hardware team.
>> Introduced a new TWL4030 power script file, which can be used by different
>> OMAP3 board with the power companion chip TWL4030.
>>
>> Updated the changes for TWL4030 errata 27 & 28, modified the
>> TWL4030 power script and voltage controller setuptime.
>> Workaround for TWL4030 errata 27 & 28 is required for
>> Si version less than or equal to TWL5030 ES1.1.
>>
>> TWL4030 script changes rebased on Kevin's PM tree in pm branch.
>>
>> Changes in v7:
>> changes to fix Nishanth Menon's comments
>> i) Added the TWL4030 Errata 27 fix
>>
>> split the first patch in v6
>> i) fix for twl4030 script load
>> ii) correct the warning print during script loading
>>
>> Added new patch files
>> i) pmic_info struct cleanup
>> ii) changing sys_off signal polarity
>>
>> Updated the change logs
>>
>> This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
>> Tested with suspend/resume script, which will test system suspend in a loop.
>> Tested for more than 1000 iterations.
>
> Good to see the TWL scripts back in the mainline kernel!
> Are the scripts compatible with the OMAP3 Beagleboard? I would like to
> test the changes on that board.
I have not tested on Beagleboard.
I think Beagleboard is using different PM IC TPSxxxx.
If its equivalent to TRITON then this script should work on it.
Regards,
Lesly A M
>
>>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: David Derrick <dderrick@ti.com>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> ---
>> Lesly A M (12):
>> omap3: pm: Fix for the TRITON sleep/wakeup sequence
>> omap3: pm: Correct the warning print during script loading
>> omap3: pm: cleanup pmic_info structure
>> omap3: pm: Using separate clk/volt setup_time for RET and OFF states
>> omap3630: pm: Adding voltage controller data
>> omap3: pm: Correcting the sys_offmode signal polarity
>> omap3: pm: Re-programing the setup time based on CORE target state
>> omap3: pm: TWL4030 power scripts for OMAP3 boards
>> omap3: pm: TWL5030 version checking
>> mfd: TWL4030: changes for TRITON Errata 27 workaround
>> omap3430: Updating the board file to use TWL4030 scripts
>> omap3630: Updating the board file to use TWL4030 scripts
>>
>> arch/arm/mach-omap2/Makefile | 12 +-
>> arch/arm/mach-omap2/board-3430sdp.c | 3 +-
>> arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +
>> arch/arm/mach-omap2/omap_twl.c | 369 +++++++++++++++++++++++---
>> arch/arm/mach-omap2/pm34xx.c | 15 +-
>> arch/arm/mach-omap2/twl4030.c | 261 ++++++++++++++++++
>> arch/arm/mach-omap2/twl4030.h | 21 ++
>> arch/arm/mach-omap2/voltage.c | 167 +++++++++---
>> arch/arm/plat-omap/include/plat/voltage.h | 49 +++-
>> drivers/mfd/twl-core.c | 50 ++++
>> drivers/mfd/twl4030-power.c | 79 ++++++-
>> include/linux/i2c/twl.h | 45 +++-
>> 12 files changed, 961 insertions(+), 112 deletions(-)
>> create mode 100644 arch/arm/mach-omap2/twl4030.c
>> create mode 100644 arch/arm/mach-omap2/twl4030.h
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence
2011-02-18 23:38 ` David Cohen
@ 2011-02-21 9:39 ` Manuel, Lesly Arackal
0 siblings, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 9:39 UTC (permalink / raw)
To: David Cohen; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi David,
On Sat, Feb 19, 2011 at 5:08 AM, David Cohen <dacohen@gmail.com> wrote:
> Hi,
>
> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>> Since the function to populate the sleep script is getting called always
>> irrespective of the flag "TWL4030_SLEEP_SCRIPT", other scripts data
>> is getting over written by the sleep script.
>
> Are you sure this is the correct patch description? For me it's something like:
> Add missing brackets to if statement.
Yes, adding the missing brackets, to fix this issue.
Ok, I will include "adding the missing brackets" in the change log.
Regards,
Lesly AM
>>
>> Signed-off-by: Lesly A M <leslyam@ti.com>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: David Derrick <dderrick@ti.com>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> ---
>> drivers/mfd/twl4030-power.c | 3 ++-
>> 1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
>> index 16422de..2c0d4d1 100644
>> --- a/drivers/mfd/twl4030-power.c
>> +++ b/drivers/mfd/twl4030-power.c
>> @@ -447,12 +447,13 @@ static int __init load_twl4030_script(struct twl4030_script *tscript,
>> if (err)
>> goto out;
>> }
>> - if (tscript->flags & TWL4030_SLEEP_SCRIPT)
>> + if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
>> if (order)
>> pr_warning("TWL4030: Bad order of scripts (sleep "\
>> "script before wakeup) Leads to boot"\
>> "failure on some boards\n");
>> err = twl4030_config_sleep_sequence(address);
>> + }
>> out:
>> return err;
>> }
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] omap3: pm: TWL5030 version checking
2011-02-18 23:51 ` David Cohen
@ 2011-02-21 10:26 ` Manuel, Lesly Arackal
0 siblings, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 10:26 UTC (permalink / raw)
To: David Cohen; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi David,
On Sat, Feb 19, 2011 at 5:21 AM, David Cohen <dacohen@gmail.com> wrote:
> Hi,
>
> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>> Added api to get the TWL5030 Si version from the IDCODE register.
>> It is used for enabling the workaround for TWL errata 27.
>>
>> Signed-off-by: Lesly A M <leslyam@ti.com>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: David Derrick <dderrick@ti.com>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> ---
>> drivers/mfd/twl-core.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/i2c/twl.h | 10 +++++++++
>> 2 files changed, 60 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
>> index a35fa7d..211c2cc 100644
>> --- a/drivers/mfd/twl-core.c
>> +++ b/drivers/mfd/twl-core.c
>> @@ -487,6 +487,56 @@ EXPORT_SYMBOL(twl_i2c_read_u8);
>>
>> /*----------------------------------------------------------------------*/
>>
>> +/**
>> + * twl_read_idcode_register - api to read the IDCODE register.
>> + * @value: returns 32 bit IDCODE register value.
>> + *
>> + * Unlocks the IDCODE register and read the 32 bit value.
>> + */
>> +int twl_read_idcode_register(u32 *value)
>> +{
>> + int err = 0;
>
> No need to initialize 'ret'.
Ok
>> +
>> + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK,
>> + R_UNLOCK_TEST_REG);
>> + if (err)
>> + pr_err("TWL4030 Unable to unlock IDCODE registers\n");
>> +
>> + err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(value),
>> + 0x0, 4);
>
> Variable 'err' is being overwritten here.
>
>> + if (err)
>> + pr_err("TWL4030: unable to read IDCODE-%d\n", err);
>> +
>> + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, R_UNLOCK_TEST_REG);
>
> Here again.
>
>> + if (err)
>> + pr_err("TWL4030 Unable to relock IDCODE registers\n");
>> +
>> + return err;
>
> And then you're returning 'err'. Unless you care only about the last
> 'err' assignment, something is wrong here, isn't it? :)
Ok, I will use a label and goto that label if there is some err on any
i2c_read/write
>
>> +}
>> +
>> +/**
>> + * twl5030_get_si_ver - api to get TWL5030 Si version.
>> + * @value: returns Si version from IDCODE.
>> + *
>> + * Api to get the TWL5030 Si version from IDCODE value.
>> + */
>> +int twl5030_get_si_ver(u32 *value)
>> +{
>> + int ret = 0;
>
> No need to initialize 'ret'.
Ok
>> + static u32 twl_idcode;
>> +
>> + if (twl_idcode == 0)
>> + ret = twl_read_idcode_register(&twl_idcode);
>> + if (ret)
>> + pr_err("TWL4030 Unable to check Si version\n");
>
> Shouldn't you return error here?
Yes,
>> +
>> + if (TWL_SIL_TYPE(twl_idcode) == TWL_SIL_5030)
>> + *value = TWL_SIL_REV(twl_idcode);
>
> Otherwise, what happens here if twl_read_idcode_register() fails?
>
>> +
>> + return ret;
>
> return 0 if the code reaches this point.
Ok. I will do the changes
Regards,
Lesly A M
>> +}
>> +EXPORT_SYMBOL(twl5030_get_si_ver);
>> +
>> static struct device *
>> add_numbered_child(unsigned chip, const char *name, int num,
>> void *pdata, unsigned pdata_len,
>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>> index f4bd475..5d3f2bf 100644
>> --- a/include/linux/i2c/twl.h
>> +++ b/include/linux/i2c/twl.h
>> @@ -150,7 +150,15 @@
>> #define MMC_PU (0x1 << 3)
>> #define MMC_PD (0x1 << 2)
>>
>> +#define R_UNLOCK_TEST_REG 0x12
>> +#define TWL_EEPROM_R_UNLOCK 0x49
>>
>> +#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
>> +#define TWL_SIL_REV(rev) ((rev) >> 24)
>> +#define TWL_SIL_5030 0x09002F
>> +#define TWL5030_REV_1_0 0x00
>> +#define TWL5030_REV_1_1 0x10
>> +#define TWL5030_REV_1_2 0x30
>>
>> #define TWL4030_CLASS_ID 0x4030
>> #define TWL6030_CLASS_ID 0x6030
>> @@ -180,6 +188,8 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
>> int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>> int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>>
>> +int twl5030_get_si_ver(u32 *value);
>> +
>> int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
>> int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
>>
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-18 23:33 ` David Cohen
2011-02-19 0:44 ` David Cohen
@ 2011-02-21 11:23 ` Manuel, Lesly Arackal
1 sibling, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 11:23 UTC (permalink / raw)
To: David Cohen; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Sat, Feb 19, 2011 at 5:03 AM, David Cohen <dacohen@gmail.com> wrote:
> Hi,
>
> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>> Workaround for TWL5030 Silicon Errata 27 & 28:
>> 27 - VDD1, VDD2, may have glitches when their output value is updated.
>> 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
>> is switched from internal to external.
>>
>> Errata 27:
>> If the DCDC regulators is running on their internal oscillator,
>> negative glitches may occur on VDD1, VDD2 output when voltage is changed.
>> The OMAP device may reboot if the VDD1 or VDD2 go below the
>> core minimum operating voltage.
>>
>> WORKAROUND
>> Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
>> the internal oscillator.
>>
>> Errata 28:
>> VDD1/VDD2 clock system may hang during switching the clock source from
>> internal oscillator to external. VDD1/VDD2 output voltages may collapse
>> if clock stops.
>>
>> WORKAROUND
>> If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
>> setuptimes to make sure the switching will happen only when HFCLKIN is stable.
>> Also use the TWL5030 watchdog to safeguard the first switching from
>> internal oscillator to HFCLKIN during the TWL5030 init.
>>
>> IMPACT
>> setup time and the power sequence is changed.
>> sleep/wakeup time values will be changed.
>>
>> The workaround changes are called from twl4030_power_init(), since we have to
>> make some i2c_read calls to check the TRITON version & the i2c will not be
>> initialized in the early stage.
>>
>> This workaround is required for TWL5030 Silicon version less than ES1.2
>> The power script & setup time changes are recommended by TI HW team.
>>
>> http://omapedia.org/wiki/TWL4030_power_scripts
>>
>> Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
>>
>> Signed-off-by: Lesly A M <leslyam@ti.com>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: David Derrick <dderrick@ti.com>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> ---
>> arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
>> arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
>> arch/arm/plat-omap/include/plat/voltage.h | 2 +
>> drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
>> include/linux/i2c/twl.h | 2 +
>> 5 files changed, 228 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
>> index f0feab9..d6984b8 100644
>> --- a/arch/arm/mach-omap2/omap_twl.c
>> +++ b/arch/arm/mach-omap2/omap_twl.c
>> @@ -176,6 +176,14 @@
>> #define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
>> #define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
>>
>> +/*
>> + * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
>> + */
>> +#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
>> +#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
>> +#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
>> +
>> static bool is_offset_valid;
>> static u8 smps_offset;
>>
>> @@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
>> .uv_to_vsel = twl6030_uv_to_vsel,
>> };
>>
>> +/**
>> + * omap3_twl5030_errata27() - update the clk & volt setup time.
>> + *
>> + * Api to update the clk & volt setup time for TWL5030 errata 27.
>> + */
>> +void omap3_twl5030_errata27(void)
>> +{
>> + if (!cpu_is_omap34xx())
>> + return;
>> +
>> + if (cpu_is_omap3630()) {
>> + omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
>> + VOLTSETUP2_TWL5030_ERRATA27;
>> + omap3630_mpu_volt_info.voltsetup_off.voltoffset =
>> + VOLTOFFSET_TWL5030_ERRATA27;
>> + omap3630_mpu_volt_info.clksetup_off.clksetup =
>> + CLKSETUP_TWL5030_ERRATA27;
>> + } else {
>> + omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
>> + VOLTSETUP2_TWL5030_ERRATA27;
>> + omap3430_mpu_volt_info.voltsetup_off.voltoffset =
>> + VOLTOFFSET_TWL5030_ERRATA27;
>> + omap3430_mpu_volt_info.clksetup_off.clksetup =
>> + CLKSETUP_TWL5030_ERRATA27;
>> + }
>> +}
>> +
>> int __init omap4_twl_init(void)
>> {
>> struct voltagedomain *voltdm;
>> diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
>> index f3d05e5..b5fb496 100644
>> --- a/arch/arm/mach-omap2/twl4030.c
>> +++ b/arch/arm/mach-omap2/twl4030.c
>> @@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
>> { 0, 0},
>> };
>>
>> +/*
>> + * Active to Sleep sequence, which is executed upon P1/P2/P3
>> + * transition for sleep.
>> + *
>> + * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
>> + * HFCLKIN to internal oscillator when the HFCLKIN is stable.
>> + */
>> +static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
>> + /*
>> + * Singular message to disable HCLKOUT.
>> + * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
>> + * HFCLKIN to internal oscillator before disabling HFCLKIN.
>> + */
>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
>> + /* Broadcast message to put res(TYPE2 = 1) to sleep */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>> + RES_STATE_SLEEP), 2},
>> + /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_SLEEP), 2},
>> +};
>> +
>> +static struct twl4030_script sleep_on_script_errata27 __initdata = {
>> + .script = sleep_on_seq_errata27,
>> + .size = ARRAY_SIZE(sleep_on_seq_errata27),
>> + .flags = TWL4030_SLEEP_SCRIPT,
>> +};
>> +
>> +/*
>> + * Sleep to Active sequence, which is executed upon P1/P2/P3
>> + * transition for wakeup.
>> + *
>> + * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
>> + */
>> +static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
>> + /*
>> + * Broadcast message to put res(TYPE2 = 2) to active.
>> + * Wait for ~10 mS (rampup time for OSC on the board)
>> + * after HFCLKIN is enabled
>> + */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 55},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 55},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 54},
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>> + RES_STATE_ACTIVE), 1},
>> + /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
>> + /*
>> + * Broadcast message to put res(TYPE2 = 1) to active.
>> + * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
>> + */
>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>> + RES_STATE_ACTIVE), 2},
>> +};
>> +
>> +static struct twl4030_script wakeup_script_errata27 __initdata = {
>> + .script = wakeup_seq_errata27,
>> + .size = ARRAY_SIZE(wakeup_seq_errata27),
>> + .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
>> +};
>> +
>> +/* TRITON script for sleep, wakeup & warm_reset */
>> +static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
>> + &sleep_on_script_errata27,
>> + &wakeup_script_errata27,
>> + &wrst_script,
>> +};
>> +
>> +/*
>> + * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
>> + * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
>> + * only during OFFMODE.
>> + * (*P2 is included if the platform uses it for modem/some other processor)
>> + */
>> +static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
>> + { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>> + { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>> + .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>> + { 0, 0},
>> +};
>> +
>> +void twl5030_script_errata27(void)
>> +{
>> + twl4030_generic_script.scripts = twl4030_scripts_errata27;
>> + twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
>> + twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
>> +}
>> +
>> struct twl4030_power_data twl4030_generic_script = {
>> .scripts = twl4030_scripts,
>> .num = ARRAY_SIZE(twl4030_scripts),
>> .resource_config = twl4030_rconfig,
>> + .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
>> + .twl5030_errata27wa_script = twl5030_script_errata27,
>> };
>> EXPORT_SYMBOL(twl4030_generic_script);
>> #endif
>> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
>> index 2d737b9..c9d899b 100644
>> --- a/arch/arm/plat-omap/include/plat/voltage.h
>> +++ b/arch/arm/plat-omap/include/plat/voltage.h
>> @@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
>> int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>> struct omap_volt_pmic_info *pmic_info);
>> void omap3_voltage_vc_update(int core_next_state);
>> +void omap3_twl5030_errata27(void);
>> void omap_change_voltscale_method(struct voltagedomain *voltdm,
>> int voltscale_method);
>> /* API to get the voltagedomain pointer */
>> @@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>> return -EINVAL;
>> }
>> void omap3_voltage_vc_update(int core_next_state) {}
>> +void omap3_twl5030_errata27(void) {}
>> static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
>> int voltscale_method) {}
>> static inline int omap_voltage_late_init(void)
>> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
>> index 8373d79..cc8a137 100644
>> --- a/drivers/mfd/twl4030-power.c
>> +++ b/drivers/mfd/twl4030-power.c
>> @@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
>> #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
>> #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
>>
>> +#define R_VDD1_OSC 0x5C
>> +#define R_VDD2_OSC 0x6A
>> +#define R_VIO_OSC 0x52
>> +#define EXT_FS_CLK_EN (0x1 << 6)
>> +
>> +#define R_WDT_CFG 0x03
>> +#define WDT_WRK_TIMEOUT 0x03
>> +
>> /* resource configuration registers
>> <RESOURCE>_DEV_GRP at address 'n+0'
>> <RESOURCE>_TYPE at address 'n+1'
>> @@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
>> return err;
>> }
>>
>> +/**
>> + * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
>> + * 27 - VDD1, VDD2, may have glitches when their output value is updated.
>> + * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
>> + * switched from internal to external.
>> + *
>> + * Workaround requires the TWL DCDCs to use HFCLK instead of
>> + * internal oscillator. Also enable TWL watchdog before switching the osc
>> + * to recover if the VDD1/VDD2 stop working.
>> + */
>> +static void __init twl_errata27_workaround(void)
>> +{
>> + u8 val;
>> + u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
>> + u8 wdt_counter_val = 0;
>> + int i;
>> + int err;
>> +
>> + /* Setup the twl wdt to take care of borderline failure case */
>> + err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
>> + R_WDT_CFG);
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
>> + R_WDT_CFG);
>> +
>> + for (i = 0; i < sizeof(smps_osc_reg); i++) {
>> + err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
>> + smps_osc_reg[i]);
>> + val |= EXT_FS_CLK_EN;
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
>> + smps_osc_reg[i]);
>> + }
>> +
>> + /* restore the original value */
>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
>> + R_WDT_CFG);
>> + if (err)
>> + pr_warning("TWL4030: workaround setup failed!\n");
>> +}
>> +
>> +bool is_twl5030_errata27wa_required(void)
>> +{
>> + u32 twl5030_si_ver;
>> + int ret = 0;
>> +
>> + ret = twl5030_get_si_ver(&twl5030_si_ver);
>> + if (ret)
>> + pr_warning("TWL4030: Unable to get the Si version\n");
>
> You can get rid of 'ret'. What about:
> if (twl5030_get_si_ver(&twl5030_si_ver))
> pr_warning("TWL4030: Unable to get the Si version\n");
Ok
>> +
>> + if (twl5030_si_ver < TWL5030_REV_1_2)
>> + return true;
>> + else
>> + return false;
>
> No need to if...else here. You can:
> return twl5030_si_ver < TWL5030_REV_1_2;
Ok, I will change it
Regards,
Lesly A M
>> +}
>> +
>> void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>> {
>> int err = 0;
>> @@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>> if (err)
>> goto unlock;
>>
>> + /* Applying TWL5030 Errata 27 WA based on Si revision &
>> + * flag updated from board file*/
>> + if (is_twl5030_errata27wa_required()) {
>> + pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
>> + twl_errata27_workaround();
>> + if (twl4030_scripts->twl5030_errata27wa_vcsetup)
>> + twl4030_scripts->twl5030_errata27wa_vcsetup();
>> +
>> + if (twl4030_scripts->twl5030_errata27wa_script)
>> + twl4030_scripts->twl5030_errata27wa_script();
>> + }
>> +
>> for (i = 0; i < twl4030_scripts->num; i++) {
>> err = load_twl4030_script(twl4030_scripts->scripts[i], address);
>> if (err)
>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>> index 5d3f2bf..26232f3 100644
>> --- a/include/linux/i2c/twl.h
>> +++ b/include/linux/i2c/twl.h
>> @@ -667,6 +667,8 @@ struct twl4030_power_data {
>> struct twl4030_script **scripts;
>> unsigned num;
>> struct twl4030_resconfig *resource_config;
>> + void (*twl5030_errata27wa_vcsetup)(void);
>> + void (*twl5030_errata27wa_script)(void);
>> #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
>> };
>>
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround
2011-02-19 22:02 ` David Cohen
@ 2011-02-21 11:25 ` Manuel, Lesly Arackal
0 siblings, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 11:25 UTC (permalink / raw)
To: David Cohen; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi David,
On Sun, Feb 20, 2011 at 3:32 AM, David Cohen <dacohen@gmail.com> wrote:
> On Sat, Feb 19, 2011 at 2:44 AM, David Cohen <dacohen@gmail.com> wrote:
>> On Sat, Feb 19, 2011 at 1:33 AM, David Cohen <dacohen@gmail.com> wrote:
>>> Hi,
>>>
>>> On Fri, Feb 18, 2011 at 7:08 PM, Lesly A M <leslyam@ti.com> wrote:
>>>> Workaround for TWL5030 Silicon Errata 27 & 28:
>>>> 27 - VDD1, VDD2, may have glitches when their output value is updated.
>>>> 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock
>>>> is switched from internal to external.
>>>>
>>>> Errata 27:
>>>> If the DCDC regulators is running on their internal oscillator,
>>>> negative glitches may occur on VDD1, VDD2 output when voltage is changed.
>>>> The OMAP device may reboot if the VDD1 or VDD2 go below the
>>>> core minimum operating voltage.
>>>>
>>>> WORKAROUND
>>>> Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of
>>>> the internal oscillator.
>>>>
>>>> Errata 28:
>>>> VDD1/VDD2 clock system may hang during switching the clock source from
>>>> internal oscillator to external. VDD1/VDD2 output voltages may collapse
>>>> if clock stops.
>>>>
>>>> WORKAROUND
>>>> If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and
>>>> setuptimes to make sure the switching will happen only when HFCLKIN is stable.
>>>> Also use the TWL5030 watchdog to safeguard the first switching from
>>>> internal oscillator to HFCLKIN during the TWL5030 init.
>>>>
>>>> IMPACT
>>>> setup time and the power sequence is changed.
>>>> sleep/wakeup time values will be changed.
>>>>
>>>> The workaround changes are called from twl4030_power_init(), since we have to
>>>> make some i2c_read calls to check the TRITON version & the i2c will not be
>>>> initialized in the early stage.
>>>>
>>>> This workaround is required for TWL5030 Silicon version less than ES1.2
>>>> The power script & setup time changes are recommended by TI HW team.
>>>>
>>>> http://omapedia.org/wiki/TWL4030_power_scripts
>>>>
>>>> Changes taken from TRITON Errata27 workaround patch by Nishanth Menon.
>>>>
>>>> Signed-off-by: Lesly A M <leslyam@ti.com>
>>>> Cc: Nishanth Menon <nm@ti.com>
>>>> Cc: David Derrick <dderrick@ti.com>
>>>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>>>> ---
>>>> arch/arm/mach-omap2/omap_twl.c | 35 +++++++++
>>>> arch/arm/mach-omap2/twl4030.c | 115 +++++++++++++++++++++++++++++
>>>> arch/arm/plat-omap/include/plat/voltage.h | 2 +
>>>> drivers/mfd/twl4030-power.c | 74 ++++++++++++++++++
>>>> include/linux/i2c/twl.h | 2 +
>>>> 5 files changed, 228 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
>>>> index f0feab9..d6984b8 100644
>>>> --- a/arch/arm/mach-omap2/omap_twl.c
>>>> +++ b/arch/arm/mach-omap2/omap_twl.c
>>>> @@ -176,6 +176,14 @@
>>>> #define OMAP3_CLKSETUP_RET 31 /* 30.5 uS */
>>>> #define OMAP3_CLKSETUP_OFF 10000 /* 10 mS */
>>>>
>>>> +/*
>>>> + * The clk/volt setuptime is adjusted to do the VDD1/VDD2 voltage rampup
>>>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled
>>>> + */
>>>> +#define CLKSETUP_TWL5030_ERRATA27 11567 /* 11.567 mS */
>>>> +#define VOLTOFFSET_TWL5030_ERRATA27 516 /* 516 uS */
>>>> +#define VOLTSETUP2_TWL5030_ERRATA27 11079 /* 11.079 mS */
>>>> +
>>>> static bool is_offset_valid;
>>>> static u8 smps_offset;
>>>>
>>>> @@ -482,6 +490,33 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
>>>> .uv_to_vsel = twl6030_uv_to_vsel,
>>>> };
>>>>
>>>> +/**
>>>> + * omap3_twl5030_errata27() - update the clk & volt setup time.
>>>> + *
>>>> + * Api to update the clk & volt setup time for TWL5030 errata 27.
>>>> + */
>>>> +void omap3_twl5030_errata27(void)
>>>> +{
>>>> + if (!cpu_is_omap34xx())
>>>> + return;
>>>> +
>>>> + if (cpu_is_omap3630()) {
>>>> + omap3630_mpu_volt_info.voltsetup_off.voltsetup2 =
>>>> + VOLTSETUP2_TWL5030_ERRATA27;
>>>> + omap3630_mpu_volt_info.voltsetup_off.voltoffset =
>>>> + VOLTOFFSET_TWL5030_ERRATA27;
>>>> + omap3630_mpu_volt_info.clksetup_off.clksetup =
>>>> + CLKSETUP_TWL5030_ERRATA27;
>>>> + } else {
>>>> + omap3430_mpu_volt_info.voltsetup_off.voltsetup2 =
>>>> + VOLTSETUP2_TWL5030_ERRATA27;
>>>> + omap3430_mpu_volt_info.voltsetup_off.voltoffset =
>>>> + VOLTOFFSET_TWL5030_ERRATA27;
>>>> + omap3430_mpu_volt_info.clksetup_off.clksetup =
>>>> + CLKSETUP_TWL5030_ERRATA27;
>>>> + }
>>>> +}
>>>> +
>>>> int __init omap4_twl_init(void)
>>>> {
>>>> struct voltagedomain *voltdm;
>>>> diff --git a/arch/arm/mach-omap2/twl4030.c b/arch/arm/mach-omap2/twl4030.c
>>>> index f3d05e5..b5fb496 100644
>>>> --- a/arch/arm/mach-omap2/twl4030.c
>>>> +++ b/arch/arm/mach-omap2/twl4030.c
>>>> @@ -137,10 +137,125 @@ static struct twl4030_resconfig twl4030_rconfig[] = {
>>>> { 0, 0},
>>>> };
>>>>
>>>> +/*
>>>> + * Active to Sleep sequence, which is executed upon P1/P2/P3
>>>> + * transition for sleep.
>>>> + *
>>>> + * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from
>>>> + * HFCLKIN to internal oscillator when the HFCLKIN is stable.
>>>> + */
>>>> +static struct twl4030_ins __initdata sleep_on_seq_errata27[] = {
>>>> + /*
>>>> + * Singular message to disable HCLKOUT.
>>>> + * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from
>>>> + * HFCLKIN to internal oscillator before disabling HFCLKIN.
>>>> + */
>>>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20},
>>>> + /* Broadcast message to put res(TYPE2 = 1) to sleep */
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>>>> + RES_STATE_SLEEP), 2},
>>>> + /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>>> + RES_STATE_SLEEP), 2},
>>>> +};
>>>> +
>>>> +static struct twl4030_script sleep_on_script_errata27 __initdata = {
>>>> + .script = sleep_on_seq_errata27,
>>>> + .size = ARRAY_SIZE(sleep_on_seq_errata27),
>>>> + .flags = TWL4030_SLEEP_SCRIPT,
>>>> +};
>>>> +
>>>> +/*
>>>> + * Sleep to Active sequence, which is executed upon P1/P2/P3
>>>> + * transition for wakeup.
>>>> + *
>>>> + * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage rampup
>>>> + * only after HFCLKIN is stabilized and the HFCLKOUT is enabled.
>>>> + */
>>>> +static struct twl4030_ins wakeup_seq_errata27[] __initdata = {
>>>> + /*
>>>> + * Broadcast message to put res(TYPE2 = 2) to active.
>>>> + * Wait for ~10 mS (rampup time for OSC on the board)
>>>> + * after HFCLKIN is enabled
>>>> + */
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>>> + RES_STATE_ACTIVE), 55},
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>>> + RES_STATE_ACTIVE), 55},
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>>> + RES_STATE_ACTIVE), 54},
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2,
>>>> + RES_STATE_ACTIVE), 1},
>>>> + /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */
>>>> + {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1},
>>>> + /*
>>>> + * Broadcast message to put res(TYPE2 = 1) to active.
>>>> + * VDD1/VDD2 rampup after HFCLKIN is stable and HFCLKOUT is enabled.
>>>> + */
>>>> + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1,
>>>> + RES_STATE_ACTIVE), 2},
>>>> +};
>>>> +
>>>> +static struct twl4030_script wakeup_script_errata27 __initdata = {
>>>> + .script = wakeup_seq_errata27,
>>>> + .size = ARRAY_SIZE(wakeup_seq_errata27),
>>>> + .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
>>>> +};
>>>> +
>>>> +/* TRITON script for sleep, wakeup & warm_reset */
>>>> +static struct twl4030_script *twl4030_scripts_errata27[] __initdata = {
>>>> + &sleep_on_script_errata27,
>>>> + &wakeup_script_errata27,
>>>> + &wrst_script,
>>>> +};
>>>> +
>>>> +/*
>>>> + * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control
>>>> + * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off
>>>> + * only during OFFMODE.
>>>> + * (*P2 is included if the platform uses it for modem/some other processor)
>>>> + */
>>>> +static struct twl4030_resconfig twl4030_rconfig_errata27[] = {
>>>> + { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>>> + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
>>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
>>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
>>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
>>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>>> + .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>>> + { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>>> + .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
>>>> + { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
>>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
>>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
>>>> + .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
>>>> + .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>>> + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
>>>> + .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP },
>>>> + { 0, 0},
>>>> +};
>>>> +
>>>> +void twl5030_script_errata27(void)
>>>> +{
>>>> + twl4030_generic_script.scripts = twl4030_scripts_errata27;
>>>> + twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_errata27);
>>>> + twl4030_generic_script.resource_config = twl4030_rconfig_errata27;
>>>> +}
>>>> +
>>>> struct twl4030_power_data twl4030_generic_script = {
>>>> .scripts = twl4030_scripts,
>>>> .num = ARRAY_SIZE(twl4030_scripts),
>>>> .resource_config = twl4030_rconfig,
>>>> + .twl5030_errata27wa_vcsetup = omap3_twl5030_errata27,
>>>> + .twl5030_errata27wa_script = twl5030_script_errata27,
>>>> };
>>>> EXPORT_SYMBOL(twl4030_generic_script);
>>>> #endif
>>>> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
>>>> index 2d737b9..c9d899b 100644
>>>> --- a/arch/arm/plat-omap/include/plat/voltage.h
>>>> +++ b/arch/arm/plat-omap/include/plat/voltage.h
>>>> @@ -152,6 +152,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
>>>> int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>>>> struct omap_volt_pmic_info *pmic_info);
>>>> void omap3_voltage_vc_update(int core_next_state);
>>>> +void omap3_twl5030_errata27(void);
>>>> void omap_change_voltscale_method(struct voltagedomain *voltdm,
>>>> int voltscale_method);
>>>> /* API to get the voltagedomain pointer */
>>>> @@ -165,6 +166,7 @@ static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
>>>> return -EINVAL;
>>>> }
>>>> void omap3_voltage_vc_update(int core_next_state) {}
>>>> +void omap3_twl5030_errata27(void) {}
>>>> static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
>>>> int voltscale_method) {}
>>>> static inline int omap_voltage_late_init(void)
>>>> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
>>>> index 8373d79..cc8a137 100644
>>>> --- a/drivers/mfd/twl4030-power.c
>>>> +++ b/drivers/mfd/twl4030-power.c
>>>> @@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b;
>>>> #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
>>>> #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
>>>>
>>>> +#define R_VDD1_OSC 0x5C
>>>> +#define R_VDD2_OSC 0x6A
>>>> +#define R_VIO_OSC 0x52
>>>> +#define EXT_FS_CLK_EN (0x1 << 6)
>>>> +
>>>> +#define R_WDT_CFG 0x03
>>>> +#define WDT_WRK_TIMEOUT 0x03
>>>> +
>>>> /* resource configuration registers
>>>> <RESOURCE>_DEV_GRP at address 'n+0'
>>>> <RESOURCE>_TYPE at address 'n+1'
>>>> @@ -511,6 +519,60 @@ int twl4030_remove_script(u8 flags)
>>>> return err;
>>>> }
>>>>
>>>> +/**
>>>> + * twl_errata27_workaround() - Workaround for TWL5030 Silicon Errata 27 & 28:
>>>> + * 27 - VDD1, VDD2, may have glitches when their output value is updated.
>>>> + * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is
>>>> + * switched from internal to external.
>>>> + *
>>>> + * Workaround requires the TWL DCDCs to use HFCLK instead of
>>>> + * internal oscillator. Also enable TWL watchdog before switching the osc
>>>> + * to recover if the VDD1/VDD2 stop working.
>>>> + */
>>>> +static void __init twl_errata27_workaround(void)
>>>> +{
>>>> + u8 val;
>>>> + u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC};
>>>> + u8 wdt_counter_val = 0;
>>>> + int i;
>>>> + int err;
>>>> +
>>>> + /* Setup the twl wdt to take care of borderline failure case */
>>>> + err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val,
>>>> + R_WDT_CFG);
>>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT,
>>>> + R_WDT_CFG);
>>>> +
>>>> + for (i = 0; i < sizeof(smps_osc_reg); i++) {
>>>> + err |= twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val,
>>>> + smps_osc_reg[i]);
>>>> + val |= EXT_FS_CLK_EN;
>>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
>>>> + smps_osc_reg[i]);
>>>> + }
>>>> +
>>>> + /* restore the original value */
>>>> + err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val,
>>>> + R_WDT_CFG);
>>>> + if (err)
>>>> + pr_warning("TWL4030: workaround setup failed!\n");
>>>> +}
>>>> +
>>>> +bool is_twl5030_errata27wa_required(void)
>>>> +{
>>>> + u32 twl5030_si_ver;
>>>> + int ret = 0;
>>>> +
>>>> + ret = twl5030_get_si_ver(&twl5030_si_ver);
>>>> + if (ret)
>>>> + pr_warning("TWL4030: Unable to get the Si version\n");
>>>
>>> You can get rid of 'ret'. What about:
>>> if (twl5030_get_si_ver(&twl5030_si_ver))
>>> pr_warning("TWL4030: Unable to get the Si version\n");
>>
>> And return error from here in case of !twl5030_get_si_ver()
>
> s/!twl5030_get_si_ver()/twl5030_get_si_ver()/
Ok, I will do it.
Regards,
Lesly A M
>>>> +
>>>> + if (twl5030_si_ver < TWL5030_REV_1_2)
>>>> + return true;
>>>> + else
>>>> + return false;
>>>
>>> No need to if...else here. You can:
>>> return twl5030_si_ver < TWL5030_REV_1_2;
>>>
>>> Regards,
>>>
>>> David Cohen
>>>
>>>> +}
>>>> +
>>>> void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>>>> {
>>>> int err = 0;
>>>> @@ -530,6 +592,18 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
>>>> if (err)
>>>> goto unlock;
>>>>
>>>> + /* Applying TWL5030 Errata 27 WA based on Si revision &
>>>> + * flag updated from board file*/
>>>> + if (is_twl5030_errata27wa_required()) {
>>>> + pr_info("TWL5030: Enabling workaround for Si Errata 27\n");
>>>> + twl_errata27_workaround();
>>>> + if (twl4030_scripts->twl5030_errata27wa_vcsetup)
>>>> + twl4030_scripts->twl5030_errata27wa_vcsetup();
>>>> +
>>>> + if (twl4030_scripts->twl5030_errata27wa_script)
>>>> + twl4030_scripts->twl5030_errata27wa_script();
>>>> + }
>>>> +
>>>> for (i = 0; i < twl4030_scripts->num; i++) {
>>>> err = load_twl4030_script(twl4030_scripts->scripts[i], address);
>>>> if (err)
>>>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>>>> index 5d3f2bf..26232f3 100644
>>>> --- a/include/linux/i2c/twl.h
>>>> +++ b/include/linux/i2c/twl.h
>>>> @@ -667,6 +667,8 @@ struct twl4030_power_data {
>>>> struct twl4030_script **scripts;
>>>> unsigned num;
>>>> struct twl4030_resconfig *resource_config;
>>>> + void (*twl5030_errata27wa_vcsetup)(void);
>>>> + void (*twl5030_errata27wa_script)(void);
>>>> #define TWL4030_RESCONFIG_UNDEF ((u8)-1)
>>>> };
>>>>
>>>> --
>>>> 1.7.1
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>>
>>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-02-21 6:55 ` Manuel, Lesly Arackal
@ 2011-02-21 11:57 ` Peter 'p2' De Schrijver
2011-02-21 12:20 ` Menon, Nishanth
0 siblings, 1 reply; 30+ messages in thread
From: Peter 'p2' De Schrijver @ 2011-02-21 11:57 UTC (permalink / raw)
To: ext Manuel, Lesly Arackal
Cc: Jean Pihet, linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Mon, Feb 21, 2011 at 12:25:01PM +0530, ext Manuel, Lesly Arackal wrote:
> Hi Jean,
>
> On Fri, Feb 18, 2011 at 10:57 PM, Jean Pihet <jean.pihet@newoldbits.com> wrote:
> > On Fri, Feb 18, 2011 at 6:08 PM, Lesly A M <leslyam@ti.com> wrote:
> >> Patch series for TWL4030 power scripts and workaround for TWL errata 27.
> >>
> >> Changes for implementing TWL4030 power scripts recommended by hardware team.
> >> Introduced a new TWL4030 power script file, which can be used by different
> >> OMAP3 board with the power companion chip TWL4030.
> >>
> >> Updated the changes for TWL4030 errata 27 & 28, modified the
> >> TWL4030 power script and voltage controller setuptime.
> >> Workaround for TWL4030 errata 27 & 28 is required for
> >> Si version less than or equal to TWL5030 ES1.1.
> >>
> >> TWL4030 script changes rebased on Kevin's PM tree in pm branch.
> >>
> >> Changes in v7:
> >> changes to fix Nishanth Menon's comments
> >> i) Added the TWL4030 Errata 27 fix
> >>
> >> split the first patch in v6
> >> i) fix for twl4030 script load
> >> ii) correct the warning print during script loading
> >>
> >> Added new patch files
> >> i) pmic_info struct cleanup
> >> ii) changing sys_off signal polarity
> >>
> >> Updated the change logs
> >>
> >> This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
> >> Tested with suspend/resume script, which will test system suspend in a loop.
> >> Tested for more than 1000 iterations.
> >
> > Good to see the TWL scripts back in the mainline kernel!
> > Are the scripts compatible with the OMAP3 Beagleboard? I would like to
> > test the changes on that board.
>
> I have not tested on Beagleboard.
> I think Beagleboard is using different PM IC TPSxxxx.
> If its equivalent to TRITON then this script should work on it.
As far as I know they are equivalent. I don't know if the errata need to
be applied though. Maybe someone from TI can comment?
Cheers,
Peter.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] omap3: pm: TWL5030 version checking
2011-02-18 17:08 ` [PATCH 09/12] omap3: pm: TWL5030 version checking Lesly A M
2011-02-18 23:51 ` David Cohen
@ 2011-02-21 12:14 ` Krishnamoorthy, Balaji T
2011-02-21 12:27 ` Manuel, Lesly Arackal
1 sibling, 1 reply; 30+ messages in thread
From: Krishnamoorthy, Balaji T @ 2011-02-21 12:14 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Fri, Feb 18, 2011 at 10:38 PM, Lesly A M <leslyam@ti.com> wrote:
<snip>
> +int twl5030_get_si_ver(u32 *value)
> +{
> + int ret = 0;
> + static u32 twl_idcode;
> +
> + if (twl_idcode == 0)
> + ret = twl_read_idcode_register(&twl_idcode);
> + if (ret)
> + pr_err("TWL4030 Unable to check Si version\n");
this if block should be under if (twl_idcode == 0)
> +
> + if (TWL_SIL_TYPE(twl_idcode) == TWL_SIL_5030)
> + *value = TWL_SIL_REV(twl_idcode);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(twl5030_get_si_ver);
> +
> static struct device *
> add_numbered_child(unsigned chip, const char *name, int num,
> void *pdata, unsigned pdata_len,
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index f4bd475..5d3f2bf 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -150,7 +150,15 @@
> #define MMC_PU (0x1 << 3)
> #define MMC_PD (0x1 << 2)
>
> +#define R_UNLOCK_TEST_REG 0x12
> +#define TWL_EEPROM_R_UNLOCK 0x49
>
> +#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
> +#define TWL_SIL_REV(rev) ((rev) >> 24)
> +#define TWL_SIL_5030 0x09002F
Is it 0x9802F or 0x09002F for TWL5030 ?
> +#define TWL5030_REV_1_0 0x00
> +#define TWL5030_REV_1_1 0x10
> +#define TWL5030_REV_1_2 0x30
>
> #define TWL4030_CLASS_ID 0x4030
> #define TWL6030_CLASS_ID 0x6030
> @@ -180,6 +188,8 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
> int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
> int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>
> +int twl5030_get_si_ver(u32 *value);
> +
> int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
> int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
>
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-02-21 11:57 ` Peter 'p2' De Schrijver
@ 2011-02-21 12:20 ` Menon, Nishanth
0 siblings, 0 replies; 30+ messages in thread
From: Menon, Nishanth @ 2011-02-21 12:20 UTC (permalink / raw)
To: Peter 'p2' De Schrijver
Cc: ext Manuel, Lesly Arackal, Jean Pihet, linux-omap, David Derrick,
Samuel Ortiz
On Mon, Feb 21, 2011 at 17:27, Peter 'p2' De Schrijver
<peter.de-schrijver@nokia.com> wrote:
[..]
> > >> This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
> > >> Tested with suspend/resume script, which will test system suspend in a loop.
> > >> Tested for more than 1000 iterations.
> > >
> > > Good to see the TWL scripts back in the mainline kernel!
> > > Are the scripts compatible with the OMAP3 Beagleboard? I would like to
> > > test the changes on that board.
> >
> > I have not tested on Beagleboard.
> > I think Beagleboard is using different PM IC TPSxxxx.
> > If its equivalent to TRITON then this script should work on it.
>
> As far as I know they are equivalent. I don't know if the errata need to
> be applied though. Maybe someone from TI can comment?
Yes for the impacted revisions.
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] omap3: pm: TWL5030 version checking
2011-02-21 12:14 ` Krishnamoorthy, Balaji T
@ 2011-02-21 12:27 ` Manuel, Lesly Arackal
0 siblings, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-02-21 12:27 UTC (permalink / raw)
To: Krishnamoorthy, Balaji T
Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
On Mon, Feb 21, 2011 at 5:44 PM, Krishnamoorthy, Balaji T
<balajitk@ti.com> wrote:
> On Fri, Feb 18, 2011 at 10:38 PM, Lesly A M <leslyam@ti.com> wrote:
>
> <snip>
>
>> +int twl5030_get_si_ver(u32 *value)
>> +{
>> + int ret = 0;
>> + static u32 twl_idcode;
>> +
>> + if (twl_idcode == 0)
>> + ret = twl_read_idcode_register(&twl_idcode);
>
>> + if (ret)
>> + pr_err("TWL4030 Unable to check Si version\n");
> this if block should be under if (twl_idcode == 0)
Ok
>> +
>> + if (TWL_SIL_TYPE(twl_idcode) == TWL_SIL_5030)
>> + *value = TWL_SIL_REV(twl_idcode);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL(twl5030_get_si_ver);
>> +
>> static struct device *
>> add_numbered_child(unsigned chip, const char *name, int num,
>> void *pdata, unsigned pdata_len,
>> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
>> index f4bd475..5d3f2bf 100644
>> --- a/include/linux/i2c/twl.h
>> +++ b/include/linux/i2c/twl.h
>> @@ -150,7 +150,15 @@
>> #define MMC_PU (0x1 << 3)
>> #define MMC_PD (0x1 << 2)
>>
>> +#define R_UNLOCK_TEST_REG 0x12
>> +#define TWL_EEPROM_R_UNLOCK 0x49
>>
>> +#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF)
>> +#define TWL_SIL_REV(rev) ((rev) >> 24)
>> +#define TWL_SIL_5030 0x09002F
>
> Is it 0x9802F or 0x09002F for TWL5030 ?
TWL5030 until ES 1.1 si the value read from the IDCODE register was
showing 0x09002F (But in TRM it is 0x9802F)
Regards,
Lesly A M
>> +#define TWL5030_REV_1_0 0x00
>> +#define TWL5030_REV_1_1 0x10
>> +#define TWL5030_REV_1_2 0x30
>>
>> #define TWL4030_CLASS_ID 0x4030
>> #define TWL6030_CLASS_ID 0x6030
>> @@ -180,6 +188,8 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
>> int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>> int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
>>
>> +int twl5030_get_si_ver(u32 *value);
>> +
>> int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
>> int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
>>
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
` (12 preceding siblings ...)
2011-02-18 17:27 ` [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Jean Pihet
@ 2011-03-01 22:24 ` Kevin Hilman
2011-03-02 5:54 ` Manuel, Lesly Arackal
13 siblings, 1 reply; 30+ messages in thread
From: Kevin Hilman @ 2011-03-01 22:24 UTC (permalink / raw)
To: Lesly A M; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Lesly A M <leslyam@ti.com> writes:
> Patch series for TWL4030 power scripts and workaround for TWL errata 27.
>
> Changes for implementing TWL4030 power scripts recommended by hardware team.
> Introduced a new TWL4030 power script file, which can be used by different
> OMAP3 board with the power companion chip TWL4030.
>
> Updated the changes for TWL4030 errata 27 & 28, modified the
> TWL4030 power script and voltage controller setuptime.
> Workaround for TWL4030 errata 27 & 28 is required for
> Si version less than or equal to TWL5030 ES1.1.
>
> TWL4030 script changes rebased on Kevin's PM tree in pm branch.
What is the dependency on my PM branch?
It looks like this can be based on mainline or l-o master.
Kevin
> Changes in v7:
> changes to fix Nishanth Menon's comments
> i) Added the TWL4030 Errata 27 fix
>
> split the first patch in v6
> i) fix for twl4030 script load
> ii) correct the warning print during script loading
>
> Added new patch files
> i) pmic_info struct cleanup
> ii) changing sys_off signal polarity
>
> Updated the change logs
>
> This changes are tested on OMAP3430 & OMAP3630 SDP with off mode enabled in suspend path.
> Tested with suspend/resume script, which will test system suspend in a loop.
> Tested for more than 1000 iterations.
>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: David Derrick <dderrick@ti.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> ---
> Lesly A M (12):
> omap3: pm: Fix for the TRITON sleep/wakeup sequence
> omap3: pm: Correct the warning print during script loading
> omap3: pm: cleanup pmic_info structure
> omap3: pm: Using separate clk/volt setup_time for RET and OFF states
> omap3630: pm: Adding voltage controller data
> omap3: pm: Correcting the sys_offmode signal polarity
> omap3: pm: Re-programing the setup time based on CORE target state
> omap3: pm: TWL4030 power scripts for OMAP3 boards
> omap3: pm: TWL5030 version checking
> mfd: TWL4030: changes for TRITON Errata 27 workaround
> omap3430: Updating the board file to use TWL4030 scripts
> omap3630: Updating the board file to use TWL4030 scripts
>
> arch/arm/mach-omap2/Makefile | 12 +-
> arch/arm/mach-omap2/board-3430sdp.c | 3 +-
> arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +
> arch/arm/mach-omap2/omap_twl.c | 369 +++++++++++++++++++++++---
> arch/arm/mach-omap2/pm34xx.c | 15 +-
> arch/arm/mach-omap2/twl4030.c | 261 ++++++++++++++++++
> arch/arm/mach-omap2/twl4030.h | 21 ++
> arch/arm/mach-omap2/voltage.c | 167 +++++++++---
> arch/arm/plat-omap/include/plat/voltage.h | 49 +++-
> drivers/mfd/twl-core.c | 50 ++++
> drivers/mfd/twl4030-power.c | 79 ++++++-
> include/linux/i2c/twl.h | 45 +++-
> 12 files changed, 961 insertions(+), 112 deletions(-)
> create mode 100644 arch/arm/mach-omap2/twl4030.c
> create mode 100644 arch/arm/mach-omap2/twl4030.h
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27
2011-03-01 22:24 ` Kevin Hilman
@ 2011-03-02 5:54 ` Manuel, Lesly Arackal
0 siblings, 0 replies; 30+ messages in thread
From: Manuel, Lesly Arackal @ 2011-03-02 5:54 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap, Nishanth Menon, David Derrick, Samuel Ortiz
Hi Kevin,
On Wed, Mar 2, 2011 at 3:54 AM, Kevin Hilman <khilman@ti.com> wrote:
> Lesly A M <leslyam@ti.com> writes:
>
>> Patch series for TWL4030 power scripts and workaround for TWL errata 27.
>>
>> Changes for implementing TWL4030 power scripts recommended by hardware team.
>> Introduced a new TWL4030 power script file, which can be used by different
>> OMAP3 board with the power companion chip TWL4030.
>>
>> Updated the changes for TWL4030 errata 27 & 28, modified the
>> TWL4030 power script and voltage controller setuptime.
>> Workaround for TWL4030 errata 27 & 28 is required for
>> Si version less than or equal to TWL5030 ES1.1.
>>
>> TWL4030 script changes rebased on Kevin's PM tree in pm branch.
>
> What is the dependency on my PM branch?
>
> It looks like this can be based on mainline or l-o master.
>
OFFMODE was not working on mainline and l-o master.
Regards,
Lesly A M
< ... >
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2011-03-02 5:54 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-18 17:08 [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Lesly A M
2011-02-18 17:08 ` [PATCH 01/12] omap3: pm: Fix for the TRITON sleep/wakeup sequence Lesly A M
2011-02-18 23:38 ` David Cohen
2011-02-21 9:39 ` Manuel, Lesly Arackal
2011-02-18 17:08 ` [PATCH 02/12] omap3: pm: Correct the warning print during script loading Lesly A M
2011-02-18 17:08 ` [PATCH 03/12] omap3: pm: cleanup pmic_info structure Lesly A M
2011-02-18 17:08 ` [PATCH 04/12] omap3: pm: Using separate clk/volt setup_time for RET and OFF states Lesly A M
2011-02-18 17:08 ` [PATCH 05/12] omap3630: pm: Adding voltage controller data Lesly A M
2011-02-18 17:08 ` [PATCH 06/12] omap3: pm: Correcting the sys_offmode signal polarity Lesly A M
2011-02-18 17:08 ` [PATCH 07/12] omap3: pm: Re-programing the setup time based on CORE target state Lesly A M
2011-02-18 17:08 ` [PATCH 08/12] omap3: pm: TWL4030 power scripts for OMAP3 boards Lesly A M
2011-02-18 17:08 ` [PATCH 09/12] omap3: pm: TWL5030 version checking Lesly A M
2011-02-18 23:51 ` David Cohen
2011-02-21 10:26 ` Manuel, Lesly Arackal
2011-02-21 12:14 ` Krishnamoorthy, Balaji T
2011-02-21 12:27 ` Manuel, Lesly Arackal
2011-02-18 17:08 ` [PATCH 10/12] mfd: TWL4030: changes for TRITON Errata 27 workaround Lesly A M
2011-02-18 23:33 ` David Cohen
2011-02-19 0:44 ` David Cohen
2011-02-19 22:02 ` David Cohen
2011-02-21 11:25 ` Manuel, Lesly Arackal
2011-02-21 11:23 ` Manuel, Lesly Arackal
2011-02-18 17:08 ` [PATCH 11/12] omap3430: Updating the board file to use TWL4030 scripts Lesly A M
2011-02-18 17:08 ` [PATCH 12/12] omap3630: " Lesly A M
2011-02-18 17:27 ` [PATCH v7 00/12] omap3: pm: TWL4030 power scripts and workaround for TWL errata 27 Jean Pihet
2011-02-21 6:55 ` Manuel, Lesly Arackal
2011-02-21 11:57 ` Peter 'p2' De Schrijver
2011-02-21 12:20 ` Menon, Nishanth
2011-03-01 22:24 ` Kevin Hilman
2011-03-02 5:54 ` Manuel, Lesly Arackal
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.