disp: msm: sde: delay cwb done wait for last frame

Commit Ifa100424733 ("disp: msm: sde: delay
encoder disable for clone mode") delays the CWB
encoder disable but it is also skipping the CWB
disable flush. That can cause the underrun on dp
display if it uses the same 3d_merge HW block. This
change reverts the portion of original code and
only delays the last cwb frame done wait. It still
keep the last CWB frame done wait as it is if crtc
is also moving to inactive state.

Change-Id: I3461188a35197f2925899ceea7ef705adf00a398
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
This commit is contained in:
Dhaval Patel
2020-09-29 11:21:07 -07:00
rodzic 90c3cec488
commit 8d6fea832e
6 zmienionych plików z 105 dodań i 77 usunięć

Wyświetl plik

@@ -1074,7 +1074,8 @@ static void _sde_encoder_phys_wb_frame_done_helper(void *arg, bool frame_error)
SDE_DEBUG("[wb:%d,%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count);
/* don't notify upper layer for internal commit */
if (phys_enc->enable_state == SDE_ENC_DISABLING)
if (phys_enc->enable_state == SDE_ENC_DISABLING &&
!phys_enc->in_clone_mode)
goto complete;
if (phys_enc->parent_ops.handle_frame_done &&
@@ -1272,6 +1273,31 @@ static bool _sde_encoder_phys_wb_is_idle(
return ret;
}
static void _sde_encoder_phys_wb_reset_state(
struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
/*
* frame count and kickoff count are only used for debug purpose. Frame
* count can be more than kickoff count at the end of disable call due
* to extra frame_done wait. It does not cause any issue because
* frame_done wait is based on retire_fence count. Leaving these
* counters for debugging purpose.
*/
if (wb_enc->frame_count != wb_enc->kickoff_count) {
SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc),
wb_enc->kickoff_count, wb_enc->frame_count,
phys_enc->in_clone_mode);
wb_enc->frame_count = wb_enc->kickoff_count;
}
phys_enc->enable_state = SDE_ENC_DISABLED;
wb_enc->crtc = NULL;
phys_enc->hw_cdm = NULL;
phys_enc->hw_ctl = NULL;
phys_enc->in_clone_mode = false;
}
static int _sde_encoder_phys_wb_wait_for_commit_done(
struct sde_encoder_phys *phys_enc, bool is_disable)
@@ -1358,7 +1384,17 @@ skip_wait:
static int sde_encoder_phys_wb_wait_for_commit_done(
struct sde_encoder_phys *phys_enc)
{
return _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false);
int rc;
if (phys_enc->enable_state == SDE_ENC_DISABLING &&
phys_enc->in_clone_mode) {
rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true);
_sde_encoder_phys_wb_reset_state(phys_enc);
} else {
rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false);
}
return rc;
}
static int sde_encoder_phys_wb_wait_for_tx_complete(
@@ -1625,7 +1661,9 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
SDE_DEBUG("[wait_for_done: wb:%d, frame:%u, kickoff:%u]\n",
hw_wb->idx - WB_0, wb_enc->frame_count,
wb_enc->kickoff_count);
_sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true);
if (!phys_enc->in_clone_mode || !wb_enc->crtc->state->active)
_sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true);
if (!phys_enc->hw_ctl || !phys_enc->parent ||
!phys_enc->sde_kms || !wb_enc->fb_disable) {
@@ -1633,11 +1671,14 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
goto exit;
}
/* avoid reset frame for CWB */
if (phys_enc->in_clone_mode) {
_sde_encoder_phys_wb_setup_cwb(phys_enc, false);
_sde_encoder_phys_wb_update_cwb_flush(phys_enc, false);
phys_enc->in_clone_mode = false;
phys_enc->enable_state = SDE_ENC_DISABLING;
if (wb_enc->crtc->state->active)
return;
goto exit;
}
@@ -1670,24 +1711,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
sde_encoder_phys_wb_irq_ctrl(phys_enc, false);
exit:
/*
* frame count and kickoff count are only used for debug purpose. Frame
* count can be more than kickoff count at the end of disable call due
* to extra frame_done wait. It does not cause any issue because
* frame_done wait is based on retire_fence count. Leaving these
* counters for debugging purpose.
*/
if (wb_enc->frame_count != wb_enc->kickoff_count) {
SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc),
wb_enc->kickoff_count, wb_enc->frame_count,
phys_enc->in_clone_mode);
wb_enc->frame_count = wb_enc->kickoff_count;
}
phys_enc->enable_state = SDE_ENC_DISABLED;
wb_enc->crtc = NULL;
phys_enc->hw_cdm = NULL;
phys_enc->hw_ctl = NULL;
_sde_encoder_phys_wb_reset_state(phys_enc);
}
/**