diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dma.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dma.c | 103 |
1 files changed, 1 insertions, 102 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index a1f329ef0641..017a803121d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -43,8 +43,6 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) uint64_t val; val = nvif_rd32(chan->userd, chan->user_get); - if (chan->user_get_hi) - val |= (uint64_t)nvif_rd32(chan->userd, chan->user_get_hi) << 32; /* reset counter as long as GET is still advancing, this is * to avoid misdetecting a GPU lockup if the GPU happens to @@ -68,111 +66,12 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) return (val - chan->push.addr) >> 2; } -void -nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length, - bool no_prefetch) -{ - struct nvif_user *user = &chan->cli->drm->client.device.user; - struct nouveau_bo *pb = chan->push.buffer; - int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; - - BUG_ON(chan->dma.ib_free < 1); - WARN_ON(length > NV50_DMA_PUSH_MAX_LENGTH); - - nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); - nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8 | - (no_prefetch ? (1 << 31) : 0)); - - chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; - - mb(); - /* Flush writes. */ - nouveau_bo_rd32(pb, 0); - - nvif_wr32(chan->userd, 0x8c, chan->dma.ib_put); - if (user->func && user->func->doorbell) - user->func->doorbell(user, chan->token); - chan->dma.ib_free--; -} - -static int -nv50_dma_push_wait(struct nouveau_channel *chan, int count) -{ - uint32_t cnt = 0, prev_get = 0; - - while (chan->dma.ib_free < count) { - uint32_t get = nvif_rd32(chan->userd, 0x88); - if (get != prev_get) { - prev_get = get; - cnt = 0; - } - - if ((++cnt & 0xff) == 0) { - udelay(1); - if (cnt > 100000) - return -EBUSY; - } - - chan->dma.ib_free = get - chan->dma.ib_put; - if (chan->dma.ib_free <= 0) - chan->dma.ib_free += chan->dma.ib_max; - } - - return 0; -} - -static int -nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) -{ - uint64_t prev_get = 0; - int ret, cnt = 0; - - ret = nv50_dma_push_wait(chan, slots + 1); - if (unlikely(ret)) - return ret; - - while (chan->dma.free < count) { - int get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - - return get; - } - - if (get <= chan->dma.cur) { - chan->dma.free = chan->dma.max - chan->dma.cur; - if (chan->dma.free >= count) - break; - - FIRE_RING(chan); - do { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - return get; - } - } while (get == 0); - chan->dma.cur = 0; - chan->dma.put = 0; - } - - chan->dma.free = get - chan->dma.cur - 1; - } - - return 0; -} - int -nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) +nouveau_dma_wait(struct nouveau_channel *chan, int size) { uint64_t prev_get = 0; int cnt = 0, get; - if (chan->dma.ib_max) - return nv50_dma_wait(chan, slots, size); - while (chan->dma.free < size) { get = READ_GET(chan, &prev_get, &cnt); if (unlikely(get == -EBUSY)) |