drm/rockchip: vop: support interlace display
authorMark Yao <mark.yao@rock-chips.com>
Tue, 6 Sep 2016 09:26:29 +0000 (17:26 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 23 Sep 2016 02:03:40 +0000 (10:03 +0800)
Change-Id: I39c66ff90d85c2ee7bc8495ed313c359f0d457d6
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
drivers/gpu/drm/rockchip/rockchip_vop_reg.c

index fe4b96cbd42044d017ab938ac396f5af92946dd0..011e7a4ade8076f1641bc36f7860631370320a28 100644 (file)
@@ -1207,15 +1207,15 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
        const struct vop_data *vop_data = vop->data;
        struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
        struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
-       u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
-       u16 hdisplay = adjusted_mode->hdisplay;
-       u16 htotal = adjusted_mode->htotal;
-       u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
+       u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+       u16 hdisplay = adjusted_mode->crtc_hdisplay;
+       u16 htotal = adjusted_mode->crtc_htotal;
+       u16 hact_st = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_start;
        u16 hact_end = hact_st + hdisplay;
-       u16 vdisplay = adjusted_mode->vdisplay;
-       u16 vtotal = adjusted_mode->vtotal;
-       u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
-       u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
+       u16 vdisplay = adjusted_mode->crtc_vdisplay;
+       u16 vtotal = adjusted_mode->crtc_vtotal;
+       u16 vsync_len = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+       u16 vact_st = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
        u16 vact_end = vact_st + vdisplay;
        uint32_t val;
 
@@ -1293,11 +1293,27 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
        VOP_CTRL_SET(vop, hact_st_end, val);
        VOP_CTRL_SET(vop, hpost_st_end, val);
 
-       VOP_CTRL_SET(vop, vtotal_pw, (vtotal << 16) | vsync_len);
+       VOP_CTRL_SET(vop, vtotal_pw, (adjusted_mode->vtotal << 16) | vsync_len);
        val = vact_st << 16;
        val |= vact_end;
        VOP_CTRL_SET(vop, vact_st_end, val);
        VOP_CTRL_SET(vop, vpost_st_end, val);
+       if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+               u16 vact_st_f1 = vtotal + vact_st + 1;
+               u16 vact_end_f1 = vact_st_f1 + vdisplay;
+
+               val = vact_st_f1 << 16 | vact_end_f1;
+               VOP_CTRL_SET(vop, vact_st_end_f1, val);
+               VOP_CTRL_SET(vop, vpost_st_end_f1, val);
+
+               val = vtotal << 16 | (vtotal + vsync_len);
+               VOP_CTRL_SET(vop, vs_st_end_f1, val);
+               VOP_CTRL_SET(vop, dsp_interlace, 1);
+               VOP_CTRL_SET(vop, p2i_en, 1);
+       } else {
+               VOP_CTRL_SET(vop, dsp_interlace, 0);
+               VOP_CTRL_SET(vop, p2i_en, 0);
+       }
 
        clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 
index 1731e184396c475c1546d550830f58568d6aab71..ce36bea4beb7c2e45d23f915d9aeba0861e35636 100644 (file)
@@ -75,6 +75,7 @@ struct vop_ctrl {
        struct vop_reg vtotal_pw;
        struct vop_reg vact_st_end;
        struct vop_reg vact_st_end_f1;
+       struct vop_reg vs_st_end_f1;
        struct vop_reg hpost_st_end;
        struct vop_reg vpost_st_end;
        struct vop_reg vpost_st_end_f1;
index f77a6522e063d9a1571f079b40ddc5171d82c33d..adfac19db8cc5582118348fb921a38b38ec6820f 100644 (file)
@@ -170,6 +170,7 @@ static const struct vop_ctrl rk3288_ctrl_data = {
        .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
        .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
        .vact_st_end_f1 = VOP_REG(RK3288_DSP_VACT_ST_END_F1, 0x1fff1fff, 0),
+       .vs_st_end_f1 = VOP_REG(RK3288_DSP_VS_ST_END_F1, 0x1fff1fff, 0),
        .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
        .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
        .vpost_st_end_f1 = VOP_REG(RK3288_POST_DSP_VACT_INFO_F1, 0x1fff1fff, 0),
@@ -180,7 +181,7 @@ static const struct vop_ctrl rk3288_ctrl_data = {
        .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
        .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
        .core_dclk_div = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 4, 3, 4, -1),
-       .p2i_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 5, 3, 4, -1),
+       .p2i_en = VOP_REG_VER(RK3399_DSP_CTRL0, 0x1, 5, 3, 4, -1),
        .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
        .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
        .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),