public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
From: Jon Hunter <jon-hunter@ti.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-omap <linux-omap@vger.kernel.org>,
	"Cousson, Benoit" <b-cousson@ti.com>
Subject: Re: [PATCH] OMAP: Fix configuration of J-Type DPLLs to work for OMAP3 and OMAP4
Date: Mon, 20 Dec 2010 09:05:00 -0600	[thread overview]
Message-ID: <4D0F709C.3010904@ti.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1012180304080.16875@utopia.booyaka.com>

On 12/18/2010 4:08 AM, Paul Walmsley wrote:
> Hello Jon
>
> On Fri, 17 Dec 2010, Jon Hunter wrote:
>
>> From: Jon Hunter<jon-hunter@ti.com>
>>
>> J-Type DPLLs have additional configuration parameters that need to
>> be programmed when setting the multipler and divider for the DPLL.
>> These parameters being the sigma delta divider (SD_DIV) for the DPLL
>> and the digital controlled oscillator (DCO) to be used by the DPLL.
>>
>> The current code is implemented specifically to configure the
>> OMAP3630 PER J-Type DPLL. The OMAP4430 USB DPLL is also a J-Type DPLL
>> and so this code needs to be updated to work for both OMAP3 and OMAP4
>> devices and any other future devices that have J-TYPE DPLLs.
>>
>> For the OMAP3630 PER DPLL both the SD_DIV and DCO paramenters are
>> used but for the OMAP4430 USB DPLL only the SD_DIV field is used.
>> The current implementation will only program the SD_DIV and DCO
>> fields if the DPLL has both and hence this does not work for
>> OMAP4430.
>>
>> In order to make the code more generic add two new fields to the
>> dpll_data structure for the SD_DIV field and DCO field bit-masks
>> and only program these fields if the masks are defined for a specific
>> DPLL. This simplifies the code and allows us to remove the flag
>> DPLL_NO_DCO_SEL.
>
> Has this patch been tested on both OMAP36xx and OMAP4 ?

Yes, I performed a quick validation on both OMAP36xx Zoom3 and OMAP4 
Blaze to make sure the values are calculated correctly and I see the 
expected result in the register.

>> Signed-off-by: Jon Hunter<jon-hunter@ti.com>
>> ---
>>   arch/arm/mach-omap2/clock.h             |    1 -
>>   arch/arm/mach-omap2/clock3xxx_data.c    |    2 +
>>   arch/arm/mach-omap2/clock44xx_data.c    |    3 +-
>>   arch/arm/mach-omap2/dpll3xxx.c          |   53 +++++++++++++++++++-----------
>>   arch/arm/plat-omap/include/plat/clock.h |    5 ++-
>>   5 files changed, 40 insertions(+), 24 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
>> index a535c7a..896584e 100644
>> --- a/arch/arm/mach-omap2/clock.h
>> +++ b/arch/arm/mach-omap2/clock.h
>> @@ -49,7 +49,6 @@
>>
>>   /* DPLL Type and DCO Selection Flags */
>>   #define DPLL_J_TYPE		0x1
>> -#define DPLL_NO_DCO_SEL		0x2
>>
>>   int omap2_clk_enable(struct clk *clk);
>>   void omap2_clk_disable(struct clk *clk);
>> diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
>> index 0579604..461b1ca 100644
> Any reason why you're removing this comment?
>> --- a/arch/arm/mach-omap2/clock3xxx_data.c
>> +++ b/arch/arm/mach-omap2/clock3xxx_data.c
>> @@ -602,6 +602,8 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
>>   	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
>>   	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
>>   	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
>> +	.dco_mask	= OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
>> +	.sddiv_mask	= OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
>>   	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
>>   	.min_divider	= 1,
>>   	.max_divider	= OMAP3_MAX_DPLL_DIV,
>> diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
>> index bfcd19f..cef179e 100644
>> --- a/arch/arm/mach-omap2/clock44xx_data.c
>> +++ b/arch/arm/mach-omap2/clock44xx_data.c
>> @@ -913,7 +913,7 @@ static struct clk usb_hs_clk_div_ck = {
>>   static struct dpll_data dpll_usb_dd = {
>>   	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_USB,
>>   	.clk_bypass	=&usb_hs_clk_div_ck,
>> -	.flags		= DPLL_J_TYPE | DPLL_NO_DCO_SEL,
>> +	.flags		= DPLL_J_TYPE,
>>   	.clk_ref	=&sys_clkin_ck,
>>   	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_USB,
>>   	.modes		= (1<<  DPLL_LOW_POWER_BYPASS) | (1<<  DPLL_LOCKED),
>> @@ -924,6 +924,7 @@ static struct dpll_data dpll_usb_dd = {
>>   	.enable_mask	= OMAP4430_DPLL_EN_MASK,
>>   	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
>>   	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
>> +	.sddiv_mask	= OMAP4430_DPLL_SD_DIV_MASK,
>>   	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
>>   	.max_divider	= OMAP4430_MAX_DPLL_DIV,
>>   	.min_divider	= 1,
>> diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
>> index ed8d330..48df8e4 100644
>> --- a/arch/arm/mach-omap2/dpll3xxx.c
>> +++ b/arch/arm/mach-omap2/dpll3xxx.c
>> @@ -225,23 +225,18 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
>>   }
>>
>>   /**
>> - * lookup_dco_sddiv -  Set j-type DPLL4 compensation variables
>> + * lookup_dco - Lookup DCO used by j-type DPLL
>>    * @clk: pointer to a DPLL struct clk
>>    * @dco: digital control oscillator selector
>> - * @sd_div: target sigma-delta divider
>>    * @m: DPLL multiplier to set
>>    * @n: DPLL divider to set
>>    *
>>    * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
>>    *
>> - * XXX This code is not needed for 3430/AM35xx; can it be optimized
>> - * out in non-multi-OMAP builds for those chips?
>
> Any reason why you're removing this comment?

My thought here was that with this change the code will only be called 
for DPLLs that have the sddiv_offset and dco_offset members set and so 
this will take care of all OMAP3 devices. In other words, it will not be 
called for OMAP34xx/AM35xx devices because these devices *should* not 
set these fields.

However, now I see that the point of this comment was to remove these 
functions from the build altogether for OMAP34xx based devices so it is 
not built into the kernel image. I am not sure how this could be 
achieved for a multi-omap2 build if you need to support both omap34xx, 
omap36xx and omap4 devices in the same build.

We don't need to remove the comments if you prefer, I was attempting a 
general clean-up of the code.

>>    */
>> -static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
>> -			     u8 n)
>> +static inline void lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
>>   {
>> -	unsigned long fint, clkinp, sd; /* watch out for overflow */
>> -	int mod1, mod2;
>> +	unsigned long fint, clkinp; /* watch out for overflow */
>>
>>   	clkinp = clk->parent->rate;
>>   	fint = (clkinp / n) * m;
>> @@ -250,6 +245,25 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
>>   		*dco = 2;
>>   	else
>>   		*dco = 4;
>> +}
>> +
>> +/**
>> + * lookup_sddiv - Calculate sigma delta divider for j-type DPLL
>> + * @clk: pointer to a DPLL struct clk
>> + * @sd_div: target sigma-delta divider
>> + * @m: DPLL multiplier to set
>> + * @n: DPLL divider to set
>> + *
>> + * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
>> + *
>> + */
>> +static inline void lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
>> +{
>> +	unsigned long clkinp, sd; /* watch out for overflow */
>> +	int mod1, mod2;
>> +
>> +	clkinp = clk->parent->rate;
>> +
>>   	/*
>>   	 * target sigma-delta to near 250MHz
>>   	 * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
>> @@ -278,6 +292,7 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
>>   static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
>>   {
>>   	struct dpll_data *dd = clk->dpll_data;
>> +	u8 dco, sd_div;
>>   	u32 v;
>>
>>   	/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
>> @@ -300,18 +315,16 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
>>   	v |= m<<  __ffs(dd->mult_mask);
>>   	v |= (n - 1)<<  __ffs(dd->div1_mask);
>>
>> -	/*
>> -	 * XXX This code is not needed for 3430/AM35XX; can it be optimized
>> -	 * out in non-multi-OMAP builds for those chips?
>> -	 */
>> -	if ((dd->flags&  DPLL_J_TYPE)&&  !(dd->flags&  DPLL_NO_DCO_SEL)) {
>> -		u8 dco, sd_div;
>> -		lookup_dco_sddiv(clk,&dco,&sd_div, m, n);
>> -		/* XXX This probably will need revision for OMAP4 */
>> -		v&= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK
>> -			| OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
>> -		v |= dco<<  __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK);
>> -		v |= sd_div<<  __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
>> +	/* Configure dco and sd_div for dplls that have these fields */
>> +	if (dd->dco_mask) {
>> +		lookup_dco(clk,&dco, m, n);
>> +		v&= ~(dd->dco_mask);
>> +		v |= dco<<  __ffs(dd->dco_mask);
>> +	}
>> +	if (dd->sddiv_mask) {
>> +		lookup_sddiv(clk,&sd_div, m, n);
>> +		v&= ~(dd->sddiv_mask);
>> +		v |= sd_div<<  __ffs(dd->sddiv_mask);
>>   	}
>>
>>   	__raw_writel(v, dd->mult_div1_reg);
>> diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
>> index fef4696..51badf9 100644
>> --- a/arch/arm/plat-omap/include/plat/clock.h
>> +++ b/arch/arm/plat-omap/include/plat/clock.h
>> @@ -119,8 +119,7 @@ struct clksel {
>>    *
>>    * Possible values for @flags:
>>    * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
>> - * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs)
>> -
>> + *
>>    * @freqsel_mask is only used on the OMAP34xx family and AM35xx.
>>    *
>>    * XXX Some DPLLs have multiple bypass inputs, so it's not technically
>> @@ -156,6 +155,8 @@ struct dpll_data {
>>   	u32			autoidle_mask;
>>   	u32			freqsel_mask;
>>   	u32			idlest_mask;
>> +	u32			dco_mask;
>> +	u32			sddiv_mask;
>>   	u8			auto_recal_bit;
>>   	u8			recal_en_bit;
>>   	u8			recal_st_bit;
>> --
>> 1.7.1
>
> The rest looks fine to me; I will probably prefix the function names with
> underscores, also I will plan drop the 'inline' and let the compiler deal
> with that.  Any objections to that?

Nope, sounds great. Thanks for the feedback.

Cheers
Jon

  reply	other threads:[~2010-12-20 15:05 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-17 20:31 [PATCH] OMAP: Fix configuration of J-Type DPLLs to work for OMAP3 and OMAP4 Jon Hunter
2010-12-18 10:08 ` Paul Walmsley
2010-12-20 15:05   ` Jon Hunter [this message]
2010-12-22  0:09     ` Paul Walmsley
2010-12-22  0:22       ` Paul Walmsley
2010-12-22  0:26         ` Paul Walmsley

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=4D0F709C.3010904@ti.com \
    --to=jon-hunter@ti.com \
    --cc=b-cousson@ti.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.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