video: rockchip: 3399 vop: fix pwm config done lead to iommu pagefault
authorHuang Jiachai <hjc@rock-chips.com>
Tue, 1 Nov 2016 08:09:16 +0000 (16:09 +0800)
committerHuang Jiachai <hjc@rock-chips.com>
Tue, 1 Nov 2016 08:17:34 +0000 (16:17 +0800)
Change-Id: Ia8e8a3ccaf9a713d96e93a435503d8b55b794f3b
Signed-off-by: Huang Jiachai <hjc@rock-chips.com>
drivers/video/rockchip/lcdc/rk322x_lcdc.c
drivers/video/rockchip/rk_fb.c
include/linux/rk_fb.h

index 4b183af24a93e307e7bc53e4315cc265e0bbaf23..bcdfc0fcdd9799af7accf0ae77b04cf754310210 100644 (file)
@@ -4558,9 +4558,11 @@ static int vop_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode,
                pr_err("%s wait vsync time out\n", __func__);
 
        spin_lock(&vop_dev->reg_lock);
-       val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1);
-       vop_msk_reg(vop_dev, CABC_CTRL0, val);
-       vop_cfg_done(vop_dev);
+       if (vop_dev->clk_on) {
+               val = V_CABC_EN(1) | V_CABC_HANDLE_EN(1);
+               vop_msk_reg(vop_dev, CABC_CTRL0, val);
+               vop_cfg_done(vop_dev);
+       }
        spin_unlock(&vop_dev->reg_lock);
 
        return 0;
@@ -4782,6 +4784,27 @@ static int vop_set_overscan(struct rk_lcdc_driver *dev_drv,
        return 0;
 }
 
+static int vop_extern_func(struct rk_lcdc_driver *dev_drv, int cmd)
+{
+       struct vop_device *vop_dev =
+           container_of(dev_drv, struct vop_device, driver);
+
+       if (unlikely(!vop_dev->clk_on)) {
+               pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on);
+               return 0;
+       }
+
+       switch (cmd) {
+       case UPDATE_CABC_PWM:
+               vop_cfg_done(vop_dev);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .open = vop_open,
        .win_direct_en = vop_win_direct_en,
@@ -4824,6 +4847,7 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .backlight_close = vop_backlight_close,
        .mmu_en    = vop_mmu_en,
        .set_overscan   = vop_set_overscan,
+       .extern_func    = vop_extern_func,
 };
 
 static irqreturn_t vop_isr(int irq, void *dev_id)
index 32625a8b113778dfc42844d7236783757b2dab62..968a25d36b69ae65b1402d43a8c95101067158ce 100644 (file)
@@ -673,7 +673,8 @@ int rk_fb_set_vop_pwm(void)
                return -1;
 
        mutex_lock(&dev_drv->win_config);
-       dev_drv->ops->cfg_done(dev_drv);
+       if (dev_drv->ops->extern_func)
+               dev_drv->ops->extern_func(dev_drv, UPDATE_CABC_PWM);
        mutex_unlock(&dev_drv->win_config);
 
        return 0;
index f1b39644b8361eb34cb791a2c4edd9784d4a259c..d91f7a2ec2a62ef71d443c058c87e0937778c56c 100755 (executable)
@@ -278,7 +278,8 @@ typedef enum {
 typedef enum {
        GET_PAGE_FAULT  = 0x0,
        CLR_PAGE_FAULT  = 0x1,
-       UNMASK_PAGE_FAULT = 0x2
+       UNMASK_PAGE_FAULT = 0x2,
+       UPDATE_CABC_PWM = 0x3
 } extern_func;
 
 enum rk_vop_feature {