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.

Reply via email to