drm/rockchip: vop: support yuv420 mode on rk3288w

Change-Id: I1b0b41df5c521b1113407ab6a87353eb1ec23a84
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
This commit is contained in:
Mark Yao
2017-10-26 10:03:36 +08:00
parent 0f391989ce
commit 3651973a75
3 changed files with 38 additions and 15 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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),