diff options
author | Rob Clark <robdclark@gmail.com> | 2016-03-17 01:18:17 +0300 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2016-05-08 17:22:14 +0300 |
commit | ba00c3f2f0c84456ffe9d548823ff4fb8e4e7ed4 (patch) | |
tree | 1cddb413a2c1f4281f938f356bf74cfaf33cedcc /drivers/gpu/drm/msm/msm_atomic.c | |
parent | ca762a8ae7f453978a4769af9dcd3cb08e45b932 (diff) | |
download | linux-ba00c3f2f0c84456ffe9d548823ff4fb8e4e7ed4.tar.xz |
drm/msm: remove fence_cbs
This was only used for atomic commit these days. So instead just give
atomic it's own work-queue where we can do a block on each bo in turn.
Simplifies things a whole bunch and makes the 'struct fence' conversion
easier.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 77 |
1 files changed, 32 insertions, 45 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index a2a3d9f25b7b..6ac7192d0ad6 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -18,18 +18,16 @@ #include "msm_drv.h" #include "msm_kms.h" #include "msm_gem.h" -#include "msm_gpu.h" /* temporary */ #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 @@ -71,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; } @@ -113,16 +107,39 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev, } } +static void wait_fences(struct msm_commit *c, bool async) +{ + int nplanes = c->dev->mode_config.num_total_plane; + ktime_t timeout = ktime_add_ms(ktime_get(), 1000); + int i; + + for (i = 0; i < nplanes; i++) { + struct drm_plane *plane = c->state->planes[i]; + struct drm_plane_state *new_state = c->state->plane_states[i]; + + if (!plane) + continue; + + if ((plane->state->fb != new_state->fb) && new_state->fb) { + struct drm_gem_object *obj = + msm_framebuffer_bo(new_state->fb, 0); + msm_gem_cpu_sync(obj, MSM_PREP_READ, &timeout); + } + } +} + /* 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; + wait_fences(c, async); + kms->funcs->prepare_commit(kms, state); drm_atomic_helper_commit_modeset_disables(dev, state); @@ -155,17 +172,9 @@ static void complete_commit(struct msm_commit *c) commit_destroy(c); } -static void fence_cb(struct msm_fence_cb *cb) +static void commit_worker(struct work_struct *work) { - 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) -{ - 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, @@ -204,9 +213,7 @@ 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; @@ -231,20 +238,6 @@ int msm_atomic_commit(struct drm_device *dev, } /* - * Figure out what fence to wait for: - */ - for (i = 0; i < nplanes; i++) { - struct drm_plane *plane = state->planes[i]; - struct drm_plane_state *new_state = state->plane_states[i]; - - if (!plane) - continue; - - if ((plane->state->fb != new_state->fb) && new_state->fb) - add_fb(c, new_state->fb); - } - - /* * Wait for pending updates on any of the same crtc's and then * mark our set of crtc's as busy: */ @@ -278,18 +271,12 @@ int msm_atomic_commit(struct drm_device *dev, * current layout. */ - if (nonblock && priv->gpu) { - msm_queue_fence_cb(priv->gpu->fctx, &c->fence_cb, c->fence); + if (nonblock) { + queue_work(priv->atomic_wq, &c->work); return 0; } - timeout = ktime_add_ms(ktime_get(), 1000); - - /* uninterruptible wait */ - if (priv->gpu) - msm_wait_fence(priv->gpu->fctx, c->fence, &timeout, false); - - complete_commit(c); + complete_commit(c, false); return 0; |