mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
drm/rockchip: vop2: Update hdr10 register
Change-Id: Iffcd3d07ab29ddac6c48ff250880daf4db39a9ab Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user