All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv5 00/14] arm: omap3: auto-ret / auto-off support
@ 2012-02-21 14:04 ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Hi,

This set applies on top of the pwrdm / clkdm / voltdm usecounting patch
set I sent last week (see:
http://www.spinics.net/lists/linux-omap/msg64670.html):

Following changes done compared to previous version.

- split out the basic usecounting support as its own set (see above)
- added lots of new comments to the code, including kerneldoc style
  function headers
- changed pmic->vp_vddmin / vddmax to simply vddmin / vddmax, these
  are now used as limits for all voltage related operations (both
  vc / vp), pmic limits are checked against the values defined for
  the omap chip itself to select proper voltage levels
- some other minor fixes proposed for the previous version

TBD:
- omap4 support (will work with this once retention works for omap4)
- pmic script support for omap3 (scaling to 0V level)

Tested on omap3 beagle with retention / off, suspend and dynamic idle.
Voltage rails for vdd1 (mpu) and vdd2 (core) measured and seen to scale
correctly to retention / off voltage levels.

-Tero


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 00/14] arm: omap3: auto-ret / auto-off support
@ 2012-02-21 14:04 ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This set applies on top of the pwrdm / clkdm / voltdm usecounting patch
set I sent last week (see:
http://www.spinics.net/lists/linux-omap/msg64670.html):

Following changes done compared to previous version.

- split out the basic usecounting support as its own set (see above)
- added lots of new comments to the code, including kerneldoc style
  function headers
- changed pmic->vp_vddmin / vddmax to simply vddmin / vddmax, these
  are now used as limits for all voltage related operations (both
  vc / vp), pmic limits are checked against the values defined for
  the omap chip itself to select proper voltage levels
- some other minor fixes proposed for the previous version

TBD:
- omap4 support (will work with this once retention works for omap4)
- pmic script support for omap3 (scaling to 0V level)

Tested on omap3 beagle with retention / off, suspend and dynamic idle.
Voltage rails for vdd1 (mpu) and vdd2 (core) measured and seen to scale
correctly to retention / off voltage levels.

-Tero

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 01/14] arm: OMAP3+: PM: VP: use uV for max and min voltage limits
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel, Nishanth Menon, Vishwanath BS

From: Nishanth Menon <nm@ti.com>

Every PMIC has it's own eccentricities, For example, one of the
PMIC has MSB set to 1 for a specific function - voltage enable!
using an hardcoded value specific for TWL when copied over to
such an implementation causes the system to crash as the MSB bit
was 0 and the voltage got disabled!.

Instead we use actual values and depend on the convertion routines
to abstract out the eccentricities of each PMIC.

With this, we can now move the voltages to a common location in
voltage.h as they are no longer dependent on PMICs and expect the
PMIC's conversion routines to set a cap if the voltage is out of
reach for the PMIC.

Reported-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |   17 -----------------
 arch/arm/mach-omap2/voltage.h  |   22 ++++++++++++++++++++--
 arch/arm/mach-omap2/vp.c       |    4 ++--
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index f515a1a..df4e7c3 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -30,16 +30,6 @@
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP3_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP3430_VP1_VLIMITTO_VDDMIN	0x14
-#define OMAP3430_VP1_VLIMITTO_VDDMAX	0x42
-#define OMAP3430_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3430_VP2_VLIMITTO_VDDMAX	0x2c
-
-#define OMAP3630_VP1_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP1_VLIMITTO_VDDMAX	0x3c
-#define OMAP3630_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP2_VLIMITTO_VDDMAX	0x30
-
 #define OMAP4_SRI2C_SLAVE_ADDR		0x12
 #define OMAP4_VDD_MPU_SR_VOLT_REG	0x55
 #define OMAP4_VDD_MPU_SR_CMD_REG	0x56
@@ -53,13 +43,6 @@
 #define OMAP4_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP4_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	0x39
-#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	0x2D
-#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	0x28
-
 static bool is_offset_valid;
 static u8 smps_offset;
 /*
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 8829201..fa5b3dc 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -118,6 +118,24 @@ struct omap_volt_data {
 	u8	vp_errgain;
 };
 
+/* Min and max voltages from OMAP perspective */
+#define OMAP3430_VP1_VLIMITTO_VDDMIN	850000
+#define OMAP3430_VP1_VLIMITTO_VDDMAX	1425000
+#define OMAP3430_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3430_VP2_VLIMITTO_VDDMAX	1150000
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP1_VLIMITTO_VDDMAX	1350000
+#define OMAP3630_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP2_VLIMITTO_VDDMAX	1200000
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	1410000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	1260000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	1200000
+
 /**
  * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
  * @slew_rate:	PMIC slew rate (in uv/us)
@@ -144,8 +162,8 @@ struct omap_voltdm_pmic {
 	u8 vp_erroroffset;
 	u8 vp_vstepmin;
 	u8 vp_vstepmax;
-	u8 vp_vddmin;
-	u8 vp_vddmax;
+	u32 vp_vddmin;
+	u32 vp_vddmax;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 807391d..6ee0b4a 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->vp_vddmin;
-	vddmax = voltdm->pmic->vp_vddmax;
+	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 01/14] arm: OMAP3+: PM: VP: use uV for max and min voltage limits
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nishanth Menon <nm@ti.com>

Every PMIC has it's own eccentricities, For example, one of the
PMIC has MSB set to 1 for a specific function - voltage enable!
using an hardcoded value specific for TWL when copied over to
such an implementation causes the system to crash as the MSB bit
was 0 and the voltage got disabled!.

Instead we use actual values and depend on the convertion routines
to abstract out the eccentricities of each PMIC.

With this, we can now move the voltages to a common location in
voltage.h as they are no longer dependent on PMICs and expect the
PMIC's conversion routines to set a cap if the voltage is out of
reach for the PMIC.

Reported-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |   17 -----------------
 arch/arm/mach-omap2/voltage.h  |   22 ++++++++++++++++++++--
 arch/arm/mach-omap2/vp.c       |    4 ++--
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index f515a1a..df4e7c3 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -30,16 +30,6 @@
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP3_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP3430_VP1_VLIMITTO_VDDMIN	0x14
-#define OMAP3430_VP1_VLIMITTO_VDDMAX	0x42
-#define OMAP3430_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3430_VP2_VLIMITTO_VDDMAX	0x2c
-
-#define OMAP3630_VP1_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP1_VLIMITTO_VDDMAX	0x3c
-#define OMAP3630_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP2_VLIMITTO_VDDMAX	0x30
-
 #define OMAP4_SRI2C_SLAVE_ADDR		0x12
 #define OMAP4_VDD_MPU_SR_VOLT_REG	0x55
 #define OMAP4_VDD_MPU_SR_CMD_REG	0x56
@@ -53,13 +43,6 @@
 #define OMAP4_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP4_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	0x39
-#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	0x2D
-#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	0x28
-
 static bool is_offset_valid;
 static u8 smps_offset;
 /*
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 8829201..fa5b3dc 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -118,6 +118,24 @@ struct omap_volt_data {
 	u8	vp_errgain;
 };
 
+/* Min and max voltages from OMAP perspective */
+#define OMAP3430_VP1_VLIMITTO_VDDMIN	850000
+#define OMAP3430_VP1_VLIMITTO_VDDMAX	1425000
+#define OMAP3430_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3430_VP2_VLIMITTO_VDDMAX	1150000
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP1_VLIMITTO_VDDMAX	1350000
+#define OMAP3630_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP2_VLIMITTO_VDDMAX	1200000
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	1410000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	1260000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	1200000
+
 /**
  * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
  * @slew_rate:	PMIC slew rate (in uv/us)
@@ -144,8 +162,8 @@ struct omap_voltdm_pmic {
 	u8 vp_erroroffset;
 	u8 vp_vstepmin;
 	u8 vp_vstepmax;
-	u8 vp_vddmin;
-	u8 vp_vddmax;
+	u32 vp_vddmin;
+	u32 vp_vddmax;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 807391d..6ee0b4a 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->vp_vddmin;
-	vddmax = voltdm->pmic->vp_vddmax;
+	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

These are now called vddmin and vddmax, as these fields will be used
globally for selecting voltage ranges for a pmic channel, and not
only for voltage processor.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |   27 ++++++++++-----------------
 arch/arm/mach-omap2/voltage.h  |    4 ++--
 arch/arm/mach-omap2/vp.c       |    4 ++--
 3 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index df4e7c3..5224fbd 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -149,8 +149,8 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
 	.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,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_MPU_SR_CONTROL_REG,
@@ -170,8 +170,8 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
 	.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,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_CORE_SR_CONTROL_REG,
@@ -191,8 +191,8 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_MPU_SR_VOLT_REG,
@@ -213,8 +213,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_IVA_SR_VOLT_REG,
@@ -235,8 +235,8 @@ static struct omap_voltdm_pmic omap4_core_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_CORE_SR_VOLT_REG,
@@ -271,13 +271,6 @@ int __init omap3_twl_init(void)
 	if (!cpu_is_omap34xx())
 		return -ENODEV;
 
-	if (cpu_is_omap3630()) {
-		omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
-		omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
-		omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
-		omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
-	}
-
 	/*
 	 * The smartreflex bit on twl4030 specifies if the setting of voltage
 	 * is done over the I2C_SR path. Since this setting is independent of
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index fa5b3dc..949938d 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -162,8 +162,8 @@ struct omap_voltdm_pmic {
 	u8 vp_erroroffset;
 	u8 vp_vstepmin;
 	u8 vp_vstepmax;
-	u32 vp_vddmin;
-	u32 vp_vddmax;
+	u32 vddmin;
+	u32 vddmax;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 6ee0b4a..d9e0650 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
-	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
+	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

These are now called vddmin and vddmax, as these fields will be used
globally for selecting voltage ranges for a pmic channel, and not
only for voltage processor.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |   27 ++++++++++-----------------
 arch/arm/mach-omap2/voltage.h  |    4 ++--
 arch/arm/mach-omap2/vp.c       |    4 ++--
 3 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index df4e7c3..5224fbd 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -149,8 +149,8 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
 	.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,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_MPU_SR_CONTROL_REG,
@@ -170,8 +170,8 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
 	.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,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_CORE_SR_CONTROL_REG,
@@ -191,8 +191,8 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_MPU_SR_VOLT_REG,
@@ -213,8 +213,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_IVA_SR_VOLT_REG,
@@ -235,8 +235,8 @@ static struct omap_voltdm_pmic omap4_core_pmic = {
 	.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,
+	.vddmin			= 0,
+	.vddmax			= 1500000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_CORE_SR_VOLT_REG,
@@ -271,13 +271,6 @@ int __init omap3_twl_init(void)
 	if (!cpu_is_omap34xx())
 		return -ENODEV;
 
-	if (cpu_is_omap3630()) {
-		omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
-		omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
-		omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
-		omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
-	}
-
 	/*
 	 * The smartreflex bit on twl4030 specifies if the setting of voltage
 	 * is done over the I2C_SR path. Since this setting is independent of
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index fa5b3dc..949938d 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -162,8 +162,8 @@ struct omap_voltdm_pmic {
 	u8 vp_erroroffset;
 	u8 vp_vstepmin;
 	u8 vp_vstepmax;
-	u32 vp_vddmin;
-	u32 vp_vddmax;
+	u32 vddmin;
+	u32 vddmax;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 6ee0b4a..d9e0650 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
-	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
+	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Introduced two new voltage domain specific parameter structures,
omap_vp_param and omap_vc_param. These are used to describe the minimum
and maximum voltages for the voltagedomains, and also the sleep voltage
levels. Existing voltage levels are also moved into these new structures,
and the voltage domain code is changed to use these.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c                |   25 ---
 arch/arm/mach-omap2/vc.c                      |  241 ++++++++++++++++++++++---
 arch/arm/mach-omap2/vc.h                      |    8 +-
 arch/arm/mach-omap2/vc3xxx_data.c             |   22 +++
 arch/arm/mach-omap2/vc44xx_data.c             |   28 +++
 arch/arm/mach-omap2/voltage.h                 |   18 ++-
 arch/arm/mach-omap2/voltagedomains3xxx_data.c |    5 +
 arch/arm/mach-omap2/voltagedomains44xx_data.c |    8 +
 arch/arm/mach-omap2/vp.h                      |    7 +
 arch/arm/mach-omap2/vp3xxx_data.c             |   10 +
 arch/arm/mach-omap2/vp44xx_data.c             |   15 ++
 11 files changed, 331 insertions(+), 56 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 5224fbd..2f20242 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -141,11 +141,6 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
 static struct omap_voltdm_pmic omap3_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1000000,
-	.ret_volt		= 975000,
-	.off_volt		= 600000,
-	.volt_setup_time	= 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
@@ -162,11 +157,6 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
 static struct omap_voltdm_pmic omap3_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt                = 1200000,
-	.onlp_volt              = 1000000,
-	.ret_volt               = 975000,
-	.off_volt               = 600000,
-	.volt_setup_time        = 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
@@ -183,11 +173,6 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
 static struct omap_voltdm_pmic omap4_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1375000,
-	.onlp_volt		= 1375000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -205,11 +190,6 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
 static struct omap_voltdm_pmic omap4_iva_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1188000,
-	.onlp_volt		= 1188000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -227,11 +207,6 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 static struct omap_voltdm_pmic omap4_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1200000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 031d116..af061c3 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -10,14 +10,18 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
 
 #include <plat/cpu.h>
+#include <plat/prcm.h>
 
 #include "voltage.h"
 #include "vc.h"
 #include "prm-regbits-34xx.h"
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
+#include "scrm44xx.h"
 
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
@@ -136,6 +140,8 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm,
 	vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
 	voltdm->write(vc_cmdval, vc->cmdval_reg);
 
+	voltdm->vc_param->on = target_volt;
+
 	omap_vp_update_errorgain(voltdm, target_volt);
 
 	return 0;
@@ -203,44 +209,208 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
 	return 0;
 }
 
-static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
+/**
+ * omap3_set_i2c_timings - sets i2c sleep timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: select whether retention or off mode values used
+ *
+ * Calculates and sets up voltage controller to use I2C based
+ * voltage scaling for sleep modes. This can be used for either off mode
+ * or retention. Off mode has additionally an option to use sys_off_mode
+ * pad, which uses a global signal to program the whole power IC to
+ * off-mode.
+ */
+static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 {
+	unsigned long voltsetup1;
+	u32 tgt_volt;
+
+	if (off_mode)
+		tgt_volt = voltdm->vc_param->off;
+	else
+		tgt_volt = voltdm->vc_param->ret;
+
+	voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
+			voltdm->pmic->slew_rate;
+
+	voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
+
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+		voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
+		voltdm->vfsm->voltsetup_reg);
+
 	/*
-	 * Voltage Manager FSM parameters init
-	 * XXX This data should be passed in from the board file
+	 * pmic is not controlling the voltage scaling during retention,
+	 * thus set voltsetup2 to 0
 	 */
-	voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
-	voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
-	voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
 }
 
-static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+/**
+ * omap3_set_off_timings - sets off-mode timings for a channel
+ * @voltdm: channel to configure
+ *
+ * Calculates and sets up off-mode timings for a channel. Off-mode
+ * can use either I2C based voltage scaling, or alternatively
+ * sys_off_mode pad can be used to send a global command to power IC.
+ * This function first checks which mode is being used, and calls
+ * omap3_set_i2c_timings() if the system is using I2C control mode.
+ * sys_off_mode has the additional benefit that voltages can be
+ * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
+ * scale to 600mV.
+ */
+static void omap3_set_off_timings(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
+	unsigned long clksetup;
+	unsigned long voltsetup2;
+	unsigned long voltsetup2_old;
+	u32 val;
 
-	if (is_initialized)
+	/* check if sys_off_mode is used to control off-mode voltages */
+	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
+	if (!(val & OMAP3430_SEL_OFF_MASK)) {
+		/* No, omap is controlling them over I2C */
+		omap3_set_i2c_timings(voltdm, true);
 		return;
+	}
+
+	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
+
+	/* voltsetup 2 in us */
+	voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;
+
+	/* convert to 32k clk cycles */
+	voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
 
-	omap3_vfsm_init(voltdm);
+	voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
 
-	is_initialized = true;
+	/*
+	 * Update voltsetup2 if higher than current value (needed because
+	 * we have multiple channels with different ramp times), also
+	 * update voltoffset always to value recommended by TRM
+	 */
+	if (voltsetup2 > voltsetup2_old) {
+		voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+		voltdm->write(clksetup - voltsetup2,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+	} else
+		voltdm->write(clksetup - voltsetup2_old,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+
+	/*
+	 * omap is not controlling voltage scaling during off-mode,
+	 * thus set voltsetup1 to 0
+	 */
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
+		voltdm->vfsm->voltsetup_reg);
+
+	/* voltoffset must be clksetup minus voltsetup2 according to TRM */
+	voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
 }
 
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+	omap3_set_off_timings(voltdm);
+}
+
+/**
+ * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
+ * @voltdm: channel to calculate values for
+ * @voltage_diff: voltage difference in microvolts
+ *
+ * Calculates voltage ramp prescaler + counter values for a voltage
+ * difference on omap4. Returns a field value suitable for writing to
+ * VOLTSETUP register for a channel in following format:
+ * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference.
+ */
+static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
+{
+	u32 prescaler;
+	u32 cycles;
+	u32 time;
+
+	time = voltage_diff / voltdm->pmic->slew_rate;
+
+	cycles = voltdm->sys_clk.rate / 1000 * time / 1000;
+
+	cycles /= 64;
+	prescaler = 0;
+
+	/* shift to next prescaler until no overflow */
+
+	/* scale for div 256 = 64 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* scale for div 512 = 256 * 2 */
+	if (cycles > 63) {
+		cycles /= 2;
+		prescaler++;
+	}
+
+	/* scale for div 2048 = 512 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* check for overflow => invalid ramp time */
+	if (cycles > 63) {
+		pr_warning("%s: invalid setuptime for vdd_%s\n", __func__,
+			voltdm->name);
+		return 0;
+	}
+
+	cycles++;
+
+	return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
+		(cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
+}
+
+/**
+ * omap4_set_timings - set voltage ramp timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: whether off-mode values are used
+ *
+ * Calculates and sets the voltage ramp up / down values for a channel.
+ */
+static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
+{
+	u32 val;
+	u32 ramp;
+
+	/* configure the setup times */
+	val = voltdm->read(voltdm->vfsm->voltsetup_reg);
+
+	if (off_mode)
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->off);
+	else
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->ret);
+
+	if (!ramp)
+		return;
+
+	val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
+
+	val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
+
+	voltdm->write(val, voltdm->vfsm->voltsetup_reg);
+}
 
 /* OMAP4 specific voltage init functions */
 static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
 	u32 vc_val;
 
-	if (is_initialized)
-		return;
+	omap4_set_timings(voltdm, true);
 
 	/* XXX These are magic numbers and do not belong! */
 	vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
 	voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
-
-	is_initialized = true;
 }
 
 /**
@@ -285,6 +455,30 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
 	initialized = true;
 }
 
+/**
+ * omap_vc_calc_vsel - calculate vsel value for a channel
+ * @voltdm: channel to calculate value for
+ * @uvolt: microvolt value to convert to vsel
+ *
+ * Converts a microvolt value to vsel value for the used PMIC.
+ * This checks whether the microvolt value is out of bounds, and
+ * adjusts the value accordingly. If unsupported value detected,
+ * warning is thrown.
+ */
+static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
+{
+	if (voltdm->pmic->vddmin > uvolt)
+		uvolt = voltdm->pmic->vddmin;
+	if (voltdm->pmic->vddmax < uvolt) {
+		WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n",
+			__func__, uvolt, voltdm->pmic->vddmax);
+		/* Lets try maximum value anyway */
+		uvolt = voltdm->pmic->vddmax;
+	}
+
+	return voltdm->pmic->uv_to_vsel(uvolt);
+}
+
 void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 {
 	struct omap_vc_channel *vc = voltdm->vc;
@@ -314,7 +508,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
 	vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
 	vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
-	vc->setup_time = voltdm->pmic->volt_setup_time;
 
 	/* Configure the i2c slave address for this VC */
 	voltdm->rmw(vc->smps_sa_mask,
@@ -338,10 +531,11 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	}
 
 	/* Set up the on, inactive, retention and off voltage */
-	on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
-	onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
-	ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
-	off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
+	on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
+	onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
+	ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret);
+	off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off);
+
 	val = ((on_vsel << vc->common->cmd_on_shift) |
 	       (onlp_vsel << vc->common->cmd_onlp_shift) |
 	       (ret_vsel << vc->common->cmd_ret_shift) |
@@ -352,11 +546,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	/* Channel configuration */
 	omap_vc_config_channel(voltdm);
 
-	/* Configure the setup times */
-	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
-		    vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
-		    voltdm->vfsm->voltsetup_reg);
-
 	omap_vc_i2c_init(voltdm);
 
 	if (cpu_is_omap34xx())
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 478bf6b..91c8d75 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -86,7 +86,6 @@ struct omap_vc_channel {
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
 	u16 cmd_reg_addr;
-	u16 setup_time;
 	u8 cfg_channel;
 	bool i2c_high_speed;
 
@@ -111,6 +110,13 @@ extern struct omap_vc_channel omap4_vc_mpu;
 extern struct omap_vc_channel omap4_vc_iva;
 extern struct omap_vc_channel omap4_vc_core;
 
+extern struct omap_vc_param omap3_mpu_vc_data;
+extern struct omap_vc_param omap3_core_vc_data;
+
+extern struct omap_vc_param omap4_mpu_vc_data;
+extern struct omap_vc_param omap4_iva_vc_data;
+extern struct omap_vc_param omap4_core_vc_data;
+
 void omap_vc_init_channel(struct voltagedomain *voltdm);
 int omap_vc_pre_scale(struct voltagedomain *voltdm,
 		      unsigned long target_volt,
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index a5ec7f8f..0535e8e 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -70,3 +70,25 @@ struct omap_vc_channel omap3_vc_core = {
 	.smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
 	.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
 };
+
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP3_ON_VOLTAGE_UV		1200000
+#define OMAP3_ONLP_VOLTAGE_UV		1000000
+#define OMAP3_RET_VOLTAGE_UV		975000
+#define OMAP3_OFF_VOLTAGE_UV		600000
+
+struct omap_vc_param omap3_mpu_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap3_core_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index d70b930..085e5d6 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -87,3 +87,31 @@ struct omap_vc_channel omap4_vc_core = {
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
 };
 
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP4_ON_VOLTAGE_UV			1375000
+#define OMAP4_ONLP_VOLTAGE_UV			1375000
+#define OMAP4_RET_VOLTAGE_UV			837500
+#define OMAP4_OFF_VOLTAGE_UV			0
+
+struct omap_vc_param omap4_mpu_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_iva_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_core_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 949938d..940a0d6 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -76,6 +76,8 @@ struct voltagedomain {
 	const struct omap_vfsm_instance *vfsm;
 	struct omap_vp_instance *vp;
 	struct omap_voltdm_pmic *pmic;
+	struct omap_vp_param *vp_param;
+	struct omap_vc_param *vc_param;
 
 	atomic_t usecount;
 	int target_state;
@@ -151,10 +153,6 @@ struct omap_volt_data {
 struct omap_voltdm_pmic {
 	int slew_rate;
 	int step_size;
-	u32 on_volt;
-	u32 onlp_volt;
-	u32 ret_volt;
-	u32 off_volt;
 	u16 volt_setup_time;
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
@@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
 	u8 (*uv_to_vsel) (unsigned long uV);
 };
 
+struct omap_vp_param {
+	u32 vddmax;
+	u32 vddmin;
+};
+
+struct omap_vc_param {
+	u32 on;
+	u32 onlp;
+	u32 ret;
+	u32 off;
+};
+
 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
 		struct omap_volt_data **volt_data);
 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index c005e2f..6bcb0f3 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -116,6 +116,11 @@ void __init omap3xxx_voltagedomains_init(void)
 		omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
 	}
 
+	omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data;
+	omap3_voltdm_core.vp_param = &omap3_core_vp_data;
+	omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data;
+	omap3_voltdm_core.vc_param = &omap3_core_vc_data;
+
 	if (cpu_is_omap3517() || cpu_is_omap3505())
 		voltdms = voltagedomains_am35xx;
 	else
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 4e11d02..11f43e4 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -104,6 +104,14 @@ void __init omap44xx_voltagedomains_init(void)
 	omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
 	omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
 
+	omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data;
+	omap4_voltdm_iva.vp_param = &omap4_iva_vp_data;
+	omap4_voltdm_core.vp_param = &omap4_core_vp_data;
+
+	omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data;
+	omap4_voltdm_iva.vc_param = &omap4_iva_vc_data;
+	omap4_voltdm_core.vc_param = &omap4_core_vc_data;
+
 	for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
 		voltdm->sys_clk.name = sys_clk_name;
 
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 7c155d2..0fdf708 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -117,6 +117,13 @@ extern struct omap_vp_instance omap4_vp_mpu;
 extern struct omap_vp_instance omap4_vp_iva;
 extern struct omap_vp_instance omap4_vp_core;
 
+extern struct omap_vp_param omap3_mpu_vp_data;
+extern struct omap_vp_param omap3_core_vp_data;
+
+extern struct omap_vp_param omap4_mpu_vp_data;
+extern struct omap_vp_param omap4_iva_vp_data;
+extern struct omap_vp_param omap4_core_vp_data;
+
 void omap_vp_init(struct voltagedomain *voltdm);
 void omap_vp_enable(struct voltagedomain *voltdm);
 void omap_vp_disable(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
index bd89f80..1914e02 100644
--- a/arch/arm/mach-omap2/vp3xxx_data.c
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -77,3 +77,13 @@ struct omap_vp_instance omap3_vp_core = {
 	.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
 	.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap3_mpu_vp_data = {
+	.vddmin			= OMAP3430_VP1_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP1_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap3_core_vp_data = {
+	.vddmin			= OMAP3430_VP2_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP2_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
index 8c031d1..e62f6b0 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -87,3 +87,18 @@ struct omap_vp_instance omap4_vp_core = {
 	.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
 	.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap4_mpu_vp_data = {
+	.vddmin			= OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_iva_vp_data = {
+	.vddmin			= OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_core_vp_data = {
+	.vddmin			= OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+};
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Introduced two new voltage domain specific parameter structures,
omap_vp_param and omap_vc_param. These are used to describe the minimum
and maximum voltages for the voltagedomains, and also the sleep voltage
levels. Existing voltage levels are also moved into these new structures,
and the voltage domain code is changed to use these.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c                |   25 ---
 arch/arm/mach-omap2/vc.c                      |  241 ++++++++++++++++++++++---
 arch/arm/mach-omap2/vc.h                      |    8 +-
 arch/arm/mach-omap2/vc3xxx_data.c             |   22 +++
 arch/arm/mach-omap2/vc44xx_data.c             |   28 +++
 arch/arm/mach-omap2/voltage.h                 |   18 ++-
 arch/arm/mach-omap2/voltagedomains3xxx_data.c |    5 +
 arch/arm/mach-omap2/voltagedomains44xx_data.c |    8 +
 arch/arm/mach-omap2/vp.h                      |    7 +
 arch/arm/mach-omap2/vp3xxx_data.c             |   10 +
 arch/arm/mach-omap2/vp44xx_data.c             |   15 ++
 11 files changed, 331 insertions(+), 56 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 5224fbd..2f20242 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -141,11 +141,6 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
 static struct omap_voltdm_pmic omap3_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1000000,
-	.ret_volt		= 975000,
-	.off_volt		= 600000,
-	.volt_setup_time	= 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
@@ -162,11 +157,6 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
 static struct omap_voltdm_pmic omap3_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt                = 1200000,
-	.onlp_volt              = 1000000,
-	.ret_volt               = 975000,
-	.off_volt               = 600000,
-	.volt_setup_time        = 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
@@ -183,11 +173,6 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
 static struct omap_voltdm_pmic omap4_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1375000,
-	.onlp_volt		= 1375000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -205,11 +190,6 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
 static struct omap_voltdm_pmic omap4_iva_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1188000,
-	.onlp_volt		= 1188000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
@@ -227,11 +207,6 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 static struct omap_voltdm_pmic omap4_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1200000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 031d116..af061c3 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -10,14 +10,18 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
 
 #include <plat/cpu.h>
+#include <plat/prcm.h>
 
 #include "voltage.h"
 #include "vc.h"
 #include "prm-regbits-34xx.h"
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
+#include "scrm44xx.h"
 
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
@@ -136,6 +140,8 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm,
 	vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
 	voltdm->write(vc_cmdval, vc->cmdval_reg);
 
+	voltdm->vc_param->on = target_volt;
+
 	omap_vp_update_errorgain(voltdm, target_volt);
 
 	return 0;
@@ -203,44 +209,208 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
 	return 0;
 }
 
-static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
+/**
+ * omap3_set_i2c_timings - sets i2c sleep timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: select whether retention or off mode values used
+ *
+ * Calculates and sets up voltage controller to use I2C based
+ * voltage scaling for sleep modes. This can be used for either off mode
+ * or retention. Off mode has additionally an option to use sys_off_mode
+ * pad, which uses a global signal to program the whole power IC to
+ * off-mode.
+ */
+static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 {
+	unsigned long voltsetup1;
+	u32 tgt_volt;
+
+	if (off_mode)
+		tgt_volt = voltdm->vc_param->off;
+	else
+		tgt_volt = voltdm->vc_param->ret;
+
+	voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
+			voltdm->pmic->slew_rate;
+
+	voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
+
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+		voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
+		voltdm->vfsm->voltsetup_reg);
+
 	/*
-	 * Voltage Manager FSM parameters init
-	 * XXX This data should be passed in from the board file
+	 * pmic is not controlling the voltage scaling during retention,
+	 * thus set voltsetup2 to 0
 	 */
-	voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
-	voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
-	voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
 }
 
-static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+/**
+ * omap3_set_off_timings - sets off-mode timings for a channel
+ * @voltdm: channel to configure
+ *
+ * Calculates and sets up off-mode timings for a channel. Off-mode
+ * can use either I2C based voltage scaling, or alternatively
+ * sys_off_mode pad can be used to send a global command to power IC.
+ * This function first checks which mode is being used, and calls
+ * omap3_set_i2c_timings() if the system is using I2C control mode.
+ * sys_off_mode has the additional benefit that voltages can be
+ * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
+ * scale to 600mV.
+ */
+static void omap3_set_off_timings(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
+	unsigned long clksetup;
+	unsigned long voltsetup2;
+	unsigned long voltsetup2_old;
+	u32 val;
 
-	if (is_initialized)
+	/* check if sys_off_mode is used to control off-mode voltages */
+	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
+	if (!(val & OMAP3430_SEL_OFF_MASK)) {
+		/* No, omap is controlling them over I2C */
+		omap3_set_i2c_timings(voltdm, true);
 		return;
+	}
+
+	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
+
+	/* voltsetup 2 in us */
+	voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;
+
+	/* convert to 32k clk cycles */
+	voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
 
-	omap3_vfsm_init(voltdm);
+	voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
 
-	is_initialized = true;
+	/*
+	 * Update voltsetup2 if higher than current value (needed because
+	 * we have multiple channels with different ramp times), also
+	 * update voltoffset always to value recommended by TRM
+	 */
+	if (voltsetup2 > voltsetup2_old) {
+		voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+		voltdm->write(clksetup - voltsetup2,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+	} else
+		voltdm->write(clksetup - voltsetup2_old,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+
+	/*
+	 * omap is not controlling voltage scaling during off-mode,
+	 * thus set voltsetup1 to 0
+	 */
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
+		voltdm->vfsm->voltsetup_reg);
+
+	/* voltoffset must be clksetup minus voltsetup2 according to TRM */
+	voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
 }
 
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+	omap3_set_off_timings(voltdm);
+}
+
+/**
+ * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
+ * @voltdm: channel to calculate values for
+ * @voltage_diff: voltage difference in microvolts
+ *
+ * Calculates voltage ramp prescaler + counter values for a voltage
+ * difference on omap4. Returns a field value suitable for writing to
+ * VOLTSETUP register for a channel in following format:
+ * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference.
+ */
+static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
+{
+	u32 prescaler;
+	u32 cycles;
+	u32 time;
+
+	time = voltage_diff / voltdm->pmic->slew_rate;
+
+	cycles = voltdm->sys_clk.rate / 1000 * time / 1000;
+
+	cycles /= 64;
+	prescaler = 0;
+
+	/* shift to next prescaler until no overflow */
+
+	/* scale for div 256 = 64 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* scale for div 512 = 256 * 2 */
+	if (cycles > 63) {
+		cycles /= 2;
+		prescaler++;
+	}
+
+	/* scale for div 2048 = 512 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* check for overflow => invalid ramp time */
+	if (cycles > 63) {
+		pr_warning("%s: invalid setuptime for vdd_%s\n", __func__,
+			voltdm->name);
+		return 0;
+	}
+
+	cycles++;
+
+	return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
+		(cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
+}
+
+/**
+ * omap4_set_timings - set voltage ramp timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: whether off-mode values are used
+ *
+ * Calculates and sets the voltage ramp up / down values for a channel.
+ */
+static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
+{
+	u32 val;
+	u32 ramp;
+
+	/* configure the setup times */
+	val = voltdm->read(voltdm->vfsm->voltsetup_reg);
+
+	if (off_mode)
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->off);
+	else
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->ret);
+
+	if (!ramp)
+		return;
+
+	val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
+
+	val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
+
+	voltdm->write(val, voltdm->vfsm->voltsetup_reg);
+}
 
 /* OMAP4 specific voltage init functions */
 static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
 	u32 vc_val;
 
-	if (is_initialized)
-		return;
+	omap4_set_timings(voltdm, true);
 
 	/* XXX These are magic numbers and do not belong! */
 	vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
 	voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
-
-	is_initialized = true;
 }
 
 /**
@@ -285,6 +455,30 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
 	initialized = true;
 }
 
+/**
+ * omap_vc_calc_vsel - calculate vsel value for a channel
+ * @voltdm: channel to calculate value for
+ * @uvolt: microvolt value to convert to vsel
+ *
+ * Converts a microvolt value to vsel value for the used PMIC.
+ * This checks whether the microvolt value is out of bounds, and
+ * adjusts the value accordingly. If unsupported value detected,
+ * warning is thrown.
+ */
+static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
+{
+	if (voltdm->pmic->vddmin > uvolt)
+		uvolt = voltdm->pmic->vddmin;
+	if (voltdm->pmic->vddmax < uvolt) {
+		WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n",
+			__func__, uvolt, voltdm->pmic->vddmax);
+		/* Lets try maximum value anyway */
+		uvolt = voltdm->pmic->vddmax;
+	}
+
+	return voltdm->pmic->uv_to_vsel(uvolt);
+}
+
 void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 {
 	struct omap_vc_channel *vc = voltdm->vc;
@@ -314,7 +508,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
 	vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
 	vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
-	vc->setup_time = voltdm->pmic->volt_setup_time;
 
 	/* Configure the i2c slave address for this VC */
 	voltdm->rmw(vc->smps_sa_mask,
@@ -338,10 +531,11 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	}
 
 	/* Set up the on, inactive, retention and off voltage */
-	on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
-	onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
-	ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
-	off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
+	on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
+	onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
+	ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret);
+	off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off);
+
 	val = ((on_vsel << vc->common->cmd_on_shift) |
 	       (onlp_vsel << vc->common->cmd_onlp_shift) |
 	       (ret_vsel << vc->common->cmd_ret_shift) |
@@ -352,11 +546,6 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 	/* Channel configuration */
 	omap_vc_config_channel(voltdm);
 
-	/* Configure the setup times */
-	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
-		    vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
-		    voltdm->vfsm->voltsetup_reg);
-
 	omap_vc_i2c_init(voltdm);
 
 	if (cpu_is_omap34xx())
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 478bf6b..91c8d75 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -86,7 +86,6 @@ struct omap_vc_channel {
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
 	u16 cmd_reg_addr;
-	u16 setup_time;
 	u8 cfg_channel;
 	bool i2c_high_speed;
 
@@ -111,6 +110,13 @@ extern struct omap_vc_channel omap4_vc_mpu;
 extern struct omap_vc_channel omap4_vc_iva;
 extern struct omap_vc_channel omap4_vc_core;
 
+extern struct omap_vc_param omap3_mpu_vc_data;
+extern struct omap_vc_param omap3_core_vc_data;
+
+extern struct omap_vc_param omap4_mpu_vc_data;
+extern struct omap_vc_param omap4_iva_vc_data;
+extern struct omap_vc_param omap4_core_vc_data;
+
 void omap_vc_init_channel(struct voltagedomain *voltdm);
 int omap_vc_pre_scale(struct voltagedomain *voltdm,
 		      unsigned long target_volt,
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index a5ec7f8f..0535e8e 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -70,3 +70,25 @@ struct omap_vc_channel omap3_vc_core = {
 	.smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
 	.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
 };
+
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP3_ON_VOLTAGE_UV		1200000
+#define OMAP3_ONLP_VOLTAGE_UV		1000000
+#define OMAP3_RET_VOLTAGE_UV		975000
+#define OMAP3_OFF_VOLTAGE_UV		600000
+
+struct omap_vc_param omap3_mpu_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap3_core_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index d70b930..085e5d6 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -87,3 +87,31 @@ struct omap_vc_channel omap4_vc_core = {
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
 };
 
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP4_ON_VOLTAGE_UV			1375000
+#define OMAP4_ONLP_VOLTAGE_UV			1375000
+#define OMAP4_RET_VOLTAGE_UV			837500
+#define OMAP4_OFF_VOLTAGE_UV			0
+
+struct omap_vc_param omap4_mpu_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_iva_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_core_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 949938d..940a0d6 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -76,6 +76,8 @@ struct voltagedomain {
 	const struct omap_vfsm_instance *vfsm;
 	struct omap_vp_instance *vp;
 	struct omap_voltdm_pmic *pmic;
+	struct omap_vp_param *vp_param;
+	struct omap_vc_param *vc_param;
 
 	atomic_t usecount;
 	int target_state;
@@ -151,10 +153,6 @@ struct omap_volt_data {
 struct omap_voltdm_pmic {
 	int slew_rate;
 	int step_size;
-	u32 on_volt;
-	u32 onlp_volt;
-	u32 ret_volt;
-	u32 off_volt;
 	u16 volt_setup_time;
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
@@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
 	u8 (*uv_to_vsel) (unsigned long uV);
 };
 
+struct omap_vp_param {
+	u32 vddmax;
+	u32 vddmin;
+};
+
+struct omap_vc_param {
+	u32 on;
+	u32 onlp;
+	u32 ret;
+	u32 off;
+};
+
 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
 		struct omap_volt_data **volt_data);
 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index c005e2f..6bcb0f3 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -116,6 +116,11 @@ void __init omap3xxx_voltagedomains_init(void)
 		omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
 	}
 
+	omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data;
+	omap3_voltdm_core.vp_param = &omap3_core_vp_data;
+	omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data;
+	omap3_voltdm_core.vc_param = &omap3_core_vc_data;
+
 	if (cpu_is_omap3517() || cpu_is_omap3505())
 		voltdms = voltagedomains_am35xx;
 	else
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 4e11d02..11f43e4 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -104,6 +104,14 @@ void __init omap44xx_voltagedomains_init(void)
 	omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
 	omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
 
+	omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data;
+	omap4_voltdm_iva.vp_param = &omap4_iva_vp_data;
+	omap4_voltdm_core.vp_param = &omap4_core_vp_data;
+
+	omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data;
+	omap4_voltdm_iva.vc_param = &omap4_iva_vc_data;
+	omap4_voltdm_core.vc_param = &omap4_core_vc_data;
+
 	for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
 		voltdm->sys_clk.name = sys_clk_name;
 
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 7c155d2..0fdf708 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -117,6 +117,13 @@ extern struct omap_vp_instance omap4_vp_mpu;
 extern struct omap_vp_instance omap4_vp_iva;
 extern struct omap_vp_instance omap4_vp_core;
 
+extern struct omap_vp_param omap3_mpu_vp_data;
+extern struct omap_vp_param omap3_core_vp_data;
+
+extern struct omap_vp_param omap4_mpu_vp_data;
+extern struct omap_vp_param omap4_iva_vp_data;
+extern struct omap_vp_param omap4_core_vp_data;
+
 void omap_vp_init(struct voltagedomain *voltdm);
 void omap_vp_enable(struct voltagedomain *voltdm);
 void omap_vp_disable(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
index bd89f80..1914e02 100644
--- a/arch/arm/mach-omap2/vp3xxx_data.c
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -77,3 +77,13 @@ struct omap_vp_instance omap3_vp_core = {
 	.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
 	.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap3_mpu_vp_data = {
+	.vddmin			= OMAP3430_VP1_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP1_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap3_core_vp_data = {
+	.vddmin			= OMAP3430_VP2_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP2_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
index 8c031d1..e62f6b0 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -87,3 +87,18 @@ struct omap_vp_instance omap4_vp_core = {
 	.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
 	.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap4_mpu_vp_data = {
+	.vddmin			= OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_iva_vp_data = {
+	.vddmin			= OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_core_vp_data = {
+	.vddmin			= OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+};
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 04/14] arm: omap: voltage: add definition for pmic startup / shutdown times
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

This is applied when PMIC is entering or leaving a sleep mode.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/voltage.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 940a0d6..54b959c 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -145,6 +145,8 @@ struct omap_volt_data {
  * @i2c_slave_addr: I2C slave address of PMIC
  * @volt_reg_addr: voltage configuration register address
  * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address
+ * @startup_time: PMIC startup time, only valid for core domain
+ * @shutdown_time: PMIC shutdown time, only valid for core domain
  * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
  * @i2c_mcode: master code value for I2C high-speed preamble transmission
  * @vsel_to_uv:	PMIC API to convert vsel value to actual voltage in uV.
@@ -162,6 +164,8 @@ struct omap_voltdm_pmic {
 	u8 vp_vstepmax;
 	u32 vddmin;
 	u32 vddmax;
+	u32 startup_time;
+	u32 shutdown_time;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 04/14] arm: omap: voltage: add definition for pmic startup / shutdown times
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

This is applied when PMIC is entering or leaving a sleep mode.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/voltage.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 940a0d6..54b959c 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -145,6 +145,8 @@ struct omap_volt_data {
  * @i2c_slave_addr: I2C slave address of PMIC
  * @volt_reg_addr: voltage configuration register address
  * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address
+ * @startup_time: PMIC startup time, only valid for core domain
+ * @shutdown_time: PMIC shutdown time, only valid for core domain
  * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
  * @i2c_mcode: master code value for I2C high-speed preamble transmission
  * @vsel_to_uv:	PMIC API to convert vsel value to actual voltage in uV.
@@ -162,6 +164,8 @@ struct omap_voltdm_pmic {
 	u8 vp_vstepmax;
 	u32 vddmin;
 	u32 vddmax;
+	u32 startup_time;
+	u32 shutdown_time;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
 	u8 i2c_mcode;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 05/14] arm: omap4: add pmic startup / shutdown times
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Both startup and shutdown take 500us at maximum, value taken from
TWL6030 data manual.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 2f20242..7830eae 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -207,6 +207,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 static struct omap_voltdm_pmic omap4_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
+	.startup_time		= 500,
+	.shutdown_time		= 500,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 05/14] arm: omap4: add pmic startup / shutdown times
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Both startup and shutdown take 500us at maximum, value taken from
TWL6030 data manual.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_twl.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 2f20242..7830eae 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -207,6 +207,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
 static struct omap_voltdm_pmic omap4_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
+	.startup_time		= 500,
+	.shutdown_time		= 500,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 06/14] arm: omap: add support for oscillator setup
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

This contains startup and shutdown times for the oscillator. By default
use ULONG_MAX. Oscillator setup is used for calculating and setting up
latencies for sleep modes that disable oscillator.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.c |   27 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h |    8 ++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 1881fe9..2402e8e 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -28,6 +28,33 @@
 
 static struct omap_device_pm_latency *pm_lats;
 
+/**
+ * struct omap2_oscillator - Describe the board main oscillator latencies
+ * @startup_time: oscillator startup latency
+ * @shutdown_time: oscillator shutdown latency
+ */
+struct omap2_oscillator {
+	u32 startup_time;
+	u32 shutdown_time;
+};
+
+static struct omap2_oscillator oscillator = {
+	.startup_time = ULONG_MAX,
+	.shutdown_time = ULONG_MAX,
+};
+
+void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
+{
+	oscillator.startup_time = tstart;
+	oscillator.shutdown_time = tshut;
+}
+
+void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
+{
+	*tstart = oscillator.startup_time;
+	*tshut = oscillator.shutdown_time;
+}
+
 static int _init_omap_device(char *name)
 {
 	struct omap_hwmod *oh;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index ec8f874..797d2da 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -141,4 +141,12 @@ static inline int omap4_twl_init(void)
 }
 #endif
 
+#ifdef CONFIG_PM
+extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
+extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
+#else
+static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
+static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
+#endif
+
 #endif
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 06/14] arm: omap: add support for oscillator setup
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

This contains startup and shutdown times for the oscillator. By default
use ULONG_MAX. Oscillator setup is used for calculating and setting up
latencies for sleep modes that disable oscillator.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.c |   27 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h |    8 ++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 1881fe9..2402e8e 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -28,6 +28,33 @@
 
 static struct omap_device_pm_latency *pm_lats;
 
+/**
+ * struct omap2_oscillator - Describe the board main oscillator latencies
+ * @startup_time: oscillator startup latency
+ * @shutdown_time: oscillator shutdown latency
+ */
+struct omap2_oscillator {
+	u32 startup_time;
+	u32 shutdown_time;
+};
+
+static struct omap2_oscillator oscillator = {
+	.startup_time = ULONG_MAX,
+	.shutdown_time = ULONG_MAX,
+};
+
+void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
+{
+	oscillator.startup_time = tstart;
+	oscillator.shutdown_time = tshut;
+}
+
+void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
+{
+	*tstart = oscillator.startup_time;
+	*tshut = oscillator.shutdown_time;
+}
+
 static int _init_omap_device(char *name)
 {
 	struct omap_hwmod *oh;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index ec8f874..797d2da 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -141,4 +141,12 @@ static inline int omap4_twl_init(void)
 }
 #endif
 
+#ifdef CONFIG_PM
+extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
+extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
+#else
+static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
+static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
+#endif
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 07/14] arm: omap3+: vp: use new vp_params for calculating vddmin and vddmax
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Now we select the vddmin and vddmax values based on both pmic and
voltage processor data, this allows usage of different power ICs.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vp.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index d9e0650..22df86d 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,10 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
-	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
+	vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin);
+	vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax);
+	vddmin = voltdm->pmic->uv_to_vsel(vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 07/14] arm: omap3+: vp: use new vp_params for calculating vddmin and vddmax
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Now we select the vddmin and vddmax values based on both pmic and
voltage processor data, this allows usage of different power ICs.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vp.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index d9e0650..22df86d 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -53,8 +53,10 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
-	vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
+	vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin);
+	vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax);
+	vddmin = voltdm->pmic->uv_to_vsel(vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(vddmax);
 
 	waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
 		    sys_clk_rate) / 1000;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 08/14] arm: omap3+: voltage: use oscillator data to calculate setup times
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

We now use the previously defined oscillator setup / shutdown times
to calculate the register values for CLKSETUP.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index af061c3..2fe4ce2 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -13,6 +13,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <asm/div64.h>
+
 #include <plat/cpu.h>
 #include <plat/prcm.h>
 
@@ -22,6 +24,7 @@
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
 #include "scrm44xx.h"
+#include "pm.h"
 
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
@@ -209,6 +212,21 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
 	return 0;
 }
 
+/* Convert microsecond value to number of 32kHz clock cycles */
+static u32 omap_usec_to_32k(u32 usec)
+{
+	/* DIV_ROUND_UP expanded to 64bit to avoid overflow */
+	u64 val = 32768ULL * (u64)usec + 1000000ULL - 1;
+	do_div(val, 1000000ULL);
+	return val;
+}
+
+/* Set oscillator setup time for omap3 */
+static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
+{
+	voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET);
+}
+
 /**
  * omap3_set_i2c_timings - sets i2c sleep timings for a channel
  * @voltdm: channel to configure
@@ -225,6 +243,12 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	unsigned long voltsetup1;
 	u32 tgt_volt;
 
+	/*
+	 * Oscillator is shut down only if we are using sys_off_mode pad,
+	 * thus we set a minimal setup time here
+	 */
+	omap3_set_clksetup(1, voltdm);
+
 	if (off_mode)
 		tgt_volt = voltdm->vc_param->off;
 	else
@@ -265,6 +289,7 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	unsigned long voltsetup2;
 	unsigned long voltsetup2_old;
 	u32 val;
+	u32 tstart, tshut;
 
 	/* check if sys_off_mode is used to control off-mode voltages */
 	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -274,6 +299,9 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 		return;
 	}
 
+	omap_pm_get_oscillator(&tstart, &tshut);
+	omap3_set_clksetup(tstart, voltdm);
+
 	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
 
 	/* voltsetup 2 in us */
@@ -370,6 +398,30 @@ static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
 }
 
 /**
+ * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield
+ * @usec: microseconds
+ * @shift: number of bits to shift left
+ * @mask: bitfield mask
+ *
+ * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is
+ * shifted to requested position, and checked agains the mask value.
+ * If larger, forced to the max value of the field (i.e. the mask itself.)
+ * Returns the SCRM bitfield value.
+ */
+static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask)
+{
+	u32 val;
+
+	val = omap_usec_to_32k(usec) << shift;
+
+	/* Check for overflow, if yes, force to max value */
+	if (val > mask)
+		val = mask;
+
+	return val;
+}
+
+/**
  * omap4_set_timings - set voltage ramp timings for a channel
  * @voltdm: channel to configure
  * @off_mode: whether off-mode values are used
@@ -380,6 +432,7 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 {
 	u32 val;
 	u32 ramp;
+	u32 tstart, tshut;
 
 	/* configure the setup times */
 	val = voltdm->read(voltdm->vfsm->voltsetup_reg);
@@ -399,6 +452,15 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 	val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
 
 	voltdm->write(val, voltdm->vfsm->voltsetup_reg);
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+
+	val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT,
+		OMAP4_SETUPTIME_MASK);
+	val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT,
+		OMAP4_DOWNTIME_MASK);
+
+	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
 }
 
 /* OMAP4 specific voltage init functions */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 08/14] arm: omap3+: voltage: use oscillator data to calculate setup times
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

We now use the previously defined oscillator setup / shutdown times
to calculate the register values for CLKSETUP.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index af061c3..2fe4ce2 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -13,6 +13,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <asm/div64.h>
+
 #include <plat/cpu.h>
 #include <plat/prcm.h>
 
@@ -22,6 +24,7 @@
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
 #include "scrm44xx.h"
+#include "pm.h"
 
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
@@ -209,6 +212,21 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm,
 	return 0;
 }
 
+/* Convert microsecond value to number of 32kHz clock cycles */
+static u32 omap_usec_to_32k(u32 usec)
+{
+	/* DIV_ROUND_UP expanded to 64bit to avoid overflow */
+	u64 val = 32768ULL * (u64)usec + 1000000ULL - 1;
+	do_div(val, 1000000ULL);
+	return val;
+}
+
+/* Set oscillator setup time for omap3 */
+static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
+{
+	voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET);
+}
+
 /**
  * omap3_set_i2c_timings - sets i2c sleep timings for a channel
  * @voltdm: channel to configure
@@ -225,6 +243,12 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	unsigned long voltsetup1;
 	u32 tgt_volt;
 
+	/*
+	 * Oscillator is shut down only if we are using sys_off_mode pad,
+	 * thus we set a minimal setup time here
+	 */
+	omap3_set_clksetup(1, voltdm);
+
 	if (off_mode)
 		tgt_volt = voltdm->vc_param->off;
 	else
@@ -265,6 +289,7 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	unsigned long voltsetup2;
 	unsigned long voltsetup2_old;
 	u32 val;
+	u32 tstart, tshut;
 
 	/* check if sys_off_mode is used to control off-mode voltages */
 	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -274,6 +299,9 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 		return;
 	}
 
+	omap_pm_get_oscillator(&tstart, &tshut);
+	omap3_set_clksetup(tstart, voltdm);
+
 	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
 
 	/* voltsetup 2 in us */
@@ -370,6 +398,30 @@ static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
 }
 
 /**
+ * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield
+ * @usec: microseconds
+ * @shift: number of bits to shift left
+ * @mask: bitfield mask
+ *
+ * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is
+ * shifted to requested position, and checked agains the mask value.
+ * If larger, forced to the max value of the field (i.e. the mask itself.)
+ * Returns the SCRM bitfield value.
+ */
+static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask)
+{
+	u32 val;
+
+	val = omap_usec_to_32k(usec) << shift;
+
+	/* Check for overflow, if yes, force to max value */
+	if (val > mask)
+		val = mask;
+
+	return val;
+}
+
+/**
  * omap4_set_timings - set voltage ramp timings for a channel
  * @voltdm: channel to configure
  * @off_mode: whether off-mode values are used
@@ -380,6 +432,7 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 {
 	u32 val;
 	u32 ramp;
+	u32 tstart, tshut;
 
 	/* configure the setup times */
 	val = voltdm->read(voltdm->vfsm->voltsetup_reg);
@@ -399,6 +452,15 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 	val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
 
 	voltdm->write(val, voltdm->vfsm->voltsetup_reg);
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+
+	val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT,
+		OMAP4_SETUPTIME_MASK);
+	val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT,
+		OMAP4_DOWNTIME_MASK);
+
+	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
 }
 
 /* OMAP4 specific voltage init functions */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 09/14] arm: omap4: use pmic params for calculating pmic setup times
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

As voltdm->pmic now contains startup and shutdown times for PMIC, use
these for calculating the fields in the PMICSETUPTIME register.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 2fe4ce2..0971221 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -461,6 +461,17 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 		OMAP4_DOWNTIME_MASK);
 
 	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
+
+	tstart = voltdm->pmic->startup_time;
+	tshut = voltdm->pmic->shutdown_time;
+
+	if (tstart && tshut) {
+		val = omap4_usec_to_val_scrm(tstart, OMAP4_WAKEUPTIME_SHIFT,
+			OMAP4_WAKEUPTIME_MASK);
+		val |= omap4_usec_to_val_scrm(tshut, OMAP4_SLEEPTIME_SHIFT,
+			OMAP4_SLEEPTIME_MASK);
+		__raw_writel(val, OMAP4_SCRM_PMICSETUPTIME);
+	}
 }
 
 /* OMAP4 specific voltage init functions */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 09/14] arm: omap4: use pmic params for calculating pmic setup times
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

As voltdm->pmic now contains startup and shutdown times for PMIC, use
these for calculating the fields in the PMICSETUPTIME register.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 2fe4ce2..0971221 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -461,6 +461,17 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 		OMAP4_DOWNTIME_MASK);
 
 	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
+
+	tstart = voltdm->pmic->startup_time;
+	tshut = voltdm->pmic->shutdown_time;
+
+	if (tstart && tshut) {
+		val = omap4_usec_to_val_scrm(tstart, OMAP4_WAKEUPTIME_SHIFT,
+			OMAP4_WAKEUPTIME_MASK);
+		val |= omap4_usec_to_val_scrm(tshut, OMAP4_SLEEPTIME_SHIFT,
+			OMAP4_SLEEPTIME_MASK);
+		__raw_writel(val, OMAP4_SCRM_PMICSETUPTIME);
+	}
 }
 
 /* OMAP4 specific voltage init functions */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 10/14] TEMP: arm: OMAP3: beagle rev-c4: enable OPP6
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Beagleboard rev-c4 has a speed sorted OMAP3530 chip which can run at 720MHz.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |   29 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/opp3xxx_data.c      |    4 ++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 7ffcd28..97678e5 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -484,6 +484,35 @@ static void __init beagle_opp_init(void)
 		return;
 	}
 
+	if (omap3_beagle_version == OMAP3BEAGLE_BOARD_C4) {
+		struct device *mpu_dev, *iva_dev;
+
+		mpu_dev = omap_device_get_by_hwmod_name("mpu");
+		iva_dev = omap_device_get_by_hwmod_name("iva");
+
+		if (!mpu_dev || !iva_dev) {
+			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+				__func__, mpu_dev, iva_dev);
+			return;
+		}
+		/* Enable MPU 720MHz opp */
+		r = opp_enable(mpu_dev, 720000000);
+
+		/* Enable IVA 520MHz opp */
+		r |= opp_enable(iva_dev, 520000000);
+
+		if (r) {
+			pr_err("%s: failed to enable higher opp %d\n",
+				__func__, r);
+			/*
+			 * Cleanup - disable the higher freqs - we dont care
+			 * about the results
+			 */
+			opp_disable(mpu_dev, 720000000);
+			opp_disable(iva_dev, 520000000);
+		}
+	}
+
 	/* Custom OPP enabled for all xM versions */
 	if (cpu_is_omap3630()) {
 		struct device *mpu_dev, *iva_dev;
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index d95f3f9..a0f5fe1 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -98,6 +98,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
 	/* MPU OPP5 */
 	OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
+	/* MPU OPP6 : omap3530 high speed grade only */
+	OPP_INITIALIZER("mpu", false, 720000000, OMAP3430_VDD_MPU_OPP5_UV),
 
 	/*
 	 * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -123,6 +125,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
 	/* DSP OPP5 */
 	OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
+	/* DSP OPP6 : omap3530 high speed grade only */
+	OPP_INITIALIZER("iva", false, 520000000, OMAP3430_VDD_MPU_OPP5_UV),
 };
 
 static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 10/14] TEMP: arm: OMAP3: beagle rev-c4: enable OPP6
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Beagleboard rev-c4 has a speed sorted OMAP3530 chip which can run at 720MHz.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |   29 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/opp3xxx_data.c      |    4 ++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 7ffcd28..97678e5 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -484,6 +484,35 @@ static void __init beagle_opp_init(void)
 		return;
 	}
 
+	if (omap3_beagle_version == OMAP3BEAGLE_BOARD_C4) {
+		struct device *mpu_dev, *iva_dev;
+
+		mpu_dev = omap_device_get_by_hwmod_name("mpu");
+		iva_dev = omap_device_get_by_hwmod_name("iva");
+
+		if (!mpu_dev || !iva_dev) {
+			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+				__func__, mpu_dev, iva_dev);
+			return;
+		}
+		/* Enable MPU 720MHz opp */
+		r = opp_enable(mpu_dev, 720000000);
+
+		/* Enable IVA 520MHz opp */
+		r |= opp_enable(iva_dev, 520000000);
+
+		if (r) {
+			pr_err("%s: failed to enable higher opp %d\n",
+				__func__, r);
+			/*
+			 * Cleanup - disable the higher freqs - we dont care
+			 * about the results
+			 */
+			opp_disable(mpu_dev, 720000000);
+			opp_disable(iva_dev, 520000000);
+		}
+	}
+
 	/* Custom OPP enabled for all xM versions */
 	if (cpu_is_omap3630()) {
 		struct device *mpu_dev, *iva_dev;
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index d95f3f9..a0f5fe1 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -98,6 +98,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
 	/* MPU OPP5 */
 	OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
+	/* MPU OPP6 : omap3530 high speed grade only */
+	OPP_INITIALIZER("mpu", false, 720000000, OMAP3430_VDD_MPU_OPP5_UV),
 
 	/*
 	 * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -123,6 +125,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
 	/* DSP OPP5 */
 	OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
+	/* DSP OPP6 : omap3530 high speed grade only */
+	OPP_INITIALIZER("iva", false, 520000000, OMAP3430_VDD_MPU_OPP5_UV),
 };
 
 static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 11/14] arm: omap: beagle: set oscillator startup time to 10ms for rev c4
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Based on the oscillator datasheet for this device.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 97678e5..5489dbe 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -511,6 +511,9 @@ static void __init beagle_opp_init(void)
 			opp_disable(mpu_dev, 720000000);
 			opp_disable(iva_dev, 520000000);
 		}
+
+		/* Set oscillator startup time to 10ms, shutdown not used */
+		omap_pm_setup_oscillator(10000, ULONG_MAX);
 	}
 
 	/* Custom OPP enabled for all xM versions */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 11/14] arm: omap: beagle: set oscillator startup time to 10ms for rev c4
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Based on the oscillator datasheet for this device.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 97678e5..5489dbe 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -511,6 +511,9 @@ static void __init beagle_opp_init(void)
 			opp_disable(mpu_dev, 720000000);
 			opp_disable(iva_dev, 520000000);
 		}
+
+		/* Set oscillator startup time to 10ms, shutdown not used */
+		omap_pm_setup_oscillator(10000, ULONG_MAX);
 	}
 
 	/* Custom OPP enabled for all xM versions */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 12/14] arm: omap3: vc: auto_ret / auto_off support
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

Voltage code will now enable / disable auto_ret / auto_off dynamically
according to the voltagedomain usecounts. This is accomplished via
the usage of the voltdm callback functions for sleep / wakeup.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |  139 +++++++++++++++++++++++++++++++++++++++------
 1 files changed, 120 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 0971221..49df835 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/string.h>
 
 #include <asm/div64.h>
 
@@ -243,12 +244,6 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	unsigned long voltsetup1;
 	u32 tgt_volt;
 
-	/*
-	 * Oscillator is shut down only if we are using sys_off_mode pad,
-	 * thus we set a minimal setup time here
-	 */
-	omap3_set_clksetup(1, voltdm);
-
 	if (off_mode)
 		tgt_volt = voltdm->vc_param->off;
 	else
@@ -262,12 +257,6 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
 		voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
 		voltdm->vfsm->voltsetup_reg);
-
-	/*
-	 * pmic is not controlling the voltage scaling during retention,
-	 * thus set voltsetup2 to 0
-	 */
-	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
 }
 
 /**
@@ -289,7 +278,6 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	unsigned long voltsetup2;
 	unsigned long voltsetup2_old;
 	u32 val;
-	u32 tstart, tshut;
 
 	/* check if sys_off_mode is used to control off-mode voltages */
 	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -299,9 +287,6 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 		return;
 	}
 
-	omap_pm_get_oscillator(&tstart, &tshut);
-	omap3_set_clksetup(tstart, voltdm);
-
 	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
 
 	/* voltsetup 2 in us */
@@ -331,17 +316,133 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	 */
 	voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
 		voltdm->vfsm->voltsetup_reg);
+}
 
-	/* voltoffset must be clksetup minus voltsetup2 according to TRM */
-	voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
+/**
+ * omap3_set_core_ret_timings - set retention timings for core domain
+ * @voltdm: pointer for core voltagedomain struct
+ *
+ * This function is called once core domain is ready to enter
+ * retention. This sets the values for the global setup variables like
+ * oscillator setup time, and the ramp times for voltages.
+ */
+static void omap3_set_core_ret_timings(struct voltagedomain *voltdm)
+{
+	/*
+	 * Oscillator is not shut down in retention, thus set minimal
+	 * clock setup time
+	 */
+	omap3_set_clksetup(1, voltdm);
+
+	/*
+	 * Reset voltsetup 2 and voltoffset when entering retention
+	 * as they are only used when pmic is controlling voltages
+	 */
+	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
+	voltdm->write(0, OMAP3_PRM_VOLTOFFSET_OFFSET);
+	omap3_set_i2c_timings(voltdm, false);
 }
 
-static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+/**
+ * omap3_set_core_off_timings - set off timings for core domain
+ * @voltdm: pointer for core voltagedomain struct
+ *
+ * This function is called once core domain is ready to enter off-mode.
+ * This sets the values for the global setup variables like oscillator
+ * setup time, and the ramp times for voltages.
+ */
+static void omap3_set_core_off_timings(struct voltagedomain *voltdm)
 {
+	u32 tstart, tshut;
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+	omap3_set_clksetup(tstart, voltdm);
 	omap3_set_off_timings(voltdm);
 }
 
 /**
+ * omap3_vc_channel_sleep - idle callback for a voltagedomain
+ * @voltdm: voltage channel that is entering idle
+ *
+ * Prepares voltage channel for entering idle. This gets called from
+ * the voltagedomain code once the usecount for the domain reaches zero.
+ * Function checks the target sleep mode and configures the channel
+ * accordingly.
+ */
+static void omap3_vc_channel_sleep(struct voltagedomain *voltdm)
+{
+	/* Set off timings if entering off */
+	if (voltdm->target_state == PWRDM_POWER_OFF)
+		omap3_set_off_timings(voltdm);
+	else
+		omap3_set_i2c_timings(voltdm, false);
+}
+
+/**
+ * omap3_vc_core_sleep - idle callback for core voltagedomain
+ * @voltdm: pointer to core voltagedomain struct
+ *
+ * Prepares core voltagedomain for idle. This checks the target sleep
+ * mode of the device (highest sleep mode of all powerdomains), and
+ * sets up the device according to this either for retention, sleep
+ * or off-mode.
+ */
+static void omap3_vc_core_sleep(struct voltagedomain *voltdm)
+{
+	u8 mode;
+
+	switch (voltdm->target_state) {
+	case PWRDM_POWER_OFF:
+		mode = OMAP3430_AUTO_OFF_MASK;
+		break;
+	case PWRDM_POWER_RET:
+		mode = OMAP3430_AUTO_RET_MASK;
+		break;
+	default:
+		mode = OMAP3430_AUTO_SLEEP_MASK;
+		break;
+	}
+
+	if (mode == OMAP3430_AUTO_OFF_MASK)
+		omap3_set_core_off_timings(voltdm);
+	else
+		omap3_set_core_ret_timings(voltdm);
+
+	voltdm->rmw(OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK |
+		    OMAP3430_AUTO_SLEEP_MASK, mode,
+		    OMAP3_PRM_VOLTCTRL_OFFSET);
+}
+
+/**
+ * omap3_vc_core_wakeup - wakeup callback for core domain
+ * @voltdm: pointer to core voltagedomain struct
+ *
+ * Resumes core voltagedomain from idle. Callback from voltagedomain
+ * code once usecount reaches non-zero value.
+ */
+static void omap3_vc_core_wakeup(struct voltagedomain *voltdm)
+{
+	voltdm->rmw(OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK |
+		    OMAP3430_AUTO_SLEEP_MASK, 0, OMAP3_PRM_VOLTCTRL_OFFSET);
+}
+
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+	/*
+	 * Set up voltagedomain callbacks for idle / resume and init
+	 * channel for retention voltage levels.
+	 */
+	if (!strcmp(voltdm->name, "core")) {
+		voltdm->sleep = omap3_vc_core_sleep;
+		voltdm->wakeup = omap3_vc_core_wakeup;
+		omap3_set_core_ret_timings(voltdm);
+	} else {
+		voltdm->sleep = omap3_vc_channel_sleep;
+		omap3_set_i2c_timings(voltdm, false);
+	}
+}
+
+/**
  * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
  * @voltdm: channel to calculate values for
  * @voltage_diff: voltage difference in microvolts
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 12/14] arm: omap3: vc: auto_ret / auto_off support
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Voltage code will now enable / disable auto_ret / auto_off dynamically
according to the voltagedomain usecounts. This is accomplished via
the usage of the voltdm callback functions for sleep / wakeup.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c |  139 +++++++++++++++++++++++++++++++++++++++------
 1 files changed, 120 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 0971221..49df835 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/string.h>
 
 #include <asm/div64.h>
 
@@ -243,12 +244,6 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	unsigned long voltsetup1;
 	u32 tgt_volt;
 
-	/*
-	 * Oscillator is shut down only if we are using sys_off_mode pad,
-	 * thus we set a minimal setup time here
-	 */
-	omap3_set_clksetup(1, voltdm);
-
 	if (off_mode)
 		tgt_volt = voltdm->vc_param->off;
 	else
@@ -262,12 +257,6 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
 	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
 		voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
 		voltdm->vfsm->voltsetup_reg);
-
-	/*
-	 * pmic is not controlling the voltage scaling during retention,
-	 * thus set voltsetup2 to 0
-	 */
-	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
 }
 
 /**
@@ -289,7 +278,6 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	unsigned long voltsetup2;
 	unsigned long voltsetup2_old;
 	u32 val;
-	u32 tstart, tshut;
 
 	/* check if sys_off_mode is used to control off-mode voltages */
 	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
@@ -299,9 +287,6 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 		return;
 	}
 
-	omap_pm_get_oscillator(&tstart, &tshut);
-	omap3_set_clksetup(tstart, voltdm);
-
 	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
 
 	/* voltsetup 2 in us */
@@ -331,17 +316,133 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)
 	 */
 	voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
 		voltdm->vfsm->voltsetup_reg);
+}
 
-	/* voltoffset must be clksetup minus voltsetup2 according to TRM */
-	voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
+/**
+ * omap3_set_core_ret_timings - set retention timings for core domain
+ * @voltdm: pointer for core voltagedomain struct
+ *
+ * This function is called once core domain is ready to enter
+ * retention. This sets the values for the global setup variables like
+ * oscillator setup time, and the ramp times for voltages.
+ */
+static void omap3_set_core_ret_timings(struct voltagedomain *voltdm)
+{
+	/*
+	 * Oscillator is not shut down in retention, thus set minimal
+	 * clock setup time
+	 */
+	omap3_set_clksetup(1, voltdm);
+
+	/*
+	 * Reset voltsetup 2 and voltoffset when entering retention
+	 * as they are only used when pmic is controlling voltages
+	 */
+	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
+	voltdm->write(0, OMAP3_PRM_VOLTOFFSET_OFFSET);
+	omap3_set_i2c_timings(voltdm, false);
 }
 
-static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+/**
+ * omap3_set_core_off_timings - set off timings for core domain
+ * @voltdm: pointer for core voltagedomain struct
+ *
+ * This function is called once core domain is ready to enter off-mode.
+ * This sets the values for the global setup variables like oscillator
+ * setup time, and the ramp times for voltages.
+ */
+static void omap3_set_core_off_timings(struct voltagedomain *voltdm)
 {
+	u32 tstart, tshut;
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+	omap3_set_clksetup(tstart, voltdm);
 	omap3_set_off_timings(voltdm);
 }
 
 /**
+ * omap3_vc_channel_sleep - idle callback for a voltagedomain
+ * @voltdm: voltage channel that is entering idle
+ *
+ * Prepares voltage channel for entering idle. This gets called from
+ * the voltagedomain code once the usecount for the domain reaches zero.
+ * Function checks the target sleep mode and configures the channel
+ * accordingly.
+ */
+static void omap3_vc_channel_sleep(struct voltagedomain *voltdm)
+{
+	/* Set off timings if entering off */
+	if (voltdm->target_state == PWRDM_POWER_OFF)
+		omap3_set_off_timings(voltdm);
+	else
+		omap3_set_i2c_timings(voltdm, false);
+}
+
+/**
+ * omap3_vc_core_sleep - idle callback for core voltagedomain
+ * @voltdm: pointer to core voltagedomain struct
+ *
+ * Prepares core voltagedomain for idle. This checks the target sleep
+ * mode of the device (highest sleep mode of all powerdomains), and
+ * sets up the device according to this either for retention, sleep
+ * or off-mode.
+ */
+static void omap3_vc_core_sleep(struct voltagedomain *voltdm)
+{
+	u8 mode;
+
+	switch (voltdm->target_state) {
+	case PWRDM_POWER_OFF:
+		mode = OMAP3430_AUTO_OFF_MASK;
+		break;
+	case PWRDM_POWER_RET:
+		mode = OMAP3430_AUTO_RET_MASK;
+		break;
+	default:
+		mode = OMAP3430_AUTO_SLEEP_MASK;
+		break;
+	}
+
+	if (mode == OMAP3430_AUTO_OFF_MASK)
+		omap3_set_core_off_timings(voltdm);
+	else
+		omap3_set_core_ret_timings(voltdm);
+
+	voltdm->rmw(OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK |
+		    OMAP3430_AUTO_SLEEP_MASK, mode,
+		    OMAP3_PRM_VOLTCTRL_OFFSET);
+}
+
+/**
+ * omap3_vc_core_wakeup - wakeup callback for core domain
+ * @voltdm: pointer to core voltagedomain struct
+ *
+ * Resumes core voltagedomain from idle. Callback from voltagedomain
+ * code once usecount reaches non-zero value.
+ */
+static void omap3_vc_core_wakeup(struct voltagedomain *voltdm)
+{
+	voltdm->rmw(OMAP3430_AUTO_OFF_MASK | OMAP3430_AUTO_RET_MASK |
+		    OMAP3430_AUTO_SLEEP_MASK, 0, OMAP3_PRM_VOLTCTRL_OFFSET);
+}
+
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+	/*
+	 * Set up voltagedomain callbacks for idle / resume and init
+	 * channel for retention voltage levels.
+	 */
+	if (!strcmp(voltdm->name, "core")) {
+		voltdm->sleep = omap3_vc_core_sleep;
+		voltdm->wakeup = omap3_vc_core_wakeup;
+		omap3_set_core_ret_timings(voltdm);
+	} else {
+		voltdm->sleep = omap3_vc_channel_sleep;
+		omap3_set_i2c_timings(voltdm, false);
+	}
+}
+
+/**
  * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
  * @voltdm: channel to calculate values for
  * @voltage_diff: voltage difference in microvolts
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 13/14] arm: omap3: voltage: fix channel configuration
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

OMAP3 uses the default settings for VDD1 channel, otherwise the settings will
overlap with VDD2 and attempting to modify VDD1 voltage will actually change
VDD2 voltage.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c          |    5 ++++-
 arch/arm/mach-omap2/vc3xxx_data.c |    1 +
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 49df835..a0023de 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -701,9 +701,12 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 		voltdm->rmw(vc->smps_cmdra_mask,
 			    vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
 			    vc->smps_cmdra_reg);
-		vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen;
+		vc->cfg_channel |= vc_cfg_bits->rac;
 	}
 
+	if (vc->cmd_reg_addr == vc->volt_reg_addr)
+		vc->cfg_channel |= vc_cfg_bits->racen;
+
 	/* Set up the on, inactive, retention and off voltage */
 	on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
 	onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index 0535e8e..75bc4aa 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = {
 };
 
 struct omap_vc_channel omap3_vc_mpu = {
+	.flags = OMAP_VC_CHANNEL_DEFAULT,
 	.common = &omap3_vc_common,
 	.smps_sa_reg	 = OMAP3_PRM_VC_SMPS_SA_OFFSET,
 	.smps_volra_reg	 = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 13/14] arm: omap3: voltage: fix channel configuration
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP3 uses the default settings for VDD1 channel, otherwise the settings will
overlap with VDD2 and attempting to modify VDD1 voltage will actually change
VDD2 voltage.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/vc.c          |    5 ++++-
 arch/arm/mach-omap2/vc3xxx_data.c |    1 +
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 49df835..a0023de 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -701,9 +701,12 @@ void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 		voltdm->rmw(vc->smps_cmdra_mask,
 			    vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
 			    vc->smps_cmdra_reg);
-		vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen;
+		vc->cfg_channel |= vc_cfg_bits->rac;
 	}
 
+	if (vc->cmd_reg_addr == vc->volt_reg_addr)
+		vc->cfg_channel |= vc_cfg_bits->racen;
+
 	/* Set up the on, inactive, retention and off voltage */
 	on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
 	onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index 0535e8e..75bc4aa 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = {
 };
 
 struct omap_vc_channel omap3_vc_mpu = {
+	.flags = OMAP_VC_CHANNEL_DEFAULT,
 	.common = &omap3_vc_common,
 	.smps_sa_reg	 = OMAP3_PRM_VC_SMPS_SA_OFFSET,
 	.smps_volra_reg	 = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 14/14] arm: omap: pm: wait for domain wakeup if changing state of idle domain
  2012-02-21 14:04 ` Tero Kristo
@ 2012-02-21 14:04   ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-omap, khilman; +Cc: linux-arm-kernel

If we are switching the state of an idle powerdomain, we must wait for
the wakeup to complete before attempting to switch to the new state,
otherwise the powerdomain may not be ready for the switch and will fail.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 2402e8e..7a669f3 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -126,6 +126,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 		} else {
 			hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
 			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+			pwrdm_wait_transition(pwrdm);
 			sleep_switch = FORCEWAKEUP_SWITCH;
 		}
 	}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCHv5 14/14] arm: omap: pm: wait for domain wakeup if changing state of idle domain
@ 2012-02-21 14:04   ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

If we are switching the state of an idle powerdomain, we must wait for
the wakeup to complete before attempting to switch to the new state,
otherwise the powerdomain may not be ready for the switch and will fail.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 2402e8e..7a669f3 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -126,6 +126,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 		} else {
 			hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
 			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+			pwrdm_wait_transition(pwrdm);
 			sleep_switch = FORCEWAKEUP_SWITCH;
 		}
 	}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
  2012-02-21 14:04   ` Tero Kristo
@ 2012-02-21 14:40     ` Menon, Nishanth
  -1 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-21 14:40 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, khilman, linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> These are now called vddmin and vddmax, as these fields will be used
> globally for selecting voltage ranges for a pmic channel, and not
> only for voltage processor.

NAK. I think we need to setup voltage for SoC limits as well. the
programmed voltage to the VP register should be:
VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)

else you could be running the SoC beyond design voltage potentially
damaging the device.

Regards,
Nishanth Menon


>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/omap_twl.c |   27 ++++++++++-----------------
>  arch/arm/mach-omap2/voltage.h  |    4 ++--
>  arch/arm/mach-omap2/vp.c       |    4 ++--
>  3 files changed, 14 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
> index df4e7c3..5224fbd 100644
> --- a/arch/arm/mach-omap2/omap_twl.c
> +++ b/arch/arm/mach-omap2/omap_twl.c
> @@ -149,8 +149,8 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
>        .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,
> +       .vddmin                 = 600000,
> +       .vddmax                 = 1450000,
>        .vp_timeout_us          = OMAP3_VP_VLIMITTO_TIMEOUT_US,
>        .i2c_slave_addr         = OMAP3_SRI2C_SLAVE_ADDR,
>        .volt_reg_addr          = OMAP3_VDD_MPU_SR_CONTROL_REG,
> @@ -170,8 +170,8 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
>        .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,
> +       .vddmin                 = 600000,
> +       .vddmax                 = 1450000,
>        .vp_timeout_us          = OMAP3_VP_VLIMITTO_TIMEOUT_US,
>        .i2c_slave_addr         = OMAP3_SRI2C_SLAVE_ADDR,
>        .volt_reg_addr          = OMAP3_VDD_CORE_SR_CONTROL_REG,
> @@ -191,8 +191,8 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
>        .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,
> +       .vddmin                 = 0,
> +       .vddmax                 = 1500000,
>        .vp_timeout_us          = OMAP4_VP_VLIMITTO_TIMEOUT_US,
>        .i2c_slave_addr         = OMAP4_SRI2C_SLAVE_ADDR,
>        .volt_reg_addr          = OMAP4_VDD_MPU_SR_VOLT_REG,
> @@ -213,8 +213,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
>        .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,
> +       .vddmin                 = 0,
> +       .vddmax                 = 1500000,
>        .vp_timeout_us          = OMAP4_VP_VLIMITTO_TIMEOUT_US,
>        .i2c_slave_addr         = OMAP4_SRI2C_SLAVE_ADDR,
>        .volt_reg_addr          = OMAP4_VDD_IVA_SR_VOLT_REG,
> @@ -235,8 +235,8 @@ static struct omap_voltdm_pmic omap4_core_pmic = {
>        .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,
> +       .vddmin                 = 0,
> +       .vddmax                 = 1500000,
>        .vp_timeout_us          = OMAP4_VP_VLIMITTO_TIMEOUT_US,
>        .i2c_slave_addr         = OMAP4_SRI2C_SLAVE_ADDR,
>        .volt_reg_addr          = OMAP4_VDD_CORE_SR_VOLT_REG,
> @@ -271,13 +271,6 @@ int __init omap3_twl_init(void)
>        if (!cpu_is_omap34xx())
>                return -ENODEV;
>
> -       if (cpu_is_omap3630()) {
> -               omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
> -               omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
> -               omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
> -               omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
> -       }
> -
>        /*
>         * The smartreflex bit on twl4030 specifies if the setting of voltage
>         * is done over the I2C_SR path. Since this setting is independent of
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index fa5b3dc..949938d 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h
> @@ -162,8 +162,8 @@ struct omap_voltdm_pmic {
>        u8 vp_erroroffset;
>        u8 vp_vstepmin;
>        u8 vp_vstepmax;
> -       u32 vp_vddmin;
> -       u32 vp_vddmax;
> +       u32 vddmin;
> +       u32 vddmax;
>        u8 vp_timeout_us;
>        bool i2c_high_speed;
>        u8 i2c_mcode;
> diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
> index 6ee0b4a..d9e0650 100644
> --- a/arch/arm/mach-omap2/vp.c
> +++ b/arch/arm/mach-omap2/vp.c
> @@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
>        sys_clk_rate = voltdm->sys_clk.rate / 1000;
>
>        timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
> -       vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
> -       vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
> +       vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
> +       vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
>
>        waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
>                    sys_clk_rate) / 1000;
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
@ 2012-02-21 14:40     ` Menon, Nishanth
  0 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-21 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> These are now called vddmin and vddmax, as these fields will be used
> globally for selecting voltage ranges for a pmic channel, and not
> only for voltage processor.

NAK. I think we need to setup voltage for SoC limits as well. the
programmed voltage to the VP register should be:
VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)

else you could be running the SoC beyond design voltage potentially
damaging the device.

Regards,
Nishanth Menon


>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
> ?arch/arm/mach-omap2/omap_twl.c | ? 27 ++++++++++-----------------
> ?arch/arm/mach-omap2/voltage.h ?| ? ?4 ++--
> ?arch/arm/mach-omap2/vp.c ? ? ? | ? ?4 ++--
> ?3 files changed, 14 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
> index df4e7c3..5224fbd 100644
> --- a/arch/arm/mach-omap2/omap_twl.c
> +++ b/arch/arm/mach-omap2/omap_twl.c
> @@ -149,8 +149,8 @@ static struct omap_voltdm_pmic omap3_mpu_pmic = {
> ? ? ? ?.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,
> + ? ? ? .vddmin ? ? ? ? ? ? ? ? = 600000,
> + ? ? ? .vddmax ? ? ? ? ? ? ? ? = 1450000,
> ? ? ? ?.vp_timeout_us ? ? ? ? ?= OMAP3_VP_VLIMITTO_TIMEOUT_US,
> ? ? ? ?.i2c_slave_addr ? ? ? ? = OMAP3_SRI2C_SLAVE_ADDR,
> ? ? ? ?.volt_reg_addr ? ? ? ? ?= OMAP3_VDD_MPU_SR_CONTROL_REG,
> @@ -170,8 +170,8 @@ static struct omap_voltdm_pmic omap3_core_pmic = {
> ? ? ? ?.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,
> + ? ? ? .vddmin ? ? ? ? ? ? ? ? = 600000,
> + ? ? ? .vddmax ? ? ? ? ? ? ? ? = 1450000,
> ? ? ? ?.vp_timeout_us ? ? ? ? ?= OMAP3_VP_VLIMITTO_TIMEOUT_US,
> ? ? ? ?.i2c_slave_addr ? ? ? ? = OMAP3_SRI2C_SLAVE_ADDR,
> ? ? ? ?.volt_reg_addr ? ? ? ? ?= OMAP3_VDD_CORE_SR_CONTROL_REG,
> @@ -191,8 +191,8 @@ static struct omap_voltdm_pmic omap4_mpu_pmic = {
> ? ? ? ?.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,
> + ? ? ? .vddmin ? ? ? ? ? ? ? ? = 0,
> + ? ? ? .vddmax ? ? ? ? ? ? ? ? = 1500000,
> ? ? ? ?.vp_timeout_us ? ? ? ? ?= OMAP4_VP_VLIMITTO_TIMEOUT_US,
> ? ? ? ?.i2c_slave_addr ? ? ? ? = OMAP4_SRI2C_SLAVE_ADDR,
> ? ? ? ?.volt_reg_addr ? ? ? ? ?= OMAP4_VDD_MPU_SR_VOLT_REG,
> @@ -213,8 +213,8 @@ static struct omap_voltdm_pmic omap4_iva_pmic = {
> ? ? ? ?.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,
> + ? ? ? .vddmin ? ? ? ? ? ? ? ? = 0,
> + ? ? ? .vddmax ? ? ? ? ? ? ? ? = 1500000,
> ? ? ? ?.vp_timeout_us ? ? ? ? ?= OMAP4_VP_VLIMITTO_TIMEOUT_US,
> ? ? ? ?.i2c_slave_addr ? ? ? ? = OMAP4_SRI2C_SLAVE_ADDR,
> ? ? ? ?.volt_reg_addr ? ? ? ? ?= OMAP4_VDD_IVA_SR_VOLT_REG,
> @@ -235,8 +235,8 @@ static struct omap_voltdm_pmic omap4_core_pmic = {
> ? ? ? ?.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,
> + ? ? ? .vddmin ? ? ? ? ? ? ? ? = 0,
> + ? ? ? .vddmax ? ? ? ? ? ? ? ? = 1500000,
> ? ? ? ?.vp_timeout_us ? ? ? ? ?= OMAP4_VP_VLIMITTO_TIMEOUT_US,
> ? ? ? ?.i2c_slave_addr ? ? ? ? = OMAP4_SRI2C_SLAVE_ADDR,
> ? ? ? ?.volt_reg_addr ? ? ? ? ?= OMAP4_VDD_CORE_SR_VOLT_REG,
> @@ -271,13 +271,6 @@ int __init omap3_twl_init(void)
> ? ? ? ?if (!cpu_is_omap34xx())
> ? ? ? ? ? ? ? ?return -ENODEV;
>
> - ? ? ? if (cpu_is_omap3630()) {
> - ? ? ? ? ? ? ? omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
> - ? ? ? ? ? ? ? omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
> - ? ? ? ? ? ? ? omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
> - ? ? ? ? ? ? ? omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
> - ? ? ? }
> -
> ? ? ? ?/*
> ? ? ? ? * The smartreflex bit on twl4030 specifies if the setting of voltage
> ? ? ? ? * is done over the I2C_SR path. Since this setting is independent of
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index fa5b3dc..949938d 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h
> @@ -162,8 +162,8 @@ struct omap_voltdm_pmic {
> ? ? ? ?u8 vp_erroroffset;
> ? ? ? ?u8 vp_vstepmin;
> ? ? ? ?u8 vp_vstepmax;
> - ? ? ? u32 vp_vddmin;
> - ? ? ? u32 vp_vddmax;
> + ? ? ? u32 vddmin;
> + ? ? ? u32 vddmax;
> ? ? ? ?u8 vp_timeout_us;
> ? ? ? ?bool i2c_high_speed;
> ? ? ? ?u8 i2c_mcode;
> diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
> index 6ee0b4a..d9e0650 100644
> --- a/arch/arm/mach-omap2/vp.c
> +++ b/arch/arm/mach-omap2/vp.c
> @@ -53,8 +53,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
> ? ? ? ?sys_clk_rate = voltdm->sys_clk.rate / 1000;
>
> ? ? ? ?timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
> - ? ? ? vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmin);
> - ? ? ? vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vp_vddmax);
> + ? ? ? vddmin = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmin);
> + ? ? ? vddmax = voltdm->pmic->uv_to_vsel(voltdm->pmic->vddmax);
>
> ? ? ? ?waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
> ? ? ? ? ? ? ? ? ? ?sys_clk_rate) / 1000;
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 06/14] arm: omap: add support for oscillator setup
  2012-02-21 14:04   ` Tero Kristo
@ 2012-02-21 14:44     ` Menon, Nishanth
  -1 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-21 14:44 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, khilman, linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> This contains startup and shutdown times for the oscillator. By default
> use ULONG_MAX. Oscillator setup is used for calculating and setting up
> latencies for sleep modes that disable oscillator.
>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  arch/arm/mach-omap2/pm.c |   27 +++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm.h |    8 ++++++++
>  2 files changed, 35 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
> index 1881fe9..2402e8e 100644
> --- a/arch/arm/mach-omap2/pm.c
> +++ b/arch/arm/mach-omap2/pm.c
> @@ -28,6 +28,33 @@
>
>  static struct omap_device_pm_latency *pm_lats;
>
> +/**
> + * struct omap2_oscillator - Describe the board main oscillator latencies
> + * @startup_time: oscillator startup latency
> + * @shutdown_time: oscillator shutdown latency
> + */
> +struct omap2_oscillator {
> +       u32 startup_time;
> +       u32 shutdown_time;
> +};
> +
> +static struct omap2_oscillator oscillator = {
> +       .startup_time = ULONG_MAX,
> +       .shutdown_time = ULONG_MAX,
> +};
> +
> +void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
> +{
> +       oscillator.startup_time = tstart;
> +       oscillator.shutdown_time = tshut;
> +}
> +
> +void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
> +{

Maybe a nitpick - variable check needed?

Regards,
Nishanth Menon


> +       *tstart = oscillator.startup_time;
> +       *tshut = oscillator.shutdown_time;
> +}
> +
>  static int _init_omap_device(char *name)
>  {
>        struct omap_hwmod *oh;
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index ec8f874..797d2da 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -141,4 +141,12 @@ static inline int omap4_twl_init(void)
>  }
>  #endif
>
> +#ifdef CONFIG_PM
> +extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
> +extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
> +#else
> +static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
> +static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
> +#endif
> +
>  #endif
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] 46+ messages in thread

* [PATCHv5 06/14] arm: omap: add support for oscillator setup
@ 2012-02-21 14:44     ` Menon, Nishanth
  0 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-21 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> This contains startup and shutdown times for the oscillator. By default
> use ULONG_MAX. Oscillator setup is used for calculating and setting up
> latencies for sleep modes that disable oscillator.
>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
> ?arch/arm/mach-omap2/pm.c | ? 27 +++++++++++++++++++++++++++
> ?arch/arm/mach-omap2/pm.h | ? ?8 ++++++++
> ?2 files changed, 35 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
> index 1881fe9..2402e8e 100644
> --- a/arch/arm/mach-omap2/pm.c
> +++ b/arch/arm/mach-omap2/pm.c
> @@ -28,6 +28,33 @@
>
> ?static struct omap_device_pm_latency *pm_lats;
>
> +/**
> + * struct omap2_oscillator - Describe the board main oscillator latencies
> + * @startup_time: oscillator startup latency
> + * @shutdown_time: oscillator shutdown latency
> + */
> +struct omap2_oscillator {
> + ? ? ? u32 startup_time;
> + ? ? ? u32 shutdown_time;
> +};
> +
> +static struct omap2_oscillator oscillator = {
> + ? ? ? .startup_time = ULONG_MAX,
> + ? ? ? .shutdown_time = ULONG_MAX,
> +};
> +
> +void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
> +{
> + ? ? ? oscillator.startup_time = tstart;
> + ? ? ? oscillator.shutdown_time = tshut;
> +}
> +
> +void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
> +{

Maybe a nitpick - variable check needed?

Regards,
Nishanth Menon


> + ? ? ? *tstart = oscillator.startup_time;
> + ? ? ? *tshut = oscillator.shutdown_time;
> +}
> +
> ?static int _init_omap_device(char *name)
> ?{
> ? ? ? ?struct omap_hwmod *oh;
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index ec8f874..797d2da 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -141,4 +141,12 @@ static inline int omap4_twl_init(void)
> ?}
> ?#endif
>
> +#ifdef CONFIG_PM
> +extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
> +extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
> +#else
> +static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
> +static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
> +#endif
> +
> ?#endif
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
  2012-02-21 14:40     ` Menon, Nishanth
@ 2012-02-21 14:53       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 46+ messages in thread
From: Russell King - ARM Linux @ 2012-02-21 14:53 UTC (permalink / raw)
  To: Menon, Nishanth; +Cc: Tero Kristo, khilman, linux-omap, linux-arm-kernel

On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > These are now called vddmin and vddmax, as these fields will be used
> > globally for selecting voltage ranges for a pmic channel, and not
> > only for voltage processor.
> 
> NAK. I think we need to setup voltage for SoC limits as well. the
> programmed voltage to the VP register should be:
> VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> 
> else you could be running the SoC beyond design voltage potentially
> damaging the device.

And if you're doing that kind of thing, you must also check that
the resulting min and max are sane.  In other words, the minimum is
less than the maximum.

Sure, it's something that should never happen (because it would be a
design error) but if it did happen...

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
@ 2012-02-21 14:53       ` Russell King - ARM Linux
  0 siblings, 0 replies; 46+ messages in thread
From: Russell King - ARM Linux @ 2012-02-21 14:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > These are now called vddmin and vddmax, as these fields will be used
> > globally for selecting voltage ranges for a pmic channel, and not
> > only for voltage processor.
> 
> NAK. I think we need to setup voltage for SoC limits as well. the
> programmed voltage to the VP register should be:
> VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> 
> else you could be running the SoC beyond design voltage potentially
> damaging the device.

And if you're doing that kind of thing, you must also check that
the resulting min and max are sane.  In other words, the minimum is
less than the maximum.

Sure, it's something that should never happen (because it would be a
design error) but if it did happen...

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
  2012-02-21 14:53       ` Russell King - ARM Linux
@ 2012-02-21 15:32         ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 15:32 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Menon, Nishanth, khilman, linux-omap, linux-arm-kernel

On Tue, 2012-02-21 at 14:53 +0000, Russell King - ARM Linux wrote:
> On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> > On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > > These are now called vddmin and vddmax, as these fields will be used
> > > globally for selecting voltage ranges for a pmic channel, and not
> > > only for voltage processor.
> > 
> > NAK. I think we need to setup voltage for SoC limits as well. the
> > programmed voltage to the VP register should be:
> > VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> > VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> > 

This kind of code is actually introduced in patch #7 of this set. VP
part of the code calculates the voltage processor vlimitto values in
omap_vp_init. VC limits are handled in omap_vc_init_channel /
omap_vc_calc_vsel.

> > else you could be running the SoC beyond design voltage potentially
> > damaging the device.
> 
> And if you're doing that kind of thing, you must also check that
> the resulting min and max are sane.  In other words, the minimum is
> less than the maximum.
> 
> Sure, it's something that should never happen (because it would be a
> design error) but if it did happen...

This could be added yes, current code assumes the limits themselves are
at least somewhat sane, doesn't hurt to add a kern dump for this case I
think as it sounds rather fatal.

-Tero



^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
@ 2012-02-21 15:32         ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-21 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-02-21 at 14:53 +0000, Russell King - ARM Linux wrote:
> On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> > On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > > These are now called vddmin and vddmax, as these fields will be used
> > > globally for selecting voltage ranges for a pmic channel, and not
> > > only for voltage processor.
> > 
> > NAK. I think we need to setup voltage for SoC limits as well. the
> > programmed voltage to the VP register should be:
> > VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> > VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> > 

This kind of code is actually introduced in patch #7 of this set. VP
part of the code calculates the voltage processor vlimitto values in
omap_vp_init. VC limits are handled in omap_vc_init_channel /
omap_vc_calc_vsel.

> > else you could be running the SoC beyond design voltage potentially
> > damaging the device.
> 
> And if you're doing that kind of thing, you must also check that
> the resulting min and max are sane.  In other words, the minimum is
> less than the maximum.
> 
> Sure, it's something that should never happen (because it would be a
> design error) but if it did happen...

This could be added yes, current code assumes the limits themselves are
at least somewhat sane, doesn't hurt to add a kern dump for this case I
think as it sounds rather fatal.

-Tero

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
  2012-02-21 15:32         ` Tero Kristo
@ 2012-02-21 15:38           ` Nishanth Menon
  -1 siblings, 0 replies; 46+ messages in thread
From: Nishanth Menon @ 2012-02-21 15:38 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Russell King - ARM Linux, khilman, linux-omap, linux-arm-kernel

On 17:32-20120221, Tero Kristo wrote:
> On Tue, 2012-02-21 at 14:53 +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> > > On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > > > These are now called vddmin and vddmax, as these fields will be used
> > > > globally for selecting voltage ranges for a pmic channel, and not
> > > > only for voltage processor.
> > > 
> > > NAK. I think we need to setup voltage for SoC limits as well. the
> > > programmed voltage to the VP register should be:
> > > VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> > > VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> > > 
> 
> This kind of code is actually introduced in patch #7 of this set. VP
> part of the code calculates the voltage processor vlimitto values in
> omap_vp_init. VC limits are handled in omap_vc_init_channel /
> omap_vc_calc_vsel.

Apologies , you are right #7 does indeed take this into consideration
probably belongs to #7, but, we also need to ensure that vp forceupdate
and vc_bypass actually keep to the requirement as well.

> 
> > > else you could be running the SoC beyond design voltage potentially
> > > damaging the device.
> > 
> > And if you're doing that kind of thing, you must also check that
> > the resulting min and max are sane.  In other words, the minimum is
> > less than the maximum.
> > 
> > Sure, it's something that should never happen (because it would be a
> > design error) but if it did happen...
> 
> This could be added yes, current code assumes the limits themselves are
> at least somewhat sane, doesn't hurt to add a kern dump for this case I
> think as it sounds rather fatal.
I agree - it is indeed the case.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields
@ 2012-02-21 15:38           ` Nishanth Menon
  0 siblings, 0 replies; 46+ messages in thread
From: Nishanth Menon @ 2012-02-21 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:32-20120221, Tero Kristo wrote:
> On Tue, 2012-02-21 at 14:53 +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 21, 2012 at 08:40:22AM -0600, Menon, Nishanth wrote:
> > > On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> > > > These are now called vddmin and vddmax, as these fields will be used
> > > > globally for selecting voltage ranges for a pmic channel, and not
> > > > only for voltage processor.
> > > 
> > > NAK. I think we need to setup voltage for SoC limits as well. the
> > > programmed voltage to the VP register should be:
> > > VP->vlimito->min = MAX(soc->vdd_min, pmic->vdd_min)
> > > VP->vlimito->max = MIN(soc->vdd_max, pmic->vdd_max)
> > > 
> 
> This kind of code is actually introduced in patch #7 of this set. VP
> part of the code calculates the voltage processor vlimitto values in
> omap_vp_init. VC limits are handled in omap_vc_init_channel /
> omap_vc_calc_vsel.

Apologies , you are right #7 does indeed take this into consideration
probably belongs to #7, but, we also need to ensure that vp forceupdate
and vc_bypass actually keep to the requirement as well.

> 
> > > else you could be running the SoC beyond design voltage potentially
> > > damaging the device.
> > 
> > And if you're doing that kind of thing, you must also check that
> > the resulting min and max are sane.  In other words, the minimum is
> > less than the maximum.
> > 
> > Sure, it's something that should never happen (because it would be a
> > design error) but if it did happen...
> 
> This could be added yes, current code assumes the limits themselves are
> at least somewhat sane, doesn't hurt to add a kern dump for this case I
> think as it sounds rather fatal.
I agree - it is indeed the case.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
  2012-02-21 14:04   ` Tero Kristo
@ 2012-02-23  1:37     ` Menon, Nishanth
  -1 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-23  1:37 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, khilman, linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
[...]
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index 949938d..940a0d6 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h

[...]
> @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
>        u8 (*uv_to_vsel) (unsigned long uV);
>  };
>
> +struct omap_vp_param {
> +       u32 vddmax;
> +       u32 vddmin;
> +};
> +

Thinking a little deeper about this(SoC level vdd min and max) on a
slightly different angle- core of the question that intend to answer
are:
 - what is the least voltage we want to allow in active transtion? it
should not be lower than retention voltage.
- what is the max voltage we want to allow in active transition? it
should be the max Nom voltage of all the OPPs for that domain.

In effect, why do we even need to register
"voltdm->vp_param->vdd[min|max]"? We already have that info - right?
On the other hand it might be safer to do this way to handle quirks in
future SoCs.. but thought I'd spit it out anyways..

> +struct omap_vc_param {
and elsewhere - please add kernel-doc struct documentation as well
when new structs are introduced?
> +       u32 on;
> +       u32 onlp;
> +       u32 ret;
> +       u32 off;
> +};
> +
[...]

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] 46+ messages in thread

* [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
@ 2012-02-23  1:37     ` Menon, Nishanth
  0 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-23  1:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
[...]
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index 949938d..940a0d6 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h

[...]
> @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
> ? ? ? ?u8 (*uv_to_vsel) (unsigned long uV);
> ?};
>
> +struct omap_vp_param {
> + ? ? ? u32 vddmax;
> + ? ? ? u32 vddmin;
> +};
> +

Thinking a little deeper about this(SoC level vdd min and max) on a
slightly different angle- core of the question that intend to answer
are:
 - what is the least voltage we want to allow in active transtion? it
should not be lower than retention voltage.
- what is the max voltage we want to allow in active transition? it
should be the max Nom voltage of all the OPPs for that domain.

In effect, why do we even need to register
"voltdm->vp_param->vdd[min|max]"? We already have that info - right?
On the other hand it might be safer to do this way to handle quirks in
future SoCs.. but thought I'd spit it out anyways..

> +struct omap_vc_param {
and elsewhere - please add kernel-doc struct documentation as well
when new structs are introduced?
> + ? ? ? u32 on;
> + ? ? ? u32 onlp;
> + ? ? ? u32 ret;
> + ? ? ? u32 off;
> +};
> +
[...]

Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
  2012-02-23  1:37     ` Menon, Nishanth
@ 2012-02-23  9:08       ` Tero Kristo
  -1 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-23  9:08 UTC (permalink / raw)
  To: Menon, Nishanth; +Cc: linux-omap, khilman, linux-arm-kernel

On Wed, 2012-02-22 at 19:37 -0600, Menon, Nishanth wrote:
> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> [...]
> > diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> > index 949938d..940a0d6 100644
> > --- a/arch/arm/mach-omap2/voltage.h
> > +++ b/arch/arm/mach-omap2/voltage.h
> 
> [...]
> > @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
> >        u8 (*uv_to_vsel) (unsigned long uV);
> >  };
> >
> > +struct omap_vp_param {
> > +       u32 vddmax;
> > +       u32 vddmin;
> > +};
> > +
> 
> Thinking a little deeper about this(SoC level vdd min and max) on a
> slightly different angle- core of the question that intend to answer
> are:
>  - what is the least voltage we want to allow in active transtion? it
> should not be lower than retention voltage.

I think this is a fair assumption, so we could init the vddmin to be the
same as the retention voltage for the domain (or even drop the
parameter.)

> - what is the max voltage we want to allow in active transition? it
> should be the max Nom voltage of all the OPPs for that domain.

Isn't it higher? I guess smartreflex can scale voltages even up from the
nominal level if we have a really old and/or bad silicon. Limiting this
to max opp would be bad, no? Maybe we could use max opp voltage + some
margin though... but what would be a safe margin here?

> 
> In effect, why do we even need to register
> "voltdm->vp_param->vdd[min|max]"? We already have that info - right?
> On the other hand it might be safer to do this way to handle quirks in
> future SoCs.. but thought I'd spit it out anyways..
> 
> > +struct omap_vc_param {
> and elsewhere - please add kernel-doc struct documentation as well
> when new structs are introduced?

Yea, I can add those for next version.

> > +       u32 on;
> > +       u32 onlp;
> > +       u32 ret;
> > +       u32 off;
> > +};
> > +
> [...]
> 
> Regards,
> Nishanth Menon



^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
@ 2012-02-23  9:08       ` Tero Kristo
  0 siblings, 0 replies; 46+ messages in thread
From: Tero Kristo @ 2012-02-23  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2012-02-22 at 19:37 -0600, Menon, Nishanth wrote:
> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
> [...]
> > diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> > index 949938d..940a0d6 100644
> > --- a/arch/arm/mach-omap2/voltage.h
> > +++ b/arch/arm/mach-omap2/voltage.h
> 
> [...]
> > @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
> >        u8 (*uv_to_vsel) (unsigned long uV);
> >  };
> >
> > +struct omap_vp_param {
> > +       u32 vddmax;
> > +       u32 vddmin;
> > +};
> > +
> 
> Thinking a little deeper about this(SoC level vdd min and max) on a
> slightly different angle- core of the question that intend to answer
> are:
>  - what is the least voltage we want to allow in active transtion? it
> should not be lower than retention voltage.

I think this is a fair assumption, so we could init the vddmin to be the
same as the retention voltage for the domain (or even drop the
parameter.)

> - what is the max voltage we want to allow in active transition? it
> should be the max Nom voltage of all the OPPs for that domain.

Isn't it higher? I guess smartreflex can scale voltages even up from the
nominal level if we have a really old and/or bad silicon. Limiting this
to max opp would be bad, no? Maybe we could use max opp voltage + some
margin though... but what would be a safe margin here?

> 
> In effect, why do we even need to register
> "voltdm->vp_param->vdd[min|max]"? We already have that info - right?
> On the other hand it might be safer to do this way to handle quirks in
> future SoCs.. but thought I'd spit it out anyways..
> 
> > +struct omap_vc_param {
> and elsewhere - please add kernel-doc struct documentation as well
> when new structs are introduced?

Yea, I can add those for next version.

> > +       u32 on;
> > +       u32 onlp;
> > +       u32 ret;
> > +       u32 off;
> > +};
> > +
> [...]
> 
> Regards,
> Nishanth Menon

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
  2012-02-23  9:08       ` Tero Kristo
@ 2012-02-23 15:05         ` Menon, Nishanth
  -1 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-23 15:05 UTC (permalink / raw)
  To: t-kristo; +Cc: linux-omap, khilman, linux-arm-kernel

On Thu, Feb 23, 2012 at 03:08, Tero Kristo <t-kristo@ti.com> wrote:
> On Wed, 2012-02-22 at 19:37 -0600, Menon, Nishanth wrote:
>> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
>> [...]
>> > diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
>> > index 949938d..940a0d6 100644
>> > --- a/arch/arm/mach-omap2/voltage.h
>> > +++ b/arch/arm/mach-omap2/voltage.h
>>
>> [...]
>> > @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
>> >        u8 (*uv_to_vsel) (unsigned long uV);
>> >  };
>> >
>> > +struct omap_vp_param {
>> > +       u32 vddmax;
>> > +       u32 vddmin;
>> > +};
>> > +
>>
>> Thinking a little deeper about this(SoC level vdd min and max) on a
>> slightly different angle- core of the question that intend to answer
>> are:
>>  - what is the least voltage we want to allow in active transtion? it
>> should not be lower than retention voltage.
>
> I think this is a fair assumption, so we could init the vddmin to be the
> same as the retention voltage for the domain (or even drop the
> parameter.)
>
>> - what is the max voltage we want to allow in active transition? it
>> should be the max Nom voltage of all the OPPs for that domain.
>
> Isn't it higher? I guess smartreflex can scale voltages even up from the
> nominal level if we have a really old and/or bad silicon. Limiting this
> to max opp would be bad, no? Maybe we could use max opp voltage + some
> margin though... but what would be a safe margin here?
Vnom voltage definition tends to be a variant - yep. at least OMAP3,4 have
intended to have Vnom as the max voltage for the worst corner lot sample
at end of life - aka worst possible voltage for that OPP. But with newer process
technologies of the future SoCs, this definition might turn out to become the
start voltage.

OK, it is safer to have vnom max at max SoC supported voltage i guess to prevent
code churn in the future and maintain compatibility with current SoCs.


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] 46+ messages in thread

* [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation
@ 2012-02-23 15:05         ` Menon, Nishanth
  0 siblings, 0 replies; 46+ messages in thread
From: Menon, Nishanth @ 2012-02-23 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 23, 2012 at 03:08, Tero Kristo <t-kristo@ti.com> wrote:
> On Wed, 2012-02-22 at 19:37 -0600, Menon, Nishanth wrote:
>> On Tue, Feb 21, 2012 at 08:04, Tero Kristo <t-kristo@ti.com> wrote:
>> [...]
>> > diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
>> > index 949938d..940a0d6 100644
>> > --- a/arch/arm/mach-omap2/voltage.h
>> > +++ b/arch/arm/mach-omap2/voltage.h
>>
>> [...]
>> > @@ -171,6 +169,18 @@ struct omap_voltdm_pmic {
>> > ? ? ? ?u8 (*uv_to_vsel) (unsigned long uV);
>> > ?};
>> >
>> > +struct omap_vp_param {
>> > + ? ? ? u32 vddmax;
>> > + ? ? ? u32 vddmin;
>> > +};
>> > +
>>
>> Thinking a little deeper about this(SoC level vdd min and max) on a
>> slightly different angle- core of the question that intend to answer
>> are:
>> ?- what is the least voltage we want to allow in active transtion? it
>> should not be lower than retention voltage.
>
> I think this is a fair assumption, so we could init the vddmin to be the
> same as the retention voltage for the domain (or even drop the
> parameter.)
>
>> - what is the max voltage we want to allow in active transition? it
>> should be the max Nom voltage of all the OPPs for that domain.
>
> Isn't it higher? I guess smartreflex can scale voltages even up from the
> nominal level if we have a really old and/or bad silicon. Limiting this
> to max opp would be bad, no? Maybe we could use max opp voltage + some
> margin though... but what would be a safe margin here?
Vnom voltage definition tends to be a variant - yep. at least OMAP3,4 have
intended to have Vnom as the max voltage for the worst corner lot sample
at end of life - aka worst possible voltage for that OPP. But with newer process
technologies of the future SoCs, this definition might turn out to become the
start voltage.

OK, it is safer to have vnom max at max SoC supported voltage i guess to prevent
code churn in the future and maintain compatibility with current SoCs.


Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2012-02-23 15:06 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-21 14:04 [PATCHv5 00/14] arm: omap3: auto-ret / auto-off support Tero Kristo
2012-02-21 14:04 ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 01/14] arm: OMAP3+: PM: VP: use uV for max and min voltage limits Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 02/14] arm: omap: voltage: renamed vp_vddmin and vp_vddmax fields Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:40   ` Menon, Nishanth
2012-02-21 14:40     ` Menon, Nishanth
2012-02-21 14:53     ` Russell King - ARM Linux
2012-02-21 14:53       ` Russell King - ARM Linux
2012-02-21 15:32       ` Tero Kristo
2012-02-21 15:32         ` Tero Kristo
2012-02-21 15:38         ` Nishanth Menon
2012-02-21 15:38           ` Nishanth Menon
2012-02-21 14:04 ` [PATCHv5 03/14] arm: omap3+: voltage: parameter segregation Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-23  1:37   ` Menon, Nishanth
2012-02-23  1:37     ` Menon, Nishanth
2012-02-23  9:08     ` Tero Kristo
2012-02-23  9:08       ` Tero Kristo
2012-02-23 15:05       ` Menon, Nishanth
2012-02-23 15:05         ` Menon, Nishanth
2012-02-21 14:04 ` [PATCHv5 04/14] arm: omap: voltage: add definition for pmic startup / shutdown times Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 05/14] arm: omap4: add " Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 06/14] arm: omap: add support for oscillator setup Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:44   ` Menon, Nishanth
2012-02-21 14:44     ` Menon, Nishanth
2012-02-21 14:04 ` [PATCHv5 07/14] arm: omap3+: vp: use new vp_params for calculating vddmin and vddmax Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 08/14] arm: omap3+: voltage: use oscillator data to calculate setup times Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 09/14] arm: omap4: use pmic params for calculating pmic " Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 10/14] TEMP: arm: OMAP3: beagle rev-c4: enable OPP6 Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 11/14] arm: omap: beagle: set oscillator startup time to 10ms for rev c4 Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 12/14] arm: omap3: vc: auto_ret / auto_off support Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 13/14] arm: omap3: voltage: fix channel configuration Tero Kristo
2012-02-21 14:04   ` Tero Kristo
2012-02-21 14:04 ` [PATCHv5 14/14] arm: omap: pm: wait for domain wakeup if changing state of idle domain Tero Kristo
2012-02-21 14:04   ` Tero Kristo

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.