diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 24540862a23f..3518ebba6fbd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -608,13 +608,9 @@ static int nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, struct nouveau_gpuobj **gpuobj_ret) { - struct drm_nouveau_private *dev_priv; + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nouveau_gpuobj *gpuobj; - if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) - return -EINVAL; - dev_priv = chan->dev->dev_private; - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); if (!gpuobj) return -ENOMEM; @@ -632,12 +628,12 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, } int -nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, - struct nouveau_gpuobj **gpuobj) +nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) { struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; struct nouveau_gpuobj_class *oc; + struct nouveau_gpuobj *gpuobj; int ret; NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); @@ -651,10 +647,12 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, return -EINVAL; found: - if (oc->engine == NVOBJ_ENGINE_SW) - return nouveau_gpuobj_sw_new(chan, class, gpuobj); - switch (oc->engine) { + case NVOBJ_ENGINE_SW: + ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); + if (ret) + return ret; + goto insert; case NVOBJ_ENGINE_GR: if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { struct nouveau_pgraph_engine *pgraph = @@ -681,41 +679,47 @@ found: nouveau_gpuobj_class_instmem_size(dev, class), 16, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, - gpuobj); + &gpuobj); if (ret) { NV_ERROR(dev, "error creating gpuobj: %d\n", ret); return ret; } if (dev_priv->card_type >= NV_50) { - nv_wo32(*gpuobj, 0, class); - nv_wo32(*gpuobj, 20, 0x00010000); + nv_wo32(gpuobj, 0, class); + nv_wo32(gpuobj, 20, 0x00010000); } else { switch (class) { case NV_CLASS_NULL: - nv_wo32(*gpuobj, 0, 0x00001030); - nv_wo32(*gpuobj, 4, 0xFFFFFFFF); + nv_wo32(gpuobj, 0, 0x00001030); + nv_wo32(gpuobj, 4, 0xFFFFFFFF); break; default: if (dev_priv->card_type >= NV_40) { - nv_wo32(*gpuobj, 0, class); + nv_wo32(gpuobj, 0, class); #ifdef __BIG_ENDIAN - nv_wo32(*gpuobj, 8, 0x01000000); + nv_wo32(gpuobj, 8, 0x01000000); #endif } else { #ifdef __BIG_ENDIAN - nv_wo32(*gpuobj, 0, class | 0x00080000); + nv_wo32(gpuobj, 0, class | 0x00080000); #else - nv_wo32(*gpuobj, 0, class); + nv_wo32(gpuobj, 0, class); #endif } } } dev_priv->engine.instmem.flush(dev); - (*gpuobj)->engine = oc->engine; - (*gpuobj)->class = oc->id; - return 0; + gpuobj->engine = oc->engine; + gpuobj->class = oc->id; + +insert: + ret = nouveau_ramht_insert(chan, handle, gpuobj); + if (ret) + NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret); + nouveau_gpuobj_ref(NULL, &gpuobj); + return ret; } static int @@ -971,7 +975,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_nouveau_grobj_alloc *init = data; - struct nouveau_gpuobj *gr = NULL; struct nouveau_channel *chan; int ret; @@ -987,18 +990,10 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, goto out; } - ret = nouveau_gpuobj_gr_new(chan, init->class, &gr); + ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class); if (ret) { NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", ret, init->channel, init->handle); - goto out; - } - - ret = nouveau_ramht_insert(chan, init->handle, gr); - nouveau_gpuobj_ref(NULL, &gr); - if (ret) { - NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", - ret, init->channel, init->handle); } out: |