diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 22:10:22 +0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 23:13:14 +0400 |
commit | 0ad72863ea426d46b2786cba9430e122a40aad0b (patch) | |
tree | bbb9346e53a5e0c16674f4e43807cad013c6cc25 /drivers | |
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')
40 files changed, 522 insertions, 479 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 3cddb955aad3..029e0555fa38 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -338,6 +338,7 @@ nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o nouveau-y += nouveau_vga.o nouveau_agp.o nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o nouveau-y += nouveau_prime.o nouveau_abi16.o +nouveau-y += nouveau_nvif.o nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o nouveau-y += nv50_fence.o nv84_fence.o nvc0_fence.o diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index e63f5d694c55..0f02df21a18d 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -70,6 +70,8 @@ nv04_display_create(struct drm_device *dev) if (!disp) return -ENOMEM; + nvif_object_map(nvif_object(&drm->device)); + nouveau_display(dev)->priv = disp; nouveau_display(dev)->dtor = nv04_display_destroy; nouveau_display(dev)->init = nv04_display_init; @@ -144,6 +146,7 @@ void nv04_display_destroy(struct drm_device *dev) { struct nv04_display *disp = nv04_display(dev); + struct nouveau_drm *drm = nouveau_drm(dev); struct drm_encoder *encoder; struct drm_crtc *crtc; @@ -170,6 +173,8 @@ nv04_display_destroy(struct drm_device *dev) nouveau_display(dev)->priv = NULL; kfree(disp); + + nvif_object_unmap(nvif_object(&drm->device)); } int diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c index c12f3a871da1..c9dc5541acbf 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -27,9 +27,6 @@ #include "hw.h" #include <subdev/bios/pll.h> -#include <subdev/fb.h> -#include <subdev/clock.h> -#include <subdev/timer.h> #define CHIPSET_NFORCE 0x01a0 #define CHIPSET_NFORCE2 0x01f0 diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index 1ed54c9b5a49..8061d8d0ce79 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -35,8 +35,6 @@ #include <drm/i2c/ch7006.h> -#include <subdev/i2c.h> - static struct nouveau_i2c_board_info nv04_tv_encoder_info[] = { { { diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 28975b732c6a..5210190744a3 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -37,7 +37,6 @@ #include <core/device.h> #include <subdev/bios/gpio.h> -#include <subdev/gpio.h> MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 6a6f20f41ae9..ae794625a5b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -27,47 +27,34 @@ #include <core/class.h> #include <core/mm.h> -#include <subdev/fb.h> -#include <subdev/timer.h> -#include <subdev/instmem.h> -#include <engine/graph.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_gem.h" #include "nouveau_chan.h" #include "nouveau_abi16.h" -void nouveau_drm_hack_device(struct nouveau_drm *, struct nvif_device *); - struct nouveau_abi16 * nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) { struct nouveau_cli *cli = nouveau_cli(file_priv); - struct nouveau_drm *drm = nouveau_drm(dev); mutex_lock(&cli->mutex); if (!cli->abi16) { struct nouveau_abi16 *abi16; cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL); if (cli->abi16) { INIT_LIST_HEAD(&abi16->channels); - abi16->client = nv_object(cli); /* allocate device object targeting client's default * device (ie. the one that belongs to the fd it * opened) */ - if (nouveau_object_new(abi16->client, NVDRM_CLIENT, - NVDRM_DEVICE, 0x0080, - &(struct nv_device_class) { + if (nvif_device_init(&cli->base.base, NULL, + NVDRM_DEVICE, NV_DEVICE_CLASS, + &(struct nv_device_class) { .device = ~0ULL, - }, - sizeof(struct nv_device_class), - (struct nouveau_object **) - &abi16->device.object) == 0) { - nouveau_drm_hack_device(drm, &abi16->device); + }, sizeof(struct nv_device_class), + &abi16->device) == 0) return cli->abi16; - } kfree(cli->abi16); cli->abi16 = NULL; @@ -81,7 +68,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) int nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret) { - struct nouveau_cli *cli = (void *)abi16->client; + struct nouveau_cli *cli = (void *)nvif_client(&abi16->device.base); mutex_unlock(&cli->mutex); return ret; } @@ -144,7 +131,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, /* destroy channel object, all children will be killed too */ if (chan->chan) { - abi16->handles &= ~(1ULL << (chan->chan->handle & 0xffff)); + abi16->handles &= ~(1ULL << (chan->chan->object->handle & 0xffff)); nouveau_channel_del(&chan->chan); } @@ -155,7 +142,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, void nouveau_abi16_fini(struct nouveau_abi16 *abi16) { - struct nouveau_cli *cli = (void *)abi16->client; + struct nouveau_cli *cli = (void *)nvif_client(&abi16->device.base); struct nouveau_abi16_chan *chan, *temp; /* cleanup channels */ @@ -164,7 +151,7 @@ nouveau_abi16_fini(struct nouveau_abi16 *abi16) } /* destroy the device object */ - nouveau_object_del(abi16->client, NVDRM_CLIENT, NVDRM_DEVICE); + nvif_device_fini(&abi16->device); kfree(cli->abi16); cli->abi16 = NULL; @@ -251,7 +238,6 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16_chan *chan; - struct nouveau_client *client; struct nvif_device *device; struct nouveau_instmem *imem; struct nouveau_fb *pfb; @@ -263,7 +249,6 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) if (!drm->channel) return nouveau_abi16_put(abi16, -ENODEV); - client = nv_client(abi16->client); device = &abi16->device; imem = nvkm_instmem(device); pfb = nvkm_fb(device); @@ -298,8 +283,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) abi16->handles |= (1ULL << init->channel); /* create channel object and initialise dma and fence management */ - ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN | - init->channel, init->fb_ctxdma_handle, + ret = nouveau_channel_new(drm, device, NVDRM_CHAN | init->channel, + init->fb_ctxdma_handle, init->tt_ctxdma_handle, &chan->chan); if (ret) goto done; @@ -330,7 +315,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) goto done; if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(chan->ntfy, client->vm, + ret = nouveau_bo_vma_add(chan->ntfy, cli->vm, &chan->ntfy_vma); if (ret) goto done; @@ -361,7 +346,7 @@ nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) return -ENOMEM; list_for_each_entry(chan, &abi16->channels, head) { - if (chan->chan->handle == (NVDRM_CHAN | req->channel)) { + if (chan->chan->object->handle == (NVDRM_CHAN | req->channel)) { nouveau_abi16_chan_fini(abi16, chan); return nouveau_abi16_put(abi16, 0); } @@ -392,8 +377,10 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, 0); } - ret = nouveau_object_new(abi16->client, NVDRM_CHAN | init->channel, - init->handle, init->class, NULL, 0, &object); + /*XXX*/ + ret = nouveau_object_new(nv_object(nvkm_client(&abi16->device.base)), + NVDRM_CHAN | init->channel, init->handle, + init->class, NULL, 0, &object); return nouveau_abi16_put(abi16, ret); } @@ -418,7 +405,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, -EINVAL); list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | info->channel)) { + if (temp->chan->object->handle == (NVDRM_CHAN | info->channel)) { chan = temp; break; } @@ -456,9 +443,11 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) args.limit += chan->ntfy->bo.offset; } - ret = nouveau_object_new(abi16->client, chan->chan->handle, - ntfy->handle, 0x003d, &args, - sizeof(args), &object); + /*XXX*/ + ret = nouveau_object_new(nv_object(nvkm_client(&abi16->device.base)), + NVDRM_CHAN | info->channel, ntfy->handle, + NV_DMA_IN_MEMORY_CLASS, &args, sizeof(args), + &object); if (ret) goto done; @@ -483,7 +472,7 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) return -ENOMEM; list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) { + if (temp->chan->object->handle == (NVDRM_CHAN | fini->channel)) { chan = temp; break; } @@ -495,7 +484,9 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) /* synchronize with the user channel and destroy the gpu object */ nouveau_channel_idle(chan->chan); - ret = nouveau_object_del(abi16->client, chan->chan->handle, fini->handle); + /*XXX*/ + ret = nouveau_object_del(nv_object(nvkm_client(&abi16->device.base)), + chan->chan->object->handle, fini->handle); if (ret) return nouveau_abi16_put(abi16, ret); diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h index de0ee3fbc52f..39844e6bfbff 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.h +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h @@ -28,7 +28,6 @@ struct nouveau_abi16_chan { }; struct nouveau_abi16 { - struct nouveau_object *client; struct nvif_device device; struct list_head channels; u64 handles; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 61429b712c3b..ffdf85f7814e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -22,8 +22,6 @@ * SOFTWARE. */ -#include <subdev/bios.h> - #include <drm/drmP.h> #include "nouveau_drm.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 9c9291b3bfb5..d222875a58d5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -30,10 +30,6 @@ #include <core/engine.h> #include <linux/swiotlb.h> -#include <subdev/fb.h> -#include <subdev/vm.h> -#include <subdev/bar.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" @@ -951,6 +947,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_channel *chan = drm->ttm.chan; + struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); struct nouveau_fence *fence; int ret; @@ -964,7 +961,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, return ret; } - mutex_lock_nested(&chan->cli->mutex, SINGLE_DEPTH_NESTING); + mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); ret = nouveau_fence_sync(bo->sync_obj, chan); if (ret == 0) { ret = drm->ttm.move(chan, bo, &bo->mem, new_mem); @@ -979,7 +976,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, } } } - mutex_unlock(&chan->cli->mutex); + mutex_unlock(&cli->mutex); return ret; } @@ -1011,9 +1008,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) int ret; do { - struct nouveau_object *object; struct nouveau_channel *chan; - u32 handle = (mthd->engine << 16) | mthd->oclass; if (mthd->engine) chan = drm->cechan; @@ -1022,13 +1017,14 @@ nouveau_bo_move_init(struct nouveau_drm *drm) if (chan == NULL) continue; - ret = nouveau_object_new(nv_object(drm), chan->handle, handle, - mthd->oclass, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, + mthd->oclass | (mthd->engine << 16), + mthd->oclass, NULL, 0, + &drm->ttm.copy); if (ret == 0) { - ret = mthd->init(chan, handle); + ret = mthd->init(chan, drm->ttm.copy.handle); if (ret) { - nouveau_object_del(nv_object(drm), - chan->handle, handle); + nvif_object_fini(&drm->ttm.copy); continue; } diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 3f450d7295fb..2072518f93fa 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; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index a3fec949a225..2a02fd56cf18 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -1,20 +1,21 @@ #ifndef __NOUVEAU_CHAN_H__ #define __NOUVEAU_CHAN_H__ -struct nouveau_cli; +#include <nvif/object.h> +struct nvif_device; struct nouveau_channel { - struct nouveau_cli *cli; + struct nvif_device *device; struct nouveau_drm *drm; - u32 handle; - u32 vram; - u32 gart; + struct nvif_object vram; + struct nvif_object gart; + struct nvif_object nvsw; struct { struct nouveau_bo *buffer; struct nouveau_vma vma; - u32 handle; + struct nvif_object ctxdma; } push; /* TODO: this will be reworked in the near future */ @@ -38,8 +39,8 @@ struct nouveau_channel { }; -int nouveau_channel_new(struct nouveau_drm *, struct nouveau_cli *, - u32 parent, u32 handle, u32 arg0, u32 arg1, +int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, + u32 handle, u32 arg0, u32 arg1, struct nouveau_channel **); void nouveau_channel_del(struct nouveau_channel **); int nouveau_channel_idle(struct nouveau_channel *); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 926f5bf2c83e..1b009f73e85f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -42,10 +42,6 @@ #include "nouveau_encoder.h" #include "nouveau_crtc.h" -#include <subdev/i2c.h> -#include <subdev/gpio.h> -#include <engine/disp.h> - #include <nvif/event.h> MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index c63615b00d56..897e08503bfb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -37,8 +37,6 @@ #include "nouveau_fence.h" -#include <engine/disp.h> - #include <core/class.h> #include <nvif/event.h> @@ -102,7 +100,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, int ret, retry = 1; do { - ret = nv_exec(disp->core, mthd, &args, sizeof(args)); + ret = nvif_exec(&disp->disp, mthd, &args, sizeof(args)); if (ret != 0) return 0; @@ -399,10 +397,10 @@ nouveau_display_create_properties(struct drm_device *dev) struct nouveau_display *disp = nouveau_display(dev); int gen; - if (nv_mclass(disp->core) < NV50_DISP_CLASS) + if (disp->disp.oclass < NV50_DISP_CLASS) gen = 0; else - if (nv_mclass(disp->core) < NVD0_DISP_CLASS) + if (disp->disp.oclass < NVD0_DISP_CLASS) gen = 1; else gen = 2; @@ -488,14 +486,14 @@ nouveau_display_create(struct drm_device *dev) int i; for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { - ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, - NVDRM_DISPLAY, oclass[i], - NULL, 0, &disp->core); + ret = nvif_object_init(nvif_object(&drm->device), NULL, + NVDRM_DISPLAY, oclass[i], + NULL, 0, &disp->disp); } if (ret == 0) { nouveau_display_create_properties(dev); - if (nv_mclass(disp->core) < NV50_DISP_CLASS) + if (disp->disp.oclass < NV50_DISP_CLASS) ret = nv04_display_create(dev); else ret = nv50_display_create(dev); @@ -528,7 +526,6 @@ void nouveau_display_destroy(struct drm_device *dev) { struct nouveau_display *disp = nouveau_display(dev); - struct nouveau_drm *drm = nouveau_drm(dev); nouveau_backlight_exit(dev); nouveau_display_vblank_fini(dev); @@ -539,7 +536,7 @@ nouveau_display_destroy(struct drm_device *dev) if (disp->dtor) disp->dtor(dev); - nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_DISPLAY); + nvif_object_fini(&disp->disp); nouveau_drm(dev)->display = NULL; kfree(disp); @@ -690,12 +687,15 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; struct nouveau_page_flip_state *s; - struct nouveau_channel *chan = drm->channel; + struct nouveau_channel *chan; + struct nouveau_cli *cli; struct nouveau_fence *fence; int ret; - if (!drm->channel) + chan = drm->channel; + if (!chan) return -ENODEV; + cli = (void *)nvif_client(&chan->device->base); s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) @@ -707,7 +707,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, goto fail_free; } - mutex_lock(&chan->cli->mutex); + mutex_lock(&cli->mutex); /* synchronise rendering channel with the kernel's channel */ spin_lock(&new_bo->bo.bdev->fence_lock); @@ -761,7 +761,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); if (ret) goto fail_unreserve; - mutex_unlock(&chan->cli->mutex); + mutex_unlock(&cli->mutex); /* Update the crtc struct and cleanup */ crtc->primary->fb = fb; @@ -777,7 +777,7 @@ fail_unreserve: drm_vblank_put(dev, nouveau_crtc(crtc)->index); ttm_bo_unreserve(&old_bo->bo); fail_unpin: - mutex_unlock(&chan->cli->mutex); + mutex_unlock(&cli->mutex); if (old_bo != new_bo) nouveau_bo_unpin(new_bo); fail_free: diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 37bf0d224a4c..88ca177cb1c7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -12,6 +12,8 @@ struct nouveau_framebuffer { u32 r_handle; u32 r_format; u32 r_pitch; + struct nvif_object h_base[4]; + struct nvif_object h_core; }; static inline struct nouveau_framebuffer * @@ -39,7 +41,7 @@ struct nouveau_display { int (*fb_ctor)(struct drm_framebuffer *); void (*fb_dtor)(struct drm_framebuffer *); - struct nouveau_object *core; + struct nvif_object disp; struct drm_property *dithering_mode; struct drm_property *dithering_depth; diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index da773abe6307..aafdd278ae3f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -84,12 +84,13 @@ void nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, int delta, int length) { + struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); struct nouveau_bo *pb = chan->push.buffer; struct nouveau_vma *vma; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; u64 offset; - vma = nouveau_bo_vma_find(bo, nv_client(chan->cli)->vm); + vma = nouveau_bo_vma_find(bo, cli->vm); BUG_ON(!vma); offset = vma->offset + delta; diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 5675ffc175ae..29cd1a9010a4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -32,9 +32,6 @@ #include <core/class.h> -#include <subdev/gpio.h> -#include <subdev/i2c.h> - static void nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, u8 *dpcd) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 051e7104106d..309be93de597 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -30,18 +30,10 @@ #include "drmP.h" #include "drm_crtc_helper.h" #include <core/device.h> -#include <core/client.h> #include <core/gpuobj.h> #include <core/class.h> #include <core/option.h> -#include <engine/device.h> -#include <engine/disp.h> -#include <engine/fifo.h> -#include <engine/software.h> - -#include <subdev/vm.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_ttm.h" @@ -109,40 +101,34 @@ static int nouveau_cli_create(u64 name, const char *sname, int size, void **pcli) { - struct nouveau_cli *cli; - int ret; - - *pcli = NULL; - ret = nouveau_client_create_(sname, name, nouveau_config, - nouveau_debug, size, pcli); - cli = *pcli; - if (ret) { - if (cli) - nouveau_client_destroy(&cli->base); - *pcli = NULL; + struct nouveau_cli *cli = *pcli = kzalloc(size, GFP_KERNEL); + if (cli) { + int ret = nvif_client_init(NULL, NULL, sname, name, + nouveau_config, nouveau_debug, + &cli->base); + if (ret == 0) + mutex_init(&cli->mutex); return ret; } - - mutex_init(&cli->mutex); - return 0; + return -ENOMEM; } static void nouveau_cli_destroy(struct nouveau_cli *cli) { - struct nouveau_object *client = nv_object(cli); - nouveau_vm_ref(NULL, &cli->base.vm, NULL); - nouveau_client_fini(&cli->base, false); - atomic_set(&client->refcount, 1); - nouveau_object_ref(NULL, &client); + nouveau_vm_ref(NULL, &nvkm_client(&cli->base)->vm, NULL); + nvif_client_fini(&cli->base); } static void nouveau_accel_fini(struct nouveau_drm *drm) { - nouveau_gpuobj_ref(NULL, &drm->notify); nouveau_channel_del(&drm->channel); + nvif_object_fini(&drm->ntfy); + nouveau_gpuobj_ref(NULL, &drm->notify); + nvif_object_fini(&drm->nvsw); nouveau_channel_del(&drm->cechan); + nvif_object_fini(&drm->ttm.copy); if (drm->fence) nouveau_fence(drm)->dtor(drm); } @@ -151,7 +137,6 @@ static void nouveau_accel_init(struct nouveau_drm *drm) { struct nvif_device *device = &drm->device; - struct nouveau_object *object; u32 arg0, arg1; u32 sclass[16]; int ret, i; @@ -163,8 +148,7 @@ nouveau_accel_init(struct nouveau_drm *drm) /*XXX: this is crap, but the fence/channel stuff is a little * backwards in some places. this will be fixed. */ - ret = nouveau_parent_lclass(nvkm_object(device), sclass, - ARRAY_SIZE(sclass)); + ret = nvif_object_sclass(&device->base, sclass, ARRAY_SIZE(sclass)); if (ret < 0) return; @@ -202,8 +186,7 @@ nouveau_accel_init(struct nouveau_drm *drm) } if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { - ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, - NVDRM_CHAN + 1, + ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, NVE0_CHANNEL_IND_ENGINE_CE0 | NVE0_CHANNEL_IND_ENGINE_CE1, 0, &drm->cechan); @@ -216,9 +199,8 @@ nouveau_accel_init(struct nouveau_drm *drm) if (device->info.chipset >= 0xa3 && device->info.chipset != 0xaa && device->info.chipset != 0xac) { - ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, - NVDRM_CHAN + 1, NvDmaFB, NvDmaTT, - &drm->cechan); + ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, + NvDmaFB, NvDmaTT, &drm->cechan); if (ret) NV_ERROR(drm, "failed to create ce channel, %d\n", ret); @@ -229,18 +211,18 @@ nouveau_accel_init(struct nouveau_drm *drm) arg1 = NvDmaTT; } - ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN, - arg0, arg1, &drm->channel); + ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN, arg0, arg1, + &drm->channel); if (ret) { NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); nouveau_accel_fini(drm); return; } - ret = nouveau_object_new(nv_object(drm), NVDRM_CHAN, NVDRM_NVSW, - nouveau_abi16_swclass(drm), NULL, 0, &object); + ret = nvif_object_init(drm->channel->object, NULL, NVDRM_NVSW, + nouveau_abi16_swclass(drm), NULL, 0, &drm->nvsw); if (ret == 0) { - struct nouveau_software_chan *swch = (void *)object->parent; + struct nouveau_software_chan *swch; ret = RING_SPACE(drm->channel, 2); if (ret == 0) { if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { @@ -252,7 +234,7 @@ nouveau_accel_init(struct nouveau_drm *drm) OUT_RING (drm->channel, 0x001f0000); } } - swch = (void *)object->parent; + swch = (void *)nvkm_object(&drm->nvsw)->parent; swch->flip = nouveau_flip_complete; swch->flip_data = drm->channel; } @@ -272,15 +254,15 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } - ret = nouveau_object_new(nv_object(drm), - drm->channel->handle, NvNotify0, - 0x003d, &(struct nv_dma_class) { + ret = nvif_object_init(drm->channel->object, NULL, NvNotify0, + NV_DMA_IN_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = drm->notify->addr, .limit = drm->notify->addr + 31 - }, sizeof(struct nv_dma_class), - &object); + }, sizeof(struct nv_dma_class), + &drm->ntfy); if (ret) { nouveau_accel_fini(drm); return; @@ -373,27 +355,6 @@ nouveau_get_hdmi_dev(struct nouveau_drm *drm) } } -void -nouveau_drm_hack_device(struct nouveau_drm *drm, struct nvif_device *device) -{ - drm->device.info.chipset = nvkm_device(&drm->device)->chipset; - switch (nvkm_device(&drm->device)->card_type) { - case NV_04: device->info.family = NV_DEVICE_INFO_V0_TNT; break; - case NV_10: device->info.family = NV_DEVICE_INFO_V0_CELSIUS; break; - case NV_11: device->info.family = NV_DEVICE_INFO_V0_CELSIUS; break; - case NV_20: device->info.family = NV_DEVICE_INFO_V0_KELVIN; break; - case NV_30: device->info.family = NV_DEVICE_INFO_V0_RANKINE; break; - case NV_40: device->info.family = NV_DEVICE_INFO_V0_CURIE; break; - case NV_50: device->info.family = NV_DEVICE_INFO_V0_TESLA; break; - case NV_C0: device->info.family = NV_DEVICE_INFO_V0_FERMI; break; - case NV_E0: device->info.family = NV_DEVICE_INFO_V0_KEPLER; break; - case GM100: device->info.family = NV_DEVICE_INFO_V0_MAXWELL; break; - default: - BUG_ON(1); - break; - } -} - static int nouveau_drm_load(struct drm_device *dev, unsigned long flags) { @@ -408,7 +369,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; - nouveau_client(drm)->debug = nouveau_dbgopt(nouveau_debug, "DRM"); + nvkm_client(&drm->client.base)->debug = + nouveau_dbgopt(nouveau_debug, "DRM"); INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); @@ -422,39 +384,34 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) /* dummy device object, doesn't init anything, but allows * agp code access to registers */ - ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT, - NVDRM_DEVICE, 0x0080, - &(struct nv_device_class) { + ret = nvif_device_init(&drm->client.base.base, NULL, + NVDRM_DEVICE, NV_DEVICE_CLASS, + &(struct nv_device_class) { .device = ~0, .disable = ~(NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY), .debug0 = ~0, - }, sizeof(struct nv_device_class), - (struct nouveau_object **) - &drm->device.object); + }, sizeof(struct nv_device_class), + &drm->device); if (ret) goto fail_device; - nouveau_drm_hack_device(drm, &drm->device); - nouveau_agp_reset(drm); - nouveau_object_del(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE); + nvif_device_fini(&drm->device); } - ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE, - 0x0080, &(struct nv_device_class) { + ret = nvif_device_init(&drm->client.base.base, NULL, NVDRM_DEVICE, + NV_DEVICE_CLASS, + &(struct nv_device_class) { .device = ~0, .disable = 0, .debug0 = 0, - }, sizeof(struct nv_device_class), - (struct nouveau_object **) - &drm->device.object); + }, sizeof(struct nv_device_class), + &drm->device); if (ret) goto fail_device; - nouveau_drm_hack_device(drm, &drm->device); - dev->irq_enabled = true; /* workaround an odd issue on nvc1 by disabling the device's @@ -473,7 +430,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto fail_device; - drm->client.base.vm = drm->client.vm; + nvkm_client(&drm->client.base)->vm = drm->client.vm; } ret = nouveau_ttm_init(drm); @@ -519,6 +476,7 @@ fail_ttm: nouveau_agp_fini(drm); nouveau_vga_fini(drm); fail_device: + nvif_device_fini(&drm->device); nouveau_cli_destroy(&drm->client); return ret; } @@ -544,6 +502,7 @@ nouveau_drm_unload(struct drm_device *dev) nouveau_agp_fini(drm); nouveau_vga_fini(drm); + nvif_device_fini(&drm->device); if (drm->hdmi_device) pci_dev_put(drm->hdmi_device); nouveau_cli_destroy(&drm->client); @@ -554,10 +513,12 @@ void nouveau_drm_device_remove(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_client *client; struct nouveau_object *device; dev->irq_enabled = false; - device = drm->client.base.device; + client = nvkm_client(&drm->client.base); + device = client->device; drm_put_dev(dev); nouveau_object_ref(NULL, &device); @@ -612,13 +573,13 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) } list_for_each_entry(cli, &drm->clients, head) { - ret = nouveau_client_fini(&cli->base, true); + ret = nvif_client_suspend(&cli->base); if (ret) goto fail_client; } NV_INFO(drm, "suspending kernel object tree...\n"); - ret = nouveau_client_fini(&drm->client.base, true); + ret = nvif_client_suspend(&drm->client.base); if (ret) goto fail_client; @@ -627,7 +588,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) fail_client: list_for_each_entry_continue_reverse(cli, &drm->clients, head) { - nouveau_client_init(&cli->base); + nvif_client_resume(&cli->base); } if (drm->fence && nouveau_fence(drm)->resume) @@ -675,7 +636,7 @@ nouveau_do_resume(struct drm_device *dev) nouveau_agp_reset(drm); NV_INFO(drm, "resuming kernel object tree...\n"); - nouveau_client_init(&drm->client.base); + nvif_client_resume(&drm->client.base); nouveau_agp_init(drm); NV_INFO(drm, "resuming client object trees...\n"); @@ -683,7 +644,7 @@ nouveau_do_resume(struct drm_device *dev) nouveau_fence(drm)->resume(drm); list_for_each_entry(cli, &drm->clients, head) { - nouveau_client_init(&cli->base); + nvif_client_resume(&cli->base); } nouveau_run_vbios_init(dev); @@ -779,6 +740,8 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) if (ret) goto out_suspend; + cli->base.super = false; + if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { ret = nouveau_vm_new(nvkm_device(&drm->device), 0, (1ULL << 40), 0x1000, &cli->vm); @@ -787,7 +750,7 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) goto out_suspend; } - cli->base.vm = cli->vm; + nvkm_client(&cli->base)->vm = cli->vm; } fpriv->driver_priv = cli; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 07e9c734cc46..a29fd210e4c6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -28,6 +28,9 @@ #include <core/client.h> #include <core/event.h> +#include <nvif/client.h> +#include <nvif/device.h> + #include <subdev/vm.h> #include <drmP.h> @@ -53,6 +56,17 @@ struct nouveau_drm_tile { bool used; }; +enum nouveau_drm_object_route { + NVDRM_OBJECT_NVIF = 0, + NVDRM_OBJECT_USIF, + NVDRM_OBJECT_ABI16, +}; + +enum nouveau_drm_notify_route { + NVDRM_NOTIFY_NVIF = 0, + NVDRM_NOTIFY_USIF +}; + enum nouveau_drm_handle { NVDRM_CLIENT = 0xffffffff, NVDRM_DEVICE = 0xdddddddd, @@ -64,7 +78,7 @@ enum nouveau_drm_handle { }; struct nouveau_cli { - struct nouveau_client base; + struct nvif_client base; struct nouveau_vm *vm; /*XXX*/ struct list_head head; struct mutex mutex; @@ -78,31 +92,6 @@ nouveau_cli(struct drm_file *fpriv) } #include <nvif/object.h> -#undef nvif_object -#undef nvif_rd08 -#undef nvif_rd16 -#undef nvif_rd32 -#undef nvif_wr08 -#undef nvif_wr16 -#undef nvif_wr32 -#undef nvif_mask -#undef nvkm_object -#undef nvif_exec - -#define nvif_object(a) ({ \ - struct nvif_object *_object = (a)->object; \ - (struct nouveau_object *)_object; \ -}) -#define nvif_rd08(a,b) nv_ro08(nvif_object(a), (b)) -#define nvif_rd16(a,b) nv_ro16(nvif_object(a), (b)) -#define nvif_rd32(a,b) nv_ro32(nvif_object(a), (b)) -#define nvif_wr08(a,b,c) nv_wo08(nvif_object(a), (b), (c)) -#define nvif_wr16(a,b,c) nv_wo16(nvif_object(a), (b), (c)) -#define nvif_wr32(a,b,c) nv_wo32(nvif_object(a), (b), (c)) -#define nvif_mask(a,b,c,d) nv_mo32(nvif_object(a), (b), (c), (d)) -#define nvkm_object(a) nvif_object(a) -#define nvif_exec(a,b,c,d) nv_exec(nvkm_object(a), (b), (c), (d)) - #include <nvif/device.h> extern int nouveau_runtime_pm; @@ -134,6 +123,7 @@ struct nouveau_drm { struct ttm_buffer_object *, struct ttm_mem_reg *, struct ttm_mem_reg *); struct nouveau_channel *chan; + struct nvif_object copy; int mtrr; } ttm; @@ -151,6 +141,8 @@ struct nouveau_drm { struct nouveau_channel *channel; struct nouveau_gpuobj *notify; struct nouveau_fbdev *fbcon; + struct nvif_object nvsw; + struct nvif_object ntfy; /* nv10-nv40 tiling regions */ struct { @@ -192,7 +184,7 @@ void nouveau_drm_device_remove(struct drm_device *dev); #define NV_PRINTK(l,c,f,a...) do { \ struct nouveau_cli *_cli = (c); \ - nv_##l(_cli, f, ##a); \ + nv_##l(_cli->base.base.priv, f, ##a); \ } while(0) #define NV_FATAL(drm,f,a...) NV_PRINTK(fatal, &(drm)->client, f, ##a) #define NV_ERROR(drm,f,a...) NV_PRINTK(error, &(drm)->client, f, ##a) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index b4d911e26ec8..6864e0361163 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -54,8 +54,6 @@ #include <core/client.h> #include <core/device.h> -#include <subdev/fb.h> - MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); static int nouveau_nofbaccel = 0; module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); @@ -241,6 +239,13 @@ nouveau_fbcon_accel_fini(struct drm_device *dev) fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; console_unlock(); nouveau_channel_idle(drm->channel); + nvif_object_fini(&fbcon->twod); + nvif_object_fini(&fbcon->blit); + nvif_object_fini(&fbcon->gdi); + nvif_object_fini(&fbcon->patt); + nvif_object_fini(&fbcon->rop); + nvif_object_fini(&fbcon->clip); + nvif_object_fini(&fbcon->surf2d); } } @@ -352,7 +357,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, chan = nouveau_nofbaccel ? NULL : drm->channel; if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nouveau_bo_vma_add(nvbo, nv_client(chan->cli)->vm, + ret = nouveau_bo_vma_add(nvbo, drm->client.vm, &fbcon->nouveau_fb.vma); if (ret) { NV_ERROR(drm, "failed to map fb into chan: %d\n", ret); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 6d857e2869c9..34658cfa8f5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -37,6 +37,13 @@ struct nouveau_fbdev { struct list_head fbdev_list; struct drm_device *dev; unsigned int saved_flags; + struct nvif_object surf2d; + struct nvif_object clip; + struct nvif_object rop; + struct nvif_object patt; + struct nvif_object gdi; + struct nvif_object blit; + struct nvif_object twod; }; void nouveau_fbcon_restore(void); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 35e32e1710bf..ace42ec92a72 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -33,8 +33,6 @@ #include "nouveau_dma.h" #include "nouveau_fence.h" -#include <engine/fifo.h> - struct fence_work { struct work_struct base; struct list_head head; @@ -184,7 +182,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) { struct nouveau_channel *chan = fence->channel; - struct nouveau_fifo *pfifo = nvkm_fifo(&chan->drm->device); + struct nouveau_fifo *pfifo = nvkm_fifo(chan->device); struct nouveau_fence_priv *priv = chan->drm->fence; struct nouveau_fence_wait wait = { .priv = priv }; int ret = 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 49320219df91..292a677bfed4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -24,8 +24,6 @@ * */ -#include <subdev/fb.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" @@ -696,7 +694,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, return -ENOMEM; list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | req->channel)) { + if (temp->chan->object->handle == (NVDRM_CHAN | req->channel)) { chan = temp->chan; break; } diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 817d41a8a0a4..afb36d66e78d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -34,10 +34,6 @@ #include "nouveau_drm.h" #include "nouveau_hwmon.h" -#include <subdev/gpio.h> -#include <subdev/timer.h> -#include <subdev/therm.h> - #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) static ssize_t nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) diff --git a/drivers/gpu/drm/nouveau/nouveau_nvif.c b/drivers/gpu/drm/nouveau/nouveau_nvif.c new file mode 100644 index 000000000000..c3838bffe24f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_nvif.c @@ -0,0 +1,133 @@ +/* + * Copyright 2014 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ + +/******************************************************************************* + * NVIF client driver - NVKM directly linked + ******************************************************************************/ + +#include <core/client.h> +#include <core/notify.h> +#include <core/ioctl.h> + +#include <nvif/client.h> +#include <nvif/driver.h> +#include <nvif/notify.h> +#include <nvif/event.h> +#include <nvif/ioctl.h> + +#include "nouveau_drm.h" + +static void +nvkm_client_unmap(void *priv, void *ptr, u32 size) +{ + iounmap(ptr); +} + +static void * +nvkm_client_map(void *priv, u64 handle, u32 size) +{ + return ioremap(handle, size); +} + +static int +nvkm_client_ioctl(void *priv, bool super, void *data, u32 size, void **hack) +{ + return nvkm_ioctl(priv, super, data, size, hack); +} + +static int +nvkm_client_resume(void *priv) +{ + return nouveau_client_init(priv); +} + +static int +nvkm_client_suspend(void *priv) +{ + return nouveau_client_fini(priv, true); +} + +static void +nvkm_client_fini(void *priv) +{ + struct nouveau_object *client = priv; + nouveau_client_fini(nv_client(client), false); + atomic_set(&client->refcount, 1); + nouveau_object_ref(NULL, &client); +} + +static int +nvkm_client_ntfy(const void *header, u32 length, const void *data, u32 size) +{ + const union { + struct nvif_notify_req_v0 v0; + } *args = header; + u8 route; + + if (length == sizeof(args->v0) && args->v0.version == 0) { + route = args->v0.route; + } else { + WARN_ON(1); + return NVKM_NOTIFY_DROP; + } + + switch (route) { + case NVDRM_NOTIFY_NVIF: + return nvif_notify(header, length, data, size); + default: + WARN_ON(1); + break; + } + + return NVKM_NOTIFY_DROP; +} + +static int +nvkm_client_init(const char *name, u64 device, const char *cfg, + const char *dbg, void **ppriv) +{ + struct nouveau_client *client; + int ret; + + ret = nouveau_client_create(name, device, cfg, dbg, &client); + *ppriv = client; + if (ret) + return ret; + + client->ntfy = nvkm_client_ntfy; + return 0; +} + +const struct nvif_driver +nvif_driver_nvkm = { + .name = "nvkm", + .init = nvkm_client_init, + .fini = nvkm_client_fini, + .suspend = nvkm_client_suspend, + .resume = nvkm_client_resume, + .ioctl = nvkm_client_ioctl, + .map = nvkm_client_map, + .unmap = nvkm_client_unmap, + .keep = false, +}; diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index ff10ef5eb298..01707e7deaf5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -1,8 +1,6 @@ #include <linux/pagemap.h> #include <linux/slab.h> -#include <subdev/fb.h> - #include "nouveau_drm.h" #include "nouveau_ttm.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index 29b6606abeaa..80f30d7c2c02 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -48,7 +48,8 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) char *buf = b; int ret, i; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_INFO, &info, sizeof(info)); + ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_INFO, + &info, sizeof(info)); if (ret) return ret; @@ -60,8 +61,8 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) .index = 0, }; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); + ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); if (ret) return ret; @@ -75,8 +76,8 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) attr.index = 0; do { attr.state = state; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); + ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); if (ret) return ret; @@ -139,7 +140,8 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, args.ustate = value; } - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args)); + ret = nvif_exec(&sysfs->ctrl, NV_CONTROL_PSTATE_USER, + &args, sizeof(args)); if (ret < 0) return ret; @@ -156,9 +158,9 @@ nouveau_sysfs_fini(struct drm_device *dev) struct nouveau_drm *drm = nouveau_drm(dev); struct nvif_device *device = &drm->device; - if (sysfs->ctrl) { + if (sysfs->ctrl.priv) { device_remove_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); - nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL); + nvif_object_fini(&sysfs->ctrl); } drm->sysfs = NULL; @@ -177,8 +179,8 @@ nouveau_sysfs_init(struct drm_device *dev) if (!sysfs) return -ENOMEM; - ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL, - NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); + ret = nvif_object_init(nvif_object(&drm->device), NULL, NVDRM_CONTROL, + NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); if (ret == 0) device_create_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate); diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.h b/drivers/gpu/drm/nouveau/nouveau_sysfs.h index 74b47f1e01ed..f973378160f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.h +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.h @@ -4,7 +4,7 @@ #include "nouveau_drm.h" struct nouveau_sysfs { - struct nouveau_object *ctrl; + struct nvif_object ctrl; }; static inline struct nouveau_sysfs * diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 8739e4d00c6d..245eebd0632d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -24,10 +24,6 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include <subdev/fb.h> -#include <subdev/vm.h> -#include <subdev/instmem.h> - #include "nouveau_drm.h" #include "nouveau_ttm.h" #include "nouveau_gem.h" diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index d3b9c7c24f49..b8ab117a8462 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -142,7 +142,6 @@ nv04_fbcon_accel_init(struct fb_info *info) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *chan = drm->channel; struct nvif_device *device = &drm->device; - struct nouveau_object *object; int surface_fmt, pattern_fmt, rect_fmt; int ret; @@ -174,35 +173,35 @@ nv04_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvCtxSurf2D, - device->info.family >= NV_DEVICE_INFO_V0_CELSIUS ? 0x0062 : 0x0042, - NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvCtxSurf2D, + device->info.family >= NV_DEVICE_INFO_V0_CELSIUS ? + 0x0062 : 0x0042, NULL, 0, &nfbdev->surf2d); if (ret) return ret; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvClipRect, - 0x0019, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvClipRect, 0x0019, NULL, 0, + &nfbdev->clip); if (ret) return ret; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvRop, - 0x0043, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvRop, 0x0043, NULL, 0, + &nfbdev->rop); if (ret) return ret; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvImagePatt, - 0x0044, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvImagePatt, 0x0044, NULL, 0, + &nfbdev->patt); if (ret) return ret; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvGdiRect, - 0x004a, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvGdiRect, 0x004a, NULL, 0, + &nfbdev->gdi); if (ret) return ret; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvImageBlit, - device->info.chipset >= 0x11 ? 0x009f : 0x005f, - NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, NvImageBlit, + device->info.chipset >= 0x11 ? 0x009f : 0x005f, + NULL, 0, &nfbdev->blit); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c index 724b815d1517..239c2c5a9615 100644 --- a/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/drivers/gpu/drm/nouveau/nv04_fence.c @@ -22,8 +22,6 @@ * Authors: Ben Skeggs */ -#include <engine/fifo.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 2d38673fc2c2..fa507817185a 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -60,7 +60,11 @@ void nv10_fence_context_del(struct nouveau_channel *chan) { struct nv10_fence_chan *fctx = chan->fence; + int i; nouveau_fence_context_del(&fctx->base); + for (i = 0; i < ARRAY_SIZE(fctx->head); i++) + nvif_object_fini(&fctx->head[i]); + nvif_object_fini(&fctx->sema); chan->fence = NULL; kfree(fctx); } diff --git a/drivers/gpu/drm/nouveau/nv10_fence.h b/drivers/gpu/drm/nouveau/nv10_fence.h index e5d9204826c2..27d1c9d2df47 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.h +++ b/drivers/gpu/drm/nouveau/nv10_fence.h @@ -7,6 +7,8 @@ struct nv10_fence_chan { struct nouveau_fence_chan base; + struct nvif_object sema; + struct nvif_object head[4]; }; struct nv10_fence_priv { diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 22aa9963ea6f..4dde5320db05 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -33,11 +33,12 @@ int nv17_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *prev, struct nouveau_channel *chan) { + struct nouveau_cli *cli = (void *)nvif_client(&prev->device->base); struct nv10_fence_priv *priv = chan->drm->fence; u32 value; int ret; - if (!mutex_trylock(&prev->cli->mutex)) + if (!mutex_trylock(&cli->mutex)) return -EBUSY; spin_lock(&priv->lock); @@ -64,7 +65,7 @@ nv17_fence_sync(struct nouveau_fence *fence, FIRE_RING (chan); } - mutex_unlock(&prev->cli->mutex); + mutex_unlock(&cli->mutex); return 0; } @@ -74,7 +75,6 @@ nv17_fence_context_new(struct nouveau_channel *chan) struct nv10_fence_priv *priv = chan->drm->fence; struct nv10_fence_chan *fctx; struct ttm_mem_reg *mem = &priv->bo->bo.mem; - struct nouveau_object *object; u32 start = mem->start * PAGE_SIZE; u32 limit = start + mem->size - 1; int ret = 0; @@ -88,15 +88,15 @@ nv17_fence_context_new(struct nouveau_channel *chan) fctx->base.read = nv10_fence_read; fctx->base.sync = nv17_fence_sync; - ret = nouveau_object_new(nv_object(chan->cli), chan->handle, - NvSema, 0x0002, - &(struct nv_dma_class) { + ret = nvif_object_init(chan->object, NULL, NvSema, + NV_DMA_FROM_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = start, .limit = limit, - }, sizeof(struct nv_dma_class), - &object); + }, sizeof(struct nv_dma_class), + &fctx->sema); if (ret) nv10_fence_context_del(chan); return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 376b23530c00..ca8c1db0ccb4 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -37,15 +37,8 @@ #include "nouveau_fence.h" #include "nv50_display.h" -#include <core/client.h> -#include <core/gpuobj.h> #include <core/class.h> -#include <subdev/timer.h> -#include <subdev/bar.h> -#include <subdev/fb.h> -#include <subdev/i2c.h> - #define EVO_DMA_NR 9 #define EVO_MASTER (0x00) @@ -62,7 +55,7 @@ #define EVO_CORE_HANDLE (0xd1500000) #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i)) -#define EVO_CHAN_OCLASS(t,c) ((nv_hclass(c) & 0xff00) | ((t) & 0x00ff)) +#define EVO_CHAN_OCLASS(t,c) (((c)->oclass & 0xff00) | ((t) & 0x00ff)) #define EVO_PUSH_HANDLE(t,i) (0xd15b0000 | (i) | \ (((NV50_DISP_##t##_CLASS) & 0x00ff) << 8)) @@ -71,34 +64,29 @@ *****************************************************************************/ struct nv50_chan { - struct nouveau_object *user; - u32 handle; + struct nvif_object user; }; static int -nv50_chan_create(struct nouveau_object *core, u32 bclass, u8 head, +nv50_chan_create(struct nvif_object *disp, u32 bclass, u8 head, void *data, u32 size, struct nv50_chan *chan) { - struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); - const u32 oclass = EVO_CHAN_OCLASS(bclass, core); + const u32 oclass = EVO_CHAN_OCLASS(bclass, disp); const u32 handle = EVO_CHAN_HANDLE(bclass, head); int ret; - ret = nouveau_object_new(client, EVO_CORE_HANDLE, handle, - oclass, data, size, &chan->user); + ret = nvif_object_init(disp, NULL, handle, oclass, data, size, + &chan->user); if (ret) return ret; - chan->handle = handle; return 0; } static void -nv50_chan_destroy(struct nouveau_object *core, struct nv50_chan *chan) +nv50_chan_destroy(struct nv50_chan *chan) { - struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); - if (chan->handle) - nouveau_object_del(client, EVO_CORE_HANDLE, chan->handle); + nvif_object_fini(&chan->user); } /****************************************************************************** @@ -110,16 +98,16 @@ struct nv50_pioc { }; static void -nv50_pioc_destroy(struct nouveau_object *core, struct nv50_pioc *pioc) +nv50_pioc_destroy(struct nv50_pioc *pioc) { - nv50_chan_destroy(core, &pioc->base); + nv50_chan_destroy(&pioc->base); } static int -nv50_pioc_create(struct nouveau_object *core, u32 bclass, u8 head, +nv50_pioc_create(struct nvif_object *disp, u32 bclass, u8 head, void *data, u32 size, struct nv50_pioc *pioc) { - return nv50_chan_create(core, bclass, head, data, size, &pioc->base); + return nv50_chan_create(disp, bclass, head, data, size, &pioc->base); } /****************************************************************************** @@ -131,6 +119,9 @@ struct nv50_dmac { dma_addr_t handle; u32 *ptr; + struct nvif_object sync; + struct nvif_object vram; + /* Protects against concurrent pushbuf access to this channel, lock is * grabbed by evo_wait (if the pushbuf reservation is successful) and * dropped again by evo_kick. */ @@ -138,68 +129,73 @@ struct nv50_dmac { }; static void -nv50_dmac_destroy(struct nouveau_object *core, struct nv50_dmac *dmac) +nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) { + nvif_object_fini(&dmac->vram); + nvif_object_fini(&dmac->sync); + + nv50_chan_destroy(&dmac->base); + if (dmac->ptr) { - struct pci_dev *pdev = nv_device(core)->pdev; + struct pci_dev *pdev = nvkm_device(nvif_device(disp))->pdev; pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle); } - - nv50_chan_destroy(core, &dmac->base); } static int -nv50_dmac_create(struct nouveau_object *core, u32 bclass, u8 head, +nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head, void *data, u32 size, u64 syncbuf, struct nv50_dmac *dmac) { - struct nouveau_fb *pfb = nouveau_fb(core); - struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); - struct nouveau_object *object; - u32 pushbuf = *(u32 *)data; + struct nouveau_fb *pfb = nvkm_fb(nvif_device(disp)); + struct nvif_object pushbuf; + u32 handle = *(u32 *)data; int ret; mutex_init(&dmac->lock); - dmac->ptr = pci_alloc_consistent(nv_device(core)->pdev, PAGE_SIZE, - &dmac->handle); + dmac->ptr = pci_alloc_consistent(nvkm_device(nvif_device(disp))->pdev, + PAGE_SIZE, &dmac->handle); if (!dmac->ptr) return -ENOMEM; - ret = nouveau_object_new(client, NVDRM_DEVICE, pushbuf, - NV_DMA_FROM_MEMORY_CLASS, - &(struct nv_dma_class) { + ret = nvif_object_init(nvif_object(nvif_device(disp)), NULL, handle, + NV_DMA_FROM_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_PCI_US | NV_DMA_ACCESS_RD, .start = dmac->handle + 0x0000, .limit = dmac->handle + 0x0fff, - }, sizeof(struct nv_dma_class), &object); + }, sizeof(struct nv_dma_class), &pushbuf); if (ret) return ret; - ret = nv50_chan_create(core, bclass, head, data, size, &dmac->base); + ret = nv50_chan_create(disp, bclass, head, data, size, &dmac->base); + nvif_object_fini(&pushbuf); if (ret) return ret; - ret = nouveau_object_new(client, dmac->base.handle, NvEvoSync, - NV_DMA_IN_MEMORY_CLASS, - &(struct nv_dma_class) { + ret = nvif_object_init(&dmac->base.user, NULL, NvEvoSync, + NV_DMA_IN_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = syncbuf + 0x0000, .limit = syncbuf + 0x0fff, - }, sizeof(struct nv_dma_class), &object); + }, sizeof(struct nv_dma_class), + &dmac->sync); if (ret) return ret; - ret = nouveau_object_new(client, dmac->base.handle, NvEvoVRAM, - NV_DMA_IN_MEMORY_CLASS, - &(struct nv_dma_class) { + ret = nvif_object_init(&dmac->base.user, NULL, NvEvoVRAM, + NV_DMA_IN_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = 0, .limit = pfb->ram->size - 1, - }, sizeof(struct nv_dma_class), &object); + }, sizeof(struct nv_dma_class), + &dmac->vram); if (ret) return ret; @@ -243,10 +239,16 @@ struct nv50_head { #define nv50_ovly(c) (&nv50_head(c)->ovly) #define nv50_oimm(c) (&nv50_head(c)->oimm) #define nv50_chan(c) (&(c)->base.base) -#define nv50_vers(c) nv_mclass(nv50_chan(c)->user) +#define nv50_vers(c) nv50_chan(c)->user.oclass + +struct nv50_fbdma { + struct list_head head; + struct nvif_object core; + struct nvif_object base[4]; +}; struct nv50_disp { - struct nouveau_object *core; + struct nvif_object *disp; struct nv50_mast mast; struct list_head fbdma; @@ -275,16 +277,16 @@ static u32 * evo_wait(void *evoc, int nr) { struct nv50_dmac *dmac = evoc; - u32 put = nv_ro32(dmac->base.user, 0x0000) / 4; + u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; mutex_lock(&dmac->lock); if (put + nr >= (PAGE_SIZE / 4) - 8) { dmac->ptr[put] = 0x20000000; - nv_wo32(dmac->base.user, 0x0000, 0x00000000); - if (!nv_wait(dmac->base.user, 0x0004, ~0, 0x00000000)) { + nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); + if (!nvkm_wait(&dmac->base.user, 0x0004, ~0, 0x00000000)) { mutex_unlock(&dmac->lock); - nv_error(dmac->base.user, "channel stalled\n"); + nv_error(nvkm_object(&dmac->base.user), "channel stalled\n"); return NULL; } @@ -298,7 +300,7 @@ static void evo_kick(u32 *push, void *evoc) { struct nv50_dmac *dmac = evoc; - nv_wo32(dmac->base.user, 0x0000, (push - dmac->ptr) << 2); + nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); mutex_unlock(&dmac->lock); } @@ -408,7 +410,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (unlikely(push == NULL)) return -EBUSY; - if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { + if (chan && chan->object->oclass < NV84_CHANNEL_IND_CLASS) { ret = RING_SPACE(chan, 8); if (ret) return ret; @@ -422,14 +424,14 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, OUT_RING (chan, sync->addr); OUT_RING (chan, sync->data); } else - if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { + if (chan && chan->object->oclass < NVC0_CHANNEL_IND_CLASS) { u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; ret = RING_SPACE(chan, 12); if (ret) return ret; BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); + OUT_RING (chan, chan->vram.handle); BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(addr ^ 0x10)); OUT_RING (chan, lower_32_bits(addr ^ 0x10)); @@ -1066,7 +1068,7 @@ nv50_crtc_lut_load(struct drm_crtc *crtc) u16 g = nv_crtc->lut.g[i] >> 2; u16 b = nv_crtc->lut.b[i] >> 2; - if (nv_mclass(disp->core) < NVD0_DISP_CLASS) { + if (disp->disp->oclass < NVD0_DISP_CLASS) { writew(r + 0x0000, lut + (i * 0x08) + 0); writew(g + 0x0000, lut + (i * 0x08) + 2); writew(b + 0x0000, lut + (i * 0x08) + 4); @@ -1133,8 +1135,8 @@ nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct nv50_curs *curs = nv50_curs(crtc); struct nv50_chan *chan = nv50_chan(curs); - nv_wo32(chan->user, 0x0084, (y << 16) | (x & 0xffff)); - nv_wo32(chan->user, 0x0080, 0x00000000); + nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff)); + nvif_wr32(&chan->user, 0x0080, 0x00000000); return 0; } @@ -1161,11 +1163,16 @@ nv50_crtc_destroy(struct drm_crtc *crtc) struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nv50_disp *disp = nv50_disp(crtc->dev); struct nv50_head *head = nv50_head(crtc); + struct nv50_fbdma *fbdma; - nv50_dmac_destroy(disp->core, &head->ovly.base); - nv50_pioc_destroy(disp->core, &head->oimm.base); - nv50_dmac_destroy(disp->core, &head->sync.base); - nv50_pioc_destroy(disp->core, &head->curs.base); + list_for_each_entry(fbdma, &disp->fbdma, head) { + nvif_object_fini(&fbdma->base[nv_crtc->index]); + } + + nv50_dmac_destroy(&head->ovly.base, disp->disp); + nv50_pioc_destroy(&head->oimm.base); + nv50_dmac_destroy(&head->sync.base, disp->disp); + nv50_pioc_destroy(&head->curs.base); /*XXX: this shouldn't be necessary, but the core doesn't call * disconnect() during the cleanup paths @@ -1220,7 +1227,7 @@ nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) } static int -nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) +nv50_crtc_create(struct drm_device *dev, int index) { struct nv50_disp *disp = nv50_disp(dev); struct nv50_head *head; @@ -1269,7 +1276,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) nv50_crtc_lut_load(crtc); /* allocate cursor resources */ - ret = nv50_pioc_create(disp->core, NV50_DISP_CURS_CLASS, index, + ret = nv50_pioc_create(disp->disp, NV50_DISP_CURS_CLASS, index, &(struct nv50_display_curs_class) { .head = index, }, sizeof(struct nv50_display_curs_class), @@ -1294,7 +1301,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) goto out; /* allocate page flip / sync resources */ - ret = nv50_dmac_create(disp->core, NV50_DISP_SYNC_CLASS, index, + ret = nv50_dmac_create(disp->disp, NV50_DISP_SYNC_CLASS, index, &(struct nv50_display_sync_class) { .pushbuf = EVO_PUSH_HANDLE(SYNC, index), .head = index, @@ -1307,7 +1314,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) head->sync.data = 0x00000000; /* allocate overlay resources */ - ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index, + ret = nv50_pioc_create(disp->disp, NV50_DISP_OIMM_CLASS, index, &(struct nv50_display_oimm_class) { .head = index, }, sizeof(struct nv50_display_oimm_class), @@ -1315,7 +1322,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) if (ret) goto out; - ret = nv50_dmac_create(disp->core, NV50_DISP_OVLY_CLASS, index, + ret = nv50_dmac_create(disp->disp, NV50_DISP_OVLY_CLASS, index, &(struct nv50_display_ovly_class) { .pushbuf = EVO_PUSH_HANDLE(OVLY, index), .head = index, @@ -1347,7 +1354,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF) dpms_ctrl |= 0x00000004; - nv_call(disp->core, NV50_DISP_DAC_PWR + or, dpms_ctrl); + nvif_exec(disp->disp, NV50_DISP_DAC_PWR + or, &dpms_ctrl, sizeof(dpms_ctrl)); } static bool @@ -1460,7 +1467,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) if (load == 0) load = 340; - ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); + ret = nvif_exec(disp->disp, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); if (ret || !load) return connector_status_disconnected; @@ -1531,9 +1538,9 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) drm_edid_to_eld(&nv_connector->base, nv_connector->edid); - nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, - nv_connector->base.eld, - nv_connector->base.eld[2] * 4); + nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, + nv_connector->base.eld, + nv_connector->base.eld[2] * 4); } static void @@ -1542,7 +1549,7 @@ nv50_audio_disconnect(struct drm_encoder *encoder) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_disp *disp = nv50_disp(encoder->dev); - nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); + nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); } /****************************************************************************** @@ -1558,6 +1565,7 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; u32 rekey = 56; /* binary driver, and tegra constant */ u32 max_ac_packet; + u32 data; nv_connector = nouveau_encoder_connector_get(nv_encoder); if (!drm_detect_hdmi_monitor(nv_connector->edid)) @@ -1568,9 +1576,8 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) max_ac_packet -= 18; /* constant from tegra */ max_ac_packet /= 32; - nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, - NV84_DISP_SOR_HDMI_PWR_STATE_ON | - (max_ac_packet << 16) | rekey); + data = NV84_DISP_SOR_HDMI_PWR_STATE_ON | (max_ac_packet << 16) | rekey; + nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); nv50_audio_mode_set(encoder, mode); } @@ -1581,10 +1588,11 @@ nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_disp *disp = nv50_disp(encoder->dev); const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; + u32 data = 0; nv50_audio_disconnect(encoder); - nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, 0x00000000); + nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); } /****************************************************************************** @@ -1597,7 +1605,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct nv50_disp *disp = nv50_disp(dev); struct drm_encoder *partner; - u32 mthd; + u32 mthd, data; nv_encoder->last_dpms = mode; @@ -1620,13 +1628,15 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) mthd |= nv_encoder->or; if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { - nv_call(disp->core, NV50_DISP_SOR_PWR | mthd, 1); + data = 1; + nvif_exec(disp->disp, NV50_DISP_SOR_PWR | mthd, &data, sizeof(data)); mthd |= NV94_DISP_SOR_DP_PWR; } else { mthd |= NV50_DISP_SOR_PWR; } - nv_call(disp->core, mthd, (mode == DRM_MODE_DPMS_ON)); + data = (mode == DRM_MODE_DPMS_ON); + nvif_exec(disp->disp, mthd, &data, sizeof(data)); } static bool @@ -1749,7 +1759,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, lvds |= 0x0200; } - nv_call(disp->core, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, lvds); + nvif_exec(disp->disp, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, &lvds, sizeof(lvds)); break; case DCB_OUTPUT_DP: if (nv_connector->base.display_info.bpc == 6) { @@ -1878,7 +1888,7 @@ nv50_pior_dpms(struct drm_encoder *encoder, int mode) struct nv50_disp *disp = nv50_disp(encoder->dev); u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; u32 ctrl = (mode == DRM_MODE_DPMS_ON); - nv_call(disp->core, NV50_DISP_PIOR_PWR + mthd, ctrl); + nvif_exec(disp->disp, NV50_DISP_PIOR_PWR + mthd, &ctrl, sizeof(ctrl)); } static bool @@ -2046,25 +2056,13 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) * Framebuffer *****************************************************************************/ -struct nv50_fbdma { - struct list_head head; - u32 name; -}; - static void -nv50_fbdma_fini(struct drm_device *dev, struct nv50_fbdma *fbdma) +nv50_fbdma_fini(struct nv50_fbdma *fbdma) { - struct nv50_disp *disp = nv50_disp(dev); - struct nv50_mast *mast = nv50_mast(dev); - struct nouveau_object *client = nv_pclass(disp->core, NV_CLIENT_CLASS); - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nv50_sync *sync = nv50_sync(crtc); - nouveau_object_del(client, sync->base.base.handle, fbdma->name); - } - - nouveau_object_del(client, mast->base.base.handle, fbdma->name); + int i; + for (i = 0; i < ARRAY_SIZE(fbdma->base); i++) + nvif_object_fini(&fbdma->base[i]); + nvif_object_fini(&fbdma->core); list_del(&fbdma->head); kfree(fbdma); } @@ -2075,15 +2073,13 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin struct nouveau_drm *drm = nouveau_drm(dev); struct nv50_disp *disp = nv50_disp(dev); struct nv50_mast *mast = nv50_mast(dev); - struct nouveau_object *client = nv_pclass(disp->core, NV_CLIENT_CLASS); - struct nouveau_object *object; struct nv_dma_class args; struct nv50_fbdma *fbdma; struct drm_crtc *crtc; int ret; list_for_each_entry(fbdma, &disp->fbdma, head) { - if (fbdma->name == name) + if (fbdma->core.handle == name) return 0; } @@ -2091,7 +2087,6 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin if (!fbdma) return -ENOMEM; list_add(&fbdma->head, &disp->fbdma); - fbdma->name = name; args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR; args.start = offset; @@ -2114,23 +2109,22 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin } list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nv50_sync *sync = nv50_sync(crtc); - ret = nouveau_object_new(client, sync->base.base.handle, - fbdma->name, NV_DMA_IN_MEMORY_CLASS, - &args, sizeof(args), &object); + struct nv50_head *head = nv50_head(crtc); + int ret = nvif_object_init(&head->sync.base.base.user, NULL, + name, NV_DMA_IN_MEMORY_CLASS, + &args, sizeof(args), + &fbdma->base[head->base.index]); if (ret) { - printk(KERN_ERR "fail %d %08x %d\n", nv50_head(crtc)->base.index, fbdma->name, ret); - nv50_fbdma_fini(dev, fbdma); + nv50_fbdma_fini(fbdma); return ret; } } - ret = nouveau_object_new(client, mast->base.base.handle, fbdma->name, - NV_DMA_IN_MEMORY_CLASS, &args, sizeof(args), - &object); + ret = nvif_object_init(&mast->base.base.user, NULL, name, + NV_DMA_IN_MEMORY_CLASS, &args, sizeof(args), + &fbdma->core); if (ret) { - printk(KERN_ERR "fail %08x %d\n", fbdma->name, ret); - nv50_fbdma_fini(dev, fbdma); + nv50_fbdma_fini(fbdma); return ret; } @@ -2173,12 +2167,12 @@ nv50_fb_ctor(struct drm_framebuffer *fb) return -EINVAL; } - if (nv_mclass(disp->core) < NV84_DISP_CLASS) { + if (disp->disp->oclass < NV84_DISP_CLASS) { nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : (fb->pitches[0] | 0x00100000); nv_fb->r_format |= kind << 16; } else - if (nv_mclass(disp->core) < NVD0_DISP_CLASS) { + if (disp->disp->oclass < NVD0_DISP_CLASS) { nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : (fb->pitches[0] | 0x00100000); } else { @@ -2228,10 +2222,10 @@ nv50_display_destroy(struct drm_device *dev) struct nv50_fbdma *fbdma, *fbtmp; list_for_each_entry_safe(fbdma, fbtmp, &disp->fbdma, head) { - nv50_fbdma_fini(dev, fbdma); + nv50_fbdma_fini(fbdma); } - nv50_dmac_destroy(disp->core, &disp->mast.base); + nv50_dmac_destroy(&disp->mast.base, disp->disp); nouveau_bo_unmap(disp->sync); if (disp->sync) @@ -2264,7 +2258,7 @@ nv50_display_create(struct drm_device *dev) nouveau_display(dev)->fini = nv50_display_fini; nouveau_display(dev)->fb_ctor = nv50_fb_ctor; nouveau_display(dev)->fb_dtor = nv50_fb_dtor; - disp->core = nouveau_display(dev)->core; + disp->disp = &nouveau_display(dev)->disp; /* small shared memory area we use for notifiers and semaphores */ ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, @@ -2284,7 +2278,7 @@ nv50_display_create(struct drm_device *dev) goto out; /* allocate master evo channel */ - ret = nv50_dmac_create(disp->core, NV50_DISP_MAST_CLASS, 0, + ret = nv50_dmac_create(disp->disp, NV50_DISP_MAST_CLASS, 0, &(struct nv50_display_mast_class) { .pushbuf = EVO_PUSH_HANDLE(MAST, 0), }, sizeof(struct nv50_display_mast_class), @@ -2293,13 +2287,13 @@ nv50_display_create(struct drm_device *dev) goto out; /* create crtc objects to represent the hw heads */ - if (nv_mclass(disp->core) >= NVD0_DISP_CLASS) + if (disp->disp->oclass >= NVD0_DISP_CLASS) crtcs = nvif_rd32(device, 0x022448); else crtcs = 2; for (i = 0; i < crtcs; i++) { - ret = nv50_crtc_create(dev, disp->core, i); + ret = nv50_crtc_create(dev, i); if (ret) goto out; } diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 52068a0910dc..a92008c9d203 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -154,7 +154,6 @@ nv50_fbcon_accel_init(struct fb_info *info) struct drm_device *dev = nfbdev->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *chan = drm->channel; - struct nouveau_object *object; int ret, format; switch (info->var.bits_per_pixel) { @@ -184,8 +183,8 @@ nv50_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, Nv2D, - 0x502d, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, Nv2D, 0x502d, NULL, 0, + &nfbdev->twod); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index 0ee363840035..d5d88a97d1b9 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -38,7 +38,6 @@ nv50_fence_context_new(struct nouveau_channel *chan) struct nv10_fence_priv *priv = chan->drm->fence; struct nv10_fence_chan *fctx; struct ttm_mem_reg *mem = &priv->bo->bo.mem; - struct nouveau_object *object; u32 start = mem->start * PAGE_SIZE; u32 limit = start + mem->size - 1; int ret, i; @@ -52,15 +51,15 @@ nv50_fence_context_new(struct nouveau_channel *chan) fctx->base.read = nv10_fence_read; fctx->base.sync = nv17_fence_sync; - ret = nouveau_object_new(nv_object(chan->cli), chan->handle, - NvSema, 0x003d, - &(struct nv_dma_class) { + ret = nvif_object_init(chan->object, NULL, NvSema, + NV_DMA_IN_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = start, .limit = limit, - }, sizeof(struct nv_dma_class), - &object); + }, sizeof(struct nv_dma_class), + &fctx->sema); /* dma objects for display sync channel semaphore blocks */ for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { @@ -68,15 +67,15 @@ nv50_fence_context_new(struct nouveau_channel *chan) u32 start = bo->bo.mem.start * PAGE_SIZE; u32 limit = start + bo->bo.mem.size - 1; - ret = nouveau_object_new(nv_object(chan->cli), chan->handle, - NvEvoSema0 + i, 0x003d, - &(struct nv_dma_class) { + ret = nvif_object_init(chan->object, NULL, NvEvoSema0 + i, + NV_DMA_IN_MEMORY_CLASS, + &(struct nv_dma_class) { .flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR, .start = start, .limit = limit, - }, sizeof(struct nv_dma_class), - &object); + }, sizeof(struct nv_dma_class), + &fctx->head[i]); } if (ret) diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 94184a94a763..28cf3b417fea 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -26,8 +26,6 @@ #include <core/client.h> #include <core/class.h> -#include <engine/fifo.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" @@ -47,7 +45,7 @@ nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) int ret = RING_SPACE(chan, 8); if (ret == 0) { BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); + OUT_RING (chan, chan->vram.handle); BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 5); OUT_RING (chan, upper_32_bits(virtual)); OUT_RING (chan, lower_32_bits(virtual)); @@ -65,7 +63,7 @@ nv84_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) int ret = RING_SPACE(chan, 7); if (ret == 0) { BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); + OUT_RING (chan, chan->vram.handle); BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(virtual)); OUT_RING (chan, lower_32_bits(virtual)); @@ -140,7 +138,7 @@ int nv84_fence_context_new(struct nouveau_channel *chan) { struct nouveau_fifo_chan *fifo = nvkm_fifo_chan(chan); - struct nouveau_cli *cli = chan->cli; + struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx; int ret, i; diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index 9dcd30f3e1e0..93e7b697ee95 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -154,11 +154,10 @@ nvc0_fbcon_accel_init(struct fb_info *info) struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_channel *chan = drm->channel; - struct nouveau_object *object; int ret, format; - ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, Nv2D, - 0x902d, NULL, 0, &object); + ret = nvif_object_init(chan->object, NULL, Nv2D, 0x902d, NULL, 0, + &nfbdev->twod); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c b/drivers/gpu/drm/nouveau/nvc0_fence.c index 9566267fbc42..341323b6beb2 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fence.c +++ b/drivers/gpu/drm/nouveau/nvc0_fence.c @@ -26,8 +26,6 @@ #include <core/client.h> #include <core/class.h> -#include <engine/fifo.h> - #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nvif/client.c b/drivers/gpu/drm/nouveau/nvif/client.c index 7048fd91be28..20fb38688b93 100644 --- a/drivers/gpu/drm/nouveau/nvif/client.c +++ b/drivers/gpu/drm/nouveau/nvif/client.c @@ -58,9 +58,7 @@ nvif_client_fini(struct nvif_client *client) const struct nvif_driver * nvif_drivers[] = { #ifdef __KERNEL__ -#if 0 &nvif_driver_nvkm, -#endif #else &nvif_driver_lib, #endif |