All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] OMAP: PM: introduce Adaptive Body-Bias LDO
@ 2010-04-16 21:33 Mike Turquette
  2010-04-16 21:33 ` [PATCH 1/3] OMAP: PM: update PRM registers for ABB Mike Turquette
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Mike Turquette @ 2010-04-16 21:33 UTC (permalink / raw)
  To: linux-omap
  Cc: Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman

This patch series introduces Forward Body-Bias (FBB), which is one
technique possible using the Adaptive Body-Bias (ABB) LDO.  FBB boosts
voltage on VDD1 PMOS back gates which helps cold devices with weak
silicon characteristics sustain voltage at high OPPs.

All OMAP devices built on the 45nm process have ABB as a part of
SmartReflex2.  This patchset introduces it for OMAP 3630 and OMAP 4 will
make use of ABB in the future.

Patch series is based on pm-wip-sr and tested on Zoom3.  Please note
that the final patch in the series is a total hack and only meant for
those wishing to test this new feature.

 arch/arm/mach-omap2/cpufreq34xx.c         |    8 +-
 arch/arm/mach-omap2/prm-regbits-34xx.h    |   22 +++++
 arch/arm/mach-omap2/prm.h                 |    6 ++
 arch/arm/mach-omap2/voltage.c             |  130 ++++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/control.h |    4 +
 5 files changed, 163 insertions(+), 7 deletions(-)


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

* [PATCH 1/3] OMAP: PM: update PRM registers for ABB
  2010-04-16 21:33 [PATCH 0/4] OMAP: PM: introduce Adaptive Body-Bias LDO Mike Turquette
@ 2010-04-16 21:33 ` Mike Turquette
  2010-04-19 21:23   ` Paul Walmsley
  2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
  2010-04-16 21:33 ` [PATCH 3/3] HACK: OMAP3630: PM: allow testing of DVFS & FBB Mike Turquette
  2 siblings, 1 reply; 15+ messages in thread
From: Mike Turquette @ 2010-04-16 21:33 UTC (permalink / raw)
  To: linux-omap
  Cc: Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

PRCM on OMAP devices using the 45nm process support Adaptive Body Bias
ldo as well as some new MPU interrupts related to voltage control.
These devices currently include OMAP 3630 and 4430.  This patch adds
these bitfields to the appropriate headers.

Also adds register offset for OMAP36XX_CONTROL_VBBLDO_EFUSE_CTRL.
Though currently unused it might be used in the future to enable other
ABB features such as active RBB and sleep RBB based on silicon
characteristics.

OMAP3630_VC_BYPASS_ACK_EN, OMAP3630_VC_VP1_ACK_EN &
OMAP3630_ABB_LDO_TRANXDONE_EN have been added for completeness sake, but
these interrupts do not have to be enabled to poll on their
corresponding status bits.

Signed-off-by: Mike Turquette <mturquette@ti.com>
---
 arch/arm/mach-omap2/prm-regbits-34xx.h    |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/prm.h                 |    6 ++++++
 arch/arm/plat-omap/include/plat/control.h |    4 ++++
 3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 0066693..58c9765 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -212,6 +212,9 @@
 /* PRM_SYSCONFIG specific bits */
 
 /* PRM_IRQSTATUS_MPU specific bits */
+#define OMAP3630_VC_BYPASS_ACK_ST			(1 << 28)
+#define OMAP3630_VC_VP1_ACK_ST				(1 << 27)
+#define OMAP3630_ABB_LDO_TRANXDONE_ST			(1 << 26)
 #define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT		25
 #define OMAP3430ES2_SND_PERIPH_DPLL_ST			(1 << 25)
 #define OMAP3430_VC_TIMEOUTERR_ST			(1 << 24)
@@ -244,6 +247,9 @@
 #define OMAP3430_FS_USB_WKUP_ST				(1 << 1)
 
 /* PRM_IRQENABLE_MPU specific bits */
+#define OMAP3630_VC_BYPASS_ACK_EN				(1 << 28)
+#define OMAP3630_VC_VP1_ACK_EN					(1 << 27)
+#define OMAP3630_ABB_LDO_TRANXDONE_EN				(1 << 26)
 #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT		25
 #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN			(1 << 25)
 #define OMAP3430_VC_TIMEOUTERR_EN				(1 << 24)
@@ -581,6 +587,22 @@
 
 /* PRM_VP2_STATUS specific bits */
 
+/* PRM_LDO_ABB_SETUP specific bits */
+#define OMAP3630_SR2_IN_TRANSITION			(1 << 6)
+#define OMAP3630_SR2_STATUS_SHIFT			3
+#define OMAP3630_SR2_STATUS_MASK			(3 << 3)
+#define OMAP3630_OPP_CHANGE				(1 << 2)
+#define OMAP3630_OPP_SEL_SHIFT				0
+#define OMAP3630_OPP_SEL_MASK				(3 << 0)
+
+/* PRM_LDO_ABB_CTRL specific bits */
+#define OMAP3630_SR2_WTCNT_VALUE_SHIFT			8
+#define OMAP3630_SR2_WTCNT_VALUE_MASK			(0xff << 8)
+#define OMAP3630_SLEEP_RBB_SEL				(1 << 3)
+#define OMAP3630_ACTIVE_FBB_SEL				(1 << 2)
+#define OMAP3630_ACTIVE_RBB_SEL				(1 << 1)
+#define OMAP3630_SR2EN					(1 << 0)
+
 /* RM_RSTST_NEON specific bits */
 
 /* PM_WKDEP_NEON specific bits */
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 5fba2aa..2a58847 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -160,6 +160,12 @@
 #define OMAP3430_PRM_VP2_VOLTAGE	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
 #define OMAP3_PRM_VP2_STATUS_OFFSET	0x00e4
 #define OMAP3430_PRM_VP2_STATUS		OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
+#define OMAP3_PRM_LDO_ABB_SETUP_OFFSET	0X00f0
+#define OMAP3630_PRM_LDO_ABB_SETUP	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, \
+								0X00f0)
+#define OMAP3_PRM_LDO_ABB_CTRL_OFFSET	0X00f4
+#define OMAP3630_PRM_LDO_ABB_CTRL	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, \
+								0X00f4)
 
 #define OMAP3_PRM_CLKSEL_OFFSET	0x0040
 #define OMAP3430_PRM_CLKSEL		OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
index d540ae8..120d0c1 100644
--- a/arch/arm/plat-omap/include/plat/control.h
+++ b/arch/arm/plat-omap/include/plat/control.h
@@ -209,6 +209,10 @@
 #define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
 #define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
 
+/* 36xx GENERAL_WKUP register offsets */
+#define OMAP36XX_CONTROL_VBBLDO_EFUSE_CTRL (OMAP343X_CONTROL_GENERAL_WKUP + \
+						0X02C)
+
 /* 34xx D2D idle-related pins, handled by PM core */
 #define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
 #define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
-- 
1.6.3.2


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

* [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-16 21:33 [PATCH 0/4] OMAP: PM: introduce Adaptive Body-Bias LDO Mike Turquette
  2010-04-16 21:33 ` [PATCH 1/3] OMAP: PM: update PRM registers for ABB Mike Turquette
@ 2010-04-16 21:33 ` Mike Turquette
  2010-04-19  7:46   ` Eduardo Valentin
                     ` (2 more replies)
  2010-04-16 21:33 ` [PATCH 3/3] HACK: OMAP3630: PM: allow testing of DVFS & FBB Mike Turquette
  2 siblings, 3 replies; 15+ messages in thread
From: Mike Turquette @ 2010-04-16 21:33 UTC (permalink / raw)
  To: linux-omap
  Cc: Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

Introduces voltscale_adaptive_body_bias function to voltage.c.
voltscale_adaptive_body_bias is called by omap_voltage_scale after a
voltage transition has occured.  Currently voltscale_adaptive_body_bias
only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
1GHz or higher.  In the future Reverse Body-Bias might be included.

FBB is an Adaptive Body-Bias technique to boost performance for weak
process devices at high OPPs. This results in voltage boost on the VDD1
PMOS back gates when running at maximum OPP.  Current recommendations
are to enable FBB on all 3630 regardless of silicon characteristics and
EFUSE values.

ABB applies to all OMAP silicon based on 45nm process, which includes
OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
to voltscale_adaptive_body_bias in the future.

Signed-off-by: Mike Turquette <mturquette@ti.com>
---
 arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index c2c8192..98d8bb3 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -37,6 +37,11 @@
 #define VP_IDLE_TIMEOUT		200
 #define VP_TRANXDONE_TIMEOUT	300
 
+#define ABB_MAX_SETTLING_TIME	30
+#define ABB_FAST_OPP		1
+#define ABB_NOMINAL_OPP		2
+#define ABB_SLOW_OPP		3
+
 /**
  * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
  * board data or PMIC data
@@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
 }
 
 /**
+ * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
+ * @target_volt: target voltage determines if ABB ldo is active or bypassed
+ *
+ * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
+ * process.  ABB can boost voltage in high OPPs for silicon with weak
+ * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
+ * for silicon with strong characteristics (Reverse Body-Bias).
+ *
+ * Only Foward Body-Bias for operating at high OPPs is implemented below, per
+ * recommendations from silicon team.
+ * Reverse Body-Bias for saving power in active cases and sleep cases is not
+ * yet implemented.
+ * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
+ * to implement it yet.
+ */
+int voltscale_adaptive_body_bias(unsigned long target_volt)
+{
+	u32 sr2en_enabled;
+	int timeout;
+	int sr2_wtcnt_value;
+
+	/* calculate SR2_WTCNT_VALUE settling time */
+	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
+			(clk_get_rate("sys_ck") / 1000000) / 8);
+
+	/* has SR2EN been enabled previously? */
+	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
+				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
+			OMAP3630_SR2EN);
+
+	/* select fast, nominal or slow OPP for ABB ldo */
+	/* FIXME: include OMAP4 once recommendations are complete */
+	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
+		/* program for fast opp - enable FBB */
+		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
+				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
+				OMAP3430_GR_MOD,
+				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+
+		/* enable the ABB ldo if not done already */
+		if (!sr2en_enabled)
+			prm_set_mod_reg_bits(OMAP3630_SR2EN,
+					OMAP3430_GR_MOD,
+					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+	} else if (sr2en_enabled) {
+		/* program for nominal opp - bypass ABB ldo */
+		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
+				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
+				OMAP3430_GR_MOD,
+				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+	} else {
+		/* nothing to do here yet... might enable RBB here someday */
+		return 0;
+	}
+
+	/* set ACTIVE_FBB_SEL for all 45nm silicon */
+	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
+			OMAP3430_GR_MOD,
+			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+
+	/* program settling time of 30us for ABB ldo transition */
+	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
+			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
+			OMAP3430_GR_MOD,
+			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
+
+	/* clear ABB ldo interrupt status */
+	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
+			OCP_MOD,
+			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+
+	/* enable ABB LDO OPP change */
+	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
+			OMAP3430_GR_MOD,
+			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
+
+	timeout = 0;
+
+	/* wait until OPP change completes */
+	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
+			(!(prm_read_mod_reg(OCP_MOD,
+					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
+			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
+		udelay(1);
+		timeout++;
+	}
+
+	if (timeout == ABB_MAX_SETTLING_TIME)
+		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
+
+	timeout = 0;
+
+	/* Clear all pending TRANXDONE interrupts/status */
+	while (timeout < ABB_MAX_SETTLING_TIME) {
+		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
+				OCP_MOD,
+				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+		if (!(prm_read_mod_reg(OCP_MOD,
+						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
+					& OMAP3630_ABB_LDO_TRANXDONE_ST))
+			break;
+
+		udelay(1);
+		timeout++;
+	}
+	if (timeout == ABB_MAX_SETTLING_TIME)
+		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
+
+	return 0;
+}
+
+/**
  * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
  *
  * This is a temporary placeholder for this API. This should ideally belong
@@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
 int omap_voltage_scale(int vdd, unsigned long target_volt,
 					unsigned long current_volt)
 {
+	int ret;
+
 	if (voltscale_vpforceupdate)
-		return vp_forceupdate_scale_voltage(vdd, target_volt,
+		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
 								current_volt);
 	else
-		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
+		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
+
+	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
+	if (ret && (cpu_is_omap3630() && vdd == VDD1))
+		ret = voltscale_adaptive_body_bias(target_volt);
+
+	return ret;
 }
 
 /**
-- 
1.6.3.2


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

* [PATCH 3/3] HACK: OMAP3630: PM: allow testing of DVFS & FBB
  2010-04-16 21:33 [PATCH 0/4] OMAP: PM: introduce Adaptive Body-Bias LDO Mike Turquette
  2010-04-16 21:33 ` [PATCH 1/3] OMAP: PM: update PRM registers for ABB Mike Turquette
  2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
@ 2010-04-16 21:33 ` Mike Turquette
  2 siblings, 0 replies; 15+ messages in thread
From: Mike Turquette @ 2010-04-16 21:33 UTC (permalink / raw)
  To: linux-omap
  Cc: Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

This hack should not be applied to any git trees.

Enables 800MHz and 1GHz OPPs on VDD1 for 36XX silicon and bypasses an
error condition in vp_forceupdate_scale_voltage to allow for voltage
scaling to happen in the absence of complete SmartReflex support.

These changes are needed to allow DVFS transitions via cpufreq on top of
pm-wip-sr and to test the FBB transitions that only happen @ 1GHz on
3630.

Not-Signed-Off-By: Mike Turquette <mturquette@ti.com>
---
 arch/arm/mach-omap2/cpufreq34xx.c |    8 ++++----
 arch/arm/mach-omap2/voltage.c     |    1 -
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/cpufreq34xx.c b/arch/arm/mach-omap2/cpufreq34xx.c
index 189c42e..47913dc 100644
--- a/arch/arm/mach-omap2/cpufreq34xx.c
+++ b/arch/arm/mach-omap2/cpufreq34xx.c
@@ -80,9 +80,9 @@ static struct omap_opp_def __initdata omap36xx_mpu_rate_table[] = {
 	/* OPP2 - OPP100 */
 	OMAP_OPP_DEF(true,  600000000, 1100000),
 	/* OPP3 - OPP-Turbo */
-	OMAP_OPP_DEF(false, 800000000, 1260000),
+	OMAP_OPP_DEF(true, 800000000, 1260000),
 	/* OPP4 - OPP-SB */
-	OMAP_OPP_DEF(false, 1000000000, 1350000),
+	OMAP_OPP_DEF(true, 1000000000, 1350000),
 	/* Terminator */
 	OMAP_OPP_DEF(0, 0, 0)
 };
@@ -102,9 +102,9 @@ static struct omap_opp_def __initdata omap36xx_dsp_rate_table[] = {
 	/* OPP2 - OPP100 */
 	OMAP_OPP_DEF(true,  520000000, 1100000),
 	/* OPP3 - OPP-Turbo */
-	OMAP_OPP_DEF(false, 660000000, 1260000),
+	OMAP_OPP_DEF(true, 660000000, 1260000),
 	/* OPP4 - OPP-SB */
-	OMAP_OPP_DEF(false, 800000000, 1350000),
+	OMAP_OPP_DEF(true, 800000000, 1350000),
 	/* Terminator */
 	OMAP_OPP_DEF(0, 0, 0)
 };
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 98d8bb3..bec8c18 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -571,7 +571,6 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
 			pr_warning("Unable to get voltage table for VDD%d \
 				during voltage scaling. Some really Wrong!",
 				vdd + 1);
-			return false;
 		}
 		vp_reg[vdd].vp_errorgain = (volt_data.vp_errorgain <<
 				OMAP3430_ERRORGAIN_SHIFT);
-- 
1.6.3.2


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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
@ 2010-04-19  7:46   ` Eduardo Valentin
  2010-04-21 21:21     ` Mike Turquette
  2010-04-20  5:42   ` Paul Walmsley
  2010-05-21 12:44   ` Eduardo Valentin
  2 siblings, 1 reply; 15+ messages in thread
From: Eduardo Valentin @ 2010-04-19  7:46 UTC (permalink / raw)
  To: ext Mike Turquette
  Cc: linux-omap, Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

Hello Mike,

On Fri, Apr 16, 2010 at 11:33:22PM +0200, ext Mike Turquette wrote:
> Introduces voltscale_adaptive_body_bias function to voltage.c.
> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
> voltage transition has occured.  Currently voltscale_adaptive_body_bias
> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
> 1GHz or higher.  In the future Reverse Body-Bias might be included.
> 
> FBB is an Adaptive Body-Bias technique to boost performance for weak
> process devices at high OPPs. This results in voltage boost on the VDD1
> PMOS back gates when running at maximum OPP.  Current recommendations
> are to enable FBB on all 3630 regardless of silicon characteristics and
> EFUSE values.
> 
> ABB applies to all OMAP silicon based on 45nm process, which includes
> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
> to voltscale_adaptive_body_bias in the future.

Nice !

> 
> Signed-off-by: Mike Turquette <mturquette@ti.com>
> ---
>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 127 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index c2c8192..98d8bb3 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -37,6 +37,11 @@
>  #define VP_IDLE_TIMEOUT		200
>  #define VP_TRANXDONE_TIMEOUT	300
>  
> +#define ABB_MAX_SETTLING_TIME	30
> +#define ABB_FAST_OPP		1
> +#define ABB_NOMINAL_OPP		2
> +#define ABB_SLOW_OPP		3
> +
>  /**
>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>   * board data or PMIC data
> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>  }
>  
>  /**
> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
> + *
> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
> + * process.  ABB can boost voltage in high OPPs for silicon with weak
> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
> + * for silicon with strong characteristics (Reverse Body-Bias).
> + *
> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
> + * recommendations from silicon team.
> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
> + * yet implemented.
> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
> + * to implement it yet.
> + */
> +int voltscale_adaptive_body_bias(unsigned long target_volt)
> +{
> +	u32 sr2en_enabled;
> +	int timeout;
> +	int sr2_wtcnt_value;
> +
> +	/* calculate SR2_WTCNT_VALUE settling time */
> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
> +			(clk_get_rate("sys_ck") / 1000000) / 8);
> +
> +	/* has SR2EN been enabled previously? */
> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
> +			OMAP3630_SR2EN);
> +
> +	/* select fast, nominal or slow OPP for ABB ldo */
> +	/* FIXME: include OMAP4 once recommendations are complete */
> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {

You are creating two steps to decide if you apply or not FBB.
Here and also bellow (omap voltage scale). Would it make sense to bind it
per opp? I mean just a flag on opp dat then you apply or not based on that flag.
Same for RBB.

> +		/* program for fast opp - enable FBB */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +
> +		/* enable the ABB ldo if not done already */
> +		if (!sr2en_enabled)
> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
> +					OMAP3430_GR_MOD,
> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +	} else if (sr2en_enabled) {
> +		/* program for nominal opp - bypass ABB ldo */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +	} else {
> +		/* nothing to do here yet... might enable RBB here someday */
> +		return 0;
> +	}
> +
> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +
> +	/* program settling time of 30us for ABB ldo transition */
> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +
> +	/* clear ABB ldo interrupt status */
> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +			OCP_MOD,
> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +
> +	/* enable ABB LDO OPP change */
> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +
> +	timeout = 0;
> +
> +	/* wait until OPP change completes */
> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
> +			(!(prm_read_mod_reg(OCP_MOD,
> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
> +		udelay(1);
> +		timeout++;
> +	}
> +
> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
> +
> +	timeout = 0;
> +
> +	/* Clear all pending TRANXDONE interrupts/status */
> +	while (timeout < ABB_MAX_SETTLING_TIME) {
> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +				OCP_MOD,
> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +		if (!(prm_read_mod_reg(OCP_MOD,
> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
> +			break;
> +
> +		udelay(1);
> +		timeout++;
> +	}

Is there any other way of implementing the above instead of busy loop / udelay?


> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
> +
> +	return 0;
> +}
> +
> +/**
>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>   *
>   * This is a temporary placeholder for this API. This should ideally belong
> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>  					unsigned long current_volt)
>  {
> +	int ret;
> +
>  	if (voltscale_vpforceupdate)
> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>  								current_volt);
>  	else
> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +
> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))

I meant here. I guess would be better to have just one place to check if you apply or not.

> +		ret = voltscale_adaptive_body_bias(target_volt);
> +
> +	return ret;
>  }
>  
>  /**
> -- 
> 1.6.3.2
> 
> --
> 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] 15+ messages in thread

* Re: [PATCH 1/3] OMAP: PM: update PRM registers for ABB
  2010-04-16 21:33 ` [PATCH 1/3] OMAP: PM: update PRM registers for ABB Mike Turquette
@ 2010-04-19 21:23   ` Paul Walmsley
  0 siblings, 0 replies; 15+ messages in thread
From: Paul Walmsley @ 2010-04-19 21:23 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-omap, Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

Hello Mike

The functional content of these macros looks fine to me (based on the 
OMAP3630 TRM Rev C) but please make a few minor style changes:

On Fri, 16 Apr 2010, Mike Turquette wrote:

> PRCM on OMAP devices using the 45nm process support Adaptive Body Bias
> ldo as well as some new MPU interrupts related to voltage control.
> These devices currently include OMAP 3630 and 4430.  This patch adds
> these bitfields to the appropriate headers.
> 
> Also adds register offset for OMAP36XX_CONTROL_VBBLDO_EFUSE_CTRL.
> Though currently unused it might be used in the future to enable other
> ABB features such as active RBB and sleep RBB based on silicon
> characteristics.
> 
> OMAP3630_VC_BYPASS_ACK_EN, OMAP3630_VC_VP1_ACK_EN &
> OMAP3630_ABB_LDO_TRANXDONE_EN have been added for completeness sake, but
> these interrupts do not have to be enabled to poll on their
> corresponding status bits.
> 
> Signed-off-by: Mike Turquette <mturquette@ti.com>
> ---
>  arch/arm/mach-omap2/prm-regbits-34xx.h    |   22 ++++++++++++++++++++++
>  arch/arm/mach-omap2/prm.h                 |    6 ++++++
>  arch/arm/plat-omap/include/plat/control.h |    4 ++++
>  3 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
> index 0066693..58c9765 100644
> --- a/arch/arm/mach-omap2/prm-regbits-34xx.h
> +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
> @@ -212,6 +212,9 @@
>  /* PRM_SYSCONFIG specific bits */
>  
>  /* PRM_IRQSTATUS_MPU specific bits */
> +#define OMAP3630_VC_BYPASS_ACK_ST			(1 << 28)
> +#define OMAP3630_VC_VP1_ACK_ST				(1 << 27)
> +#define OMAP3630_ABB_LDO_TRANXDONE_ST			(1 << 26)

Please append _MASK to the names of all register bitfield macros.  This is 
not consistent in the current macro include files, but will be soon.

>  #define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT		25
>  #define OMAP3430ES2_SND_PERIPH_DPLL_ST			(1 << 25)
>  #define OMAP3430_VC_TIMEOUTERR_ST			(1 << 24)
> @@ -244,6 +247,9 @@
>  #define OMAP3430_FS_USB_WKUP_ST				(1 << 1)
>  
>  /* PRM_IRQENABLE_MPU specific bits */
> +#define OMAP3630_VC_BYPASS_ACK_EN				(1 << 28)
> +#define OMAP3630_VC_VP1_ACK_EN					(1 << 27)
> +#define OMAP3630_ABB_LDO_TRANXDONE_EN				(1 << 26)

as above

>  #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT		25
>  #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN			(1 << 25)
>  #define OMAP3430_VC_TIMEOUTERR_EN				(1 << 24)
> @@ -581,6 +587,22 @@
>  
>  /* PRM_VP2_STATUS specific bits */
>  
> +/* PRM_LDO_ABB_SETUP specific bits */
> +#define OMAP3630_SR2_IN_TRANSITION			(1 << 6)

as above

> +#define OMAP3630_SR2_STATUS_SHIFT			3
> +#define OMAP3630_SR2_STATUS_MASK			(3 << 3)
> +#define OMAP3630_OPP_CHANGE				(1 << 2)

as above

> +#define OMAP3630_OPP_SEL_SHIFT				0
> +#define OMAP3630_OPP_SEL_MASK				(3 << 0)
> +
> +/* PRM_LDO_ABB_CTRL specific bits */
> +#define OMAP3630_SR2_WTCNT_VALUE_SHIFT			8
> +#define OMAP3630_SR2_WTCNT_VALUE_MASK			(0xff << 8)
> +#define OMAP3630_SLEEP_RBB_SEL				(1 << 3)
> +#define OMAP3630_ACTIVE_FBB_SEL				(1 << 2)
> +#define OMAP3630_ACTIVE_RBB_SEL				(1 << 1)
> +#define OMAP3630_SR2EN					(1 << 0)

as above


> +
>  /* RM_RSTST_NEON specific bits */
>  
>  /* PM_WKDEP_NEON specific bits */
> diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
> index 5fba2aa..2a58847 100644
> --- a/arch/arm/mach-omap2/prm.h
> +++ b/arch/arm/mach-omap2/prm.h
> @@ -160,6 +160,12 @@
>  #define OMAP3430_PRM_VP2_VOLTAGE	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
>  #define OMAP3_PRM_VP2_STATUS_OFFSET	0x00e4
>  #define OMAP3430_PRM_VP2_STATUS		OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
> +#define OMAP3_PRM_LDO_ABB_SETUP_OFFSET	0X00f0

Please use a lowercase 'x' in the macro value, as per the style of the 
rest of this file.  Also, if this register was only introduced with 3630, 
then the name of the macro should be 'OMAP3630_PRM_LDO_ABB_SETUP_OFFSET' 
to indicate this.  (Only macro names for registers that are available on 
all OMAP3-family chips should start with "OMAP3_".)

> +#define OMAP3630_PRM_LDO_ABB_SETUP	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, \
> +								0X00f0)
> +#define OMAP3_PRM_LDO_ABB_CTRL_OFFSET	0X00f4
> +#define OMAP3630_PRM_LDO_ABB_CTRL	OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, \
> +								0X00f4)

as above

>  
>  #define OMAP3_PRM_CLKSEL_OFFSET	0x0040
>  #define OMAP3430_PRM_CLKSEL		OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
> diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
> index d540ae8..120d0c1 100644
> --- a/arch/arm/plat-omap/include/plat/control.h
> +++ b/arch/arm/plat-omap/include/plat/control.h
> @@ -209,6 +209,10 @@
>  #define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
>  #define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
>  
> +/* 36xx GENERAL_WKUP register offsets */
> +#define OMAP36XX_CONTROL_VBBLDO_EFUSE_CTRL (OMAP343X_CONTROL_GENERAL_WKUP + \
> +						0X02C)

as above

> +
>  /* 34xx D2D idle-related pins, handled by PM core */
>  #define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
>  #define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
> -- 
> 1.6.3.2
> 
> --
> 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
> 


- Paul

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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
  2010-04-19  7:46   ` Eduardo Valentin
@ 2010-04-20  5:42   ` Paul Walmsley
  2010-04-21 22:13     ` Mike Turquette
  2010-05-21 12:44   ` Eduardo Valentin
  2 siblings, 1 reply; 15+ messages in thread
From: Paul Walmsley @ 2010-04-20  5:42 UTC (permalink / raw)
  To: Mike Turquette
  Cc: eduardo.valentin, linux-omap, Vishwanath Sripathy,
	Thara Gopinath, Shweta Gulati, Nishanth Menon, Kevin Hilman,
	Mike Turquette

Hi Mike,

some comments.

On Fri, 16 Apr 2010, Mike Turquette wrote:

> Introduces voltscale_adaptive_body_bias function to voltage.c.
> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
> voltage transition has occured.  Currently voltscale_adaptive_body_bias
> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
> 1GHz or higher.  In the future Reverse Body-Bias might be included.
> 
> FBB is an Adaptive Body-Bias technique to boost performance for weak
> process devices at high OPPs. This results in voltage boost on the VDD1
> PMOS back gates when running at maximum OPP.  Current recommendations
> are to enable FBB on all 3630 regardless of silicon characteristics and
> EFUSE values.
> 
> ABB applies to all OMAP silicon based on 45nm process, which includes
> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
> to voltscale_adaptive_body_bias in the future.

Great work on the patch changelog and kerneldoc on the functions - I wish 
everyone wrote patch changelogs like this.

> Signed-off-by: Mike Turquette <mturquette@ti.com>
> ---
>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 127 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index c2c8192..98d8bb3 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c

Please move this code to a separate file - would suggest mach-omap2/abb.c.  
The rationale here is that many OMAP2+ platforms won't need this code, and 
we can skip compiling it in those cases.


> @@ -37,6 +37,11 @@
>  #define VP_IDLE_TIMEOUT		200
>  #define VP_TRANXDONE_TIMEOUT	300
>  

Please add a bit of documentation here to indicate what unit 
ABB_MAX_SETTLING_TIME is in, and where this number comes from.

> +#define ABB_MAX_SETTLING_TIME	30

Please add some documentation here to to note that these are the 
PRM_LDO_ABB_SETUP.OPP_SEL register bitfield values.

> +#define ABB_FAST_OPP		1
> +#define ABB_NOMINAL_OPP		2
> +#define ABB_SLOW_OPP		3
> +
>  /**
>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>   * board data or PMIC data
> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>  }
>  
>  /**
> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
> + *
> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
> + * process.  ABB can boost voltage in high OPPs for silicon with weak
> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
> + * for silicon with strong characteristics (Reverse Body-Bias).
> + *
> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
> + * recommendations from silicon team.
> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
> + * yet implemented.
> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
> + * to implement it yet.

Please consider adding a short section describing the function return 
values (per Documentation/kernel-doc-nano-HOWTO.txt).

> + */
> +int voltscale_adaptive_body_bias(unsigned long target_volt)

Since this code appears to be OMAP36xx-specific, please note that in the 
function name.  Also this is VDD1-specific, so might be worth noting that 
there as well.

It's probably worth splitting this single function up into init(), 
enable(), disable(), and probably a _transition_poll() function.

> +{
> +	u32 sr2en_enabled;
> +	int timeout;
> +	int sr2_wtcnt_value;
> +
> +	/* calculate SR2_WTCNT_VALUE settling time */
> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
> +			(clk_get_rate("sys_ck") / 1000000) / 8);
> +
> +	/* has SR2EN been enabled previously? */
> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
> +			OMAP3630_SR2EN);

The above code should be separated out into a function that is run once at 
init.  (and then perhaps once every time these registers are changed - 
will the ROM code touch these when entering or exiting off-mode?) No point 
always executing this stuff for every OPP change if it only needs to be 
done infrequently.  PRM accesses, especially reads, slow the ARM down, so 
it's worthwhile avoiding them.

> +
> +	/* select fast, nominal or slow OPP for ABB ldo */
> +	/* FIXME: include OMAP4 once recommendations are complete */
> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {

Please integrate this type of information into the OPP table or 
somewhere similar, since this is SoC-specific configuration data.

> +		/* program for fast opp - enable FBB */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);

Can you foresee a situation in which there would be multiple FBB-using 
OPPs?  If so, it might be worth keeping track of the previous contents of 
this register in RAM, to avoid the PRM accesses.

> +		/* enable the ABB ldo if not done already */
> +		if (!sr2en_enabled)
> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
> +					OMAP3430_GR_MOD,
> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +	} else if (sr2en_enabled) {
> +		/* program for nominal opp - bypass ABB ldo */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +	} else {
> +		/* nothing to do here yet... might enable RBB here someday */
> +		return 0;
> +	}
> +
> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);

Can this be moved to init code?

By the way, what is the hardware's exact definition of a 'fast 
OPP'/'nominal OPP'/'slow OPP' ?

> +	/* program settling time of 30us for ABB ldo transition */
> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);

Looks like this can also be moved to init code.

> +
> +	/* clear ABB ldo interrupt status */
> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +			OCP_MOD,
> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +
> +	/* enable ABB LDO OPP change */
> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +
> +	timeout = 0;
> +
> +	/* wait until OPP change completes */
> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
> +			(!(prm_read_mod_reg(OCP_MOD,
> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {

I take it that this code is executing with interrupts disabled?

Can the ABB LDO interrupt just be disabled, and the 
PRM_LDO_ABB_SETUP.OPP_CHANGE bit read to determine if the LDO change is 
complete?  That might cut out some of the code that polls this TRANXDONE 
interrupt, which seems hacky if reading OPP_CHANGE works.

> +		udelay(1);
> +		timeout++;
> +	}

Will the ABB LDO always take 30us to transition if that is what was 
programmed, or can it finish early?  If the former, then presumably this 
loop timeout needs to be increased?

> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");

Should be a WARN() instead since this should never happen.

> +	timeout = 0;
> +
> +	/* Clear all pending TRANXDONE interrupts/status */
> +	while (timeout < ABB_MAX_SETTLING_TIME) {

Can this interrupt status register really take 30 microseconds to clear?

> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +				OCP_MOD,
> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +		if (!(prm_read_mod_reg(OCP_MOD,
> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
> +			break;
> +
> +		udelay(1);
> +		timeout++;
> +	}
> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");

Should be a WARN() instead since this should never happen.

> +
> +	return 0;
> +}
> +
> +/**
>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>   *
>   * This is a temporary placeholder for this API. This should ideally belong
> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>  					unsigned long current_volt)
>  {
> +	int ret;
> +


Is it safe to leave VDD1 FBB enabled while switching to a lower voltage?  
If it is unknown, shouldn't there be a test here to determine whether the 
voltage is going down, and disabling FBB in that case?

>  	if (voltscale_vpforceupdate)
> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>  								current_volt);
>  	else
> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +
> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
> +		ret = voltscale_adaptive_body_bias(target_volt);
> +
> +	return ret;
>  }
>  
>  /**
> -- 
> 1.6.3.2
> 
> --
> 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
> 


- Paul

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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-19  7:46   ` Eduardo Valentin
@ 2010-04-21 21:21     ` Mike Turquette
  2010-04-22 13:56       ` Nishanth Menon
  0 siblings, 1 reply; 15+ messages in thread
From: Mike Turquette @ 2010-04-21 21:21 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: ext Mike Turquette, linux-omap, Sripathy, Vishwanath, Gopinath,
	Thara, Gulati, Shweta, Menon, Nishanth, Kevin Hilman

Eduardo Valentin wrote:
> Hello Mike,
> 
> On Fri, Apr 16, 2010 at 11:33:22PM +0200, ext Mike Turquette wrote:
>> Introduces voltscale_adaptive_body_bias function to voltage.c.
>> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
>> voltage transition has occured.  Currently voltscale_adaptive_body_bias
>> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
>> 1GHz or higher.  In the future Reverse Body-Bias might be included.
>>
>> FBB is an Adaptive Body-Bias technique to boost performance for weak
>> process devices at high OPPs. This results in voltage boost on the VDD1
>> PMOS back gates when running at maximum OPP.  Current recommendations
>> are to enable FBB on all 3630 regardless of silicon characteristics and
>> EFUSE values.
>>
>> ABB applies to all OMAP silicon based on 45nm process, which includes
>> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
>> to voltscale_adaptive_body_bias in the future.
> 
> Nice !
> 
>> Signed-off-by: Mike Turquette <mturquette@ti.com>
>> ---
>>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>>  1 files changed, 127 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
>> index c2c8192..98d8bb3 100644
>> --- a/arch/arm/mach-omap2/voltage.c
>> +++ b/arch/arm/mach-omap2/voltage.c
>> @@ -37,6 +37,11 @@
>>  #define VP_IDLE_TIMEOUT		200
>>  #define VP_TRANXDONE_TIMEOUT	300
>>  
>> +#define ABB_MAX_SETTLING_TIME	30
>> +#define ABB_FAST_OPP		1
>> +#define ABB_NOMINAL_OPP		2
>> +#define ABB_SLOW_OPP		3
>> +
>>  /**
>>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>>   * board data or PMIC data
>> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>>  }
>>  
>>  /**
>> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
>> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
>> + *
>> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
>> + * process.  ABB can boost voltage in high OPPs for silicon with weak
>> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
>> + * for silicon with strong characteristics (Reverse Body-Bias).
>> + *
>> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
>> + * recommendations from silicon team.
>> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
>> + * yet implemented.
>> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
>> + * to implement it yet.
>> + */
>> +int voltscale_adaptive_body_bias(unsigned long target_volt)
>> +{
>> +	u32 sr2en_enabled;
>> +	int timeout;
>> +	int sr2_wtcnt_value;
>> +
>> +	/* calculate SR2_WTCNT_VALUE settling time */
>> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
>> +			(clk_get_rate("sys_ck") / 1000000) / 8);
>> +
>> +	/* has SR2EN been enabled previously? */
>> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
>> +			OMAP3630_SR2EN);
>> +
>> +	/* select fast, nominal or slow OPP for ABB ldo */
>> +	/* FIXME: include OMAP4 once recommendations are complete */
>> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> 
> You are creating two steps to decide if you apply or not FBB.
> Here and also bellow (omap voltage scale). Would it make sense to bind it
> per opp? I mean just a flag on opp dat then you apply or not based on that flag.
> Same for RBB.

Eduardo,

Thanks for reviewing.

There has been some offline discussion about the best way to handle the 
the relationship between FBB enable flags and OPPs:

1) extend OPP table
2) piggyback on Thara's SR hwmod structures
	This probably won't work given Paul's review comments
3) other wacky stuff

After some discussion about the best way to do this I will definitely 
lose the duplicate checks and replace with some nice table look-up.

Extending the OPP table is gross for OMAP2 and OMAP3430.  Piggybacking 
on SR stuff is just a hack and there is no real relationship between ABB 
ldo and SR.  The crux of the issue is how to relate FBB enable flags to 
OPP table.  hwmod?  Ideas on this are very welcome.

>> +		/* program for fast opp - enable FBB */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +
>> +		/* enable the ABB ldo if not done already */
>> +		if (!sr2en_enabled)
>> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
>> +					OMAP3430_GR_MOD,
>> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +	} else if (sr2en_enabled) {
>> +		/* program for nominal opp - bypass ABB ldo */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +	} else {
>> +		/* nothing to do here yet... might enable RBB here someday */
>> +		return 0;
>> +	}
>> +
>> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
>> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +
>> +	/* program settling time of 30us for ABB ldo transition */
>> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
>> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +
>> +	/* clear ABB ldo interrupt status */
>> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +			OCP_MOD,
>> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +
>> +	/* enable ABB LDO OPP change */
>> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +
>> +	timeout = 0;
>> +
>> +	/* wait until OPP change completes */
>> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
>> +			(!(prm_read_mod_reg(OCP_MOD,
>> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
>> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
>> +		udelay(1);
>> +		timeout++;
>> +	}
>> +
>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
>> +
>> +	timeout = 0;
>> +
>> +	/* Clear all pending TRANXDONE interrupts/status */
>> +	while (timeout < ABB_MAX_SETTLING_TIME) {
>> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +				OCP_MOD,
>> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +		if (!(prm_read_mod_reg(OCP_MOD,
>> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
>> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
>> +			break;
>> +
>> +		udelay(1);
>> +		timeout++;
>> +	}
> 
> Is there any other way of implementing the above instead of busy loop / udelay?

I can defer the work for 30us if that is what you mean.  Not sure we 
want to always wait for the length of the timeout to continue though. 
Any time spent at 1GHz on 3630 should be "protected" by running FBB.

Or did you have something else in mind besides a workqueue on a timer?

> 
>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>>   *
>>   * This is a temporary placeholder for this API. This should ideally belong
>> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>>  					unsigned long current_volt)
>>  {
>> +	int ret;
>> +
>>  	if (voltscale_vpforceupdate)
>> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
>> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>>  								current_volt);
>>  	else
>> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +
>> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
>> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
> 
> I meant here. I guess would be better to have just one place to check if you apply or not.

I think I will keep the cpu_is_* check here, and then 
voltscale_adaptive_body_bias can use a nice table look-up instead of 
rechecking as I mentioned above.

Thanks much,
Mike

>> +		ret = voltscale_adaptive_body_bias(target_volt);
>> +
>> +	return ret;
>>  }
>>  
>>  /**
>> -- 
>> 1.6.3.2
>>
>> --
>> 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] 15+ messages in thread

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-20  5:42   ` Paul Walmsley
@ 2010-04-21 22:13     ` Mike Turquette
  0 siblings, 0 replies; 15+ messages in thread
From: Mike Turquette @ 2010-04-21 22:13 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Mike Turquette, eduardo.valentin, linux-omap, Sripathy,
	Vishwanath, Gopinath, Thara, Gulati, Shweta, Menon, Nishanth,
	Kevin Hilman

Paul Walmsley wrote:
> Hi Mike,
> 
> some comments.
> 
> On Fri, 16 Apr 2010, Mike Turquette wrote:
> 
>> Introduces voltscale_adaptive_body_bias function to voltage.c.
>> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
>> voltage transition has occured.  Currently voltscale_adaptive_body_bias
>> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
>> 1GHz or higher.  In the future Reverse Body-Bias might be included.
>>
>> FBB is an Adaptive Body-Bias technique to boost performance for weak
>> process devices at high OPPs. This results in voltage boost on the VDD1
>> PMOS back gates when running at maximum OPP.  Current recommendations
>> are to enable FBB on all 3630 regardless of silicon characteristics and
>> EFUSE values.
>>
>> ABB applies to all OMAP silicon based on 45nm process, which includes
>> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
>> to voltscale_adaptive_body_bias in the future.
> 
> Great work on the patch changelog and kerneldoc on the functions - I wish 
> everyone wrote patch changelogs like this.
> 
>> Signed-off-by: Mike Turquette <mturquette@ti.com>
>> ---
>>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>>  1 files changed, 127 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
>> index c2c8192..98d8bb3 100644
>> --- a/arch/arm/mach-omap2/voltage.c
>> +++ b/arch/arm/mach-omap2/voltage.c
> 
> Please move this code to a separate file - would suggest mach-omap2/abb.c.  
> The rationale here is that many OMAP2+ platforms won't need this code, and 
> we can skip compiling it in those cases.

Paul,

Thanks for reviewing.

Moving the code to a new file is fine.  Next patchset will do this.

> 
>> @@ -37,6 +37,11 @@
>>  #define VP_IDLE_TIMEOUT		200
>>  #define VP_TRANXDONE_TIMEOUT	300
>>  
> 
> Please add a bit of documentation here to indicate what unit 
> ABB_MAX_SETTLING_TIME is in, and where this number comes from.
> 
>> +#define ABB_MAX_SETTLING_TIME	30
> 
> Please add some documentation here to to note that these are the 
> PRM_LDO_ABB_SETUP.OPP_SEL register bitfield values.

Will do.

>> +#define ABB_FAST_OPP		1
>> +#define ABB_NOMINAL_OPP		2
>> +#define ABB_SLOW_OPP		3
>> +
>>  /**
>>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>>   * board data or PMIC data
>> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>>  }
>>  
>>  /**
>> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
>> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
>> + *
>> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
>> + * process.  ABB can boost voltage in high OPPs for silicon with weak
>> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
>> + * for silicon with strong characteristics (Reverse Body-Bias).
>> + *
>> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
>> + * recommendations from silicon team.
>> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
>> + * yet implemented.
>> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
>> + * to implement it yet.
> 
> Please consider adding a short section describing the function return 
> values (per Documentation/kernel-doc-nano-HOWTO.txt).

Good catch.  Forgot about that part.

>> + */
>> +int voltscale_adaptive_body_bias(unsigned long target_volt)
> 
> Since this code appears to be OMAP36xx-specific, please note that in the 
> function name.  Also this is VDD1-specific, so might be worth noting that 
> there as well.
> 
> It's probably worth splitting this single function up into init(), 
> enable(), disable(), and probably a _transition_poll() function.
> 
>> +{
>> +	u32 sr2en_enabled;
>> +	int timeout;
>> +	int sr2_wtcnt_value;
>> +
>> +	/* calculate SR2_WTCNT_VALUE settling time */
>> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
>> +			(clk_get_rate("sys_ck") / 1000000) / 8);
>> +
>> +	/* has SR2EN been enabled previously? */
>> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
>> +			OMAP3630_SR2EN);
> 
> The above code should be separated out into a function that is run once at 
> init.  (and then perhaps once every time these registers are changed - 
> will the ROM code touch these when entering or exiting off-mode?) No point 
> always executing this stuff for every OPP change if it only needs to be 
> done infrequently.  PRM accesses, especially reads, slow the ARM down, so 
> it's worthwhile avoiding them.

Yes, this is  a goof.  My original patch for the Android 2.6.29 kernel 
had the one-time setup stuff in prcm_setup_regs, wrapped in cpu_is_3630. 
  I can call an abb_init function there or just bang the registers directly.

>> +
>> +	/* select fast, nominal or slow OPP for ABB ldo */
>> +	/* FIXME: include OMAP4 once recommendations are complete */
>> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> 
> Please integrate this type of information into the OPP table or 
> somewhere similar, since this is SoC-specific configuration data.

This is a big question mark I think.  Check out Eduardo's review thread 
for more discussion on this.

>> +		/* program for fast opp - enable FBB */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> 
> Can you foresee a situation in which there would be multiple FBB-using 
> OPPs?  If so, it might be worth keeping track of the previous contents of 
> this register in RAM, to avoid the PRM accesses.

Yes, that is possible.

>> +		/* enable the ABB ldo if not done already */
>> +		if (!sr2en_enabled)
>> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
>> +					OMAP3430_GR_MOD,
>> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +	} else if (sr2en_enabled) {
>> +		/* program for nominal opp - bypass ABB ldo */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +	} else {
>> +		/* nothing to do here yet... might enable RBB here someday */
>> +		return 0;
>> +	}
>> +
>> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
>> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> 
> Can this be moved to init code?

Probably.  Don't think there is ever a time when we'll want to disable this.

> By the way, what is the hardware's exact definition of a 'fast 
> OPP'/'nominal OPP'/'slow OPP' ?

Fast OPP = FBB (forward body-bias)
Nominal OPP = bypass
Slow OPP = RBB (reverse body-bias)

>> +	/* program settling time of 30us for ABB ldo transition */
>> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
>> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> 
> Looks like this can also be moved to init code.

Agreed.

>> +
>> +	/* clear ABB ldo interrupt status */
>> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +			OCP_MOD,
>> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +
>> +	/* enable ABB LDO OPP change */
>> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +
>> +	timeout = 0;
>> +
>> +	/* wait until OPP change completes */
>> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
>> +			(!(prm_read_mod_reg(OCP_MOD,
>> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
>> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
> 
> I take it that this code is executing with interrupts disabled?
> 
> Can the ABB LDO interrupt just be disabled, and the 
> PRM_LDO_ABB_SETUP.OPP_CHANGE bit read to determine if the LDO change is 
> complete?  That might cut out some of the code that polls this TRANXDONE 
> interrupt, which seems hacky if reading OPP_CHANGE works.

I never set PRM_IRQENABLE_MPU.ABB_LDO_TRANXDONE_EN because we don't need 
an interrupt to sample PRM_IRQSTATUS_MPU.ABB_LDO_TRANXDONE_ST.  It seems 
wise to avoid the interrupt path if possible.

However you raise an interesting point.  The TRM does state that 
PRM_LDO_ABB_SETUP.OPP_CHANGE is automatically cleared by HW when the 
transition completes, so this bit should technically give us the same 
information as PRM_IRQSTATUS_MPU.ABB_LDO_TRANXDONE_ST.  I'll look into it.

>> +		udelay(1);
>> +		timeout++;
>> +	}
> 
> Will the ABB LDO always take 30us to transition if that is what was 
> programmed, or can it finish early?  If the former, then presumably this 
> loop timeout needs to be increased?

It can finish earlier, and often does.  Usually between 15-24us IIRC.

>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
> 
> Should be a WARN() instead since this should never happen.

OK.

>> +	timeout = 0;
>> +
>> +	/* Clear all pending TRANXDONE interrupts/status */
>> +	while (timeout < ABB_MAX_SETTLING_TIME) {
> 
> Can this interrupt status register really take 30 microseconds to clear?

Yeah this can probably die.  There are some quirks about 
prcm_interrupt_handler that I'm trying to solve here, but I think I'll 
follow that up with another patch soon instead of doing it this way.

>> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +				OCP_MOD,
>> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +		if (!(prm_read_mod_reg(OCP_MOD,
>> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
>> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
>> +			break;
>> +
>> +		udelay(1);
>> +		timeout++;
>> +	}
>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
> 
> Should be a WARN() instead since this should never happen.

OK.

>> +
>> +	return 0;
>> +}
>> +
>> +/**
>>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>>   *
>>   * This is a temporary placeholder for this API. This should ideally belong
>> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>>  					unsigned long current_volt)
>>  {
>> +	int ret;
>> +
> 
> 
> Is it safe to leave VDD1 FBB enabled while switching to a lower voltage?  
> If it is unknown, shouldn't there be a test here to determine whether the 
> voltage is going down, and disabling FBB in that case?

It is safe.  It is NOT safe to run at 1GHz without FBB enabled on 3630, 
so I think the current sequencing is fine in that we will always step 
the frequency down, then the voltage and finally bypass ABB.

Regards,
Mike

>>  	if (voltscale_vpforceupdate)
>> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
>> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>>  								current_volt);
>>  	else
>> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +
>> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
>> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
>> +		ret = voltscale_adaptive_body_bias(target_volt);
>> +
>> +	return ret;
>>  }
>>  
>>  /**
>> -- 
>> 1.6.3.2
>>
>> --
>> 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
>>
> 
> 
> - Paul


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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-21 21:21     ` Mike Turquette
@ 2010-04-22 13:56       ` Nishanth Menon
  2010-04-23  7:03         ` Eduardo Valentin
  0 siblings, 1 reply; 15+ messages in thread
From: Nishanth Menon @ 2010-04-22 13:56 UTC (permalink / raw)
  To: Turquette, Mike
  Cc: eduardo.valentin, ext Mike Turquette, linux-omap, Sripathy,
	Vishwanath, Gopinath, Thara, Gulati, Shweta, Kevin Hilman

Turquette, Mike had written, on 04/21/2010 04:21 PM, the following:
[...]

>>>  
>>>  /**
>>> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
>>> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
>>> + *
>>> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
>>> + * process.  ABB can boost voltage in high OPPs for silicon with weak
>>> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
>>> + * for silicon with strong characteristics (Reverse Body-Bias).
>>> + *
>>> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
>>> + * recommendations from silicon team.
>>> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
>>> + * yet implemented.
>>> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
>>> + * to implement it yet.
>>> + */
>>> +int voltscale_adaptive_body_bias(unsigned long target_volt)
>>> +{
>>> +	u32 sr2en_enabled;
>>> +	int timeout;
>>> +	int sr2_wtcnt_value;
>>> +
>>> +	/* calculate SR2_WTCNT_VALUE settling time */
>>> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
>>> +			(clk_get_rate("sys_ck") / 1000000) / 8);
>>> +
>>> +	/* has SR2EN been enabled previously? */
>>> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
>>> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
>>> +			OMAP3630_SR2EN);
>>> +
>>> +	/* select fast, nominal or slow OPP for ABB ldo */
>>> +	/* FIXME: include OMAP4 once recommendations are complete */
>>> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
>> You are creating two steps to decide if you apply or not FBB.
>> Here and also bellow (omap voltage scale). Would it make sense to bind it
>> per opp? I mean just a flag on opp dat then you apply or not based on that flag.
>> Same for RBB.
> 
> Eduardo,
> 
> Thanks for reviewing.
> 
> There has been some offline discussion about the best way to handle the 
> the relationship between FBB enable flags and OPPs:
> 
> 1) extend OPP table
> 2) piggyback on Thara's SR hwmod structures
> 	This probably won't work given Paul's review comments
> 3) other wacky stuff
> 
> After some discussion about the best way to do this I will definitely 
> lose the duplicate checks and replace with some nice table look-up.
> 
> Extending the OPP table is gross for OMAP2 and OMAP3430.  Piggybacking 
> on SR stuff is just a hack and there is no real relationship between ABB 
> ldo and SR.  The crux of the issue is how to relate FBB enable flags to 
> OPP table.  hwmod?  Ideas on this are very welcome.
> 
might be a good idea for using
I vote for 2) omap_volt_data in voltage.c and using the flag there.

1) is a bad idea as ABB is not present in older silicon and opp table 
should ideally be independent of silicon and contain only common data..

[...]

-- 
Regards,
Nishanth Menon

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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-22 13:56       ` Nishanth Menon
@ 2010-04-23  7:03         ` Eduardo Valentin
  0 siblings, 0 replies; 15+ messages in thread
From: Eduardo Valentin @ 2010-04-23  7:03 UTC (permalink / raw)
  To: ext Nishanth Menon
  Cc: Turquette, Mike, Valentin Eduardo (Nokia-D/Helsinki),
	ext Mike Turquette, linux-omap, Sripathy, Vishwanath, Gopinath,
	Thara, Gulati, Shweta, Kevin Hilman

On Thu, Apr 22, 2010 at 03:56:53PM +0200, ext Nishanth Menon wrote:
> Turquette, Mike had written, on 04/21/2010 04:21 PM, the following:
> [...]
> 
> >>>  
> >>>  /**
> >>> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
> >>> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
> >>> + *
> >>> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
> >>> + * process.  ABB can boost voltage in high OPPs for silicon with weak
> >>> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
> >>> + * for silicon with strong characteristics (Reverse Body-Bias).
> >>> + *
> >>> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
> >>> + * recommendations from silicon team.
> >>> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
> >>> + * yet implemented.
> >>> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
> >>> + * to implement it yet.
> >>> + */
> >>> +int voltscale_adaptive_body_bias(unsigned long target_volt)
> >>> +{
> >>> +	u32 sr2en_enabled;
> >>> +	int timeout;
> >>> +	int sr2_wtcnt_value;
> >>> +
> >>> +	/* calculate SR2_WTCNT_VALUE settling time */
> >>> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
> >>> +			(clk_get_rate("sys_ck") / 1000000) / 8);
> >>> +
> >>> +	/* has SR2EN been enabled previously? */
> >>> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
> >>> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
> >>> +			OMAP3630_SR2EN);
> >>> +
> >>> +	/* select fast, nominal or slow OPP for ABB ldo */
> >>> +	/* FIXME: include OMAP4 once recommendations are complete */
> >>> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> >> You are creating two steps to decide if you apply or not FBB.
> >> Here and also bellow (omap voltage scale). Would it make sense to bind it
> >> per opp? I mean just a flag on opp dat then you apply or not based on that flag.
> >> Same for RBB.
> > 
> > Eduardo,
> > 
> > Thanks for reviewing.
> > 
> > There has been some offline discussion about the best way to handle the 
> > the relationship between FBB enable flags and OPPs:
> > 
> > 1) extend OPP table
> > 2) piggyback on Thara's SR hwmod structures
> > 	This probably won't work given Paul's review comments
> > 3) other wacky stuff
> > 
> > After some discussion about the best way to do this I will definitely 
> > lose the duplicate checks and replace with some nice table look-up.
> > 
> > Extending the OPP table is gross for OMAP2 and OMAP3430.  Piggybacking 
> > on SR stuff is just a hack and there is no real relationship between ABB 
> > ldo and SR.  The crux of the issue is how to relate FBB enable flags to 
> > OPP table.  hwmod?  Ideas on this are very welcome.
> > 
> might be a good idea for using
> I vote for 2) omap_volt_data in voltage.c and using the flag there.

This was actually what I was also thinking. if you stick your flag on omap_volt_data
should be enough.

> 
> 1) is a bad idea as ABB is not present in older silicon and opp table 
> should ideally be independent of silicon and contain only common data..

indeed.

> 
> [...]
> 
> -- 
> Regards,
> Nishanth Menon

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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
  2010-04-19  7:46   ` Eduardo Valentin
  2010-04-20  5:42   ` Paul Walmsley
@ 2010-05-21 12:44   ` Eduardo Valentin
  2010-05-21 12:47     ` Eduardo Valentin
  2010-05-21 15:02     ` Mike Turquette
  2 siblings, 2 replies; 15+ messages in thread
From: Eduardo Valentin @ 2010-05-21 12:44 UTC (permalink / raw)
  To: ext Mike Turquette
  Cc: linux-omap, Vishwanath Sripathy, Thara Gopinath, Shweta Gulati,
	Nishanth Menon, Kevin Hilman, Mike Turquette

Hello Mike,

On Fri, Apr 16, 2010 at 11:33:22PM +0200, ext Mike Turquette wrote:
> Introduces voltscale_adaptive_body_bias function to voltage.c.
> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
> voltage transition has occured.  Currently voltscale_adaptive_body_bias
> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
> 1GHz or higher.  In the future Reverse Body-Bias might be included.
> 
> FBB is an Adaptive Body-Bias technique to boost performance for weak
> process devices at high OPPs. This results in voltage boost on the VDD1
> PMOS back gates when running at maximum OPP.  Current recommendations
> are to enable FBB on all 3630 regardless of silicon characteristics and
> EFUSE values.
> 
> ABB applies to all OMAP silicon based on 45nm process, which includes
> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
> to voltscale_adaptive_body_bias in the future.


What is not clear to me in this ABB activation is about the idle path.
At least, from your patch, it looks like it does care about ABB & system in idle state.

So, my question is, what is the recommendation if system idles in 1GHz OPP with FBB enabled?
Should we care to disable it by software and re-enable it while waking up?

Or is it somehow bound to SmartReflex activation (then your patch would rely to the fact that
SR is enabled & disabled before & after WFI)?

> 
> Signed-off-by: Mike Turquette <mturquette@ti.com>
> ---
>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 127 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index c2c8192..98d8bb3 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -37,6 +37,11 @@
>  #define VP_IDLE_TIMEOUT		200
>  #define VP_TRANXDONE_TIMEOUT	300
>  
> +#define ABB_MAX_SETTLING_TIME	30
> +#define ABB_FAST_OPP		1
> +#define ABB_NOMINAL_OPP		2
> +#define ABB_SLOW_OPP		3
> +
>  /**
>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>   * board data or PMIC data
> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>  }
>  
>  /**
> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
> + *
> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
> + * process.  ABB can boost voltage in high OPPs for silicon with weak
> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
> + * for silicon with strong characteristics (Reverse Body-Bias).
> + *
> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
> + * recommendations from silicon team.
> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
> + * yet implemented.
> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
> + * to implement it yet.
> + */
> +int voltscale_adaptive_body_bias(unsigned long target_volt)
> +{
> +	u32 sr2en_enabled;
> +	int timeout;
> +	int sr2_wtcnt_value;
> +
> +	/* calculate SR2_WTCNT_VALUE settling time */
> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
> +			(clk_get_rate("sys_ck") / 1000000) / 8);
> +
> +	/* has SR2EN been enabled previously? */
> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
> +			OMAP3630_SR2EN);
> +
> +	/* select fast, nominal or slow OPP for ABB ldo */
> +	/* FIXME: include OMAP4 once recommendations are complete */
> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> +		/* program for fast opp - enable FBB */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +
> +		/* enable the ABB ldo if not done already */
> +		if (!sr2en_enabled)
> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
> +					OMAP3430_GR_MOD,
> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +	} else if (sr2en_enabled) {
> +		/* program for nominal opp - bypass ABB ldo */
> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
> +				OMAP3430_GR_MOD,
> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +	} else {
> +		/* nothing to do here yet... might enable RBB here someday */
> +		return 0;
> +	}
> +
> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +
> +	/* program settling time of 30us for ABB ldo transition */
> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> +
> +	/* clear ABB ldo interrupt status */
> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +			OCP_MOD,
> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +
> +	/* enable ABB LDO OPP change */
> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
> +			OMAP3430_GR_MOD,
> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> +
> +	timeout = 0;
> +
> +	/* wait until OPP change completes */
> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
> +			(!(prm_read_mod_reg(OCP_MOD,
> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
> +		udelay(1);
> +		timeout++;
> +	}
> +
> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
> +
> +	timeout = 0;
> +
> +	/* Clear all pending TRANXDONE interrupts/status */
> +	while (timeout < ABB_MAX_SETTLING_TIME) {
> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> +				OCP_MOD,
> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> +		if (!(prm_read_mod_reg(OCP_MOD,
> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
> +			break;
> +
> +		udelay(1);
> +		timeout++;
> +	}
> +	if (timeout == ABB_MAX_SETTLING_TIME)
> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
> +
> +	return 0;
> +}
> +
> +/**
>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>   *
>   * This is a temporary placeholder for this API. This should ideally belong
> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>  					unsigned long current_volt)
>  {
> +	int ret;
> +
>  	if (voltscale_vpforceupdate)
> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>  								current_volt);
>  	else
> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> +
> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
> +		ret = voltscale_adaptive_body_bias(target_volt);
> +
> +	return ret;
>  }
>  
>  /**
> -- 
> 1.6.3.2
> 
> --
> 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] 15+ messages in thread

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-05-21 12:44   ` Eduardo Valentin
@ 2010-05-21 12:47     ` Eduardo Valentin
  2010-05-21 15:02     ` Mike Turquette
  1 sibling, 0 replies; 15+ messages in thread
From: Eduardo Valentin @ 2010-05-21 12:47 UTC (permalink / raw)
  To: Valentin Eduardo (Nokia-D/Helsinki)
  Cc: ext Mike Turquette, linux-omap, Vishwanath Sripathy,
	Thara Gopinath, Shweta Gulati, Nishanth Menon, Kevin Hilman,
	Mike Turquette

On Fri, May 21, 2010 at 02:44:54PM +0200, Valentin Eduardo (Nokia-D/Helsinki) wrote:
> Hello Mike,
> 
> On Fri, Apr 16, 2010 at 11:33:22PM +0200, ext Mike Turquette wrote:
> > Introduces voltscale_adaptive_body_bias function to voltage.c.
> > voltscale_adaptive_body_bias is called by omap_voltage_scale after a
> > voltage transition has occured.  Currently voltscale_adaptive_body_bias
> > only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
> > 1GHz or higher.  In the future Reverse Body-Bias might be included.
> > 
> > FBB is an Adaptive Body-Bias technique to boost performance for weak
> > process devices at high OPPs. This results in voltage boost on the VDD1
> > PMOS back gates when running at maximum OPP.  Current recommendations
> > are to enable FBB on all 3630 regardless of silicon characteristics and
> > EFUSE values.
> > 
> > ABB applies to all OMAP silicon based on 45nm process, which includes
> > OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
> > to voltscale_adaptive_body_bias in the future.
> 
> 
> What is not clear to me in this ABB activation is about the idle path.
> At least, from your patch, it looks like it does care about ABB & system in idle state.

I mean, I could NOT find anything regarding idle state handling in your patch.

> 
> So, my question is, what is the recommendation if system idles in 1GHz OPP with FBB enabled?
> Should we care to disable it by software and re-enable it while waking up?
> 
> Or is it somehow bound to SmartReflex activation (then your patch would rely to the fact that
> SR is enabled & disabled before & after WFI)?
> 
> > 
> > Signed-off-by: Mike Turquette <mturquette@ti.com>
> > ---
> >  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
> >  1 files changed, 127 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> > index c2c8192..98d8bb3 100644
> > --- a/arch/arm/mach-omap2/voltage.c
> > +++ b/arch/arm/mach-omap2/voltage.c
> > @@ -37,6 +37,11 @@
> >  #define VP_IDLE_TIMEOUT		200
> >  #define VP_TRANXDONE_TIMEOUT	300
> >  
> > +#define ABB_MAX_SETTLING_TIME	30
> > +#define ABB_FAST_OPP		1
> > +#define ABB_NOMINAL_OPP		2
> > +#define ABB_SLOW_OPP		3
> > +
> >  /**
> >   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
> >   * board data or PMIC data
> > @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
> >  }
> >  
> >  /**
> > + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
> > + * @target_volt: target voltage determines if ABB ldo is active or bypassed
> > + *
> > + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
> > + * process.  ABB can boost voltage in high OPPs for silicon with weak
> > + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
> > + * for silicon with strong characteristics (Reverse Body-Bias).
> > + *
> > + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
> > + * recommendations from silicon team.
> > + * Reverse Body-Bias for saving power in active cases and sleep cases is not
> > + * yet implemented.
> > + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
> > + * to implement it yet.
> > + */
> > +int voltscale_adaptive_body_bias(unsigned long target_volt)
> > +{
> > +	u32 sr2en_enabled;
> > +	int timeout;
> > +	int sr2_wtcnt_value;
> > +
> > +	/* calculate SR2_WTCNT_VALUE settling time */
> > +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
> > +			(clk_get_rate("sys_ck") / 1000000) / 8);
> > +
> > +	/* has SR2EN been enabled previously? */
> > +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
> > +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
> > +			OMAP3630_SR2EN);
> > +
> > +	/* select fast, nominal or slow OPP for ABB ldo */
> > +	/* FIXME: include OMAP4 once recommendations are complete */
> > +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> > +		/* program for fast opp - enable FBB */
> > +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> > +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
> > +				OMAP3430_GR_MOD,
> > +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> > +
> > +		/* enable the ABB ldo if not done already */
> > +		if (!sr2en_enabled)
> > +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
> > +					OMAP3430_GR_MOD,
> > +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> > +	} else if (sr2en_enabled) {
> > +		/* program for nominal opp - bypass ABB ldo */
> > +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> > +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
> > +				OMAP3430_GR_MOD,
> > +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> > +	} else {
> > +		/* nothing to do here yet... might enable RBB here someday */
> > +		return 0;
> > +	}
> > +
> > +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
> > +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
> > +			OMAP3430_GR_MOD,
> > +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> > +
> > +	/* program settling time of 30us for ABB ldo transition */
> > +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
> > +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
> > +			OMAP3430_GR_MOD,
> > +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> > +
> > +	/* clear ABB ldo interrupt status */
> > +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> > +			OCP_MOD,
> > +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> > +
> > +	/* enable ABB LDO OPP change */
> > +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
> > +			OMAP3430_GR_MOD,
> > +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> > +
> > +	timeout = 0;
> > +
> > +	/* wait until OPP change completes */
> > +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
> > +			(!(prm_read_mod_reg(OCP_MOD,
> > +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
> > +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
> > +		udelay(1);
> > +		timeout++;
> > +	}
> > +
> > +	if (timeout == ABB_MAX_SETTLING_TIME)
> > +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
> > +
> > +	timeout = 0;
> > +
> > +	/* Clear all pending TRANXDONE interrupts/status */
> > +	while (timeout < ABB_MAX_SETTLING_TIME) {
> > +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> > +				OCP_MOD,
> > +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> > +		if (!(prm_read_mod_reg(OCP_MOD,
> > +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
> > +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
> > +			break;
> > +
> > +		udelay(1);
> > +		timeout++;
> > +	}
> > +	if (timeout == ABB_MAX_SETTLING_TIME)
> > +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> >   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
> >   *
> >   * This is a temporary placeholder for this API. This should ideally belong
> > @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
> >  int omap_voltage_scale(int vdd, unsigned long target_volt,
> >  					unsigned long current_volt)
> >  {
> > +	int ret;
> > +
> >  	if (voltscale_vpforceupdate)
> > -		return vp_forceupdate_scale_voltage(vdd, target_volt,
> > +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
> >  								current_volt);
> >  	else
> > -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> > +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> > +
> > +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
> > +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
> > +		ret = voltscale_adaptive_body_bias(target_volt);
> > +
> > +	return ret;
> >  }
> >  
> >  /**
> > -- 
> > 1.6.3.2
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-05-21 12:44   ` Eduardo Valentin
  2010-05-21 12:47     ` Eduardo Valentin
@ 2010-05-21 15:02     ` Mike Turquette
  2010-05-21 16:30       ` Eduardo Valentin
  1 sibling, 1 reply; 15+ messages in thread
From: Mike Turquette @ 2010-05-21 15:02 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: ext Mike Turquette, linux-omap, Sripathy, Vishwanath, Gopinath,
	Thara, Gulati, Shweta, Menon, Nishanth, Kevin Hilman

Eduardo Valentin wrote:
> Hello Mike,
> 
> On Fri, Apr 16, 2010 at 11:33:22PM +0200, ext Mike Turquette wrote:
>> Introduces voltscale_adaptive_body_bias function to voltage.c.
>> voltscale_adaptive_body_bias is called by omap_voltage_scale after a
>> voltage transition has occured.  Currently voltscale_adaptive_body_bias
>> only implements Forward Body-Bias (FBB) for OMAP3630 when MPU runs at
>> 1GHz or higher.  In the future Reverse Body-Bias might be included.
>>
>> FBB is an Adaptive Body-Bias technique to boost performance for weak
>> process devices at high OPPs. This results in voltage boost on the VDD1
>> PMOS back gates when running at maximum OPP.  Current recommendations
>> are to enable FBB on all 3630 regardless of silicon characteristics and
>> EFUSE values.
>>
>> ABB applies to all OMAP silicon based on 45nm process, which includes
>> OMAP4.  OMAP4 recommendations for ABB are not complete and will be added
>> to voltscale_adaptive_body_bias in the future.
> 
> 
> What is not clear to me in this ABB activation is about the idle path.
> At least, from your patch, it looks like it does care about ABB & system in idle state.
> 
> So, my question is, what is the recommendation if system idles in 1GHz OPP with FBB enabled?
> Should we care to disable it by software and re-enable it while waking up?

The recommendation for 3630 is to always have FBB enabled at 1GHz or 
higher on the ARM.  This includes idle states.  There was some internal 
discussion about disabling FBB around idle, but the decision was to 
leave it enabled due to stability issues when running at high OPPs. 
This increases leakage during idle, but not significantly I'm told.  I 
haven't measured the delta in idle caused by this.

For OMAP4 recommendations might be to disable around idle path.  My V2 
patchset (will publish next week) breaks this code up into enable_fbb() 
disable_fbb() functions which makes this sort of thing easy.

> Or is it somehow bound to SmartReflex activation (then your patch would rely to the fact that
> SR is enabled & disabled before & after WFI)?

No, it does not mirror SR explicitly and this is intentional due to 
stability issues mentioned above.

Regards,
Mike

>> Signed-off-by: Mike Turquette <mturquette@ti.com>
>> ---
>>  arch/arm/mach-omap2/voltage.c |  129 ++++++++++++++++++++++++++++++++++++++++-
>>  1 files changed, 127 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
>> index c2c8192..98d8bb3 100644
>> --- a/arch/arm/mach-omap2/voltage.c
>> +++ b/arch/arm/mach-omap2/voltage.c
>> @@ -37,6 +37,11 @@
>>  #define VP_IDLE_TIMEOUT		200
>>  #define VP_TRANXDONE_TIMEOUT	300
>>  
>> +#define ABB_MAX_SETTLING_TIME	30
>> +#define ABB_FAST_OPP		1
>> +#define ABB_NOMINAL_OPP		2
>> +#define ABB_SLOW_OPP		3
>> +
>>  /**
>>   * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
>>   * board data or PMIC data
>> @@ -635,6 +640,118 @@ static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
>>  }
>>  
>>  /**
>> + * voltscale_adaptive_body_bias - controls ABB ldo during voltage scaling
>> + * @target_volt: target voltage determines if ABB ldo is active or bypassed
>> + *
>> + * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
>> + * process.  ABB can boost voltage in high OPPs for silicon with weak
>> + * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
>> + * for silicon with strong characteristics (Reverse Body-Bias).
>> + *
>> + * Only Foward Body-Bias for operating at high OPPs is implemented below, per
>> + * recommendations from silicon team.
>> + * Reverse Body-Bias for saving power in active cases and sleep cases is not
>> + * yet implemented.
>> + * OMAP4 hardward also supports ABB ldo, but no recommendations have been made
>> + * to implement it yet.
>> + */
>> +int voltscale_adaptive_body_bias(unsigned long target_volt)
>> +{
>> +	u32 sr2en_enabled;
>> +	int timeout;
>> +	int sr2_wtcnt_value;
>> +
>> +	/* calculate SR2_WTCNT_VALUE settling time */
>> +	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME *
>> +			(clk_get_rate("sys_ck") / 1000000) / 8);
>> +
>> +	/* has SR2EN been enabled previously? */
>> +	sr2en_enabled = (prm_read_mod_reg(OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_CTRL_OFFSET) &
>> +			OMAP3630_SR2EN);
>> +
>> +	/* select fast, nominal or slow OPP for ABB ldo */
>> +	/* FIXME: include OMAP4 once recommendations are complete */
>> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
>> +		/* program for fast opp - enable FBB */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +
>> +		/* enable the ABB ldo if not done already */
>> +		if (!sr2en_enabled)
>> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
>> +					OMAP3430_GR_MOD,
>> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +	} else if (sr2en_enabled) {
>> +		/* program for nominal opp - bypass ABB ldo */
>> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
>> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
>> +				OMAP3430_GR_MOD,
>> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +	} else {
>> +		/* nothing to do here yet... might enable RBB here someday */
>> +		return 0;
>> +	}
>> +
>> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
>> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +
>> +	/* program settling time of 30us for ABB ldo transition */
>> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
>> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
>> +
>> +	/* clear ABB ldo interrupt status */
>> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +			OCP_MOD,
>> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +
>> +	/* enable ABB LDO OPP change */
>> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
>> +			OMAP3430_GR_MOD,
>> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
>> +
>> +	timeout = 0;
>> +
>> +	/* wait until OPP change completes */
>> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
>> +			(!(prm_read_mod_reg(OCP_MOD,
>> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
>> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
>> +		udelay(1);
>> +		timeout++;
>> +	}
>> +
>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
>> +
>> +	timeout = 0;
>> +
>> +	/* Clear all pending TRANXDONE interrupts/status */
>> +	while (timeout < ABB_MAX_SETTLING_TIME) {
>> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
>> +				OCP_MOD,
>> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
>> +		if (!(prm_read_mod_reg(OCP_MOD,
>> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
>> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
>> +			break;
>> +
>> +		udelay(1);
>> +		timeout++;
>> +	}
>> +	if (timeout == ABB_MAX_SETTLING_TIME)
>> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
>>   *
>>   * This is a temporary placeholder for this API. This should ideally belong
>> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
>>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>>  					unsigned long current_volt)
>>  {
>> +	int ret;
>> +
>>  	if (voltscale_vpforceupdate)
>> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
>> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
>>  								current_volt);
>>  	else
>> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
>> +
>> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
>> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
>> +		ret = voltscale_adaptive_body_bias(target_volt);
>> +
>> +	return ret;
>>  }
>>  
>>  /**
>> -- 
>> 1.6.3.2
>>
>> --
>> 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] 15+ messages in thread

* Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
  2010-05-21 15:02     ` Mike Turquette
@ 2010-05-21 16:30       ` Eduardo Valentin
  0 siblings, 0 replies; 15+ messages in thread
From: Eduardo Valentin @ 2010-05-21 16:30 UTC (permalink / raw)
  To: ext Mike Turquette
  Cc: Valentin Eduardo (Nokia-D/Helsinki),
	ext Mike Turquette, linux-omap, Sripathy, Vishwanath, Gopinath,
	Thara, Gulati, Shweta, Menon, Nishanth, Kevin Hilman,
	Jouni Hogander

Hello Mike,

On Fri, May 21, 2010 at 05:02:11PM +0200, ext Mike Turquette wrote:
> Eduardo Valentin wrote:
> > Hello Mike,
> > 
> > 
> > What is not clear to me in this ABB activation is about the idle path.
> > At least, from your patch, it looks like it does care about ABB & system in idle state.
> > 
> > So, my question is, what is the recommendation if system idles in 1GHz OPP with FBB enabled?
> > Should we care to disable it by software and re-enable it while waking up?
> 
> The recommendation for 3630 is to always have FBB enabled at 1GHz or 
> higher on the ARM.  This includes idle states.  There was some internal 
> discussion about disabling FBB around idle, but the decision was to 
> leave it enabled due to stability issues when running at high OPPs. 
> This increases leakage during idle, but not significantly I'm told.  I 
> haven't measured the delta in idle caused by this.


Right. I also expect that it will increase the leakage current during idle.
In this case, I think the beast becomes more interesting. So, better to understand it.

It is worth to know the estimated leakage caused by this feature, as in a normal system,
the idle case should be the one in use in most of the time.


> 
> For OMAP4 recommendations might be to disable around idle path.  My V2 
> patchset (will publish next week) breaks this code up into enable_fbb() 
> disable_fbb() functions which makes this sort of thing easy.
> 
> > Or is it somehow bound to SmartReflex activation (then your patch would rely to the fact that
> > SR is enabled & disabled before & after WFI)?
> 
> No, it does not mirror SR explicitly and this is intentional due to 
> stability issues mentioned above.
> 
> Regards,
> Mike
> 
> >> Signed-off-by: Mike Turquette <mturquette@ti.com>

...

> >> +	if (cpu_is_omap3630() && (target_volt >= 1350000)) {
> >> +		/* program for fast opp - enable FBB */
> >> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> >> +				(ABB_FAST_OPP << OMAP3630_OPP_SEL_SHIFT),
> >> +				OMAP3430_GR_MOD,
> >> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);

Then, the next question is obviously if the hw is smart enough to do not generate
leakage if idle in other OPPs. I mean, will FBB be bound only to 1GHz after this configuration?
For instance, are we going to gain extra leakage if:

1. System decides to go to 1GHz
2. FBB joins the fun
3. System decides to go to lower opp



> >> +
> >> +		/* enable the ABB ldo if not done already */
> >> +		if (!sr2en_enabled)
> >> +			prm_set_mod_reg_bits(OMAP3630_SR2EN,
> >> +					OMAP3430_GR_MOD,
> >> +					OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> >> +	} else if (sr2en_enabled) {
> >> +		/* program for nominal opp - bypass ABB ldo */
> >> +		prm_rmw_mod_reg_bits(OMAP3630_OPP_SEL_MASK,
> >> +				(ABB_NOMINAL_OPP << OMAP3630_OPP_SEL_SHIFT),
> >> +				OMAP3430_GR_MOD,
> >> +				OMAP3_PRM_LDO_ABB_SETUP_OFFSET);


If this part disables the thing, then while going to lower opp should not increase leakage.
Otherwise, would be nice to think in something to avoid that. Maybe lowering opp before entering idle,
if going from 1GHz to idle :(


Of course that, depending on the governor in use, usually we lower opp before going to idle..
But transition from 1GHz to idle is still possible. That's why having some numbers of estimated
leakage is important.

> >> +	} else {
> >> +		/* nothing to do here yet... might enable RBB here someday */
> >> +		return 0;
> >> +	}
> >> +
> >> +	/* set ACTIVE_FBB_SEL for all 45nm silicon */
> >> +	prm_set_mod_reg_bits(OMAP3630_ACTIVE_FBB_SEL,
> >> +			OMAP3430_GR_MOD,
> >> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> >> +
> >> +	/* program settling time of 30us for ABB ldo transition */
> >> +	prm_rmw_mod_reg_bits(OMAP3630_SR2_WTCNT_VALUE_MASK,
> >> +			(sr2_wtcnt_value << OMAP3630_SR2_WTCNT_VALUE_SHIFT),
> >> +			OMAP3430_GR_MOD,
> >> +			OMAP3_PRM_LDO_ABB_CTRL_OFFSET);
> >> +
> >> +	/* clear ABB ldo interrupt status */
> >> +	prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> >> +			OCP_MOD,
> >> +			OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> >> +
> >> +	/* enable ABB LDO OPP change */
> >> +	prm_set_mod_reg_bits(OMAP3630_OPP_CHANGE,
> >> +			OMAP3430_GR_MOD,
> >> +			OMAP3_PRM_LDO_ABB_SETUP_OFFSET);
> >> +
> >> +	timeout = 0;
> >> +
> >> +	/* wait until OPP change completes */
> >> +	while ((timeout < ABB_MAX_SETTLING_TIME ) &&
> >> +			(!(prm_read_mod_reg(OCP_MOD,
> >> +					    OMAP2_PRCM_IRQSTATUS_MPU_OFFSET) &
> >> +			   OMAP3630_ABB_LDO_TRANXDONE_ST))) {
> >> +		udelay(1);
> >> +		timeout++;
> >> +	}
> >> +
> >> +	if (timeout == ABB_MAX_SETTLING_TIME)
> >> +		pr_debug("ABB: TRANXDONE timed out waiting for OPP change\n");
> >> +
> >> +	timeout = 0;
> >> +
> >> +	/* Clear all pending TRANXDONE interrupts/status */
> >> +	while (timeout < ABB_MAX_SETTLING_TIME) {
> >> +		prm_write_mod_reg(OMAP3630_ABB_LDO_TRANXDONE_ST,
> >> +				OCP_MOD,
> >> +				OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
> >> +		if (!(prm_read_mod_reg(OCP_MOD,
> >> +						OMAP2_PRCM_IRQSTATUS_MPU_OFFSET)
> >> +					& OMAP3630_ABB_LDO_TRANXDONE_ST))
> >> +			break;
> >> +
> >> +		udelay(1);
> >> +		timeout++;
> >> +	}
> >> +	if (timeout == ABB_MAX_SETTLING_TIME)
> >> +		pr_debug("ABB: TRANXDONE timed out trying to clear status\n");
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +/**
> >>   * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
> >>   *
> >>   * This is a temporary placeholder for this API. This should ideally belong
> >> @@ -758,11 +875,19 @@ void omap_voltageprocessor_disable(int vp_id)
> >>  int omap_voltage_scale(int vdd, unsigned long target_volt,
> >>  					unsigned long current_volt)
> >>  {
> >> +	int ret;
> >> +
> >>  	if (voltscale_vpforceupdate)
> >> -		return vp_forceupdate_scale_voltage(vdd, target_volt,
> >> +		ret = vp_forceupdate_scale_voltage(vdd, target_volt,
> >>  								current_volt);
> >>  	else
> >> -		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> >> +		ret = vc_bypass_scale_voltage(vdd, target_volt, current_volt);
> >> +
> >> +	/* FIXME OMAP4 needs ABB too; recommendations not yet complete */
> >> +	if (ret && (cpu_is_omap3630() && vdd == VDD1))
> >> +		ret = voltscale_adaptive_body_bias(target_volt);
> >> +
> >> +	return ret;
> >>  }
> >>  
> >>  /**
> >> -- 
> >> 1.6.3.2
> >>
> >> --
> >> 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] 15+ messages in thread

end of thread, other threads:[~2010-05-21 16:25 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16 21:33 [PATCH 0/4] OMAP: PM: introduce Adaptive Body-Bias LDO Mike Turquette
2010-04-16 21:33 ` [PATCH 1/3] OMAP: PM: update PRM registers for ABB Mike Turquette
2010-04-19 21:23   ` Paul Walmsley
2010-04-16 21:33 ` [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G Mike Turquette
2010-04-19  7:46   ` Eduardo Valentin
2010-04-21 21:21     ` Mike Turquette
2010-04-22 13:56       ` Nishanth Menon
2010-04-23  7:03         ` Eduardo Valentin
2010-04-20  5:42   ` Paul Walmsley
2010-04-21 22:13     ` Mike Turquette
2010-05-21 12:44   ` Eduardo Valentin
2010-05-21 12:47     ` Eduardo Valentin
2010-05-21 15:02     ` Mike Turquette
2010-05-21 16:30       ` Eduardo Valentin
2010-04-16 21:33 ` [PATCH 3/3] HACK: OMAP3630: PM: allow testing of DVFS & FBB Mike Turquette

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.