Commit 40dad89c authored by Jessica Zhang's avatar Jessica Zhang Committed by Abhinav Kumar

drm/msm/dpu: Don't always set merge_3d pending flush

Don't set the merge_3d pending flush bits if the mode_3d is
BLEND_3D_NONE.

Always flushing merge_3d can cause timeout issues when there are
multiple commits with concurrent writeback enabled.

This is because the video phys enc waits for the hw_ctl flush register
to be completely cleared [1] in its wait_for_commit_done(), but the WB
encoder always sets the merge_3d pending flush during each commit
regardless of if the merge_3d is actually active.

This means that the hw_ctl flush register will never be 0 when there are
multiple CWB commits and the video phys enc will hit vblank timeout
errors after the first CWB commit.

[1] commit fe9df3f5 ("drm/msm/dpu: add real wait_for_commit_done()")

Fixes: 3e79527a ("drm/msm/dpu: enable merge_3d support on sm8150/sm8250")
Fixes: d7d0e73f ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback")
Signed-off-by: default avatarJessica Zhang <quic_jesszhan@quicinc.com>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/619092/
Link: https://lore.kernel.org/r/20241009-mode3d-fix-v1-1-c0258354fadc@quicinc.comSigned-off-by: default avatarAbhinav Kumar <quic_abhinavk@quicinc.com>
parent e4a45582
...@@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) ...@@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
struct dpu_hw_ctl *ctl; struct dpu_hw_ctl *ctl;
const struct msm_format *fmt; const struct msm_format *fmt;
u32 fmt_fourcc; u32 fmt_fourcc;
u32 mode_3d;
ctl = phys_enc->hw_ctl; ctl = phys_enc->hw_ctl;
fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0); fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0);
mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
DPU_DEBUG_VIDENC(phys_enc, "\n"); DPU_DEBUG_VIDENC(phys_enc, "\n");
...@@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) ...@@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
goto skip_flush; goto skip_flush;
ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d) if (mode_3d && ctl->ops.update_pending_flush_merge_3d &&
phys_enc->hw_pp->merge_3d)
ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm) if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm)
......
...@@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) ...@@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
struct dpu_hw_pingpong *hw_pp; struct dpu_hw_pingpong *hw_pp;
struct dpu_hw_cdm *hw_cdm; struct dpu_hw_cdm *hw_cdm;
u32 pending_flush = 0; u32 pending_flush = 0;
u32 mode_3d;
if (!phys_enc) if (!phys_enc)
return; return;
...@@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) ...@@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
hw_pp = phys_enc->hw_pp; hw_pp = phys_enc->hw_pp;
hw_ctl = phys_enc->hw_ctl; hw_ctl = phys_enc->hw_ctl;
hw_cdm = phys_enc->hw_cdm; hw_cdm = phys_enc->hw_cdm;
mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
...@@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) ...@@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
if (hw_ctl->ops.update_pending_flush_wb) if (hw_ctl->ops.update_pending_flush_wb)
hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx); hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx);
if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d) if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d &&
hw_pp && hw_pp->merge_3d)
hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
hw_pp->merge_3d->idx); hw_pp->merge_3d->idx);
......
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