From 1d2a1e53865266a67fb569705eba3ec992682721 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 20 Aug 2015 14:54:17 +1000 Subject: drm/nouveau/ramht: remove dependence on namedb Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h index cc132ea..5ee6298 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h @@ -2,19 +2,27 @@ #define __NVKM_RAMHT_H__ #include +struct nvkm_ramht_data { + struct nvkm_gpuobj *inst; + int chid; + u32 handle; +}; + struct nvkm_ramht { - struct nvkm_gpuobj gpuobj; + struct nvkm_device *device; + struct nvkm_gpuobj *parent; + struct nvkm_gpuobj *gpuobj; + int size; int bits; + struct nvkm_ramht_data data[]; }; -int nvkm_ramht_insert(struct nvkm_ramht *, int chid, u32 handle, u32 context); +int nvkm_ramht_new(struct nvkm_device *, u32 size, u32 align, + struct nvkm_gpuobj *, struct nvkm_ramht **); +void nvkm_ramht_del(struct nvkm_ramht **); +int nvkm_ramht_insert(struct nvkm_ramht *, struct nvkm_object *, + int chid, int addr, u32 handle, u32 context); void nvkm_ramht_remove(struct nvkm_ramht *, int cookie); -int nvkm_ramht_new(struct nvkm_object *, struct nvkm_object *, u32 size, - u32 align, struct nvkm_ramht **); - -static inline void -nvkm_ramht_ref(struct nvkm_ramht *obj, struct nvkm_ramht **ref) -{ - nvkm_gpuobj_ref(&obj->gpuobj, (struct nvkm_gpuobj **)ref); -} +struct nvkm_gpuobj * +nvkm_ramht_search(struct nvkm_ramht *, int chid, u32 handle); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c index 061aded..307d532 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c @@ -33,74 +33,143 @@ nvkm_ramht_hash(struct nvkm_ramht *ramht, int chid, u32 handle) } hash ^= chid << (ramht->bits - 4); - hash = hash << 3; return hash; } -int -nvkm_ramht_insert(struct nvkm_ramht *ramht, int chid, u32 handle, u32 context) +struct nvkm_gpuobj * +nvkm_ramht_search(struct nvkm_ramht *ramht, int chid, u32 handle) { - struct nvkm_gpuobj *gpuobj = &ramht->gpuobj; - int ret = -ENOSPC; u32 co, ho; co = ho = nvkm_ramht_hash(ramht, chid, handle); - nvkm_kmap(gpuobj); do { - if (!nvkm_ro32(gpuobj, co + 4)) { - nvkm_wo32(gpuobj, co + 0, handle); - nvkm_wo32(gpuobj, co + 4, context); - ret = co; - break; + if (ramht->data[co].chid == chid) { + if (ramht->data[co].handle == handle) + return ramht->data[co].inst; } - co += 8; - if (co >= nv_gpuobj(ramht)->size) + if (++co >= ramht->size) co = 0; } while (co != ho); - nvkm_done(gpuobj); - return ret; + return NULL; +} + +static int +nvkm_ramht_update(struct nvkm_ramht *ramht, int co, struct nvkm_object *object, + int chid, int addr, u32 handle, u32 context) +{ + struct nvkm_ramht_data *data = &ramht->data[co]; + u64 inst = 0x00000040; /* just non-zero for <=g8x fifo ramht */ + int ret; + + nvkm_gpuobj_del(&data->inst); + data->chid = chid; + data->handle = handle; + + if (!object) { + inst = 0; + goto done; + } + + if (nv_iclass(object, NV_GPUOBJ_CLASS)) { + struct nvkm_gpuobj *gpuobj = nv_gpuobj(object); + if (ramht->device->card_type >= NV_50) + inst = gpuobj->node->offset; + else + inst = gpuobj->addr; + goto done; + } + + ret = nvkm_object_bind(object, ramht->parent, 16, &data->inst); + if (ret) { + if (ret != -ENODEV) { + data->chid = -1; + return ret; + } + data->inst = NULL; + } + + if (data->inst) { + if (ramht->device->card_type >= NV_50) + inst = data->inst->node->offset; + else + inst = data->inst->addr; + } + +done: + if (addr < 0) context |= inst << -addr; + else context |= inst >> addr; + + nvkm_kmap(ramht->gpuobj); + nvkm_wo32(ramht->gpuobj, (co << 3) + 0, handle); + nvkm_wo32(ramht->gpuobj, (co << 3) + 4, context); + nvkm_done(ramht->gpuobj); + return co + 1; } void nvkm_ramht_remove(struct nvkm_ramht *ramht, int cookie) { - struct nvkm_gpuobj *gpuobj = &ramht->gpuobj; - nvkm_kmap(gpuobj); - nvkm_wo32(gpuobj, cookie + 0, 0x00000000); - nvkm_wo32(gpuobj, cookie + 4, 0x00000000); - nvkm_done(gpuobj); + if (--cookie >= 0) + nvkm_ramht_update(ramht, cookie, NULL, -1, 0, 0, 0); } -static struct nvkm_oclass -nvkm_ramht_oclass = { - .handle = 0x0000abcd, - .ofuncs = &(struct nvkm_ofuncs) { - .ctor = NULL, - .dtor = _nvkm_gpuobj_dtor, - .init = _nvkm_gpuobj_init, - .fini = _nvkm_gpuobj_fini, - .rd32 = _nvkm_gpuobj_rd32, - .wr32 = _nvkm_gpuobj_wr32, - }, -}; +int +nvkm_ramht_insert(struct nvkm_ramht *ramht, struct nvkm_object *object, + int chid, int addr, u32 handle, u32 context) +{ + u32 co, ho; + + if (nvkm_ramht_search(ramht, chid, handle)) + return -EEXIST; + + co = ho = nvkm_ramht_hash(ramht, chid, handle); + do { + if (ramht->data[co].chid < 0) { + return nvkm_ramht_update(ramht, co, object, chid, + addr, handle, context); + } + + if (++co >= ramht->size) + co = 0; + } while (co != ho); + + return -ENOSPC; +} + +void +nvkm_ramht_del(struct nvkm_ramht **pramht) +{ + struct nvkm_ramht *ramht = *pramht; + if (ramht) { + nvkm_gpuobj_del(&ramht->gpuobj); + kfree(*pramht); + *pramht = NULL; + } +} int -nvkm_ramht_new(struct nvkm_object *parent, struct nvkm_object *pargpu, - u32 size, u32 align, struct nvkm_ramht **pramht) +nvkm_ramht_new(struct nvkm_device *device, u32 size, u32 align, + struct nvkm_gpuobj *parent, struct nvkm_ramht **pramht) { struct nvkm_ramht *ramht; - int ret; + int ret, i; - ret = nvkm_gpuobj_create(parent, parent->engine ? - &parent->engine->subdev.object : NULL, /* > 3) * + sizeof(*ramht->data), GFP_KERNEL))) + return -ENOMEM; + + ramht->device = device; + ramht->parent = parent; + ramht->size = size >> 3; + ramht->bits = order_base_2(ramht->size); + for (i = 0; i < ramht->size; i++) + ramht->data[i].chid = -1; - ramht->bits = order_base_2(nv_gpuobj(ramht)->size >> 3); - return 0; + ret = nvkm_gpuobj_new(ramht->device, size, align, true, + ramht->parent, &ramht->gpuobj); + if (ret) + nvkm_ramht_del(pramht); + return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c index 4161326..7a8ea49 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c @@ -80,7 +80,7 @@ gf110_disp_dmac_object_attach(struct nvkm_object *parent, struct nv50_disp_chan *chan = (void *)parent; u32 addr = nv_gpuobj(object)->node->offset; u32 data = (chan->chid << 27) | (addr << 9) | 0x00000001; - return nvkm_ramht_insert(base->ramht, chan->chid, name, data); + return nvkm_ramht_insert(base->ramht, NULL, chan->chid, 0, name, data); } static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 2568e5d..a3632d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -193,7 +193,7 @@ nv50_disp_dmac_object_attach(struct nvkm_object *parent, u32 addr = nv_gpuobj(object)->node->offset; u32 chid = chan->chid; u32 data = (chid << 28) | (addr << 10) | chid; - return nvkm_ramht_insert(base->ramht, chid, name, data); + return nvkm_ramht_insert(base->ramht, NULL, chid, 0, name, data); } static void @@ -1153,6 +1153,8 @@ nv50_disp_main_ctor(struct nvkm_object *parent, { struct nv50_disp *disp = (void *)engine; struct nv50_disp_base *base; + struct nvkm_device *device = disp->base.engine.subdev.device; + struct nvkm_gpuobj *instmem = (void *)parent; int ret; ret = nvkm_parent_create(parent, engine, oclass, 0, @@ -1161,15 +1163,14 @@ nv50_disp_main_ctor(struct nvkm_object *parent, if (ret) return ret; - return nvkm_ramht_new(nv_object(base), nv_object(base), 0x1000, 0, - &base->ramht); + return nvkm_ramht_new(device, 0x1000, 0, instmem, &base->ramht); } void nv50_disp_main_dtor(struct nvkm_object *object) { struct nv50_disp_base *base = (void *)object; - nvkm_ramht_ref(NULL, &base->ramht); + nvkm_ramht_del(&base->ramht); nvkm_parent_destroy(&base->base); } @@ -1235,7 +1236,7 @@ nv50_disp_main_init(struct nvkm_object *object) } /* point at display engine memory area (hash table, objects) */ - nvkm_wr32(device, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9); + nvkm_wr32(device, 0x610010, (base->ramht->gpuobj->addr >> 8) | 9); /* enable supervisor interrupts, disable everything else */ nvkm_wr32(device, 0x61002c, 0x00000370); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c index 058296b..2997193 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c @@ -161,7 +161,7 @@ g84_fifo_object_attach(struct nvkm_object *parent, } } - return nvkm_ramht_insert(chan->ramht, 0, handle, context); + return nvkm_ramht_insert(chan->ramht, NULL, 0, 0, handle, context); } static int @@ -172,6 +172,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, union { struct nv50_channel_dma_v0 v0; } *args = data; + struct nvkm_device *device = parent->engine->subdev.device; struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; int ret; @@ -208,7 +209,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, args->v0.chid = chan->base.chid; - ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, + ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj, &chan->ramht); if (ret) return ret; @@ -232,7 +233,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_wo32(base->ramfc, 0x7c, 0x30000001); nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | (4 << 24) /* SEARCH_FULL */ | - (chan->ramht->gpuobj.node->offset >> 4)); + (chan->ramht->gpuobj->node->offset >> 4)); nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10); nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12); nvkm_done(base->ramfc); @@ -247,6 +248,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, union { struct nv50_channel_gpfifo_v0 v0; } *args = data; + struct nvkm_device *device = parent->engine->subdev.device; struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; u64 ioffset, ilength; @@ -285,7 +287,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, args->v0.chid = chan->base.chid; - ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, + ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj, &chan->ramht); if (ret) return ret; @@ -309,7 +311,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_wo32(base->ramfc, 0x7c, 0x30000001); nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | (4 << 24) /* SEARCH_FULL */ | - (chan->ramht->gpuobj.node->offset >> 4)); + (chan->ramht->gpuobj->node->offset >> 4)); nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10); nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12); nvkm_done(base->ramfc); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index 4bec707..cd50093 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -86,7 +86,7 @@ nv04_fifo_object_attach(struct nvkm_object *parent, context |= chid << 24; mutex_lock(&nv_subdev(fifo)->mutex); - ret = nvkm_ramht_insert(imem->ramht, chid, handle, context); + ret = nvkm_ramht_insert(imem->ramht, NULL, chid, 0, handle, context); mutex_unlock(&nv_subdev(fifo)->mutex); return ret; } @@ -625,7 +625,7 @@ nv04_fifo_init(struct nvkm_object *object) nvkm_wr32(device, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ((ramht->bits - 9) << 16) | - (ramht->gpuobj.addr >> 8)); + (ramht->gpuobj->addr >> 8)); nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8); nvkm_wr32(device, NV03_PFIFO_RAMFC, nvkm_memory_addr(ramfc) >> 8); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c index 69b9d42..e271804 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c @@ -191,7 +191,7 @@ nv17_fifo_init(struct nvkm_object *object) nvkm_wr32(device, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ((ramht->bits - 9) << 16) | - (ramht->gpuobj.addr >> 8)); + (ramht->gpuobj->addr >> 8)); nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8); nvkm_wr32(device, NV03_PFIFO_RAMFC, nvkm_memory_addr(ramfc) >> 8 | 0x00010000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c index a2d8da8..f2f0e3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c @@ -98,7 +98,7 @@ nv40_fifo_object_attach(struct nvkm_object *parent, context |= chid << 23; mutex_lock(&nv_subdev(fifo)->mutex); - ret = nvkm_ramht_insert(imem->ramht, chid, handle, context); + ret = nvkm_ramht_insert(imem->ramht, NULL, chid, 0, handle, context); mutex_unlock(&nv_subdev(fifo)->mutex); return ret; } @@ -322,7 +322,7 @@ nv40_fifo_init(struct nvkm_object *object) nvkm_wr32(device, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ((ramht->bits - 9) << 16) | - (ramht->gpuobj.addr >> 8)); + (ramht->gpuobj->addr >> 8)); nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8); switch (nv_device(fifo)->chipset) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 620c0cf..2b37fda 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -182,7 +182,7 @@ nv50_fifo_object_attach(struct nvkm_object *parent, } } - return nvkm_ramht_insert(chan->ramht, 0, handle, context); + return nvkm_ramht_insert(chan->ramht, NULL, 0, 0, handle, context); } void @@ -200,6 +200,7 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, union { struct nv50_channel_dma_v0 v0; } *args = data; + struct nvkm_device *device = parent->engine->subdev.device; struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; int ret; @@ -231,7 +232,7 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, nv_parent(chan)->object_attach = nv50_fifo_object_attach; nv_parent(chan)->object_detach = nv50_fifo_object_detach; - ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, + ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj, &chan->ramht); if (ret) return ret; @@ -250,7 +251,7 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_wo32(base->ramfc, 0x7c, 0x30000001); nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | (4 << 24) /* SEARCH_FULL */ | - (chan->ramht->gpuobj.node->offset >> 4)); + (chan->ramht->gpuobj->node->offset >> 4)); nvkm_done(base->ramfc); return 0; } @@ -263,6 +264,7 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, union { struct nv50_channel_gpfifo_v0 v0; } *args = data; + struct nvkm_device *device = parent->engine->subdev.device; struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; u64 ioffset, ilength; @@ -296,7 +298,7 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, nv_parent(chan)->object_attach = nv50_fifo_object_attach; nv_parent(chan)->object_detach = nv50_fifo_object_detach; - ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, + ret = nvkm_ramht_new(device, 0x8000, 16, &base->base.gpuobj, &chan->ramht); if (ret) return ret; @@ -315,7 +317,7 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_wo32(base->ramfc, 0x7c, 0x30000001); nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | (4 << 24) /* SEARCH_FULL */ | - (chan->ramht->gpuobj.node->offset >> 4)); + (chan->ramht->gpuobj->node->offset >> 4)); nvkm_done(base->ramfc); return 0; } @@ -324,7 +326,7 @@ void nv50_fifo_chan_dtor(struct nvkm_object *object) { struct nv50_fifo_chan *chan = (void *)object; - nvkm_ramht_ref(NULL, &chan->ramht); + nvkm_ramht_del(&chan->ramht); nvkm_fifo_channel_destroy(&chan->base); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index 56330cc..1df4527 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -156,7 +156,7 @@ nv04_instmem_dtor(struct nvkm_object *object) struct nv04_instmem *imem = (void *)object; nvkm_memory_del(&imem->base.ramfc); nvkm_memory_del(&imem->base.ramro); - nvkm_ramht_ref(NULL, &imem->base.ramht); + nvkm_ramht_del(&imem->base.ramht); nvkm_memory_del(&imem->base.vbios); nvkm_mm_fini(&imem->heap); nvkm_instmem_destroy(&imem->base); @@ -198,8 +198,7 @@ nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine, return ret; /* 0x10000-0x18000: reserve for RAMHT */ - ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, - &imem->base.ramht); + ret = nvkm_ramht_new(device, 0x08000, 0, NULL, &imem->base.ramht); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 5a2709d..8e7a115 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -157,7 +157,7 @@ nv40_instmem_dtor(struct nvkm_object *object) struct nv40_instmem *imem = (void *)object; nvkm_memory_del(&imem->base.ramfc); nvkm_memory_del(&imem->base.ramro); - nvkm_ramht_ref(NULL, &imem->base.ramht); + nvkm_ramht_del(&imem->base.ramht); nvkm_memory_del(&imem->base.vbios); nvkm_mm_fini(&imem->heap); if (imem->iomem) @@ -227,8 +227,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine, return ret; /* 0x10000-0x18000: reserve for RAMHT */ - ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, - &imem->base.ramht); + ret = nvkm_ramht_new(device, 0x08000, 0, NULL, &imem->base.ramht); if (ret) return ret; -- cgit v0.10.2