video: rockchip: vop: 3399: fix polarity config error
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk322x_lcdc.c
index 386708e53f45a333087e0ecc6ce4a25bc23ddda8..53e61871071b165942ddc86c1dc7aaa426401e4b 100644 (file)
@@ -473,6 +473,8 @@ static int vop_win_direct_en(struct rk_lcdc_driver *drv,
 {
        struct vop_device *vop_dev =
            container_of(drv, struct vop_device, driver);
+
+       drv->win[win_id]->state = en;
        if (win_id == 0)
                win0_enable(vop_dev, en);
        else if (win_id == 1)
@@ -1453,13 +1455,6 @@ static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
                val = V_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
                    V_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
                vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val);
-               if (win->alpha_en == 1) {
-                       vop_alpha_cfg(dev_drv, win_id);
-               } else {
-                       val = V_WIN0_SRC_ALPHA_EN(0);
-                       vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val);
-               }
-
        } else {
                val = V_WIN0_EN(win->state);
                vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val);
@@ -1593,13 +1588,6 @@ static int vop_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
                        val = V_WIN2_MST3_EN(0);
                        vop_msk_reg(vop_dev, WIN2_CTRL0 + off, val);
                }
-
-               if (win->alpha_en == 1) {
-                       vop_alpha_cfg(dev_drv, win_id);
-               } else {
-                       val = V_WIN2_SRC_ALPHA_EN(0);
-                       vop_msk_reg(vop_dev, WIN2_SRC_ALPHA_CTRL + off, val);
-               }
        } else {
                val = V_WIN2_EN(win->state) | V_WIN2_MST0_EN(0) |
                    V_WIN2_MST1_EN(0) | V_WIN2_MST2_EN(0) | V_WIN2_MST3_EN(0);
@@ -1644,13 +1632,6 @@ static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id)
                val = V_HWC_DSP_XST(win->area[0].dsp_stx) |
                    V_HWC_DSP_YST(win->area[0].dsp_sty);
                vop_msk_reg(vop_dev, HWC_DSP_ST, val);
-
-               if (win->alpha_en == 1) {
-                       vop_alpha_cfg(dev_drv, win_id);
-               } else {
-                       val = V_WIN2_SRC_ALPHA_EN(0);
-                       vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val);
-               }
        } else {
                val = V_HWC_EN(win->state);
                vop_msk_reg(vop_dev, HWC_CTRL0, val);
@@ -1808,6 +1789,10 @@ static int vop_config_timing(struct rk_lcdc_driver *dev_drv)
                vop_msk_reg(vop_dev, LINE_FLAG, val);
        }
        vop_post_cfg(dev_drv);
+       if ((x_res <= VOP_INPUT_MAX_WIDTH / 2) && (vop_dev->id == 0))
+               vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(1));
+       else
+               vop_msk_reg(vop_dev, SYS_CTRL, V_POST_LB_MODE(0));
 
        return 0;
 }
@@ -2013,6 +1998,12 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                        }
                        val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0);
                        vop_msk_reg(vop_dev, SYS_CTRL, val);
+                       val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
+                               V_HDMI_VSYNC_POL(screen->pin_vsync) |
+                               V_HDMI_DEN_POL(screen->pin_den) |
+                               V_HDMI_DCLK_POL(screen->pin_dclk);
+                       /*hsync vsync den dclk polo,dither */
+                       vop_msk_reg(vop_dev, DSP_CTRL1, val);
                        break;
                case SCREEN_RGB:
                case SCREEN_LVDS:
@@ -2022,10 +2013,22 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                case SCREEN_MIPI:
                        val = V_MIPI_OUT_EN(1);
                        vop_msk_reg(vop_dev, SYS_CTRL, val);
+                       val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
+                               V_MIPI_VSYNC_POL(screen->pin_vsync) |
+                               V_MIPI_DEN_POL(screen->pin_den) |
+                               V_MIPI_DCLK_POL(screen->pin_dclk);
+                       /*hsync vsync den dclk polo,dither */
+                       vop_msk_reg(vop_dev, DSP_CTRL1, val);
                        break;
                case SCREEN_DUAL_MIPI:
                        val = V_MIPI_OUT_EN(1) | V_MIPI_DUAL_CHANNEL_EN(1);
                        vop_msk_reg(vop_dev, SYS_CTRL, val);
+                       val = V_MIPI_HSYNC_POL(screen->pin_hsync) |
+                               V_MIPI_VSYNC_POL(screen->pin_vsync) |
+                               V_MIPI_DEN_POL(screen->pin_den) |
+                               V_MIPI_DCLK_POL(screen->pin_dclk);
+                       /*hsync vsync den dclk polo,dither */
+                       vop_msk_reg(vop_dev, DSP_CTRL1, val);
                        break;
                case SCREEN_EDP:
                        if ((VOP_CHIP(vop_dev) == VOP_RK3399) &&
@@ -2033,18 +2036,18 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                face = OUT_P101010;
                        val = V_EDP_OUT_EN(1);
                        vop_msk_reg(vop_dev, SYS_CTRL, val);
+                       val = V_EDP_HSYNC_POL(screen->pin_hsync) |
+                               V_EDP_VSYNC_POL(screen->pin_vsync) |
+                               V_EDP_DEN_POL(screen->pin_den) |
+                               V_EDP_DCLK_POL(screen->pin_dclk);
+                       /*hsync vsync den dclk polo,dither */
+                       vop_msk_reg(vop_dev, DSP_CTRL1, val);
                        break;
                default:
                        dev_err(vop_dev->dev, "un supported interface[%d]!\n",
                                screen->type);
                        break;
                }
-               val = V_HDMI_HSYNC_POL(screen->pin_hsync) |
-                       V_HDMI_VSYNC_POL(screen->pin_vsync) |
-                       V_HDMI_DEN_POL(screen->pin_den) |
-                       V_HDMI_DCLK_POL(screen->pin_dclk);
-               /*hsync vsync den dclk polo,dither */
-               vop_msk_reg(vop_dev, DSP_CTRL1, val);
 
                if (screen->color_mode == COLOR_RGB)
                        dev_drv->overlay_mode = VOP_RGB_DOMAIN;
@@ -2109,6 +2112,8 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
        return 0;
 }
 
+static int vop_early_suspend(struct rk_lcdc_driver *dev_drv);
+static int vop_early_resume(struct rk_lcdc_driver *dev_drv);
 /*enable layer,open:1,enable;0 disable*/
 static void vop_layer_enable(struct vop_device *vop_dev,
                             unsigned int win_id, bool open)
@@ -2133,14 +2138,21 @@ static void vop_layer_enable(struct vop_device *vop_dev,
                                              vop_dev->driver.win[win_id]);
                        vop_cfg_done(vop_dev);
                }
-               /* if no layer used,disable lcdc */
-               if (!vop_dev->atv_layer_cnt) {
+       }
+       spin_unlock(&vop_dev->reg_lock);
+       /* if no layer used,disable lcdc */
+       if (vop_dev->prop == EXTEND) {
+               if (!vop_dev->atv_layer_cnt && !open) {
+                       vop_early_suspend(&vop_dev->driver);
                        dev_info(vop_dev->dev,
                                 "no layer is used,go to standby!\n");
                        vop_dev->standby = 1;
+               } else if (open) {
+                       vop_early_resume(&vop_dev->driver);
+                       dev_info(vop_dev->dev, "wake up from standby!\n");
                }
        }
-       spin_unlock(&vop_dev->reg_lock);
+
 }
 
 static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
@@ -2155,8 +2167,9 @@ static int vop_enable_irq(struct rk_lcdc_driver *dev_drv)
        val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1 |
                INTR_WIN0_EMPTY | INTR_WIN1_EMPTY | INTR_HWC_EMPTY |
                INTR_POST_BUF_EMPTY;
+       val |= val << 16;
 
-       vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val);
+       vop_msk_reg(vop_dev, INTR_EN0, val);
 
        return 0;
 }
@@ -3872,7 +3885,7 @@ static ssize_t vop_get_disp_info(struct rk_lcdc_driver *dev_drv,
        spin_unlock(&vop_dev->reg_lock);
        size += snprintf(dsp_buf, 80,
                "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
-               layer1_sel, layer0_sel, layer2_sel, layer3_sel);
+               layer3_sel, layer2_sel, layer1_sel, layer0_sel);
        strcat(buf, dsp_buf);
        memset(dsp_buf, 0, sizeof(dsp_buf));
        /* win0 */
@@ -4135,7 +4148,10 @@ static int vop_config_done(struct rk_lcdc_driver *dev_drv)
        vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby));
        for (i = 0; i < dev_drv->lcdc_win_num; i++) {
                win = dev_drv->win[i];
+               vop_alpha_cfg(dev_drv, i);
                fbdc_en |= win->area[0].fbdc_en;
+               vop_dev->atv_layer_cnt &= ~(1 << win->id);
+               vop_dev->atv_layer_cnt |= (win->state << win->id);
                if ((win->state == 0) && (win->last_state == 1)) {
                        switch (win->id) {
                        case 0:
@@ -4218,7 +4234,7 @@ static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable)
        if (enable)
                enable_irq(vop_dev->irq);
        else
-               disable_irq(vop_dev->irq);
+               disable_irq_nosync(vop_dev->irq);
        return 0;
 }