backlight: backlight shine when frenquence change, fix it
authorlyx <lyx@rock-chips.com>
Fri, 24 Sep 2010 08:11:01 +0000 (01:11 -0700)
committerlyx <lyx@rock-chips.com>
Fri, 24 Sep 2010 08:11:01 +0000 (01:11 -0700)
1.use pwd clk
2.when write register, should disable clk, enable it after writen

drivers/video/backlight/rk2818_backlight.c

index 759b79adc239af658fd6accead598f1125235c6a..c2d9d7c70fffd36d9389ff3713ffa08396b29714 100644 (file)
@@ -52,8 +52,9 @@
 #define read_pwm_reg(id, addr)              __raw_readl(addr+(RK2818_PWM_BASE+id*0x10))    
 #define mask_pwm_reg(id, addr, msk, val)    write_dma_reg(id, addr, (val)|((~(msk))&read_dma_reg(id, addr)))
 
-
-static struct backlight_device *rk2818_bl = NULL;
+static struct clk *pwm_clk;
+static unsigned long pwm_clk_rate;
+static struct backlight_device *rk2818_bl;
 static int suspend_flag = 0;
 #define BACKLIGHT_SEE_MINVALUE 52
 
@@ -107,61 +108,61 @@ static struct backlight_ops rk2818_bl_ops = {
        .get_brightness = rk2818_bl_get_brightness,
 };
 
-
+#ifdef CONFIG_CPU_FREQ
 static int rk2818_bl_change_clk(struct notifier_block *nb, unsigned long val, void *data)
 {
     struct rk2818_bl_info *rk2818_bl_info;
     u32 id;
     u32 divl, divh, tmp;
     u32 div_total;
-    struct clk* pclk; 
+       int is_suspended = suspend_flag;
 
-    if (!rk2818_bl)
-    {
-        DBG(KERN_CRIT "%s: backlight device does not exist \n",
-               __func__); 
+       if (!rk2818_bl) {
+               DBG(KERN_CRIT "%s: backlight device does not exist\n", __func__);
                return -ENODEV;         
     }
     
-    switch (val) 
-    {
+       switch (val) {
     case CPUFREQ_PRECHANGE:        
          break;
     case CPUFREQ_POSTCHANGE:
+               if (clk_get_rate(pwm_clk) == pwm_clk_rate)
+                       break;
+               pwm_clk_rate = clk_get_rate(pwm_clk);
          rk2818_bl_info = rk2818_bl->dev.parent->platform_data;
          id = rk2818_bl_info->pwm_id;
      
-         pclk = clk_get(NULL, "arm_pclk");
-         if (!pclk || IS_ERR(pclk)) 
-         {
-               printk(KERN_ERR "%s, %s, failed to get lcd clock source\n",__FILE__, __FUNCTION__);
-               return -ENODEV; 
-         }
+
          
          divl = read_pwm_reg(id, PWM_REG_LRC);
          divh = read_pwm_reg(id, PWM_REG_HRC);
      
-         tmp = clk_get_rate(pclk)/PWM_APB_PRE_DIV;
+               tmp = pwm_clk_rate / PWM_APB_PRE_DIV;
          tmp >>= (1 + (PWM_DIV >> 9));
 
-         clk_put(pclk);
          
          div_total = (tmp) ? tmp : 1;
          tmp = div_total*divh/divl;
          
+               if (!is_suspended)
+                       clk_disable(pwm_clk);
          write_pwm_reg(id, PWM_REG_LRC, div_total);
          write_pwm_reg(id, PWM_REG_HRC, tmp);    
          write_pwm_reg(id, PWM_REG_CNTR, 0);  
+               if (!is_suspended)
+                       clk_enable(pwm_clk);
          break;
     }
    
     return 0;
 }   
+#endif
 static void rk2818_delaybacklight_timer(unsigned long data)
 {
        struct rk2818_bl_info *rk2818_bl_info = (struct rk2818_bl_info *)data;
        u32 id, brightness;
        u32 div_total, divh;
+       clk_enable(pwm_clk);
        id = rk2818_bl_info->pwm_id;
     brightness = rk2818_bl->props.brightness;
     div_total = read_pwm_reg(id, PWM_REG_LRC);
@@ -197,6 +198,7 @@ static void rk2818_bl_suspend(struct early_suspend *h)
     DBG("%s: ==========  suspend  =============== \n",__func__); 
 
     write_pwm_reg(id, PWM_REG_HRC, divh);
+       clk_disable(pwm_clk);
 
     suspend_flag = 1;
     
@@ -242,7 +244,6 @@ static int rk2818_backlight_probe(struct platform_device *pdev)
     struct rk2818_bl_info *rk2818_bl_info = pdev->dev.platform_data;
     u32 id  =  rk2818_bl_info->pwm_id;
     u32 divh, div_total;
-    struct clk* arm_pclk; 
  
     DBG("%s::=======================================\n",__func__);
 
@@ -259,16 +260,16 @@ static int rk2818_backlight_probe(struct platform_device *pdev)
                return -ENODEV;         
        }
        
-    arm_pclk = clk_get(NULL, "arm_pclk");
-    if (!arm_pclk || IS_ERR(arm_pclk)) 
-    {
-               printk(KERN_ERR "failed to get lcd clock source\n");
+       if (!pwm_clk)
+               pwm_clk = clk_get(NULL, "pwm");
+       if (!pwm_clk || IS_ERR(pwm_clk)) {
+               printk(KERN_ERR "failed to get pwm clock source\n");
                return -ENODEV; 
        }
-    div_total = clk_get_rate(arm_pclk)/PWM_APB_PRE_DIV;
+       pwm_clk_rate = clk_get_rate(pwm_clk);
+       div_total = pwm_clk_rate / PWM_APB_PRE_DIV;
 
        
-    clk_put(arm_pclk);
     
     div_total >>= (1 + (PWM_DIV >> 9));
     div_total = (div_total) ? div_total : 1;
@@ -282,14 +283,18 @@ static int rk2818_backlight_probe(struct platform_device *pdev)
     /*init timer to dispose workqueue */
     setup_timer(&rk2818_bl_info->timer, rk2818_delaybacklight_timer, (unsigned long)rk2818_bl_info);
 
+#ifdef CONFIG_CPU_FREQ
     rk2818_bl_info->freq_transition.notifier_call = rk2818_bl_change_clk;   
     cpufreq_register_notifier(&rk2818_bl_info->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
         
+//     clk_disable(pwm_clk);
     write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_RESET);
     write_pwm_reg(id, PWM_REG_LRC, div_total);
     write_pwm_reg(id, PWM_REG_HRC, divh);
     write_pwm_reg(id, PWM_REG_CNTR, 0x0);
     write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TIME_EN);
+       clk_enable(pwm_clk);
    
        rk2818_bl->props.power = FB_BLANK_UNBLANK;
        rk2818_bl->props.fb_blank = FB_BLANK_UNBLANK;
@@ -319,7 +324,11 @@ static int rk2818_backlight_remove(struct platform_device *pdev)
 #ifdef CONFIG_HAS_EARLYSUSPEND
         unregister_early_suspend(&bl_early_suspend);
 #endif       
+#ifdef CONFIG_CPU_FREQ
         cpufreq_unregister_notifier(&rk2818_bl_info->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+               clk_disable(pwm_clk);
+               clk_put(pwm_clk);
         if (rk2818_bl_info && rk2818_bl_info->io_deinit) {
             rk2818_bl_info->io_deinit();
         }