disp: msm: reset lm blend stages for missing vsync

MDSS INTF HW block does not generate vsync if controller
turns off the link clock prematurely. This leads to
frame trigger timeout and SDE driver triggers the retire
fence after 84ms to recover gracefully. A client may switch
source pipe from one CTL path to another CTL path based
on delayed retire fence. It can lead to other ctl path
hang. This can be resolved by resetting the lm blend
stages for each missing vsync frame trigger.

Change-Id: I5a6ed03afbdad83d8fd6decc593d39e04bef62e4
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
This commit is contained in:
Dhaval Patel
2021-09-21 14:35:18 -07:00
父節點 958acc9e7c
當前提交 fc2226ea25
共有 5 個文件被更改,包括 38 次插入53 次删除

查看文件

@@ -3225,6 +3225,19 @@ void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc,
ctl->ops.clear_pending_flush(ctl);
}
void sde_encoder_helper_phys_reset(struct sde_encoder_phys *phys_enc)
{
struct sde_hw_ctl *ctl = phys_enc->hw_ctl;
struct sde_ctl_flush_cfg cfg;
ctl->ops.reset(ctl);
sde_encoder_helper_reset_mixers(phys_enc, NULL);
ctl->ops.get_pending_flush(ctl, &cfg);
SDE_EVT32(DRMID(phys_enc->parent), cfg.pending_flush_mask);
ctl->ops.trigger_flush(ctl);
ctl->ops.trigger_start(ctl);
}
static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
enum sde_intf_type type, u32 controller_id)
{
@@ -4357,47 +4370,7 @@ end:
return ret;
}
/**
* _sde_encoder_reset_ctl_hw - reset h/w configuration for all ctl's associated
* with the specified encoder, and unstage all pipes from it
* @encoder: encoder pointer
* Returns: 0 on success
*/
static int _sde_encoder_reset_ctl_hw(struct drm_encoder *drm_enc)
{
struct sde_encoder_virt *sde_enc;
struct sde_encoder_phys *phys;
unsigned int i;
int rc = 0;
if (!drm_enc) {
SDE_ERROR("invalid encoder\n");
return -EINVAL;
}
sde_enc = to_sde_encoder_virt(drm_enc);
SDE_ATRACE_BEGIN("encoder_release_lm");
SDE_DEBUG_ENC(sde_enc, "\n");
for (i = 0; i < sde_enc->num_phys_encs; i++) {
phys = sde_enc->phys_encs[i];
if (!phys)
continue;
SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0);
rc = sde_encoder_helper_reset_mixers(phys, NULL);
if (rc)
SDE_EVT32(DRMID(drm_enc), rc, SDE_EVTLOG_ERROR);
}
SDE_ATRACE_END("encoder_release_lm");
return rc;
}
void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error,
bool config_changed)
void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool config_changed)
{
struct sde_encoder_virt *sde_enc;
struct sde_encoder_phys *phys;
@@ -4412,10 +4385,6 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error,
SDE_DEBUG_ENC(sde_enc, "\n");
/* create a 'no pipes' commit to release buffers on errors */
if (is_error)
_sde_encoder_reset_ctl_hw(drm_enc);
if (sde_enc->delay_kickoff) {
u32 loop_count = 20;
u32 sleep = DELAY_KICKOFF_POLL_TIMEOUT_US / loop_count;