From ae112b461ec48861f763a579b7eddaa3ace543b0 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Mon, 21 Dec 2020 16:23:51 +0800 Subject: [PATCH] drm/rockchip: vop2: Update hdr10 register Change-Id: Iffcd3d07ab29ddac6c48ff250880daf4db39a9ab Signed-off-by: Andy Yan --- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 11 +- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 116 ++++++++++--------- drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 13 ++- 3 files changed, 76 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index f6632c45667d..f9ca1ca99812 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -545,6 +545,7 @@ struct vop2_video_port_regs { struct vop_reg mipi_dual_channel_swap; struct vop_reg dsp_lut_en; + struct vop_reg hdr10_en; struct vop_reg hdr_lut_update_en; struct vop_reg hdr_lut_mode; struct vop_reg hdr_lut_mst; @@ -561,11 +562,11 @@ struct vop2_video_port_regs { struct vop_reg hdr2sdr_dst_min; struct vop_reg hdr2sdr_dst_max; struct vop_reg hdr2sdr_normfacgamma; - struct vop_reg hdr2sdr_eetf_oetf_y0_offset; - struct vop_reg hdr2sdr_sat_y0_offset; - struct vop_reg sdr2hdr_eotf_oetf_y0_offset; - struct vop_reg sdr2hdr_oetf_dx_pow1_offset; - struct vop_reg sdr2hdr_oetf_xn1_offset; + uint32_t hdr2sdr_eetf_oetf_y0_offset; + uint32_t hdr2sdr_sat_y0_offset; + uint32_t sdr2hdr_eotf_oetf_y0_offset; + uint32_t sdr2hdr_oetf_dx_pow1_offset; + uint32_t sdr2hdr_oetf_xn1_offset; struct vop_reg hdr_src_color_ctrl; struct vop_reg hdr_dst_color_ctrl; struct vop_reg hdr_src_alpha_ctrl; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index ee030842bf81..08b1fa8a8af7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -166,6 +166,11 @@ enum vop2_afbc_format { VOP2_AFBC_FMT_YUV422_10BIT = 0xe, }; +enum vop2_hdr_lut_mode { + VOP2_HDR_LUT_MODE_AXI, + VOP2_HDR_LUT_MODE_AHB, +}; + enum vop2_pending { VOP_PENDING_FB_UNREF, }; @@ -603,6 +608,7 @@ static void vop2_load_hdr2sdr_table(struct vop2_video_port *vp) const struct vop2_data *vop2_data = vop2->data; const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; const struct vop_hdr_table *table = vp_data->hdr_table; + const struct vop2_video_port_regs *regs = vp->regs; uint32_t hdr2sdr_eetf_oetf_yn[33]; int i; @@ -610,17 +616,12 @@ static void vop2_load_hdr2sdr_table(struct vop2_video_port *vp) hdr2sdr_eetf_oetf_yn[i] = table->hdr2sdr_eetf_yn[i] + (table->hdr2sdr_bt1886oetf_yn[i] << 16); - vop2_writel(vop2, table->hdr2sdr_eetf_oetf_y0_offset, - hdr2sdr_eetf_oetf_yn[0]); - for (i = 1; i < 33; i++) - vop2_writel(vop2, - table->hdr2sdr_eetf_oetf_y1_offset + (i - 1) * 4, + for (i = 0; i < 33; i++) + vop2_writel(vop2, regs->hdr2sdr_eetf_oetf_y0_offset + i * 4, hdr2sdr_eetf_oetf_yn[i]); - vop2_writel(vop2, table->hdr2sdr_sat_y0_offset, - table->hdr2sdr_sat_yn[0]); - for (i = 1; i < 9; i++) - vop2_writel(vop2, table->hdr2sdr_sat_y1_offset + (i - 1) * 4, + for (i = 0; i < 9; i++) + vop2_writel(vop2, regs->hdr2sdr_sat_y0_offset + i * 4, table->hdr2sdr_sat_yn[i]); } @@ -630,6 +631,7 @@ static void vop2_load_sdr2hdr_table(struct vop2_video_port *vp, int sdr2hdr_tf) const struct vop2_data *vop2_data = vop2->data; const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; const struct vop_hdr_table *table = vp_data->hdr_table; + const struct vop2_video_port_regs *regs = vp->regs; uint32_t sdr2hdr_eotf_oetf_yn[65]; uint32_t sdr2hdr_oetf_dx_dxpow[64]; int i; @@ -648,21 +650,20 @@ static void vop2_load_sdr2hdr_table(struct vop2_video_port *vp, int sdr2hdr_tf) table->sdr2hdr_bt1886eotf_yn_for_hlg_hdr[i] + (table->sdr2hdr_st2084oetf_yn_for_hlg_hdr[i] << 18); } - vop2_writel(vop2, table->sdr2hdr_eotf_oetf_y0_offset, - sdr2hdr_eotf_oetf_yn[0]); - for (i = 1; i < 65; i++) - vop2_writel(vop2, table->sdr2hdr_eotf_oetf_y1_offset + - (i - 1) * 4, sdr2hdr_eotf_oetf_yn[i]); + + for (i = 0; i < 65; i++) + vop2_writel(vop2, regs->sdr2hdr_eotf_oetf_y0_offset + i * 4, + sdr2hdr_eotf_oetf_yn[i]); for (i = 0; i < 64; i++) { sdr2hdr_oetf_dx_dxpow[i] = table->sdr2hdr_st2084oetf_dxn[i] + (table->sdr2hdr_st2084oetf_dxn_pow2[i] << 16); - vop2_writel(vop2, table->sdr2hdr_oetf_dx_dxpow1_offset + i * 4, + vop2_writel(vop2, regs->sdr2hdr_oetf_dx_pow1_offset + i * 4, sdr2hdr_oetf_dx_dxpow[i]); } for (i = 0; i < 63; i++) - vop2_writel(vop2, table->sdr2hdr_oetf_xn1_offset + i * 4, + vop2_writel(vop2, regs->sdr2hdr_oetf_xn1_offset + i * 4, table->sdr2hdr_st2084oetf_xn[i]); } @@ -2537,6 +2538,7 @@ static void vop2_crtc_regs_dump(struct drm_crtc *crtc, struct seq_file *s) RK3568_ESMART1_CTRL0, RK3568_SMART0_CTRL0, RK3568_SMART1_CTRL0, + RK3568_HDR_LUT_CTRL, }; uint32_t buf[64]; unsigned int len = ARRAY_SIZE(buf); @@ -3221,11 +3223,14 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id) const struct vop2_data *vop2_data = vop2->data; const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id]; const struct vop_hdr_table *hdr_table = vp_data->hdr_table; - int hdr_en = 0; - int hdr2sdr_en = 0; - int sdr2hdr_en = 0; - int sdr2hdr_tf = 0; - int sdr2hdr_r2r_mode = 0; + uint32_t lut_mode = VOP2_HDR_LUT_MODE_AHB; + uint32_t sdr2hdr_r2r_mode = 0; + bool hdr_en = 0; + bool hdr2sdr_en = 0; + bool sdr2hdr_en = 0; + bool sdr2hdr_tf = 0; + bool hdr2sdr_tf_update = 1; + bool sdr2hdr_tf_update = 1; /* * Check whether this video port support hdr or not @@ -3249,24 +3254,28 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id) * the other attached win must for ui, and should do sdr2hdr. * */ - if (hdr_en) { - if (vcstate->eotf < SMPTE_ST2084) - hdr2sdr_en = 1; - if ((vcstate->eotf == SMPTE_ST2084) && (vp->nr_wins > 1)) { - sdr2hdr_en = 1; - sdr2hdr_r2r_mode = BT709_TO_BT2020; + if (vp->hdr_in && !vp->hdr_out) + hdr2sdr_en = 1; + + if (vp->hdr_out) + sdr2hdr_en = 1; + + if (sdr2hdr_en) { + sdr2hdr_r2r_mode = BT709_TO_BT2020; + if (vp->hdr_in) sdr2hdr_tf = SDR2HDR_FOR_HDR; - } - } else { - if (vcstate->eotf == SMPTE_ST2084) { - sdr2hdr_en = 1; + else sdr2hdr_tf = SDR2HDR_FOR_BT2020; - sdr2hdr_r2r_mode = BT709_TO_BT2020; - } } + VOP_MODULE_SET(vop2, vp, hdr10_en, hdr_en); + + if (hdr2sdr_en || sdr2hdr_en) + VOP_MODULE_SET(vop2, vp, hdr_lut_mode, lut_mode); + if (hdr2sdr_en) { - vop2_load_hdr2sdr_table(vp); + if (hdr2sdr_tf_update) + vop2_load_hdr2sdr_table(vp); VOP_MODULE_SET(vop2, vp, hdr2sdr_src_min, hdr_table->hdr2sdr_src_range_min); VOP_MODULE_SET(vop2, vp, hdr2sdr_src_max, hdr_table->hdr2sdr_src_range_max); VOP_MODULE_SET(vop2, vp, hdr2sdr_normfaceetf, hdr_table->hdr2sdr_normfaceetf); @@ -3274,19 +3283,17 @@ static void vop2_setup_hdr10(struct vop2_video_port *vp, uint8_t win_phys_id) VOP_MODULE_SET(vop2, vp, hdr2sdr_dst_max, hdr_table->hdr2sdr_dst_range_max); VOP_MODULE_SET(vop2, vp, hdr2sdr_normfacgamma, hdr_table->hdr2sdr_normfacgamma); } + VOP_MODULE_SET(vop2, vp, hdr2sdr_en, hdr2sdr_en); if (sdr2hdr_en) { - vop2_load_sdr2hdr_table(vp, sdr2hdr_tf); - VOP_MODULE_SET(vop2, vp, sdr2hdr_eotf_en, 1); - VOP_MODULE_SET(vop2, vp, sdr2hdr_r2r_en, 1); + if (sdr2hdr_tf_update) + vop2_load_sdr2hdr_table(vp, sdr2hdr_tf); VOP_MODULE_SET(vop2, vp, sdr2hdr_r2r_mode, sdr2hdr_r2r_mode); - VOP_MODULE_SET(vop2, vp, sdr2hdr_oetf_en, 1); - - } else { - VOP_MODULE_SET(vop2, vp, sdr2hdr_bypass_en, 1); } - - VOP_MODULE_SET(vop2, vp, hdr2sdr_en, hdr2sdr_en); + VOP_MODULE_SET(vop2, vp, sdr2hdr_oetf_en, sdr2hdr_en); + VOP_MODULE_SET(vop2, vp, sdr2hdr_eotf_en, sdr2hdr_en); + VOP_MODULE_SET(vop2, vp, sdr2hdr_r2r_en, sdr2hdr_en); + VOP_MODULE_SET(vop2, vp, sdr2hdr_bypass_en, !sdr2hdr_en); } static void vop2_parse_alpha(struct vop2_alpha *alpha, int pixel_alpha_en, @@ -3561,20 +3568,23 @@ static void vop2_setup_dly_for_vp(struct vop2_video_port *vp) struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; u16 hsync_len = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; u16 hdisplay = adjusted_mode->crtc_hdisplay; - u32 bg_dly, pre_scan_dly; + u32 bg_dly = vp_data->pre_scan_max_dly[0]; + u32 pre_scan_dly; if (vp_data->hdr_table) { - if (vp->hdr_in && !vp->hdr_out) - bg_dly = vp_data->pre_scan_max_dly[1] - vp->bg_ovl_dly; - else if (vp->hdr_out) - bg_dly = vp_data->pre_scan_max_dly[2] - vp->bg_ovl_dly; - else - bg_dly = vp_data->pre_scan_max_dly[3] - vp->bg_ovl_dly; - - } else { - bg_dly = vp_data->pre_scan_max_dly[0] - vp->bg_ovl_dly; + if (vp->hdr_in) { + if (vp->hdr_out) + bg_dly = vp_data->pre_scan_max_dly[2]; + } else { + if (vp->hdr_out) + bg_dly = vp_data->pre_scan_max_dly[1]; + else + bg_dly = vp_data->pre_scan_max_dly[3]; + } } + bg_dly -= vp->bg_ovl_dly; + pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; pre_scan_dly = (pre_scan_dly << 16) | hsync_len; VOP_MODULE_SET(vop2, vp, bg_dly, bg_dly); diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 51ca06ba581d..78387ec5d9a2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -380,6 +380,7 @@ static const struct vop2_video_port_regs rk3568_vop_vp0_regs = { .mipi_dual_en = VOP_REG(RK3568_VP0_MIPI_CTRL, 0x1, 20), .mipi_dual_channel_swap = VOP_REG(RK3568_VP0_MIPI_CTRL, 0x1, 21), .dsp_lut_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 28), + .hdr10_en = VOP_REG(RK3568_OVL_CTRL, 0x1, 4), .hdr_lut_update_en = VOP_REG(RK3568_HDR_LUT_CTRL, 0x1, 0), .hdr_lut_mode = VOP_REG(RK3568_HDR_LUT_CTRL, 0x1, 1), .hdr_lut_mst = VOP_REG(RK3568_HDR_LUT_MST, 0xffffffff, 0), @@ -396,11 +397,11 @@ static const struct vop2_video_port_regs rk3568_vop_vp0_regs = { .hdr2sdr_dst_min = VOP_REG(RK3568_HDR2SDR_DST_RANGE, 0xffff, 0), .hdr2sdr_dst_max = VOP_REG(RK3568_HDR2SDR_DST_RANGE, 0xffff, 16), .hdr2sdr_normfacgamma = VOP_REG(RK3568_HDR2SDR_NORMFACCGAMMA, 0xffff, 0), - .hdr2sdr_eetf_oetf_y0_offset = VOP_REG(RK3568_HDR_EETF_OETF_Y0, 0xffffffff, 0), - .hdr2sdr_sat_y0_offset = VOP_REG(RK3568_HDR_SAT_Y0, 0xffffffff, 0), - .sdr2hdr_eotf_oetf_y0_offset = VOP_REG(RK3568_HDR_EOTF_OETF_Y0, 0xffffffff, 0), - .sdr2hdr_oetf_dx_pow1_offset = VOP_REG(RK3568_HDR_OETF_DX_POW1, 0xffffffff, 0), - .sdr2hdr_oetf_xn1_offset = VOP_REG(RK3568_HDR_OETF_XN1, 0xffffffff, 0), + .hdr2sdr_eetf_oetf_y0_offset = RK3568_HDR_EETF_OETF_Y0, + .hdr2sdr_sat_y0_offset = RK3568_HDR_SAT_Y0, + .sdr2hdr_eotf_oetf_y0_offset = RK3568_HDR_EOTF_OETF_Y0, + .sdr2hdr_oetf_dx_pow1_offset = RK3568_HDR_OETF_DX_POW1, + .sdr2hdr_oetf_xn1_offset = RK3568_HDR_OETF_XN1, .hdr_src_color_ctrl = VOP_REG(RK3568_HDR0_SRC_COLOR_CTRL, 0xffffffff, 0), .hdr_dst_color_ctrl = VOP_REG(RK3568_HDR0_DST_COLOR_CTRL, 0xffffffff, 0), .hdr_src_alpha_ctrl = VOP_REG(RK3568_HDR0_SRC_ALPHA_CTRL, 0xffffffff, 0), @@ -519,7 +520,7 @@ static const struct vop2_video_port_data rk3568_vop_video_ports[] = { .soc_id = 0x3568, .feature = VOP_FEATURE_OUTPUT_10BIT, .max_output = { 4096, 2304 }, - .pre_scan_max_dly = { 40, 49, 33, 42 }, + .pre_scan_max_dly = { 69, 53, 53, 42 }, .intr = &rk3568_vp0_intr, .hdr_table = &rk3568_vop_hdr_table, .regs = &rk3568_vop_vp0_regs,