diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 18:10:22 (GMT) |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 19:13:14 (GMT) |
commit | 0ad72863ea426d46b2786cba9430e122a40aad0b (patch) | |
tree | bbb9346e53a5e0c16674f4e43807cad013c6cc25 /drivers/gpu/drm/nouveau/nouveau_chan.c | |
parent | 967e7bde8739fe3b215f7537e8f1f39c044902af (diff) | |
download | linux-0ad72863ea426d46b2786cba9430e122a40aad0b.tar.xz |
drm/nouveau: port to nvif client/device/objects
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_chan.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_chan.c | 110 |
1 files changed, 48 insertions, 62 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 3f450d7..2072518 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -27,12 +27,6 @@ #include <core/device.h> #include <core/class.h> -#include <subdev/fb.h> -#include <subdev/vm.h> -#include <subdev/instmem.h> - -#include <engine/software.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_bo.h" @@ -47,7 +41,7 @@ module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); int nouveau_channel_idle(struct nouveau_channel *chan) { - struct nouveau_cli *cli = chan->cli; + struct nouveau_cli *cli = (void *)nvif_client(chan->object); struct nouveau_fence *fence = NULL; int ret; @@ -59,7 +53,7 @@ nouveau_channel_idle(struct nouveau_channel *chan) if (ret) NV_PRINTK(error, cli, "failed to idle channel 0x%08x [%s]\n", - chan->handle, cli->base.name); + chan->object->handle, nvkm_client(&cli->base)->name); return ret; } @@ -68,36 +62,36 @@ nouveau_channel_del(struct nouveau_channel **pchan) { struct nouveau_channel *chan = *pchan; if (chan) { - struct nouveau_object *client = nv_object(chan->cli); if (chan->fence) { nouveau_channel_idle(chan); nouveau_fence(chan->drm)->context_del(chan); } - nouveau_object_del(client, NVDRM_DEVICE, chan->handle); - nouveau_object_del(client, NVDRM_DEVICE, chan->push.handle); + nvif_object_fini(&chan->nvsw); + nvif_object_fini(&chan->gart); + nvif_object_fini(&chan->vram); + nvif_object_ref(NULL, &chan->object); + nvif_object_fini(&chan->push.ctxdma); nouveau_bo_vma_del(chan->push.buffer, &chan->push.vma); nouveau_bo_unmap(chan->push.buffer); if (chan->push.buffer && chan->push.buffer->pin_refcnt) nouveau_bo_unpin(chan->push.buffer); nouveau_bo_ref(NULL, &chan->push.buffer); + nvif_device_ref(NULL, &chan->device); kfree(chan); } *pchan = NULL; } static int -nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, - u32 parent, u32 handle, u32 size, - struct nouveau_channel **pchan) +nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, + u32 handle, u32 size, struct nouveau_channel **pchan) { - struct nvif_device *device = &drm->device; + struct nouveau_cli *cli = (void *)nvif_client(&device->base); struct nouveau_instmem *imem = nvkm_instmem(device); struct nouveau_vmmgr *vmm = nvkm_vmmgr(device); struct nouveau_fb *pfb = nvkm_fb(device); - struct nouveau_client *client = &cli->base; struct nv_dma_class args = {}; struct nouveau_channel *chan; - struct nouveau_object *push; u32 target; int ret; @@ -105,9 +99,8 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, if (!chan) return -ENOMEM; - chan->cli = cli; + nvif_device_ref(device, &chan->device); chan->drm = drm; - chan->handle = handle; /* allocate memory for dma push buffer */ target = TTM_PL_FLAG_TT; @@ -132,10 +125,9 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, * we be able to call out to other (indirect) push buffers */ chan->push.vma.offset = chan->push.buffer->bo.offset; - chan->push.handle = NVDRM_PUSH | (handle & 0xffff); if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(chan->push.buffer, client->vm, + ret = nouveau_bo_vma_add(chan->push.buffer, cli->vm, &chan->push.vma); if (ret) { nouveau_channel_del(pchan); @@ -144,7 +136,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM; args.start = 0; - args.limit = client->vm->vmm->limit - 1; + args.limit = cli->vm->vmm->limit - 1; } else if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) { u64 limit = pfb->ram->size - imem->reserved - 1; @@ -174,9 +166,9 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, } } - ret = nouveau_object_new(nv_object(chan->cli), parent, - chan->push.handle, 0x0002, - &args, sizeof(args), &push); + ret = nvif_object_init(nvif_object(device), NULL, NVDRM_PUSH | + (handle & 0xffff), NV_DMA_FROM_MEMORY_CLASS, + &args, sizeof(args), &chan->push.ctxdma); if (ret) { nouveau_channel_del(pchan); return ret; @@ -186,9 +178,8 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, } static int -nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, - u32 parent, u32 handle, u32 engine, - struct nouveau_channel **pchan) +nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, + u32 handle, u32 engine, struct nouveau_channel **pchan) { static const u16 oclasses[] = { NVE0_CHANNEL_IND_CLASS, NVC0_CHANNEL_IND_CLASS, @@ -201,22 +192,20 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, int ret; /* allocate dma push buffer */ - ret = nouveau_channel_prep(drm, cli, parent, handle, 0x12000, &chan); + ret = nouveau_channel_prep(drm, device, handle, 0x12000, &chan); *pchan = chan; if (ret) return ret; /* create channel object */ - args.pushbuf = chan->push.handle; + args.pushbuf = chan->push.ctxdma.handle; args.ioffset = 0x10000 + chan->push.vma.offset; args.ilength = 0x02000; args.engine = engine; do { - ret = nouveau_object_new(nv_object(cli), parent, handle, - *oclass++, &args, sizeof(args), - (struct nouveau_object **) - &chan->object); + ret = nvif_object_new(nvif_object(device), handle, *oclass++, + &args, sizeof(args), &chan->object); if (ret == 0) return ret; } while (*oclass); @@ -226,8 +215,8 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, } static int -nouveau_channel_dma(struct nouveau_drm *drm, struct nouveau_cli *cli, - u32 parent, u32 handle, struct nouveau_channel **pchan) +nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, + u32 handle, struct nouveau_channel **pchan) { static const u16 oclasses[] = { NV40_CHANNEL_DMA_CLASS, NV17_CHANNEL_DMA_CLASS, @@ -240,20 +229,18 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nouveau_cli *cli, int ret; /* allocate dma push buffer */ - ret = nouveau_channel_prep(drm, cli, parent, handle, 0x10000, &chan); + ret = nouveau_channel_prep(drm, device, handle, 0x10000, &chan); *pchan = chan; if (ret) return ret; /* create channel object */ - args.pushbuf = chan->push.handle; + args.pushbuf = chan->push.ctxdma.handle; args.offset = chan->push.vma.offset; do { - ret = nouveau_object_new(nv_object(cli), parent, handle, - *oclass++, &args, sizeof(args), - (struct nouveau_object **) - &chan->object); + ret = nvif_object_new(nvif_object(device), handle, *oclass++, + &args, sizeof(args), &chan->object); if (ret == 0) return ret; } while (ret && *oclass); @@ -265,13 +252,12 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nouveau_cli *cli, static int nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) { - struct nouveau_client *client = nv_client(chan->cli); - struct nvif_device *device = &chan->drm->device; + struct nvif_device *device = chan->device; + struct nouveau_cli *cli = (void *)nvif_client(&device->base); struct nouveau_instmem *imem = nvkm_instmem(device); struct nouveau_vmmgr *vmm = nvkm_vmmgr(device); struct nouveau_fb *pfb = nvkm_fb(device); struct nouveau_software_chan *swch; - struct nouveau_object *object; struct nv_dma_class args = {}; int ret, i; @@ -280,22 +266,23 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM; args.start = 0; - args.limit = client->vm->vmm->limit - 1; + args.limit = cli->vm->vmm->limit - 1; } else { args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR; args.start = 0; args.limit = pfb->ram->size - imem->reserved - 1; } - ret = nouveau_object_new(nv_object(client), chan->handle, vram, - 0x003d, &args, sizeof(args), &object); + ret = nvif_object_init(chan->object, NULL, vram, + NV_DMA_IN_MEMORY_CLASS, &args, + sizeof(args), &chan->vram); if (ret) return ret; if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM; args.start = 0; - args.limit = client->vm->vmm->limit - 1; + args.limit = cli->vm->vmm->limit - 1; } else if (chan->drm->agp.stat == ENABLED) { args.flags = NV_DMA_TARGET_AGP | NV_DMA_ACCESS_RDWR; @@ -308,17 +295,15 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.limit = vmm->limit - 1; } - ret = nouveau_object_new(nv_object(client), chan->handle, gart, - 0x003d, &args, sizeof(args), &object); + ret = nvif_object_init(chan->object, NULL, gart, + NV_DMA_IN_MEMORY_CLASS, &args, + sizeof(args), &chan->gart); if (ret) return ret; - - chan->vram = vram; - chan->gart = gart; } /* initialise dma tracking parameters */ - switch (nv_hclass(chan->object) & 0x00ff) { + switch (chan->object->oclass & 0x00ff) { case 0x006b: case 0x006e: chan->user_put = 0x40; @@ -350,12 +335,12 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) /* allocate software object class (used for fences on <= nv05) */ if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) { - ret = nouveau_object_new(nv_object(client), chan->handle, - NvSw, 0x006e, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvSw, 0x006e, + NULL, 0, &chan->nvsw); if (ret) return ret; - swch = (void *)object->parent; + swch = (void *)nvkm_object(&chan->nvsw)->parent; swch->flip = nouveau_flip_complete; swch->flip_data = chan; @@ -373,16 +358,17 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) } int -nouveau_channel_new(struct nouveau_drm *drm, struct nouveau_cli *cli, - u32 parent, u32 handle, u32 arg0, u32 arg1, +nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, + u32 handle, u32 arg0, u32 arg1, struct nouveau_channel **pchan) { + struct nouveau_cli *cli = (void *)nvif_client(&device->base); int ret; - ret = nouveau_channel_ind(drm, cli, parent, handle, arg0, pchan); + ret = nouveau_channel_ind(drm, device, handle, arg0, pchan); if (ret) { NV_PRINTK(debug, cli, "ib channel create, %d\n", ret); - ret = nouveau_channel_dma(drm, cli, parent, handle, pchan); + ret = nouveau_channel_dma(drm, device, handle, pchan); if (ret) { NV_PRINTK(debug, cli, "dma channel create, %d\n", ret); return ret; |