Hi, On 10/04/2014 07:53 AM, Siarhei Siamashka wrote: > When PLL5P is used as a parent clock for some of the peripherals, > the current code just selects some hardcoded divisors. This happens > to work, but only under assumption that the PLL5P clock speed is > somewhere between 360MHz and 480MHz (the typical DRAM clock speeds). > > However with some tweaks for the DRAM parameters, it is possible to > clock DRAM up to 600MHz and more on some devices: > > http://lists.denx.de/pipermail/u-boot/2014-July/183981.html > > And this introduces concerns about the hardcoded divisors in the > kernel, which may cause some peripherals to operate at abnormally > high clock speeds if the PLL5 clock speed is too fast (PLL5 is used > for clocking DRAM). > > Moreover, it makes sense to avoid pre-dividing PLL5P and make it run > even faster than DRAM. This provides better granularity of the clock > speed selection for MBUS, G2D and everything else that is using PLL5P > as the parent clock. but running PLL5P faster means that the hardcoded > divisors become even more inappropriate. > > This patch improves the clock divisors selection for G2D, ACE and > DEBE to insure that they can work correctly with any PLL5P clock > speed. > > Signed-off-by: Siarhei Siamashka <[email protected]>
Looks good: Acked-by: Hans de Goede <[email protected]> Can we please get this merged, I'm working on getting the sunxi-3.4 kernels to work with upstream u-boot, so that we can stop maintaining our own fork, and this is necessary for this. Regards, Hans > --- > drivers/char/sunxi_g2d/g2d.c | 8 ++++++-- > drivers/media/audio/sun4i_dev_ace.c | 7 ++++++- > drivers/video/sunxi/disp/disp_clk.c | 17 ++++++++--------- > 3 files changed, 20 insertions(+), 12 deletions(-) > > diff --git a/drivers/char/sunxi_g2d/g2d.c b/drivers/char/sunxi_g2d/g2d.c > index 288685a..539c726 100644 > --- a/drivers/char/sunxi_g2d/g2d.c > +++ b/drivers/char/sunxi_g2d/g2d.c > @@ -29,9 +29,12 @@ > struct clk *g2d_ahbclk,*g2d_dramclk,*g2d_mclk,*g2d_src; > extern __g2d_drv_t g2d_ext_hd; > > +/* Arbitrarily pick 240MHz (TODO: confirm what is the real limit) */ > +#define G2D_CLOCK_SPEED_LIMIT 240000000 > + > int g2d_openclk(void) > { > - __u32 ret; > + __u32 ret, g2d_div; > > /* ahb g2d gating */ > g2d_ahbclk = clk_get(NULL,"ahb_de_mix"); > @@ -51,7 +54,8 @@ int g2d_openclk(void) > clk_put(g2d_src); > > ret = clk_get_rate(g2d_src); > - clk_set_rate(g2d_mclk,ret/2); > + g2d_div = DIV_ROUND_UP(ret, G2D_CLOCK_SPEED_LIMIT); > + clk_set_rate(g2d_mclk, ret / g2d_div); > > return 0; > } > diff --git a/drivers/media/audio/sun4i_dev_ace.c > b/drivers/media/audio/sun4i_dev_ace.c > index 59fdfeb..e3599f6 100644 > --- a/drivers/media/audio/sun4i_dev_ace.c > +++ b/drivers/media/audio/sun4i_dev_ace.c > @@ -91,10 +91,14 @@ static irqreturn_t ace_interrupt(int irq, void *dev) > return IRQ_HANDLED; > } > > +/* 200MHz is the limit for ACE_CLK_REG (see the A10 User Manual) */ > +#define ACE_CLOCK_SPEED_LIMIT 200000000 > + > static long ace_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long > arg) > { > int ret_val = 0; > unsigned long test_arg; > + int pll5_div; > __ace_req_e mpara; > unsigned long rate; > switch (cmd){ > @@ -137,7 +141,8 @@ static long ace_dev_ioctl(struct file *filp, unsigned int > cmd, unsigned long arg > printk("try to set parent of ace_moduleclk to > ace_pll5clk failed!\n"); > } > rate = clk_get_rate(ace_pll5_pclk); > - if(clk_set_rate(ace_moduleclk, rate/2)) { > + pll5_div = DIV_ROUND_UP(rate, ACE_CLOCK_SPEED_LIMIT); > + if(clk_set_rate(ace_moduleclk, rate / pll5_div)) { > printk("try to set ace_moduleclk rate > failed!!!\n"); > goto out; > } > diff --git a/drivers/video/sunxi/disp/disp_clk.c > b/drivers/video/sunxi/disp/disp_clk.c > index abd1877..ff46bcc 100644 > --- a/drivers/video/sunxi/disp/disp_clk.c > +++ b/drivers/video/sunxi/disp/disp_clk.c > @@ -120,9 +120,12 @@ __disp_clk_tab clk_tab = { > } > }; > > +/* 300MHz */ > +#define DEBE_CLOCK_SPEED_LIMIT 300000000 > + > __s32 image_clk_init(__u32 sel) > { > - __u32 dram_pll; > + __u32 dram_pll, pll5_div; > > if (sel == 0) { > h_debe0ahbclk = OSAL_CCMU_OpenMclk(AW_MOD_CLK_AHB_DEBE0); > @@ -137,10 +140,8 @@ __s32 image_clk_init(__u32 sel) > OSAL_CCMU_SetMclkSrc(h_debe0mclk, AW_SYS_CLK_PLL5P); > > dram_pll = OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL5P); > - if (dram_pll < 300000000) > - OSAL_CCMU_SetMclkDiv(h_debe0mclk, 1); > - else > - OSAL_CCMU_SetMclkDiv(h_debe0mclk, 2); > + pll5_div = DIV_ROUND_UP(dram_pll, DEBE_CLOCK_SPEED_LIMIT); > + OSAL_CCMU_SetMclkDiv(h_debe0mclk, pll5_div); > > OSAL_CCMU_MclkOnOff(h_debe0ahbclk, CLK_ON); > if (sunxi_is_sun4i()) { > @@ -162,10 +163,8 @@ __s32 image_clk_init(__u32 sel) > OSAL_CCMU_SetMclkSrc(h_debe1mclk, AW_SYS_CLK_PLL5P); > > dram_pll = OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL5P); > - if (dram_pll < 300000000) > - OSAL_CCMU_SetMclkDiv(h_debe1mclk, 1); > - else > - OSAL_CCMU_SetMclkDiv(h_debe1mclk, 2); > + pll5_div = DIV_ROUND_UP(dram_pll, DEBE_CLOCK_SPEED_LIMIT); > + OSAL_CCMU_SetMclkDiv(h_debe1mclk, pll5_div); > > OSAL_CCMU_MclkOnOff(h_debe1ahbclk, CLK_ON); > if (sunxi_is_sun4i()) { > -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
