X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fvideo%2Frockchip%2Flcdc%2Frk322x_lcdc.c;h=8c0c16095cf7fd7d1917733caf50cc2b5c5af51d;hb=534c1ca9c257a81dd1b456f9244c1a1bfa0f7af7;hp=3f647251b07cf8479ece9aec701ae304e0faf6c3;hpb=dd8a1e839ab5e3a12bce13c9e91e0749262b1181;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.c b/drivers/video/rockchip/lcdc/rk322x_lcdc.c index 3f647251b07c..8c0c16095cf7 100644 --- a/drivers/video/rockchip/lcdc/rk322x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.c @@ -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,7 +1789,7 @@ 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) + 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)); @@ -1979,6 +1960,20 @@ static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) V_DITHER_DOWN_SEL(0) | V_DITHER_DOWN_MODE(0); break; + case OUT_YUV_422: + face = OUT_YUV_422; + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) | + V_PRE_DITHER_DOWN_EN(1) | + V_DITHER_DOWN_SEL(0) | + V_DITHER_DOWN_MODE(0); + break; + case OUT_YUV_422_10BIT: + face = OUT_YUV_422; + val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) | + V_PRE_DITHER_DOWN_EN(0) | + V_DITHER_DOWN_SEL(0) | + V_DITHER_DOWN_MODE(0); + break; case OUT_P101010: face = OUT_P101010; val = V_DITHER_DOWN_EN(0) | V_DITHER_UP_EN(1) | @@ -2017,6 +2012,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: @@ -2026,10 +2027,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) && @@ -2037,18 +2050,37 @@ 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; + case SCREEN_DP: + dclk_ddr = 0; + if ((VOP_CHIP(vop_dev) == VOP_RK3399) && + ((screen->face == OUT_P888) || + (screen->face == OUT_P101010))) { + if (vop_dev->id == 0) + face = OUT_P101010; + else + face = OUT_P888; + } + val = V_DP_OUT_EN(1); + vop_msk_reg(vop_dev, SYS_CTRL, val); + val = V_DP_HSYNC_POL(screen->pin_hsync) | + V_DP_VSYNC_POL(screen->pin_vsync) | + V_DP_DEN_POL(screen->pin_den) | + V_DP_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; @@ -2113,6 +2145,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) @@ -2137,14 +2171,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) @@ -2159,8 +2200,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; } @@ -3876,7 +3918,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 */ @@ -4139,7 +4181,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: @@ -4222,7 +4267,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; }