diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 47 |
1 files changed, 18 insertions, 29 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 5c6130969f4d..e3892c263f27 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -18,16 +18,16 @@ #include "msm_drv.h" #include "msm_kms.h" #include "msm_gem.h" +#include "msm_fence.h" struct msm_commit { struct drm_device *dev; struct drm_atomic_state *state; - uint32_t fence; - struct msm_fence_cb fence_cb; + struct work_struct work; uint32_t crtc_mask; }; -static void fence_cb(struct msm_fence_cb *cb); +static void commit_worker(struct work_struct *work); /* block until specified crtcs are no longer pending update, and * atomically mark them as pending update @@ -69,11 +69,7 @@ static struct msm_commit *commit_init(struct drm_atomic_state *state) c->dev = state->dev; c->state = state; - /* TODO we might need a way to indicate to run the cb on a - * different wq so wait_for_vblanks() doesn't block retiring - * bo's.. - */ - INIT_FENCE_CB(&c->fence_cb, fence_cb); + INIT_WORK(&c->work, commit_worker); return c; } @@ -114,13 +110,15 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev, /* The (potentially) asynchronous part of the commit. At this point * nothing can fail short of armageddon. */ -static void complete_commit(struct msm_commit *c) +static void complete_commit(struct msm_commit *c, bool async) { struct drm_atomic_state *state = c->state; struct drm_device *dev = state->dev; struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; + drm_atomic_helper_wait_for_fences(dev, state); + kms->funcs->prepare_commit(kms, state); drm_atomic_helper_commit_modeset_disables(dev, state); @@ -153,17 +151,9 @@ static void complete_commit(struct msm_commit *c) commit_destroy(c); } -static void fence_cb(struct msm_fence_cb *cb) -{ - struct msm_commit *c = - container_of(cb, struct msm_commit, fence_cb); - complete_commit(c); -} - -static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb) +static void commit_worker(struct work_struct *work) { - struct drm_gem_object *obj = msm_framebuffer_bo(fb, 0); - c->fence = max(c->fence, msm_gem_fence(to_msm_bo(obj), MSM_PREP_READ)); + complete_commit(container_of(work, struct msm_commit, work), true); } int msm_atomic_check(struct drm_device *dev, @@ -201,9 +191,9 @@ int msm_atomic_check(struct drm_device *dev, int msm_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { + struct msm_drm_private *priv = dev->dev_private; int nplanes = dev->mode_config.num_total_plane; int ncrtcs = dev->mode_config.num_crtc; - ktime_t timeout; struct msm_commit *c; int i, ret; @@ -237,8 +227,12 @@ int msm_atomic_commit(struct drm_device *dev, if (!plane) continue; - if ((plane->state->fb != new_state->fb) && new_state->fb) - add_fb(c, new_state->fb); + if ((plane->state->fb != new_state->fb) && new_state->fb) { + struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0); + struct msm_gem_object *msm_obj = to_msm_bo(obj); + + new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv); + } } /* @@ -276,16 +270,11 @@ int msm_atomic_commit(struct drm_device *dev, */ if (nonblock) { - msm_queue_fence_cb(dev, &c->fence_cb, c->fence); + queue_work(priv->atomic_wq, &c->work); return 0; } - timeout = ktime_add_ms(ktime_get(), 1000); - - /* uninterruptible wait */ - msm_wait_fence(dev, c->fence, &timeout, false); - - complete_commit(c); + complete_commit(c, false); return 0; |