diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvc0_fence.c')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_fence.c | 156 |
1 files changed, 31 insertions, 125 deletions
diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c b/drivers/gpu/drm/nouveau/nvc0_fence.c index 47ab388a606..9566267fbc4 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fence.c +++ b/drivers/gpu/drm/nouveau/nvc0_fence.c @@ -22,163 +22,69 @@ * Authors: Ben Skeggs */ -#include "drmP.h" -#include "nouveau_drv.h" +#include <core/object.h> +#include <core/client.h> +#include <core/class.h> + +#include <engine/fifo.h> + +#include "nouveau_drm.h" #include "nouveau_dma.h" -#include "nouveau_fifo.h" -#include "nouveau_ramht.h" #include "nouveau_fence.h" -struct nvc0_fence_priv { - struct nouveau_fence_priv base; - struct nouveau_bo *bo; -}; - -struct nvc0_fence_chan { - struct nouveau_fence_chan base; - struct nouveau_vma vma; -}; +#include "nv50_display.h" static int -nvc0_fence_emit(struct nouveau_fence *fence) +nvc0_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) { - struct nouveau_channel *chan = fence->channel; - struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE]; - u64 addr = fctx->vma.offset + chan->id * 16; - int ret; - - ret = RING_SPACE(chan, 5); + int ret = RING_SPACE(chan, 6); if (ret == 0) { - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, fence->sequence); + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 5); + OUT_RING (chan, upper_32_bits(virtual)); + OUT_RING (chan, lower_32_bits(virtual)); + OUT_RING (chan, sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); + OUT_RING (chan, 0x00000000); FIRE_RING (chan); } - return ret; } static int -nvc0_fence_sync(struct nouveau_fence *fence, - struct nouveau_channel *prev, struct nouveau_channel *chan) +nvc0_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) { - struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE]; - u64 addr = fctx->vma.offset + prev->id * 16; - int ret; - - ret = RING_SPACE(chan, 5); + int ret = RING_SPACE(chan, 5); if (ret == 0) { BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, fence->sequence); + OUT_RING (chan, upper_32_bits(virtual)); + OUT_RING (chan, lower_32_bits(virtual)); + OUT_RING (chan, sequence); OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL | NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); FIRE_RING (chan); } - return ret; } -static u32 -nvc0_fence_read(struct nouveau_channel *chan) -{ - struct nvc0_fence_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_FENCE); - return nouveau_bo_rd32(priv->bo, chan->id * 16/4); -} - -static void -nvc0_fence_context_del(struct nouveau_channel *chan, int engine) -{ - struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine); - struct nvc0_fence_chan *fctx = chan->engctx[engine]; - - nouveau_bo_vma_del(priv->bo, &fctx->vma); - nouveau_fence_context_del(&fctx->base); - chan->engctx[engine] = NULL; - kfree(fctx); -} - static int -nvc0_fence_context_new(struct nouveau_channel *chan, int engine) +nvc0_fence_context_new(struct nouveau_channel *chan) { - struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine); - struct nvc0_fence_chan *fctx; - int ret; - - fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL); - if (!fctx) - return -ENOMEM; - - nouveau_fence_context_new(&fctx->base); - - ret = nouveau_bo_vma_add(priv->bo, chan->vm, &fctx->vma); - if (ret) - nvc0_fence_context_del(chan, engine); - - nouveau_bo_wr32(priv->bo, chan->id * 16/4, 0x00000000); + int ret = nv84_fence_context_new(chan); + if (ret == 0) { + struct nv84_fence_chan *fctx = chan->fence; + fctx->base.emit32 = nvc0_fence_emit32; + fctx->base.sync32 = nvc0_fence_sync32; + } return ret; } -static int -nvc0_fence_fini(struct drm_device *dev, int engine, bool suspend) -{ - return 0; -} - -static int -nvc0_fence_init(struct drm_device *dev, int engine) -{ - return 0; -} - -static void -nvc0_fence_destroy(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_fence_priv *priv = nv_engine(dev, engine); - - nouveau_bo_unmap(priv->bo); - nouveau_bo_ref(NULL, &priv->bo); - dev_priv->eng[engine] = NULL; - kfree(priv); -} - int -nvc0_fence_create(struct drm_device *dev) +nvc0_fence_create(struct nouveau_drm *drm) { - struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_fence_priv *priv; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->base.engine.destroy = nvc0_fence_destroy; - priv->base.engine.init = nvc0_fence_init; - priv->base.engine.fini = nvc0_fence_fini; - priv->base.engine.context_new = nvc0_fence_context_new; - priv->base.engine.context_del = nvc0_fence_context_del; - priv->base.emit = nvc0_fence_emit; - priv->base.sync = nvc0_fence_sync; - priv->base.read = nvc0_fence_read; - dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine; - - ret = nouveau_bo_new(dev, 16 * pfifo->channels, 0, TTM_PL_FLAG_VRAM, - 0, 0, NULL, &priv->bo); + int ret = nv84_fence_create(drm); if (ret == 0) { - ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); - if (ret == 0) - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_ref(NULL, &priv->bo); + struct nv84_fence_priv *priv = drm->fence; + priv->base.context_new = nvc0_fence_context_new; } - - if (ret) - nvc0_fence_destroy(dev, NVOBJ_ENGINE_FENCE); return ret; } |
