rk: ion: assign sg's dma_length in ion allocation if CONFIG_NEED_SG_DMA_LENGTH is set
[firefly-linux-kernel-4.4.55.git] / drivers / pwm / pwm-rockchip.c
old mode 100644 (file)
new mode 100755 (executable)
index a15b38d..288f1b4
@@ -81,7 +81,7 @@ module_param_named(dbg_level, pwm_dbg_level, int, 0644);
 #define PWMCR_MIN_PRESCALE     0x00
 #define PWMCR_MAX_PRESCALE     0x07
 
-#define PWMDCR_MIN_DUTY                0x0001
+#define PWMDCR_MIN_DUTY                0x0000
 #define PWMDCR_MAX_DUTY                0xFFFF
 
 #define PWMPCR_MIN_PERIOD              0x0001
@@ -97,6 +97,8 @@ module_param_named(dbg_level, pwm_dbg_level, int, 0644);
  struct rk_pwm_chip {
        void __iomem *base;
        struct clk *clk;
+       struct clk *aclk_lcdc;
+       struct clk *hclk_lcdc;
        struct pwm_chip chip;
        unsigned int pwm_id;
        spinlock_t              lock;
@@ -191,11 +193,11 @@ static int  rk_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
        conf |= (prescale << DW_PWM_PRESCALE);
        barrier();
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,off);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_HRC,dc);//0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_LRC, pv);//0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,0);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,on|conf);
        
        spin_unlock_irqrestore(lock, flags);    
@@ -229,11 +231,11 @@ static void rk_pwm_resume_v1(struct pwm_chip *chip, struct pwm_device *pwm)
        int     off =  PWM_RESET;
 
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,off);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_HRC,pc->pwm_duty);//0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_LRC, pc->pwm_period);//0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,pc->pwm_count);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,pc->pwm_ctrl);
 }
 /* config for rockchip,pwm*/
@@ -300,11 +302,11 @@ static int  rk_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
        conf |= (prescale << RK_PWM_PRESCALE);  
        barrier();
        //rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,off);
-       //dsb();
+       //dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_DUTY,dc);//0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_PERIOD,pv);//0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,0);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,on|conf);
        spin_unlock_irqrestore(lock, flags);    
 
@@ -342,7 +344,7 @@ static void rk_pwm_resume_v2(struct pwm_chip *chip, struct pwm_device *pwm)
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_DUTY,    pc->pwm_duty);//0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_PERIOD, pc->pwm_period);//0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,pc->pwm_count);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,pc->pwm_ctrl);
 }
 
@@ -417,11 +419,11 @@ static int  rk_pwm_config_v3(struct pwm_chip *chip, struct pwm_device *pwm,
        barrier();
 //     rk_pwm_writel(pc, pwm->hwpwm, VOP_REG_CTRL,off);
        
-//     dsb();
+//     dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_DUTY,dc);   //   2    0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_PERIOD,pv);   // 4 0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, VOP_REG_CNTR,0);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, VOP_REG_CTRL,on|conf);
 
        spin_unlock_irqrestore(lock, flags);    
@@ -456,7 +458,7 @@ static void rk_pwm_resume_v3(struct pwm_chip *chip, struct pwm_device *pwm)
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_DUTY,    pc->pwm_duty);//0x1900);// dc);
        rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_PERIOD, pc->pwm_period);//0x5dc0);//pv);
        rk_pwm_writel(pc, pwm->hwpwm, VOP_REG_CNTR,pc->pwm_count);
-       dsb();
+       dsb(sy);
        rk_pwm_writel(pc, pwm->hwpwm, VOP_REG_CTRL,pc->pwm_ctrl);
 }
 
@@ -467,13 +469,29 @@ static int  rk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        struct rk_pwm_chip *pc = to_rk_pwm_chip(chip);
        int ret;
        
-       ret = clk_prepare_enable(pc->clk);
+       ret = clk_enable(pc->clk);
        if (ret)
                return ret;
 
+       if (pc->aclk_lcdc) {
+               ret = clk_enable(pc->aclk_lcdc);
+               if (ret)
+                       return ret;
+       }
+       if (pc->hclk_lcdc) {
+               ret = clk_enable(pc->hclk_lcdc);
+               if (ret)
+                       return ret;
+       }
+
        ret = pc->config(chip, pwm, duty_ns, period_ns);
-       
-       clk_disable_unprepare(pc->clk);
+
+       if (pc->aclk_lcdc)
+               clk_disable(pc->aclk_lcdc);
+       if (pc->hclk_lcdc)
+               clk_disable(pc->hclk_lcdc);
+
+       clk_disable(pc->clk);
 
        return 0;
 }
@@ -482,10 +500,21 @@ static int rk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        struct rk_pwm_chip *pc = to_rk_pwm_chip(chip);
        int ret = 0;
 
-       ret = clk_prepare_enable(pc->clk);
+       ret = clk_enable(pc->clk);
        if (ret)
                return ret;
 
+       if (pc->aclk_lcdc) {
+               ret = clk_enable(pc->aclk_lcdc);
+               if (ret)
+                       return ret;
+       }
+       if (pc->hclk_lcdc) {
+               ret = clk_enable(pc->hclk_lcdc);
+               if (ret)
+                       return ret;
+       }
+
        pc->set_enable(chip, pwm,true);
        return 0;
 }
@@ -496,7 +525,12 @@ static void rk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 
        pc->set_enable(chip, pwm,false);
 
-       clk_disable_unprepare(pc->clk);
+       if (pc->aclk_lcdc)
+               clk_disable(pc->aclk_lcdc);
+       if (pc->hclk_lcdc)
+               clk_disable(pc->hclk_lcdc);
+
+       clk_disable(pc->clk);
 
 }
 
@@ -568,14 +602,31 @@ static int rk_pwm_probe(struct platform_device *pdev)
        }
 
        pc->base = of_iomap(np, 0);
-       if (IS_ERR(pc->base)){
+       if (IS_ERR(pc->base)) {
                printk("PWM base ERR \n");
                return PTR_ERR(pc->base);
        }
-       pc->clk = devm_clk_get(&pdev->dev,"pclk_pwm");
+       pc->clk = devm_clk_get(&pdev->dev, "pclk_pwm");
        if (IS_ERR(pc->clk))
                return PTR_ERR(pc->clk);
 
+       if (of_device_is_compatible(np, "rockchip,vop-pwm")) {
+               pc->aclk_lcdc = devm_clk_get(&pdev->dev, "aclk_lcdc");
+               if (IS_ERR(pc->aclk_lcdc))
+                       return PTR_ERR(pc->aclk_lcdc);
+
+               pc->hclk_lcdc = devm_clk_get(&pdev->dev, "hclk_lcdc");
+               if (IS_ERR(pc->hclk_lcdc))
+                       return PTR_ERR(pc->hclk_lcdc);
+
+               ret = clk_prepare(pc->aclk_lcdc);
+               if (ret)
+                       return ret;
+               clk_prepare(pc->hclk_lcdc);
+               if (ret)
+                       return ret;
+       }
+
        platform_set_drvdata(pdev, pc);
        data = of_id->data;
        pc->config = data->config;
@@ -587,9 +638,14 @@ static int rk_pwm_probe(struct platform_device *pdev)
        pc->chip.base = -1;
        pc->chip.npwm = NUM_PWM;
        spin_lock_init(&pc->lock);
+       ret = clk_prepare(pc->clk);
+       if (ret)
+               return ret;
 
-       /* Following enables PWM chip, channels would still be enabled individually through their control register */
-       DBG("npwm = %d, of_pwm_ncells =%d \n", pc->chip.npwm,pc->chip.of_pwm_n_cells);
+       /* Following enables PWM chip, channels would still
+       be enabled individually through their control register */
+       DBG("npwm = %d, of_pwm_ncells =%d \n"
+               , pc->chip.npwm, pc->chip.of_pwm_n_cells);
        ret = pwmchip_add(&pc->chip);
        if (ret < 0){
                printk("failed to add pwm\n");