Skip to content

Commit

Permalink
drm/nouveau: rework gpu-specific instmem interfaces
Browse files Browse the repository at this point in the history
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Dec 3, 2010
1 parent dc1e5c0 commit e41115d
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 243 deletions.
44 changes: 21 additions & 23 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,16 @@ enum nouveau_flags {

#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
#define NVOBJ_FLAG_ZERO_FREE (1 << 2)

#define NVOBJ_CINST_GLOBAL 0xdeadbeef

struct nouveau_gpuobj {
struct drm_device *dev;
struct kref refcount;
struct list_head list;

struct drm_mm_node *im_pramin;
struct nouveau_bo *im_backing;
void *node;
u32 *suspend;
int im_bound;

uint32_t flags;

Expand Down Expand Up @@ -288,11 +289,11 @@ struct nouveau_instmem_engine {
int (*suspend)(struct drm_device *dev);
void (*resume)(struct drm_device *dev);

int (*populate)(struct drm_device *, struct nouveau_gpuobj *,
u32 *size, u32 align);
void (*clear)(struct drm_device *, struct nouveau_gpuobj *);
int (*bind)(struct drm_device *, struct nouveau_gpuobj *);
int (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
int (*get)(struct nouveau_gpuobj *, u32 size, u32 align);
void (*put)(struct nouveau_gpuobj *);
int (*map)(struct nouveau_gpuobj *);
void (*unmap)(struct nouveau_gpuobj *);

void (*flush)(struct drm_device *);
};

Expand Down Expand Up @@ -1182,23 +1183,21 @@ extern int nv04_instmem_init(struct drm_device *);
extern void nv04_instmem_takedown(struct drm_device *);
extern int nv04_instmem_suspend(struct drm_device *);
extern void nv04_instmem_resume(struct drm_device *);
extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
u32 *size, u32 align);
extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
extern int nv04_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align);
extern void nv04_instmem_put(struct nouveau_gpuobj *);
extern int nv04_instmem_map(struct nouveau_gpuobj *);
extern void nv04_instmem_unmap(struct nouveau_gpuobj *);
extern void nv04_instmem_flush(struct drm_device *);

/* nv50_instmem.c */
extern int nv50_instmem_init(struct drm_device *);
extern void nv50_instmem_takedown(struct drm_device *);
extern int nv50_instmem_suspend(struct drm_device *);
extern void nv50_instmem_resume(struct drm_device *);
extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
u32 *size, u32 align);
extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
extern int nv50_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align);
extern void nv50_instmem_put(struct nouveau_gpuobj *);
extern int nv50_instmem_map(struct nouveau_gpuobj *);
extern void nv50_instmem_unmap(struct nouveau_gpuobj *);
extern void nv50_instmem_flush(struct drm_device *);
extern void nv84_instmem_flush(struct drm_device *);
extern void nv50_vm_flush(struct drm_device *, int engine);
Expand All @@ -1208,11 +1207,10 @@ extern int nvc0_instmem_init(struct drm_device *);
extern void nvc0_instmem_takedown(struct drm_device *);
extern int nvc0_instmem_suspend(struct drm_device *);
extern void nvc0_instmem_resume(struct drm_device *);
extern int nvc0_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
u32 *size, u32 align);
extern void nvc0_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
extern int nvc0_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
extern int nvc0_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
extern int nvc0_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align);
extern void nvc0_instmem_put(struct nouveau_gpuobj *);
extern int nvc0_instmem_map(struct nouveau_gpuobj *);
extern void nvc0_instmem_unmap(struct nouveau_gpuobj *);
extern void nvc0_instmem_flush(struct drm_device *);

/* nv04_mc.c */
Expand Down
112 changes: 37 additions & 75 deletions drivers/gpu/drm/nouveau/nouveau_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,14 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
struct nouveau_gpuobj **gpuobj_ret)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine;
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
struct nouveau_gpuobj *gpuobj;
struct drm_mm_node *ramin = NULL;
int ret;
int ret, i;

NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
chan ? chan->id : -1, size, align, flags);

if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
return -EINVAL;

gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
if (!gpuobj)
return -ENOMEM;
Expand All @@ -193,88 +190,45 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
spin_unlock(&dev_priv->ramin_lock);

if (chan) {
NV_DEBUG(dev, "channel heap\n");

ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0);
if (ramin)
ramin = drm_mm_get_block(ramin, size, align);

if (!ramin) {
nouveau_gpuobj_ref(NULL, &gpuobj);
return -ENOMEM;
}
} else {
NV_DEBUG(dev, "global heap\n");

/* allocate backing pages, sets vinst */
ret = engine->instmem.populate(dev, gpuobj, &size, align);
if (ret) {
nouveau_gpuobj_ref(NULL, &gpuobj);
return ret;
}

/* try and get aperture space */
do {
if (drm_mm_pre_get(&dev_priv->ramin_heap))
return -ENOMEM;

spin_lock(&dev_priv->ramin_lock);
ramin = drm_mm_search_free(&dev_priv->ramin_heap, size,
align, 0);
if (ramin == NULL) {
spin_unlock(&dev_priv->ramin_lock);
nouveau_gpuobj_ref(NULL, &gpuobj);
return -ENOMEM;
}

ramin = drm_mm_get_block_atomic(ramin, size, align);
spin_unlock(&dev_priv->ramin_lock);
} while (ramin == NULL);
gpuobj->pinst = chan->ramin->pinst;
if (gpuobj->pinst != ~0)
gpuobj->pinst += ramin->start;

/* on nv50 it's ok to fail, we have a fallback path */
if (!ramin && dev_priv->card_type < NV_50) {
nouveau_gpuobj_ref(NULL, &gpuobj);
return -ENOMEM;
}
}
if (dev_priv->card_type < NV_50)
gpuobj->cinst = gpuobj->pinst;
else
gpuobj->cinst = ramin->start;

/* if we got a chunk of the aperture, map pages into it */
gpuobj->im_pramin = ramin;
if (!chan && gpuobj->im_pramin && dev_priv->ramin_available) {
ret = engine->instmem.bind(dev, gpuobj);
gpuobj->vinst = ramin->start + chan->ramin->vinst;
gpuobj->node = ramin;
} else {
ret = instmem->get(gpuobj, size, align);
if (ret) {
nouveau_gpuobj_ref(NULL, &gpuobj);
return ret;
}
}

/* calculate the various different addresses for the object */
if (chan) {
gpuobj->pinst = chan->ramin->pinst;
if (gpuobj->pinst != ~0)
gpuobj->pinst += gpuobj->im_pramin->start;

if (dev_priv->card_type < NV_50) {
gpuobj->cinst = gpuobj->pinst;
} else {
gpuobj->cinst = gpuobj->im_pramin->start;
gpuobj->vinst = gpuobj->im_pramin->start +
chan->ramin->vinst;
}
} else {
if (gpuobj->im_pramin)
gpuobj->pinst = gpuobj->im_pramin->start;
else
ret = -ENOSYS;
if (dev_priv->ramin_available)
ret = instmem->map(gpuobj);
if (ret)
gpuobj->pinst = ~0;
gpuobj->cinst = 0xdeadbeef;

gpuobj->cinst = NVOBJ_CINST_GLOBAL;
}

if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
int i;

for (i = 0; i < gpuobj->size; i += 4)
nv_wo32(gpuobj, i, 0);
engine->instmem.flush(dev);
instmem->flush(dev);
}


Expand Down Expand Up @@ -326,26 +280,34 @@ nouveau_gpuobj_del(struct kref *ref)
container_of(ref, struct nouveau_gpuobj, refcount);
struct drm_device *dev = gpuobj->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine;
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
int i;

NV_DEBUG(dev, "gpuobj %p\n", gpuobj);

if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
if (gpuobj->node && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
for (i = 0; i < gpuobj->size; i += 4)
nv_wo32(gpuobj, i, 0);
engine->instmem.flush(dev);
instmem->flush(dev);
}

if (gpuobj->dtor)
gpuobj->dtor(dev, gpuobj);

if (gpuobj->im_backing)
engine->instmem.clear(dev, gpuobj);
if (gpuobj->cinst == NVOBJ_CINST_GLOBAL) {
if (gpuobj->node) {
instmem->unmap(gpuobj);
instmem->put(gpuobj);
}
} else {
if (gpuobj->node) {
spin_lock(&dev_priv->ramin_lock);
drm_mm_put_block(gpuobj->node);
spin_unlock(&dev_priv->ramin_lock);
}
}

spin_lock(&dev_priv->ramin_lock);
if (gpuobj->im_pramin)
drm_mm_put_block(gpuobj->im_pramin);
list_del(&gpuobj->list);
spin_unlock(&dev_priv->ramin_lock);

Expand Down Expand Up @@ -385,7 +347,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
kref_init(&gpuobj->refcount);
gpuobj->size = size;
gpuobj->pinst = pinst;
gpuobj->cinst = 0xdeadbeef;
gpuobj->cinst = NVOBJ_CINST_GLOBAL;
gpuobj->vinst = vinst;

if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
Expand Down Expand Up @@ -935,7 +897,7 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
int i;

list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
if (gpuobj->cinst != 0xdeadbeef)
if (gpuobj->cinst != NVOBJ_CINST_GLOBAL)
continue;

gpuobj->suspend = vmalloc(gpuobj->size);
Expand Down
56 changes: 28 additions & 28 deletions drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv04_instmem_takedown;
engine->instmem.suspend = nv04_instmem_suspend;
engine->instmem.resume = nv04_instmem_resume;
engine->instmem.populate = nv04_instmem_populate;
engine->instmem.clear = nv04_instmem_clear;
engine->instmem.bind = nv04_instmem_bind;
engine->instmem.unbind = nv04_instmem_unbind;
engine->instmem.get = nv04_instmem_get;
engine->instmem.put = nv04_instmem_put;
engine->instmem.map = nv04_instmem_map;
engine->instmem.unmap = nv04_instmem_unmap;
engine->instmem.flush = nv04_instmem_flush;
engine->mc.init = nv04_mc_init;
engine->mc.takedown = nv04_mc_takedown;
Expand Down Expand Up @@ -106,10 +106,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv04_instmem_takedown;
engine->instmem.suspend = nv04_instmem_suspend;
engine->instmem.resume = nv04_instmem_resume;
engine->instmem.populate = nv04_instmem_populate;
engine->instmem.clear = nv04_instmem_clear;
engine->instmem.bind = nv04_instmem_bind;
engine->instmem.unbind = nv04_instmem_unbind;
engine->instmem.get = nv04_instmem_get;
engine->instmem.put = nv04_instmem_put;
engine->instmem.map = nv04_instmem_map;
engine->instmem.unmap = nv04_instmem_unmap;
engine->instmem.flush = nv04_instmem_flush;
engine->mc.init = nv04_mc_init;
engine->mc.takedown = nv04_mc_takedown;
Expand Down Expand Up @@ -163,10 +163,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv04_instmem_takedown;
engine->instmem.suspend = nv04_instmem_suspend;
engine->instmem.resume = nv04_instmem_resume;
engine->instmem.populate = nv04_instmem_populate;
engine->instmem.clear = nv04_instmem_clear;
engine->instmem.bind = nv04_instmem_bind;
engine->instmem.unbind = nv04_instmem_unbind;
engine->instmem.get = nv04_instmem_get;
engine->instmem.put = nv04_instmem_put;
engine->instmem.map = nv04_instmem_map;
engine->instmem.unmap = nv04_instmem_unmap;
engine->instmem.flush = nv04_instmem_flush;
engine->mc.init = nv04_mc_init;
engine->mc.takedown = nv04_mc_takedown;
Expand Down Expand Up @@ -220,10 +220,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv04_instmem_takedown;
engine->instmem.suspend = nv04_instmem_suspend;
engine->instmem.resume = nv04_instmem_resume;
engine->instmem.populate = nv04_instmem_populate;
engine->instmem.clear = nv04_instmem_clear;
engine->instmem.bind = nv04_instmem_bind;
engine->instmem.unbind = nv04_instmem_unbind;
engine->instmem.get = nv04_instmem_get;
engine->instmem.put = nv04_instmem_put;
engine->instmem.map = nv04_instmem_map;
engine->instmem.unmap = nv04_instmem_unmap;
engine->instmem.flush = nv04_instmem_flush;
engine->mc.init = nv04_mc_init;
engine->mc.takedown = nv04_mc_takedown;
Expand Down Expand Up @@ -280,10 +280,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv04_instmem_takedown;
engine->instmem.suspend = nv04_instmem_suspend;
engine->instmem.resume = nv04_instmem_resume;
engine->instmem.populate = nv04_instmem_populate;
engine->instmem.clear = nv04_instmem_clear;
engine->instmem.bind = nv04_instmem_bind;
engine->instmem.unbind = nv04_instmem_unbind;
engine->instmem.get = nv04_instmem_get;
engine->instmem.put = nv04_instmem_put;
engine->instmem.map = nv04_instmem_map;
engine->instmem.unmap = nv04_instmem_unmap;
engine->instmem.flush = nv04_instmem_flush;
engine->mc.init = nv40_mc_init;
engine->mc.takedown = nv40_mc_takedown;
Expand Down Expand Up @@ -343,10 +343,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nv50_instmem_takedown;
engine->instmem.suspend = nv50_instmem_suspend;
engine->instmem.resume = nv50_instmem_resume;
engine->instmem.populate = nv50_instmem_populate;
engine->instmem.clear = nv50_instmem_clear;
engine->instmem.bind = nv50_instmem_bind;
engine->instmem.unbind = nv50_instmem_unbind;
engine->instmem.get = nv50_instmem_get;
engine->instmem.put = nv50_instmem_put;
engine->instmem.map = nv50_instmem_map;
engine->instmem.unmap = nv50_instmem_unmap;
if (dev_priv->chipset == 0x50)
engine->instmem.flush = nv50_instmem_flush;
else
Expand Down Expand Up @@ -449,10 +449,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.takedown = nvc0_instmem_takedown;
engine->instmem.suspend = nvc0_instmem_suspend;
engine->instmem.resume = nvc0_instmem_resume;
engine->instmem.populate = nvc0_instmem_populate;
engine->instmem.clear = nvc0_instmem_clear;
engine->instmem.bind = nvc0_instmem_bind;
engine->instmem.unbind = nvc0_instmem_unbind;
engine->instmem.get = nvc0_instmem_get;
engine->instmem.put = nvc0_instmem_put;
engine->instmem.map = nvc0_instmem_map;
engine->instmem.unmap = nvc0_instmem_unmap;
engine->instmem.flush = nvc0_instmem_flush;
engine->mc.init = nv50_mc_init;
engine->mc.takedown = nv50_mc_takedown;
Expand Down
Loading

0 comments on commit e41115d

Please sign in to comment.