diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 27c9ae563f2f..87a91148a731 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -5,7 +5,6 @@ */ #include <drm/drm_atomic_uapi.h> -#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_vblank.h> #include "msm_atomic_trace.h" @@ -13,20 +12,6 @@ #include "msm_gem.h" #include "msm_kms.h" -int msm_atomic_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct msm_drm_private *priv = plane->dev->dev_private; - struct msm_kms *kms = priv->kms; - - if (!new_state->fb) - return 0; - - drm_gem_plane_helper_prepare_fb(plane, new_state); - - return msm_framebuffer_prepare(new_state->fb, kms->aspace); -} - /* * Helpers to control vblanks while we flush.. basically just to ensure * that vblank accounting is switched on, so we get valid seqn/timestamp @@ -130,7 +115,7 @@ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer, timer->kms = kms; timer->crtc_idx = crtc_idx; - timer->worker = kthread_create_worker(0, "atomic-worker-%d", crtc_idx); + timer->worker = kthread_run_worker(0, "atomic-worker-%d", crtc_idx); if (IS_ERR(timer->worker)) { int ret = PTR_ERR(timer->worker); timer->worker = NULL; @@ -170,6 +155,8 @@ static bool can_do_async(struct drm_atomic_state *state, for_each_new_crtc_in_state(state, crtc, crtc_state, i) { if (drm_atomic_crtc_needs_modeset(crtc_state)) return false; + if (!crtc_state->active) + return false; if (++num_crtcs > 1) return false; *async_crtc = crtc; @@ -194,6 +181,35 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state) return mask; } +int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) +{ + struct msm_drm_private *priv = dev->dev_private; + struct msm_kms *kms = priv->kms; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + struct drm_crtc *crtc; + int i, ret = 0; + + /* + * FIXME: stop setting allow_modeset and move this check to the DPU + * driver. + */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if ((old_crtc_state->ctm && !new_crtc_state->ctm) || + (!old_crtc_state->ctm && new_crtc_state->ctm)) { + new_crtc_state->mode_changed = true; + state->allow_modeset = true; + } + } + + if (kms && kms->funcs && kms->funcs->check_mode_changed) + ret = kms->funcs->check_mode_changed(kms, state); + if (ret) + return ret; + + return drm_atomic_helper_check(dev, state); +} + void msm_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; @@ -201,8 +217,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) struct msm_kms *kms = priv->kms; struct drm_crtc *async_crtc = NULL; unsigned crtc_mask = get_crtc_mask(state); - bool async = kms->funcs->vsync_time && - can_do_async(state, &async_crtc); + bool async = can_do_async(state, &async_crtc); trace_msm_atomic_commit_tail_start(async, crtc_mask); @@ -217,11 +232,14 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask); + atomic_set(&kms->fault_snapshot_capture, 0); + /* * Now that there is no in-progress flush, prepare the * current update: */ - kms->funcs->prepare_commit(kms, state); + if (kms->funcs->prepare_commit) + kms->funcs->prepare_commit(kms, state); /* * Push atomic updates down to hardware: @@ -246,7 +264,9 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) kms->pending_crtc_mask |= crtc_mask; - vsync_time = kms->funcs->vsync_time(kms, async_crtc); + if (drm_crtc_next_vblank_start(async_crtc, &vsync_time)) + goto fallback; + wakeup_time = ktime_sub(vsync_time, ms_to_ktime(1)); msm_hrtimer_queue_work(&timer->work, wakeup_time, @@ -268,6 +288,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) return; } +fallback: /* * If there is any async flush pending on updated crtcs, fold * them into the current flush. |
