Loading drivers/gpu/drm/msm/sde/sde_crtc.c +15 −9 Original line number Diff line number Diff line Loading @@ -1490,6 +1490,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) struct sde_crtc_state *cstate; struct sde_kms *sde_kms; unsigned long flags; bool disable_inprogress = false; if (!work) { SDE_ERROR("invalid work handle\n"); Loading @@ -1515,6 +1516,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) SDE_DEBUG("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event, ktime_to_ns(fevent->ts)); disable_inprogress = fevent->event & SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; fevent->event &= ~SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE || (fevent->event & SDE_ENCODER_FRAME_EVENT_ERROR) || Loading @@ -1528,9 +1532,6 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) atomic_read(&sde_crtc->frame_pending)); SDE_EVT32(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE1); /* don't propagate unexpected frame done events */ return; } else if (atomic_dec_return(&sde_crtc->frame_pending) == 0) { /* release bandwidth and other resources */ SDE_DEBUG("crtc%d ts:%lld last pending\n", Loading @@ -1538,13 +1539,15 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) ktime_to_ns(fevent->ts)); SDE_EVT32(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE2); if (!disable_inprogress) sde_core_perf_crtc_release_bw(crtc); } else { SDE_EVT32_VERBOSE(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE3); } if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE) if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE && !disable_inprogress) sde_core_perf_crtc_update(crtc, 0, false); } else { SDE_ERROR("crtc%d ts:%lld unknown event %u\n", crtc->base.id, Loading Loading @@ -1580,7 +1583,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) pipe_id = drm_crtc_index(crtc); SDE_DEBUG("crtc%d\n", crtc->base.id); SDE_EVT32_VERBOSE(DRMID(crtc)); SDE_EVT32_VERBOSE(DRMID(crtc), event); spin_lock_irqsave(&sde_crtc->spin_lock, flags); fevent = list_first_entry_or_null(&sde_crtc->frame_event_list, Loading @@ -1599,7 +1602,11 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) fevent->event = event; fevent->crtc = crtc; fevent->ts = ktime_get(); kthread_queue_work(&priv->disp_thread[pipe_id].worker, &fevent->work); if (event & SDE_ENCODER_FRAME_EVENT_DURING_DISABLE) sde_crtc_frame_event_work(&fevent->work); else kthread_queue_work(&priv->disp_thread[pipe_id].worker, &fevent->work); } void sde_crtc_complete_commit(struct drm_crtc *crtc, Loading Loading @@ -2415,8 +2422,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) if (atomic_read(&sde_crtc->frame_pending)) { /* release bandwidth and other resources */ SDE_ERROR("crtc%d invalid frame pending\n", crtc->base.id); SDE_ERROR("crtc%d invalid frame pending\n", crtc->base.id); SDE_EVT32(DRMID(crtc), atomic_read(&sde_crtc->frame_pending), SDE_EVTLOG_FUNC_CASE2); sde_core_perf_crtc_release_bw(crtc); Loading drivers/gpu/drm/msm/sde/sde_encoder.c +16 −12 Original line number Diff line number Diff line Loading @@ -142,7 +142,6 @@ enum sde_enc_rc_states { * Bit0 = phys_encs[0] etc. * @crtc_frame_event_cb: callback handler for frame event * @crtc_frame_event_cb_data: callback handler private data * @crtc_frame_event: callback event * @frame_done_timeout: frame done timeout in Hz * @frame_done_timer: watchdog timer for frame done event * @rsc_client: rsc client pointer Loading @@ -160,6 +159,7 @@ enum sde_enc_rc_states { * @rsc_cfg: rsc configuration * @cur_conn_roi: current connector roi * @prv_conn_roi: previous connector roi to optimize if unchanged * @disable_inprogress: sde encoder disable is in progress. */ struct sde_encoder_virt { struct drm_encoder base; Loading @@ -184,7 +184,6 @@ struct sde_encoder_virt { DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL); void (*crtc_frame_event_cb)(void *, u32 event); void *crtc_frame_event_cb_data; u32 crtc_frame_event; atomic_t frame_done_timeout; struct timer_list frame_done_timer; Loading @@ -204,6 +203,7 @@ struct sde_encoder_virt { struct sde_encoder_rsc_config rsc_cfg; struct sde_rect cur_conn_roi; struct sde_rect prv_conn_roi; bool disable_inprogress; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -1456,6 +1456,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) SDE_EVT32(DRMID(drm_enc)); sde_enc->cur_master = NULL; sde_enc->disable_inprogress = false; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading @@ -1514,6 +1515,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); sde_enc->disable_inprogress = true; SDE_EVT32(DRMID(drm_enc)); Loading Loading @@ -1664,7 +1666,6 @@ static void sde_encoder_frame_done_callback( for (i = 0; i < sde_enc->num_phys_encs; i++) if (sde_enc->phys_encs[i] == ready_phys) { clear_bit(i, sde_enc->frame_busy_mask); sde_enc->crtc_frame_event |= event; SDE_EVT32_VERBOSE(DRMID(drm_enc), i, sde_enc->frame_busy_mask[0]); } Loading @@ -1676,10 +1677,12 @@ static void sde_encoder_frame_done_callback( sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_FRAME_DONE); if (sde_enc->disable_inprogress) event |= SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; if (sde_enc->crtc_frame_event_cb) sde_enc->crtc_frame_event_cb( sde_enc->crtc_frame_event_cb_data, sde_enc->crtc_frame_event); sde_enc->crtc_frame_event_cb_data, event); } } Loading Loading @@ -1861,7 +1864,6 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) } pending_flush = 0x0; sde_enc->crtc_frame_event = 0; /* update pending counts and trigger kickoff ctl flush atomically */ spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags); Loading Loading @@ -2679,6 +2681,7 @@ static void sde_encoder_frame_done_timeout(unsigned long data) struct drm_encoder *drm_enc = (struct drm_encoder *) data; struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); struct msm_drm_private *priv; u32 event; if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { SDE_ERROR("invalid parameters\n"); Loading @@ -2696,13 +2699,14 @@ static void sde_encoder_frame_done_timeout(unsigned long data) return; } SDE_EVT32(DRMID(drm_enc), 2, sde_enc->crtc_frame_event); SDE_ERROR_ENC(sde_enc, "frame done timeout, frame_event %d\n", sde_enc->crtc_frame_event); SDE_ERROR_ENC(sde_enc, "frame done timeout\n"); event = SDE_ENCODER_FRAME_EVENT_ERROR; if (sde_enc->disable_inprogress) event |= SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; sde_enc->crtc_frame_event_cb(sde_enc->crtc_frame_event_cb_data, sde_enc->crtc_frame_event | SDE_ENCODER_FRAME_EVENT_ERROR); SDE_EVT32(DRMID(drm_enc), event); sde_enc->crtc_frame_event_cb(sde_enc->crtc_frame_event_cb_data, event); } static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { Loading drivers/gpu/drm/msm/sde/sde_encoder.h +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #define SDE_ENCODER_FRAME_EVENT_DONE BIT(0) #define SDE_ENCODER_FRAME_EVENT_ERROR BIT(1) #define SDE_ENCODER_FRAME_EVENT_PANEL_DEAD BIT(2) #define SDE_ENCODER_FRAME_EVENT_DURING_DISABLE BIT(3) /** * Encoder functions and data types Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +15 −9 Original line number Diff line number Diff line Loading @@ -1490,6 +1490,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) struct sde_crtc_state *cstate; struct sde_kms *sde_kms; unsigned long flags; bool disable_inprogress = false; if (!work) { SDE_ERROR("invalid work handle\n"); Loading @@ -1515,6 +1516,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) SDE_DEBUG("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event, ktime_to_ns(fevent->ts)); disable_inprogress = fevent->event & SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; fevent->event &= ~SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE || (fevent->event & SDE_ENCODER_FRAME_EVENT_ERROR) || Loading @@ -1528,9 +1532,6 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) atomic_read(&sde_crtc->frame_pending)); SDE_EVT32(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE1); /* don't propagate unexpected frame done events */ return; } else if (atomic_dec_return(&sde_crtc->frame_pending) == 0) { /* release bandwidth and other resources */ SDE_DEBUG("crtc%d ts:%lld last pending\n", Loading @@ -1538,13 +1539,15 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) ktime_to_ns(fevent->ts)); SDE_EVT32(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE2); if (!disable_inprogress) sde_core_perf_crtc_release_bw(crtc); } else { SDE_EVT32_VERBOSE(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_CASE3); } if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE) if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE && !disable_inprogress) sde_core_perf_crtc_update(crtc, 0, false); } else { SDE_ERROR("crtc%d ts:%lld unknown event %u\n", crtc->base.id, Loading Loading @@ -1580,7 +1583,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) pipe_id = drm_crtc_index(crtc); SDE_DEBUG("crtc%d\n", crtc->base.id); SDE_EVT32_VERBOSE(DRMID(crtc)); SDE_EVT32_VERBOSE(DRMID(crtc), event); spin_lock_irqsave(&sde_crtc->spin_lock, flags); fevent = list_first_entry_or_null(&sde_crtc->frame_event_list, Loading @@ -1599,7 +1602,11 @@ static void sde_crtc_frame_event_cb(void *data, u32 event) fevent->event = event; fevent->crtc = crtc; fevent->ts = ktime_get(); kthread_queue_work(&priv->disp_thread[pipe_id].worker, &fevent->work); if (event & SDE_ENCODER_FRAME_EVENT_DURING_DISABLE) sde_crtc_frame_event_work(&fevent->work); else kthread_queue_work(&priv->disp_thread[pipe_id].worker, &fevent->work); } void sde_crtc_complete_commit(struct drm_crtc *crtc, Loading Loading @@ -2415,8 +2422,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) if (atomic_read(&sde_crtc->frame_pending)) { /* release bandwidth and other resources */ SDE_ERROR("crtc%d invalid frame pending\n", crtc->base.id); SDE_ERROR("crtc%d invalid frame pending\n", crtc->base.id); SDE_EVT32(DRMID(crtc), atomic_read(&sde_crtc->frame_pending), SDE_EVTLOG_FUNC_CASE2); sde_core_perf_crtc_release_bw(crtc); Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +16 −12 Original line number Diff line number Diff line Loading @@ -142,7 +142,6 @@ enum sde_enc_rc_states { * Bit0 = phys_encs[0] etc. * @crtc_frame_event_cb: callback handler for frame event * @crtc_frame_event_cb_data: callback handler private data * @crtc_frame_event: callback event * @frame_done_timeout: frame done timeout in Hz * @frame_done_timer: watchdog timer for frame done event * @rsc_client: rsc client pointer Loading @@ -160,6 +159,7 @@ enum sde_enc_rc_states { * @rsc_cfg: rsc configuration * @cur_conn_roi: current connector roi * @prv_conn_roi: previous connector roi to optimize if unchanged * @disable_inprogress: sde encoder disable is in progress. */ struct sde_encoder_virt { struct drm_encoder base; Loading @@ -184,7 +184,6 @@ struct sde_encoder_virt { DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL); void (*crtc_frame_event_cb)(void *, u32 event); void *crtc_frame_event_cb_data; u32 crtc_frame_event; atomic_t frame_done_timeout; struct timer_list frame_done_timer; Loading @@ -204,6 +203,7 @@ struct sde_encoder_virt { struct sde_encoder_rsc_config rsc_cfg; struct sde_rect cur_conn_roi; struct sde_rect prv_conn_roi; bool disable_inprogress; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) Loading Loading @@ -1456,6 +1456,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) SDE_EVT32(DRMID(drm_enc)); sde_enc->cur_master = NULL; sde_enc->disable_inprogress = false; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading @@ -1514,6 +1515,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) priv = drm_enc->dev->dev_private; sde_kms = to_sde_kms(priv->kms); sde_enc->disable_inprogress = true; SDE_EVT32(DRMID(drm_enc)); Loading Loading @@ -1664,7 +1666,6 @@ static void sde_encoder_frame_done_callback( for (i = 0; i < sde_enc->num_phys_encs; i++) if (sde_enc->phys_encs[i] == ready_phys) { clear_bit(i, sde_enc->frame_busy_mask); sde_enc->crtc_frame_event |= event; SDE_EVT32_VERBOSE(DRMID(drm_enc), i, sde_enc->frame_busy_mask[0]); } Loading @@ -1676,10 +1677,12 @@ static void sde_encoder_frame_done_callback( sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_FRAME_DONE); if (sde_enc->disable_inprogress) event |= SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; if (sde_enc->crtc_frame_event_cb) sde_enc->crtc_frame_event_cb( sde_enc->crtc_frame_event_cb_data, sde_enc->crtc_frame_event); sde_enc->crtc_frame_event_cb_data, event); } } Loading Loading @@ -1861,7 +1864,6 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) } pending_flush = 0x0; sde_enc->crtc_frame_event = 0; /* update pending counts and trigger kickoff ctl flush atomically */ spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags); Loading Loading @@ -2679,6 +2681,7 @@ static void sde_encoder_frame_done_timeout(unsigned long data) struct drm_encoder *drm_enc = (struct drm_encoder *) data; struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); struct msm_drm_private *priv; u32 event; if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { SDE_ERROR("invalid parameters\n"); Loading @@ -2696,13 +2699,14 @@ static void sde_encoder_frame_done_timeout(unsigned long data) return; } SDE_EVT32(DRMID(drm_enc), 2, sde_enc->crtc_frame_event); SDE_ERROR_ENC(sde_enc, "frame done timeout, frame_event %d\n", sde_enc->crtc_frame_event); SDE_ERROR_ENC(sde_enc, "frame done timeout\n"); event = SDE_ENCODER_FRAME_EVENT_ERROR; if (sde_enc->disable_inprogress) event |= SDE_ENCODER_FRAME_EVENT_DURING_DISABLE; sde_enc->crtc_frame_event_cb(sde_enc->crtc_frame_event_cb_data, sde_enc->crtc_frame_event | SDE_ENCODER_FRAME_EVENT_ERROR); SDE_EVT32(DRMID(drm_enc), event); sde_enc->crtc_frame_event_cb(sde_enc->crtc_frame_event_cb_data, event); } static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = { Loading
drivers/gpu/drm/msm/sde/sde_encoder.h +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #define SDE_ENCODER_FRAME_EVENT_DONE BIT(0) #define SDE_ENCODER_FRAME_EVENT_ERROR BIT(1) #define SDE_ENCODER_FRAME_EVENT_PANEL_DEAD BIT(2) #define SDE_ENCODER_FRAME_EVENT_DURING_DISABLE BIT(3) /** * Encoder functions and data types Loading