Commit a5c0fa44 authored by Urja Rannikko's avatar Urja Rannikko Committed by Heiko Stuebner

drm/rockchip: vop: Support dithering to RGB666

Splits out the dither register bits and introduces
the same config enumerations as in the rockchip kernel tree.
Tested to fix the banding on my ASUS C201.
Signed-off-by: default avatarUrja Rannikko <urjaman@gmail.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20190318154412.26994-1-urjaman@gmail.com
parent 530b2842
...@@ -1029,6 +1029,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -1029,6 +1029,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start; u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
u16 vact_end = vact_st + vdisplay; u16 vact_end = vact_st + vdisplay;
uint32_t pin_pol, val; uint32_t pin_pol, val;
int dither_bpc = s->output_bpc ? s->output_bpc : 10;
int ret; int ret;
mutex_lock(&vop->vop_lock); mutex_lock(&vop->vop_lock);
...@@ -1086,11 +1087,19 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -1086,11 +1087,19 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
s->output_mode = ROCKCHIP_OUT_MODE_P888; s->output_mode = ROCKCHIP_OUT_MODE_P888;
if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && s->output_bpc == 8) if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8)
VOP_REG_SET(vop, common, pre_dither_down, 1); VOP_REG_SET(vop, common, pre_dither_down, 1);
else else
VOP_REG_SET(vop, common, pre_dither_down, 0); VOP_REG_SET(vop, common, pre_dither_down, 0);
if (dither_bpc == 6) {
VOP_REG_SET(vop, common, dither_down_sel, DITHER_DOWN_ALLEGRO);
VOP_REG_SET(vop, common, dither_down_mode, RGB888_TO_RGB666);
VOP_REG_SET(vop, common, dither_down_en, 1);
} else {
VOP_REG_SET(vop, common, dither_down_en, 0);
}
VOP_REG_SET(vop, common, out_mode, s->output_mode); VOP_REG_SET(vop, common, out_mode, s->output_mode);
VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len); VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
......
...@@ -71,7 +71,9 @@ struct vop_common { ...@@ -71,7 +71,9 @@ struct vop_common {
struct vop_reg dsp_blank; struct vop_reg dsp_blank;
struct vop_reg data_blank; struct vop_reg data_blank;
struct vop_reg pre_dither_down; struct vop_reg pre_dither_down;
struct vop_reg dither_down; struct vop_reg dither_down_sel;
struct vop_reg dither_down_mode;
struct vop_reg dither_down_en;
struct vop_reg dither_up; struct vop_reg dither_up;
struct vop_reg gate_en; struct vop_reg gate_en;
struct vop_reg mmu_en; struct vop_reg mmu_en;
...@@ -287,6 +289,16 @@ enum scale_down_mode { ...@@ -287,6 +289,16 @@ enum scale_down_mode {
SCALE_DOWN_AVG = 0x1 SCALE_DOWN_AVG = 0x1
}; };
enum dither_down_mode {
RGB888_TO_RGB565 = 0x0,
RGB888_TO_RGB666 = 0x1
};
enum dither_down_mode_sel {
DITHER_DOWN_ALLEGRO = 0x0,
DITHER_DOWN_FRC = 0x1
};
enum vop_pol { enum vop_pol {
HSYNC_POSITIVE = 0, HSYNC_POSITIVE = 0,
VSYNC_POSITIVE = 1, VSYNC_POSITIVE = 1,
......
...@@ -137,6 +137,9 @@ static const struct vop_common rk3036_common = { ...@@ -137,6 +137,9 @@ static const struct vop_common rk3036_common = {
.standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30), .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
.out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0), .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
.dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24), .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
.dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
.dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
.dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
.cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0), .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
}; };
...@@ -200,6 +203,9 @@ static const struct vop_common px30_common = { ...@@ -200,6 +203,9 @@ static const struct vop_common px30_common = {
.standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1), .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
.out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16), .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
.dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14), .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
.dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
.dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
.dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
.cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0), .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
}; };
...@@ -365,6 +371,8 @@ static const struct vop_common rk3066_common = { ...@@ -365,6 +371,8 @@ static const struct vop_common rk3066_common = {
.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1), .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0), .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0), .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
.dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
.dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
}; };
...@@ -458,6 +466,9 @@ static const struct vop_common rk3188_common = { ...@@ -458,6 +466,9 @@ static const struct vop_common rk3188_common = {
.standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30), .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
.out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0), .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
.cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0), .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
.dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
.dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
.dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24),
}; };
...@@ -585,8 +596,10 @@ static const struct vop_common rk3288_common = { ...@@ -585,8 +596,10 @@ static const struct vop_common rk3288_common = {
.standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22), .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
.gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23), .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
.mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20), .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
.pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1), .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
.dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
.dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6), .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
.data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19), .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
.dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
...@@ -878,7 +891,10 @@ static const struct vop_misc rk3328_misc = { ...@@ -878,7 +891,10 @@ static const struct vop_misc rk3328_misc = {
static const struct vop_common rk3328_common = { static const struct vop_common rk3328_common = {
.standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22), .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
.dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1), .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
.dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
.dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
.pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
.dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6), .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
.dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment