mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
drm/rockchip: vop2: Fix no signal when switch YUV420 to RGB/YUV444 in hdmi frl mode
The timing of YUV420 at the same resolution is different from other color formats. Therefore, if timing switch of vop is later than the switching process of hdmi, hdmi timing will be abnormal. In hdmi frl mode, input ipi clk is different from output link clk frequency, which makes it difficult to restore after the timing error. Therefore, it is necessary to ensure that the output mode of vop is switched before hdmi switch to ensure the correct timing Change-Id: I4633670f13a28975eb37a68ad597956d87a159c3 Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
@@ -8553,6 +8553,41 @@ static void vop3_setup_pipe_dly(struct vop2_video_port *vp, const struct vop2_zp
|
||||
}
|
||||
}
|
||||
|
||||
static void vop2_crtc_setup_output_mode(struct drm_crtc *crtc)
|
||||
{
|
||||
uint8_t out_mode;
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
struct vop2 *vop2 = vp->vop2;
|
||||
const struct vop2_data *vop2_data = vop2->data;
|
||||
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
|
||||
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
|
||||
|
||||
if ((vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
|
||||
!(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
|
||||
vcstate->output_if & VOP_OUTPUT_IF_BT656)
|
||||
out_mode = ROCKCHIP_OUT_MODE_P888;
|
||||
else
|
||||
out_mode = vcstate->output_mode;
|
||||
|
||||
if (out_mode == ROCKCHIP_OUT_MODE_YUV420) {
|
||||
if (vop2->version == VOP_VERSION_RK3588 && output_if_is_dp(vcstate->output_if))
|
||||
out_mode = RK3588_DP_OUT_MODE_YUV420;
|
||||
} else if (out_mode == ROCKCHIP_OUT_MODE_YUV422) {
|
||||
if (vop2->version == VOP_VERSION_RK3576 && output_if_is_edp(vcstate->output_if))
|
||||
out_mode = RK3576_EDP_OUT_MODE_YUV422;
|
||||
else if (vop2->version == VOP_VERSION_RK3588 &&
|
||||
output_if_is_edp(vcstate->output_if))
|
||||
out_mode = RK3588_EDP_OUTPUT_MODE_YUV422;
|
||||
else if (vop2->version == VOP_VERSION_RK3576 &&
|
||||
output_if_is_hdmi(vcstate->output_if))
|
||||
out_mode = RK3576_HDMI_OUT_MODE_YUV422;
|
||||
else if (output_if_is_dp(vcstate->output_if))
|
||||
out_mode = RK3588_DP_OUT_MODE_YUV422;
|
||||
}
|
||||
|
||||
VOP_MODULE_SET(vop2, vp, out_mode, out_mode);
|
||||
}
|
||||
|
||||
static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
|
||||
{
|
||||
struct vop2_video_port *vp = to_vop2_video_port(crtc);
|
||||
@@ -8988,6 +9023,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_sta
|
||||
vop3_setup_pipe_dly(vp, NULL);
|
||||
|
||||
vop2_crtc_csu_set_rate(crtc);
|
||||
vop2_crtc_setup_output_mode(crtc);
|
||||
|
||||
vop2_cfg_done(crtc);
|
||||
|
||||
/*
|
||||
@@ -11019,33 +11056,9 @@ static void vop2_cfg_update(struct drm_crtc *crtc,
|
||||
struct vop2_video_port *splice_vp = &vop2->vps[vp_data->splice_vp_id];
|
||||
uint32_t val;
|
||||
uint32_t r, g, b;
|
||||
uint8_t out_mode;
|
||||
|
||||
spin_lock(&vop2->reg_lock);
|
||||
|
||||
if ((vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
|
||||
!(vp_data->feature & VOP_FEATURE_OUTPUT_10BIT)) ||
|
||||
vcstate->output_if & VOP_OUTPUT_IF_BT656)
|
||||
out_mode = ROCKCHIP_OUT_MODE_P888;
|
||||
else
|
||||
out_mode = vcstate->output_mode;
|
||||
|
||||
if (out_mode == ROCKCHIP_OUT_MODE_YUV420) {
|
||||
if (vop2->version == VOP_VERSION_RK3588 && output_if_is_dp(vcstate->output_if))
|
||||
out_mode = RK3588_DP_OUT_MODE_YUV420;
|
||||
} else if (out_mode == ROCKCHIP_OUT_MODE_YUV422) {
|
||||
if (vop2->version == VOP_VERSION_RK3576 && output_if_is_edp(vcstate->output_if))
|
||||
out_mode = RK3576_EDP_OUT_MODE_YUV422;
|
||||
else if (vop2->version == VOP_VERSION_RK3588 && output_if_is_edp(vcstate->output_if))
|
||||
out_mode = RK3588_EDP_OUTPUT_MODE_YUV422;
|
||||
else if (vop2->version == VOP_VERSION_RK3576 && output_if_is_hdmi(vcstate->output_if))
|
||||
out_mode = RK3576_HDMI_OUT_MODE_YUV422;
|
||||
else if (output_if_is_dp(vcstate->output_if))
|
||||
out_mode = RK3588_DP_OUT_MODE_YUV422;
|
||||
}
|
||||
|
||||
VOP_MODULE_SET(vop2, vp, out_mode, out_mode);
|
||||
|
||||
vop2_post_color_swap(crtc);
|
||||
|
||||
vop2_dither_setup(vcstate, crtc);
|
||||
@@ -11183,6 +11196,14 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_stat
|
||||
vop2_wait_for_scan_timing_from_the_assigned_line(vp, current_line, vtotal >> 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* In some cases(such as seamless hdr switching) the crtc
|
||||
* atomic enable will not be run, but vop output mode may
|
||||
* also be modified. So vop2_crtc_setup_output_mode must
|
||||
* be call in crtc atomic flush
|
||||
*/
|
||||
vop2_crtc_setup_output_mode(crtc);
|
||||
|
||||
vop2_cfg_update(crtc, old_cstate);
|
||||
|
||||
if (!vop2->is_iommu_enabled && vop2->is_iommu_needed) {
|
||||
|
||||
Reference in New Issue
Block a user