Loading msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading msm/sde/sde_encoder_phys_cmd.c +23 −19 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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)) Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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, Loading Loading
msm/sde/sde_encoder_phys.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading
msm/sde/sde_encoder_phys_cmd.c +23 −19 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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)) Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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, Loading