aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c105
1 files changed, 31 insertions, 74 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index e7c100ba63a1..b6bcb254f4ab 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -132,7 +132,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
}
}
- instmem->prepare_access(dev, true);
co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
do {
if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
@@ -143,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
nv_wo32(dev, ramht, (co + 4)/4, ctx);
list_add_tail(&ref->list, &chan->ramht_refs);
- instmem->finish_access(dev);
+ instmem->flush(dev);
return 0;
}
NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
@@ -153,7 +152,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
if (co >= dev_priv->ramht_size)
co = 0;
} while (co != ho);
- instmem->finish_access(dev);
NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
return -ENOMEM;
@@ -173,7 +171,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
return;
}
- instmem->prepare_access(dev, true);
co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
do {
if (nouveau_ramht_entry_valid(dev, ramht, co) &&
@@ -186,7 +183,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);
list_del(&ref->list);
- instmem->finish_access(dev);
+ instmem->flush(dev);
return;
}
@@ -195,7 +192,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
co = 0;
} while (co != ho);
list_del(&ref->list);
- instmem->finish_access(dev);
NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
chan->id, ref->handle);
@@ -209,7 +205,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine;
struct nouveau_gpuobj *gpuobj;
- struct mem_block *pramin = NULL;
+ struct drm_mm *pramin = NULL;
int ret;
NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
@@ -233,25 +229,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
* available.
*/
if (chan) {
- if (chan->ramin_heap) {
- NV_DEBUG(dev, "private heap\n");
- pramin = chan->ramin_heap;
- } else
- if (dev_priv->card_type < NV_50) {
- NV_DEBUG(dev, "global heap fallback\n");
- pramin = dev_priv->ramin_heap;
- }
+ NV_DEBUG(dev, "channel heap\n");
+ pramin = &chan->ramin_heap;
} else {
NV_DEBUG(dev, "global heap\n");
- pramin = dev_priv->ramin_heap;
- }
-
- if (!pramin) {
- NV_ERROR(dev, "No PRAMIN heap!\n");
- return -EINVAL;
- }
+ pramin = &dev_priv->ramin_heap;
- if (!chan) {
ret = engine->instmem.populate(dev, gpuobj, &size);
if (ret) {
nouveau_gpuobj_del(dev, &gpuobj);
@@ -260,9 +243,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
}
/* Allocate a chunk of the PRAMIN aperture */
- gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size,
- drm_order(align),
- (struct drm_file *)-2, 0);
+ gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0);
+ if (gpuobj->im_pramin)
+ gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align);
+
if (!gpuobj->im_pramin) {
nouveau_gpuobj_del(dev, &gpuobj);
return -ENOMEM;
@@ -279,10 +263,9 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
int i;
- engine->instmem.prepare_access(dev, true);
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
nv_wo32(dev, gpuobj, i/4, 0);
- engine->instmem.finish_access(dev);
+ engine->instmem.flush(dev);
}
*gpuobj_ret = gpuobj;
@@ -370,10 +353,9 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
}
if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
- engine->instmem.prepare_access(dev, true);
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
nv_wo32(dev, gpuobj, i/4, 0);
- engine->instmem.finish_access(dev);
+ engine->instmem.flush(dev);
}
if (gpuobj->dtor)
@@ -386,7 +368,7 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
if (gpuobj->flags & NVOBJ_FLAG_FAKE)
kfree(gpuobj->im_pramin);
else
- nouveau_mem_free_block(gpuobj->im_pramin);
+ drm_mm_put_block(gpuobj->im_pramin);
}
list_del(&gpuobj->list);
@@ -589,7 +571,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
if (p_offset != ~0) {
- gpuobj->im_pramin = kzalloc(sizeof(struct mem_block),
+ gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node),
GFP_KERNEL);
if (!gpuobj->im_pramin) {
nouveau_gpuobj_del(dev, &gpuobj);
@@ -605,10 +587,9 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
}
if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
- dev_priv->engine.instmem.prepare_access(dev, true);
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
nv_wo32(dev, gpuobj, i/4, 0);
- dev_priv->engine.instmem.finish_access(dev);
+ dev_priv->engine.instmem.flush(dev);
}
if (pref) {
@@ -696,8 +677,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
return ret;
}
- instmem->prepare_access(dev, true);
-
if (dev_priv->card_type < NV_50) {
uint32_t frame, adjust, pte_flags = 0;
@@ -734,7 +713,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
nv_wo32(dev, *gpuobj, 5, flags5);
}
- instmem->finish_access(dev);
+ instmem->flush(dev);
(*gpuobj)->engine = NVOBJ_ENGINE_SW;
(*gpuobj)->class = class;
@@ -849,7 +828,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
return ret;
}
- dev_priv->engine.instmem.prepare_access(dev, true);
if (dev_priv->card_type >= NV_50) {
nv_wo32(dev, *gpuobj, 0, class);
nv_wo32(dev, *gpuobj, 5, 0x00010000);
@@ -874,7 +852,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
}
}
}
- dev_priv->engine.instmem.finish_access(dev);
+ dev_priv->engine.instmem.flush(dev);
(*gpuobj)->engine = NVOBJ_ENGINE_GR;
(*gpuobj)->class = class;
@@ -920,6 +898,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
base = 0;
/* PGRAPH context */
+ size += dev_priv->engine.graph.grctx_size;
if (dev_priv->card_type == NV_50) {
/* Various fixed table thingos */
@@ -930,12 +909,8 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
size += 0x8000;
/* RAMFC */
size += 0x1000;
- /* PGRAPH context */
- size += 0x70000;
}
- NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
- chan->id, size, base);
ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
&chan->ramin);
if (ret) {
@@ -944,8 +919,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
}
pramin = chan->ramin->gpuobj;
- ret = nouveau_mem_init_heap(&chan->ramin_heap,
- pramin->im_pramin->start + base, size);
+ ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size);
if (ret) {
NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
nouveau_gpuobj_ref_del(dev, &chan->ramin);
@@ -969,15 +943,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
- /* Reserve a block of PRAMIN for the channel
- *XXX: maybe on <NV50 too at some point
- */
- if (0 || dev_priv->card_type == NV_50) {
- ret = nouveau_gpuobj_channel_init_pramin(chan);
- if (ret) {
- NV_ERROR(dev, "init pramin\n");
- return ret;
- }
+ /* Allocate a chunk of memory for per-channel object storage */
+ ret = nouveau_gpuobj_channel_init_pramin(chan);
+ if (ret) {
+ NV_ERROR(dev, "init pramin\n");
+ return ret;
}
/* NV50 VM
@@ -988,17 +958,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
if (dev_priv->card_type >= NV_50) {
uint32_t vm_offset, pde;
- instmem->prepare_access(dev, true);
-
vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
vm_offset += chan->ramin->gpuobj->im_pramin->start;
ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
0, &chan->vm_pd, NULL);
- if (ret) {
- instmem->finish_access(dev);
+ if (ret)
return ret;
- }
for (i = 0; i < 0x4000; i += 8) {
nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
@@ -1008,10 +974,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
dev_priv->gart_info.sg_ctxdma,
&chan->vm_gart_pt);
- if (ret) {
- instmem->finish_access(dev);
+ if (ret)
return ret;
- }
nv_wo32(dev, chan->vm_pd, pde++,
chan->vm_gart_pt->instance | 0x03);
nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
@@ -1021,17 +985,15 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
dev_priv->vm_vram_pt[i],
&chan->vm_vram_pt[i]);
- if (ret) {
- instmem->finish_access(dev);
+ if (ret)
return ret;
- }
nv_wo32(dev, chan->vm_pd, pde++,
chan->vm_vram_pt[i]->instance | 0x61);
nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
}
- instmem->finish_access(dev);
+ instmem->flush(dev);
}
/* RAMHT */
@@ -1130,8 +1092,8 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
- if (chan->ramin_heap)
- nouveau_mem_takedown(&chan->ramin_heap);
+ if (chan->ramin_heap.free_stack.next)
+ drm_mm_takedown(&chan->ramin_heap);
if (chan->ramin)
nouveau_gpuobj_ref_del(dev, &chan->ramin);
@@ -1164,10 +1126,8 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
return -ENOMEM;
}
- dev_priv->engine.instmem.prepare_access(dev, false);
for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
- dev_priv->engine.instmem.finish_access(dev);
}
return 0;
@@ -1212,10 +1172,9 @@ nouveau_gpuobj_resume(struct drm_device *dev)
if (!gpuobj->im_backing_suspend)
continue;
- dev_priv->engine.instmem.prepare_access(dev, true);
for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
- dev_priv->engine.instmem.finish_access(dev);
+ dev_priv->engine.instmem.flush(dev);
}
nouveau_gpuobj_suspend_cleanup(dev);
@@ -1232,7 +1191,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
struct nouveau_channel *chan;
int ret;
- NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
if (init->handle == ~0)
@@ -1283,7 +1241,6 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
struct nouveau_channel *chan;
int ret;
- NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);