From 3651973a75bf5d51fc52b7ecd246f619220e2788 Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Thu, 26 Oct 2017 10:03:36 +0800 Subject: [PATCH] drm/rockchip: vop: support yuv420 mode on rk3288w Change-Id: I1b0b41df5c521b1113407ab6a87353eb1ec23a84 Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 39 +++++++++++++++------ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 ++ drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 12 ++++--- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 17abc34b77f3..fb8489e4f9f4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -50,9 +50,9 @@ #define MAX_VOPS 2 #define VOP_REG_SUPPORT(vop, reg) \ - (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \ - reg.begin_minor <= VOP_MINOR(vop->data->version) && \ - reg.end_minor >= VOP_MINOR(vop->data->version) && \ + (!reg.major || (reg.major == VOP_MAJOR(vop->version) && \ + reg.begin_minor <= VOP_MINOR(vop->version) && \ + reg.end_minor >= VOP_MINOR(vop->version) && \ reg.mask)) #define VOP_WIN_SUPPORT(vop, win, name) \ @@ -191,6 +191,8 @@ struct vop { bool is_iommu_needed; bool is_enabled; + u32 version; + /* mutex vsync_ work */ struct mutex vsync_mutex; bool vsync_work_pending; @@ -935,6 +937,16 @@ static void vop_power_enable(struct drm_crtc *crtc) memcpy(vop->regsbak, vop->regs, vop->len); + if (VOP_CTRL_SUPPORT(vop, version)) { + uint32_t version = VOP_CTRL_GET(vop, version); + + /* + * Fixup rk3288w version. + */ + if (version && version == 0x0a05) + vop->version = VOP_VERSION(3, 1); + } + vop->is_enabled = true; return; @@ -1716,8 +1728,8 @@ vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode, return MODE_BAD_HVALUE; if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && - VOP_MAJOR(vop->data->version) == 3 && - VOP_MINOR(vop->data->version) <= 2) + VOP_MAJOR(vop->version) == 3 && + VOP_MINOR(vop->version) <= 2) return MODE_BAD; if (mode->flags & DRM_MODE_FLAG_DBLCLK) @@ -2011,18 +2023,24 @@ static void vop_crtc_enable(struct drm_crtc *crtc) VOP_CTRL_SET(vop, dither_down, val); VOP_CTRL_SET(vop, dclk_ddr, s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0); - VOP_CTRL_SET(vop, overlay_mode, is_yuv_output(s->bus_format)); + VOP_CTRL_SET(vop, hdmi_dclk_out_en, + s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0); + if (VOP_CTRL_SUPPORT(vop, overlay_mode)) { + VOP_CTRL_SET(vop, overlay_mode, is_yuv_output(s->bus_format)); + VOP_CTRL_SET(vop, bcsh_r2y_en, !is_yuv_output(s->bus_format)); + VOP_CTRL_SET(vop, bcsh_y2r_en, !is_yuv_output(s->bus_format)); + } else { + VOP_CTRL_SET(vop, bcsh_r2y_en, is_yuv_output(s->bus_format)); + } VOP_CTRL_SET(vop, dsp_out_yuv, is_yuv_output(s->bus_format)); - VOP_CTRL_SET(vop, bcsh_r2y_en, !is_yuv_output(s->bus_format)); - VOP_CTRL_SET(vop, bcsh_y2r_en, !is_yuv_output(s->bus_format)); /* * Background color is 10bit depth if vop version >= 3.5 */ if (!is_yuv_output(s->bus_format)) val = 0; - else if (VOP_MAJOR(vop->data->version) == 3 && - VOP_MINOR(vop->data->version) >= 5) + else if (VOP_MAJOR(vop->version) == 3 && + VOP_MINOR(vop->version) >= 5) val = 0x20010200; else val = 0x801080; @@ -3465,6 +3483,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) vop->data = vop_data; vop->drm_dev = drm_dev; vop->num_wins = num_wins; + vop->version = vop_data->version; dev_set_drvdata(dev, vop); ret = vop_win_init(vop); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 5f3a5710e81b..049ec30dfa9d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -87,6 +87,7 @@ struct vop_csc { }; struct vop_ctrl { + struct vop_reg version; struct vop_reg standby; struct vop_reg htotal_pw; struct vop_reg hact_st_end; @@ -108,6 +109,7 @@ struct vop_ctrl { struct vop_reg core_dclk_div; struct vop_reg dclk_ddr; struct vop_reg p2i_en; + struct vop_reg hdmi_dclk_out_en; struct vop_reg rgb_en; struct vop_reg lvds_en; struct vop_reg edp_en; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 1a9c032f5000..748809fb705d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -169,6 +169,7 @@ static const struct vop_win_phy *rk3288_area_data[] = { }; static const struct vop_ctrl rk3288_ctrl_data = { + .version = VOP_REG(RK3288_VERSION_INFO, 0xffff, 16), .standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22), .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), @@ -190,8 +191,9 @@ static const struct vop_ctrl rk3288_ctrl_data = { .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1), .core_dclk_div = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 4, 3, 4, -1), .p2i_en = VOP_REG_VER(RK3366_DSP_CTRL0, 0x1, 5, 3, 4, -1), - .dclk_ddr = VOP_REG_VER(RK3368_DSP_CTRL0, 0x1, 8, 3, 2, -1), + .dclk_ddr = VOP_REG_VER(RK3288_DSP_CTRL0, 0x1, 8, 3, 1, -1), .dp_en = VOP_REG_VER(RK3399_SYS_CTRL, 0x1, 11, 3, 5, -1), + .hdmi_dclk_out_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 1, 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), @@ -253,10 +255,10 @@ static const struct vop_ctrl rk3288_ctrl_data = { .bcsh_out_mode = VOP_REG(RK3288_BCSH_BCS, 0x3, 0), .bcsh_sin_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 0), .bcsh_cos_hue = VOP_REG(RK3288_BCSH_H, 0x1ff, 16), - .bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 2, -1), - .bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 2, -1), - .bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 2, -1), - .bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 2, -1), + .bcsh_r2y_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 6, 3, 1, -1), + .bcsh_r2y_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 4, 3, 1, -1), + .bcsh_y2r_csc_mode = VOP_REG_VER(RK3368_BCSH_CTRL, 0x3, 2, 3, 1, -1), + .bcsh_y2r_en = VOP_REG_VER(RK3368_BCSH_CTRL, 0x1, 0, 3, 1, -1), .bcsh_color_bar = VOP_REG(RK3288_BCSH_COLOR_BAR, 0xffffff, 8), .bcsh_en = VOP_REG(RK3288_BCSH_COLOR_BAR, 0x1, 0),