Hello Jon

On Fri, 17 Dec 2010, Jon Hunter wrote:

> From: Jon Hunter <[email protected]>
> 
> 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 ?

> Signed-off-by: Jon Hunter <[email protected]>
> ---
>  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?

>   */
> -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?


- Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to