diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 9cbb35c289de..d7ea1f80ea12 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -826,11 +826,22 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win *win, uint16_t lb_mode; uint32_t val; const struct vop_data *vop_data = vop->data; + struct drm_display_mode *adjusted_mode = &vop->rockchip_crtc.crtc.state->adjusted_mode; int vskiplines; if (!win->phy->scl) return; + if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) && vop->version == VOP_VERSION(2, 2)) { + VOP_SCL_SET(vop, win, scale_yrgb_x, ((src_w << 12) / dst_w)); + VOP_SCL_SET(vop, win, scale_yrgb_y, ((src_h << 12) / dst_h)); + if (is_yuv) { + VOP_SCL_SET(vop, win, scale_cbcr_x, ((cbcr_src_w << 12) / dst_w)); + VOP_SCL_SET(vop, win, scale_cbcr_y, ((cbcr_src_h << 12) / dst_h)); + } + return; + } + if (!(vop_data->feature & VOP_FEATURE_ALPHA_SCALE)) { if (is_alpha_support(pixel_format) && (src_w != dst_w || src_h != dst_h)) @@ -2011,6 +2022,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_h = 4; actual_h = dsp_h * actual_h / drm_rect_height(dest); } + if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) && vop->version == VOP_VERSION(2, 2)) + dsp_h = dsp_h / 2; act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); @@ -2019,6 +2032,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, dsp_stx = dest->x1 + mode->crtc_htotal - mode->crtc_hsync_start; dsp_sty = dest->y1 + mode->crtc_vtotal - mode->crtc_vsync_start; + if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) && vop->version == VOP_VERSION(2, 2)) + dsp_sty = dest->y1 / 2 + mode->crtc_vtotal - mode->crtc_vsync_start; dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); s = to_rockchip_crtc_state(crtc->state); @@ -2046,7 +2061,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, if (win->phy->scl) scl_vop_cal_scl_fac(vop, win, actual_w, actual_h, - drm_rect_width(dest), drm_rect_height(dest), + drm_rect_width(dest), dsp_h, fb->format->format); if (VOP_WIN_SUPPORT(vop, win, color_key)) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index bedf2a99a793..280faffeded9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -254,6 +254,7 @@ struct vop_ctrl { struct vop_reg post_scl_factor; struct vop_reg post_scl_ctrl; struct vop_reg dsp_interlace; + struct vop_reg dsp_interlace_pol; struct vop_reg global_regdone_en; struct vop_reg auto_gate_en; struct vop_reg post_lb_mode; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index ba43530af653..e47f5e865537 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -1239,19 +1239,27 @@ static const struct vop_intr rk3036_intr = { static const struct vop_ctrl rk3036_ctrl_data = { .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30), + .sw_dac_sel = VOP_REG(RK3036_SYS_CTRL, 0x1, 29), .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), + .dsp_interlace = VOP_REG(RK3036_DSP_CTRL0, 0x1, 12), .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24), + .dsp_background = VOP_REG(RK3036_DSP_CTRL1, 0xffffff, 0), .dclk_pol = VOP_REG(RK3036_DSP_CTRL0, 0x1, 7), .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0x7, 4), .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27), + .tve_sw_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 25), + .dsp_interlace_pol = VOP_REG(RK3036_DSP_CTRL0, 0x1, 13), .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11), .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10), .dither_up_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 9), .dsp_layer_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 8), .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), + .tve_dclk_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 20), + .tve_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 21), .hdmi_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 22), .hdmi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 23), + .core_dclk_div = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 30), .hdmi_pin_pol = VOP_REG(RK3036_INT_SCALER, 0x7, 4), .rgb_en = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 24), .rgb_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 25), @@ -1261,6 +1269,8 @@ static const struct vop_ctrl rk3036_ctrl_data = { .mipi_dclk_pol = VOP_REG(RK3036_AXI_BUS_CTRL, 0x1, 29), .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), + .vs_st_end_f1 = VOP_REG(RK3036_DSP_VS_ST_END_F1, 0x1fff1fff, 0), + .vact_st_end_f1 = VOP_REG(RK3036_DSP_VACT_ST_END_F1, 0x1fff1fff, 0), .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0), };