Loading drivers/gpu/drm/msm/sde/sde_connector.c +12 −1 Original line number Diff line number Diff line Loading @@ -903,7 +903,18 @@ void sde_connector_complete_commit(struct drm_connector *connector, } /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, 0); sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, false); } void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts) { if (!connector) { SDE_ERROR("invalid connector\n"); return; } /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, true); } static enum drm_connector_status Loading drivers/gpu/drm/msm/sde/sde_connector.h +7 −0 Original line number Diff line number Diff line Loading @@ -448,6 +448,13 @@ void sde_connector_prepare_fence(struct drm_connector *connector); */ void sde_connector_complete_commit(struct drm_connector *connector, ktime_t ts); /** * sde_connector_commit_reset - reset the completion signal * @connector: Pointer to drm connector object * @ts: timestamp to be updated in the fence signalling */ void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts); /** * sde_connector_get_info - query display specific information * @connector: Pointer to drm connector object Loading drivers/gpu/drm/msm/sde/sde_crtc.c +11 −2 Original line number Diff line number Diff line Loading @@ -2041,7 +2041,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) if (fevent->event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE) { SDE_ATRACE_BEGIN("signal_release_fence"); sde_fence_signal(&sde_crtc->output_fence, fevent->ts, 0); sde_fence_signal(&sde_crtc->output_fence, fevent->ts, false); SDE_ATRACE_END("signal_release_fence"); } Loading Loading @@ -2992,7 +2992,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) struct sde_crtc_irq_info *node = NULL; struct drm_event event; u32 power_on; int ret; int ret, i; if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { SDE_ERROR("invalid crtc\n"); Loading Loading @@ -3067,6 +3067,15 @@ static void sde_crtc_disable(struct drm_crtc *crtc) sde_power_handle_unregister_event(&priv->phandle, sde_crtc->power_event); /** * All callbacks are unregistered and frame done waits are complete * at this point. No buffers are accessed by hardware. * reset the fence timeline if there is any issue. */ sde_fence_signal(&sde_crtc->output_fence, ktime_get(), true); for (i = 0; i < cstate->num_connectors; ++i) sde_connector_commit_reset(cstate->connectors[i], ktime_get()); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; Loading drivers/gpu/drm/msm/sde/sde_fence.c +17 −5 Original line number Diff line number Diff line Loading @@ -338,7 +338,8 @@ int sde_fence_create(struct sde_fence_context *ctx, uint64_t *val, return rc; } void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool reset_timeline) { unsigned long flags; struct sde_fence *fc, *next; Loading @@ -348,14 +349,25 @@ void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) if (!ctx) { SDE_ERROR("invalid ctx, %pK\n", ctx); return; } else if (is_error) { return; } INIT_LIST_HEAD(&local_list_head); spin_lock_irqsave(&ctx->lock, flags); if (reset_timeline) { if ((int)(ctx->done_count - ctx->commit_count) < 0) { SDE_ERROR( "timeline reset attempt! done count:%d commit:%d\n", ctx->done_count, ctx->commit_count); ctx->done_count = ctx->commit_count; SDE_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, ktime_to_us(ts), reset_timeline, SDE_EVTLOG_FATAL); } else { spin_unlock_irqrestore(&ctx->lock, flags); return; } } else if ((int)(ctx->done_count - ctx->commit_count) < 0) { ++ctx->done_count; SDE_DEBUG("fence_signal:done count:%d commit count:%d\n", ctx->done_count, ctx->commit_count); Loading @@ -363,7 +375,7 @@ void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) SDE_ERROR("extra signal attempt! done count:%d commit:%d\n", ctx->done_count, ctx->commit_count); SDE_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, ktime_to_us(ts), SDE_EVTLOG_FATAL); ktime_to_us(ts), reset_timeline, SDE_EVTLOG_FATAL); spin_unlock_irqrestore(&ctx->lock, flags); return; } Loading drivers/gpu/drm/msm/sde/sde_fence.h +3 −3 Original line number Diff line number Diff line Loading @@ -128,10 +128,10 @@ int sde_fence_create(struct sde_fence_context *fence, uint64_t *val, * sde_fence_signal - advance fence timeline to signal outstanding fences * @fence: Pointer fence container * @ts: fence timestamp * @is_error: Set to non-zero if the commit didn't complete successfully * @reset_timeline: reset the fence timeline to done count equal to commit count */ void sde_fence_signal(struct sde_fence_context *fence, ktime_t ts, bool is_error); bool reset_timeline); #else static inline void *sde_sync_get(uint64_t fd) { Loading Loading @@ -170,7 +170,7 @@ static inline int sde_fence_get(struct sde_fence_context *fence, uint64_t *val) } static inline void sde_fence_signal(struct sde_fence_context *fence, ktime_t ts, bool is_error) ktime_t ts, bool reset_timeline) { /* do nothing */ } Loading Loading
drivers/gpu/drm/msm/sde/sde_connector.c +12 −1 Original line number Diff line number Diff line Loading @@ -903,7 +903,18 @@ void sde_connector_complete_commit(struct drm_connector *connector, } /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, 0); sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, false); } void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts) { if (!connector) { SDE_ERROR("invalid connector\n"); return; } /* signal connector's retire fence */ sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, true); } static enum drm_connector_status Loading
drivers/gpu/drm/msm/sde/sde_connector.h +7 −0 Original line number Diff line number Diff line Loading @@ -448,6 +448,13 @@ void sde_connector_prepare_fence(struct drm_connector *connector); */ void sde_connector_complete_commit(struct drm_connector *connector, ktime_t ts); /** * sde_connector_commit_reset - reset the completion signal * @connector: Pointer to drm connector object * @ts: timestamp to be updated in the fence signalling */ void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts); /** * sde_connector_get_info - query display specific information * @connector: Pointer to drm connector object Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +11 −2 Original line number Diff line number Diff line Loading @@ -2041,7 +2041,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work) if (fevent->event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE) { SDE_ATRACE_BEGIN("signal_release_fence"); sde_fence_signal(&sde_crtc->output_fence, fevent->ts, 0); sde_fence_signal(&sde_crtc->output_fence, fevent->ts, false); SDE_ATRACE_END("signal_release_fence"); } Loading Loading @@ -2992,7 +2992,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) struct sde_crtc_irq_info *node = NULL; struct drm_event event; u32 power_on; int ret; int ret, i; if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { SDE_ERROR("invalid crtc\n"); Loading Loading @@ -3067,6 +3067,15 @@ static void sde_crtc_disable(struct drm_crtc *crtc) sde_power_handle_unregister_event(&priv->phandle, sde_crtc->power_event); /** * All callbacks are unregistered and frame done waits are complete * at this point. No buffers are accessed by hardware. * reset the fence timeline if there is any issue. */ sde_fence_signal(&sde_crtc->output_fence, ktime_get(), true); for (i = 0; i < cstate->num_connectors; ++i) sde_connector_commit_reset(cstate->connectors[i], ktime_get()); memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers)); sde_crtc->num_mixers = 0; Loading
drivers/gpu/drm/msm/sde/sde_fence.c +17 −5 Original line number Diff line number Diff line Loading @@ -338,7 +338,8 @@ int sde_fence_create(struct sde_fence_context *ctx, uint64_t *val, return rc; } void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool reset_timeline) { unsigned long flags; struct sde_fence *fc, *next; Loading @@ -348,14 +349,25 @@ void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) if (!ctx) { SDE_ERROR("invalid ctx, %pK\n", ctx); return; } else if (is_error) { return; } INIT_LIST_HEAD(&local_list_head); spin_lock_irqsave(&ctx->lock, flags); if (reset_timeline) { if ((int)(ctx->done_count - ctx->commit_count) < 0) { SDE_ERROR( "timeline reset attempt! done count:%d commit:%d\n", ctx->done_count, ctx->commit_count); ctx->done_count = ctx->commit_count; SDE_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, ktime_to_us(ts), reset_timeline, SDE_EVTLOG_FATAL); } else { spin_unlock_irqrestore(&ctx->lock, flags); return; } } else if ((int)(ctx->done_count - ctx->commit_count) < 0) { ++ctx->done_count; SDE_DEBUG("fence_signal:done count:%d commit count:%d\n", ctx->done_count, ctx->commit_count); Loading @@ -363,7 +375,7 @@ void sde_fence_signal(struct sde_fence_context *ctx, ktime_t ts, bool is_error) SDE_ERROR("extra signal attempt! done count:%d commit:%d\n", ctx->done_count, ctx->commit_count); SDE_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, ktime_to_us(ts), SDE_EVTLOG_FATAL); ktime_to_us(ts), reset_timeline, SDE_EVTLOG_FATAL); spin_unlock_irqrestore(&ctx->lock, flags); return; } Loading
drivers/gpu/drm/msm/sde/sde_fence.h +3 −3 Original line number Diff line number Diff line Loading @@ -128,10 +128,10 @@ int sde_fence_create(struct sde_fence_context *fence, uint64_t *val, * sde_fence_signal - advance fence timeline to signal outstanding fences * @fence: Pointer fence container * @ts: fence timestamp * @is_error: Set to non-zero if the commit didn't complete successfully * @reset_timeline: reset the fence timeline to done count equal to commit count */ void sde_fence_signal(struct sde_fence_context *fence, ktime_t ts, bool is_error); bool reset_timeline); #else static inline void *sde_sync_get(uint64_t fd) { Loading Loading @@ -170,7 +170,7 @@ static inline int sde_fence_get(struct sde_fence_context *fence, uint64_t *val) } static inline void sde_fence_signal(struct sde_fence_context *fence, ktime_t ts, bool is_error) ktime_t ts, bool reset_timeline) { /* do nothing */ } Loading