#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
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;
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);
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*/
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);
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);
}
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);
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);
}
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;
}
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;
}
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);
}
}
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;
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");