drm/rockchip: vop2: Fix HDR2SDR

1. Add hdr2sdr_bypass_en and hdr2sdr_auto_gating_en bits, which
unmentationed in TRM.
2. HDR2SDR and SDR2HDR should overlay in RGB color space.
3. Window csc should be disabled when HDR2SDR or SDR2HDR enabled.

Change-Id: Ic3e15c3f0ddb5adf23a4962366749228f5117a9f
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
Andy Yan
2020-12-24 15:55:43 +08:00
committed by Tao Huang
parent f2475bcde5
commit 363b2d2f7b
3 changed files with 52 additions and 16 deletions

View File

@@ -557,8 +557,10 @@ struct vop2_video_port_regs {
struct vop_reg sdr2hdr_r2r_mode;
struct vop_reg sdr2hdr_oetf_en;
struct vop_reg sdr2hdr_bypass_en;
struct vop_reg sdr2hdr_gating_en;
struct vop_reg sdr2hdr_auto_gating_en;
struct vop_reg hdr2sdr_en;
struct vop_reg hdr2sdr_bypass_en;
struct vop_reg hdr2sdr_auto_gating_en;
struct vop_reg hdr2sdr_src_min;
struct vop_reg hdr2sdr_src_max;
struct vop_reg hdr2sdr_normfaceetf;

View File

@@ -216,6 +216,8 @@ struct vop2_plane_state {
dma_addr_t yrgb_mst;
dma_addr_t uv_mst;
bool afbc_en;
bool hdr_in;
bool hdr2sdr_en;
bool r2y_en;
bool y2r_en;
uint32_t csc_mode;
@@ -349,6 +351,11 @@ struct vop2_video_port {
*
*/
bool hdr_out;
/*
* @sdr2hdr_en: All the ui plane need to do sdr2hdr for a hdr_out enabled vp.
*
*/
bool sdr2hdr_en;
/**
* @bg_ovl_dly: The timing delay from background layer
@@ -1286,18 +1293,29 @@ static void vop2_disable_all_planes_for_crtc(struct drm_crtc *crtc)
* 11. RGB --> bypass --> RGB_OUTPUT(709)
*/
static void vop2_setup_csc_mode(struct rockchip_crtc_state *vcstate,
static void vop2_setup_csc_mode(struct vop2_video_port *vp,
struct vop2_plane_state *vpstate)
{
struct drm_plane_state *pstate = &vpstate->base;
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
int is_input_yuv = is_yuv_support(pstate->fb->format->format);
int is_output_yuv = is_yuv_output(vcstate->bus_format);
int is_output_yuv = vcstate->yuv_overlay;
int input_csc = vpstate->color_space;
int output_csc = vcstate->color_space;
vpstate->y2r_en = 0;
vpstate->r2y_en = 0;
vpstate->csc_mode = 0;
/* hdr2sdr and sdr2hdr will do csc itself */
if (vpstate->hdr2sdr_en) {
/* This is hdr2sdr enabled plane */
return;
} else if (!vpstate->hdr_in && vp->sdr2hdr_en) {
/* This is sdr2hdr enabled plane */
return;
}
if (is_input_yuv && !is_output_yuv) {
vpstate->y2r_en = 1;
vpstate->csc_mode = vop2_convert_csc_mode(input_csc);
@@ -1872,8 +1890,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_plane_s
struct drm_plane_state *pstate = plane->state;
struct drm_crtc *crtc = pstate->crtc;
struct vop2_win *win = to_vop2_win(plane);
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
struct vop2 *vop2 = win->vop2;
struct drm_framebuffer *fb = pstate->fb;
@@ -1963,7 +1981,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, struct drm_plane_s
format = vop2_convert_format(fb->format->format);
vop2_setup_csc_mode(vcstate, vpstate);
vop2_setup_csc_mode(vp, vpstate);
spin_lock(&vop2->reg_lock);
@@ -3134,7 +3152,6 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
else
out_mode = vcstate->output_mode;
VOP_MODULE_SET(vop2, vp, out_mode, out_mode);
VOP_MODULE_SET(vop2, vp, overlay_mode, is_yuv_output(vcstate->bus_format));
if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
VOP_MODULE_SET(vop2, vp, dsp_data_swap, DSP_RB_SWAP);
@@ -3190,11 +3207,6 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state
clk_set_rate(vp->dclk, adjusted_mode->crtc_clock * 1000);
if (is_yuv_output(vcstate->bus_format))
val = 0x20010200;
else
val = 0;
VOP_MODULE_SET(vop2, vp, dsp_background, val);
vop2_post_config(crtc);
vop2_cfg_done(crtc);
@@ -3236,8 +3248,8 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id)
bool hdr2sdr_en = 0;
bool sdr2hdr_en = 0;
bool sdr2hdr_tf = 0;
bool hdr2sdr_tf_update = 1;
bool sdr2hdr_tf_update = 1;
bool hdr2sdr_tf_update = 0;
bool sdr2hdr_tf_update = 0;
/*
* Check whether this video port support hdr or not
@@ -3264,9 +3276,13 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id)
if (vp->hdr_in && !vp->hdr_out)
hdr2sdr_en = 1;
if (vp->hdr_out)
if (vp->hdr_out && (vp->nr_wins > 1))
sdr2hdr_en = 1;
vp->sdr2hdr_en = sdr2hdr_en;
vpstate->hdr_in = hdr_en;
vpstate->hdr2sdr_en = hdr2sdr_en;
if (sdr2hdr_en) {
sdr2hdr_r2r_mode = BT709_TO_BT2020;
if (vp->hdr_in)
@@ -3277,8 +3293,13 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id)
VOP_MODULE_SET(vop2, vp, hdr10_en, hdr_en);
if (hdr2sdr_en || sdr2hdr_en)
if (hdr2sdr_en || sdr2hdr_en) {
/*
* HDR2SDR and SDR2HDR must overlay in yuv color space
*/
vcstate->yuv_overlay = false;
VOP_MODULE_SET(vop2, vp, hdr_lut_mode, lut_mode);
}
if (hdr2sdr_en) {
if (hdr2sdr_tf_update)
@@ -3291,6 +3312,7 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id)
VOP_MODULE_SET(vop2, vp, hdr2sdr_normfacgamma, hdr_table->hdr2sdr_normfacgamma);
}
VOP_MODULE_SET(vop2, vp, hdr2sdr_en, hdr2sdr_en);
VOP_MODULE_SET(vop2, vp, hdr2sdr_bypass_en, !hdr2sdr_en);
if (sdr2hdr_en) {
if (sdr2hdr_tf_update)
@@ -3778,10 +3800,20 @@ static void vop2_cfg_update(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
struct vop2 *vop2 = vp->vop2;
uint32_t val;
spin_lock(&vop2->reg_lock);
VOP_MODULE_SET(vop2, vp, overlay_mode, vcstate->yuv_overlay);
if (vcstate->yuv_overlay)
val = 0x20010200;
else
val = 0;
VOP_MODULE_SET(vop2, vp, dsp_background, val);
vop2_tv_config_update(crtc, old_crtc_state);
vop2_post_config(crtc);

View File

@@ -391,8 +391,10 @@ static const struct vop2_video_port_regs rk3568_vop_vp0_regs = {
.sdr2hdr_r2r_mode = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 2),
.sdr2hdr_oetf_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 3),
.sdr2hdr_bypass_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 8),
.sdr2hdr_gating_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 9),
.sdr2hdr_auto_gating_en = VOP_REG(RK3568_SDR2HDR_CTRL, 0x1, 9),
.hdr2sdr_en = VOP_REG(RK3568_HDR2SDR_CTRL, 0x1, 0),
.hdr2sdr_bypass_en = VOP_REG(RK3568_HDR2SDR_CTRL, 0x1, 8),
.hdr2sdr_auto_gating_en = VOP_REG(RK3568_HDR2SDR_CTRL, 0x1, 9),
.hdr2sdr_src_min = VOP_REG(RK3568_HDR2SDR_SRC_RANGE, 0x3fff, 0),
.hdr2sdr_src_max = VOP_REG(RK3568_HDR2SDR_SRC_RANGE, 0x3fff, 16),
.hdr2sdr_normfaceetf = VOP_REG(RK3568_HDR2SDR_NORMFACEETF, 0x7ff, 0),