RE: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Paul Walmsley [mailto:paul@xxxxxxxxx]
> Sent: Tuesday, January 19, 2010 11:39 PM
> To: Turquette, Mike
> Cc: Kauppi Ari (EXT-Ixonos/Oulu); G.N, Vijayakumar; linux-omap@xxxxxxxxxxxxxxx;
> khilman@xxxxxxxxxxxxxxxxxxx; Sripathy, Vishwanath
> Subject: Re: [PATCHV2 2/2] OMAP3630: Clock: Fixing HSDivider Limitation
> 
> Hi,
> 
> On Tue, 19 Jan 2010, Mike Turquette wrote:
> 
> > Kauppi Ari (EXT-Ixonos/Oulu) wrote:
> > > On Mon, 2010-01-18 at 19:04 +0100, ext Paul Walmsley wrote:
> 
> (some missing attribution here)
> 
> > > > > +int omap3_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
> > > > > +{
> > > > > +	u32 v;
> > > > > +	int ret;
> > > > > +
> > > > > +	/* enable the clock */
> > > > > +	ret = omap2_dflt_clk_enable(clk);
> > > > > +
> > > > > +	/* Restore the dividers */
> > > > > +	if (!ret) {
> > > > > +		v = __raw_readl(clk->parent->clksel_reg);
> > > > > +		v += (1 << clk->parent->clksel_shift);
> > > > Using += here could affect many bits in the register if the add carries.
> > > > This doesn't seem like what you want.
> > > >
> > > > Also, isn't there a risk of side-effects here, that if this bit was not
> > > > already set, that everything further down the clock tree from this could
> > > > be affected?  Wouldn't it be best to just rewrite the correct clksel
> > > > value?
> > >
> > > The assumption is that the divider is correct in the register so I guess
> > > the clock tree should be fine? The proper clksel/divider has been
> > > earlier set but for some reason HW loses the divider if PWRDN is
> > > toggled.
> >
> > In my testing that assumption was always correct.  In fact that is what made
> > this bug very difficult to track down: the register values were always the
> > correct value programmed initially but the actual clocks were wrong.
> >
> > > Our experiments with this issue show that just read/write of same value
> > > is not enough to refresh the HW. The clksel has to be written with a
> > > different divider first and then write the original divider back.
> >
> > ACK to the above comment.  Registers need to be changed to a different value
> > and back.
> 
> Please put that into the comments on the function.  Right now it says "Any
> write to the corresponding CM_CLKSEL register will refresh the dividers."
> 
> Also, in that case the v += / v -= seems more appropriate.  The concern
> then is, what happens if the divider is already at its maximum value?
> Won't it wrap around, which could potentially result in excessively high
> clocks further down the tree?  In this case it might be best to step down
> to the next lowest divider, rather than wrapping.  Maybe something like
> this?  (untested)
> 
>     u32 orig_v, v, c, clksel_shift, max_div;
> 
>     [...]
> 
>     v = __raw_readl(clk->parent->clksel_reg);
>     orig_v = v;
> 
>     clksel_shift = __ffs(clk->parent->clksel_mask);
> 
>     max_div = clk->parent->clksel_mask >> clksel_shift;
> 
>     /* Isolate the current divider */
>     c = v & clk->parent->clksel_mask;
>     c >>= clksel_shift;
> 
>     /* Prevent excessively high clock rates if divider would wrap */
>     c += (c == max_div) ? -1 : 1;
> 
>     /* Write the temporarily altered divider back */
>     c <<= clksel_shift;
>     v &= ~c;
>     v |= c;
>     __raw_writel(v, clk->parent->clksel_reg);
> 
>     /* Write the original divider */
>     __raw_writel(orig_v, clk->parent->clksel_reg);
> 
> 
This seems to better than which currently I have; I will incorporate and test it for the same.  I will add few more comments to have a better clarity in the same function.

Thanks
Vijay

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

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux