linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mike Turquette <mturquette@ti.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: Mike Turquette <mturquette@gmail.com>,
	"eduardo.valentin@nokia.com" <eduardo.valentin@nokia.com>,
	"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
	"Sripathy, Vishwanath" <vishwanath.bs@ti.com>,
	"Gopinath, Thara" <thara@ti.com>,
	"Gulati, Shweta" <shweta.gulati@ti.com>,
	"Menon, Nishanth" <nm@ti.com>,
	Kevin Hilman <khilman@deeprootsystems.com>
Subject: Re: [PATCH 2/3] OMAP3630: PM: implement Foward Body-Bias for OPP1G
Date: Wed, 21 Apr 2010 17:13:30 -0500	[thread overview]
Message-ID: <4BCF788A.9080003@ti.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1004192257510.23407@utopia.booyaka.com>

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


  reply	other threads:[~2010-04-21 22:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BCF788A.9080003@ti.com \
    --to=mturquette@ti.com \
    --cc=eduardo.valentin@nokia.com \
    --cc=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=mturquette@gmail.com \
    --cc=nm@ti.com \
    --cc=paul@pwsan.com \
    --cc=shweta.gulati@ti.com \
    --cc=thara@ti.com \
    --cc=vishwanath.bs@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).