Merge "disp: msm: sde: move HW recovery outside ppdone wait"

This commit is contained in:
qctecmdr 2020-05-05 20:30:53 -07:00 • committed by Gerrit - the friendly Code Review server
commit e9b326e3f2
2 changed files with 25 additions and 19 deletions

View file

@ -293,6 +293,7 @@ struct sde_encoder_irq {
* programming ROT and MDP fetch start
* @frame_trigger_mode: frame trigger mode indication for command
* mode display
* @recovered: flag set to true when recovered from pp timeout
*/
struct sde_encoder_phys {
struct drm_encoder *parent;
@ -335,6 +336,7 @@ struct sde_encoder_phys {
bool in_clone_mode;
int vfp_cached;
enum frame_trigger_mode_type frame_trigger_mode;
bool recovered;
};
static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)

View file

@ -173,11 +173,14 @@ static void _sde_encoder_phys_cmd_update_intf_cfg(
static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
{
struct sde_encoder_phys *phys_enc = arg;
struct sde_encoder_phys_cmd *cmd_enc;
u32 event = 0;
if (!phys_enc || !phys_enc->hw_pp)
return;
cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
SDE_ATRACE_BEGIN("pp_done_irq");
/* notify all synchronous clients first, then asynchronous clients */
@ -188,6 +191,8 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
spin_lock(phys_enc->enc_spinlock);
phys_enc->parent_ops.handle_frame_done(phys_enc->parent,
phys_enc, event);
if (cmd_enc->pp_timeout_report_cnt)
phys_enc->recovered = true;
spin_unlock(phys_enc->enc_spinlock);
}
@ -482,11 +487,12 @@ static void sde_encoder_phys_cmd_mode_set(
}
static int _sde_encoder_phys_cmd_handle_ppdone_timeout(
struct sde_encoder_phys *phys_enc,
bool recovery_events)
struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_cmd *cmd_enc =
to_sde_encoder_phys_cmd(phys_enc);
bool recovery_events = sde_encoder_recovery_events_enabled(
phys_enc->parent);
u32 frame_event = SDE_ENCODER_FRAME_EVENT_ERROR
| SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE;
struct drm_connector *conn;
@ -728,10 +734,7 @@ static bool _sde_encoder_phys_cmd_is_scheduler_idle(
static int _sde_encoder_phys_cmd_wait_for_idle(
struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_cmd *cmd_enc =
to_sde_encoder_phys_cmd(phys_enc);
struct sde_encoder_wait_info wait_info = {0};
bool recovery_events;
int ret;
if (!phys_enc) {
@ -745,8 +748,6 @@ static int _sde_encoder_phys_cmd_wait_for_idle(
wait_info.wq = &phys_enc->pending_kickoff_wq;
wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
recovery_events = sde_encoder_recovery_events_enabled(
phys_enc->parent);
/* slave encoder doesn't enable for ppsplit */
if (_sde_encoder_phys_is_ppsplit_slave(phys_enc))
@ -761,18 +762,7 @@ static int _sde_encoder_phys_cmd_wait_for_idle(
if (_sde_encoder_phys_cmd_is_scheduler_idle(phys_enc))
return 0;
_sde_encoder_phys_cmd_handle_ppdone_timeout(phys_enc,
recovery_events);
} else if (!ret) {
if (cmd_enc->pp_timeout_report_cnt && recovery_events) {
struct drm_connector *conn = phys_enc->connector;
sde_connector_event_notify(conn,
DRM_EVENT_SDE_HW_RECOVERY,
sizeof(uint8_t),
SDE_RECOVERY_SUCCESS);
}
cmd_enc->pp_timeout_report_cnt = 0;
_sde_encoder_phys_cmd_handle_ppdone_timeout(phys_enc);
}
return ret;
@ -1379,6 +1369,7 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
to_sde_encoder_phys_cmd(phys_enc);
int ret = 0;
u32 extra_frame_trigger_time;
bool recovery_events;
if (!phys_enc || !phys_enc->hw_pp) {
SDE_ERROR("invalid encoder\n");
@ -1407,6 +1398,19 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
}
}
if (phys_enc->recovered) {
recovery_events = sde_encoder_recovery_events_enabled(
phys_enc->parent);
if (cmd_enc->pp_timeout_report_cnt && recovery_events)
sde_connector_event_notify(phys_enc->connector,
DRM_EVENT_SDE_HW_RECOVERY,
sizeof(uint8_t),
SDE_RECOVERY_SUCCESS);
cmd_enc->pp_timeout_report_cnt = 0;
phys_enc->recovered = false;
}
if (sde_connector_is_qsync_updated(phys_enc->connector)) {
tc_cfg.sync_threshold_start =
_get_tearcheck_threshold(phys_enc,