drm/nouveau: rebase per-channel pramin heap offsets to 0
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Sep 2010 05:24:30 +0000 (15:24 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 24 Sep 2010 06:20:07 +0000 (16:20 +1000)
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_fifo.c

index 372adfdd9de03b102092b7d16ebd0e92f78095b3..b8511c122f5fb938d697be76a3563a3c73f6dd1f 100644 (file)
@@ -151,6 +151,10 @@ struct nouveau_gpuobj {
        uint32_t flags;
        int refcount;
 
+       u32 pinst;
+       u32 cinst;
+       u64 vinst;
+
        uint32_t engine;
        uint32_t class;
 
index 52db13cd75b2dbd8d0e44b05be441baa9f3a49c3..552f5131650f8cdca97fdee9f69337126438c1b8 100644 (file)
@@ -131,6 +131,23 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
                }
        }
 
+       /* calculate the various different addresses for the object */
+       if (chan) {
+               gpuobj->pinst = gpuobj->im_pramin->start +
+                               chan->ramin->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->gpuobj->im_backing_start;
+               }
+       } else {
+               gpuobj->pinst = gpuobj->im_pramin->start;
+               gpuobj->cinst = 0xdeadbeef;
+               gpuobj->vinst = gpuobj->im_backing_start;
+       }
+
        if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
                int i;
 
@@ -260,19 +277,16 @@ nouveau_gpuobj_instance_get(struct drm_device *dev,
        /* <NV50 use PRAMIN address everywhere */
        if (dev_priv->card_type < NV_50) {
                *inst = gpuobj->im_pramin->start;
+               if (gpuobj->im_channel) {
+                       cpramin = gpuobj->im_channel->ramin->gpuobj;
+                       *inst += cpramin->im_pramin->start;
+               }
                return 0;
        }
 
-       if (chan && gpuobj->im_channel != chan) {
-               NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n",
-                        gpuobj->im_channel->id, chan->id);
-               return -EINVAL;
-       }
-
        /* NV50 channel-local instance */
        if (chan) {
-               cpramin = chan->ramin->gpuobj;
-               *inst = gpuobj->im_pramin->start - cpramin->im_pramin->start;
+               *inst = gpuobj->im_pramin->start;
                return 0;
        }
 
@@ -288,8 +302,7 @@ nouveau_gpuobj_instance_get(struct drm_device *dev,
        } else {
                /* ...from local heap */
                cpramin = gpuobj->im_channel->ramin->gpuobj;
-               *inst = cpramin->im_backing_start +
-                       (gpuobj->im_pramin->start - cpramin->im_pramin->start);
+               *inst = cpramin->im_backing_start + gpuobj->im_pramin->start;
                return 0;
        }
 
@@ -458,6 +471,10 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
                gpuobj->im_backing_start = b_offset;
        }
 
+       gpuobj->pinst = gpuobj->im_pramin->start;
+       gpuobj->cinst = 0xdeadbeef;
+       gpuobj->vinst = gpuobj->im_backing_start;
+
        if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
                for (i = 0; i < gpuobj->im_pramin->size; i += 4)
                        nv_wo32(gpuobj, i, 0);
@@ -789,7 +806,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
        }
        pramin = chan->ramin->gpuobj;
 
-       ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size);
+       ret = drm_mm_init(&chan->ramin_heap, base, size);
        if (ret) {
                NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
                nouveau_gpuobj_ref_del(dev, &chan->ramin);
@@ -1124,13 +1141,11 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
 u32
 nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset)
 {
-       struct drm_device *dev = gpuobj->dev;
-       return nv_ri32(dev, gpuobj->im_pramin->start + offset);
+       return nv_ri32(gpuobj->dev, gpuobj->pinst + offset);
 }
 
 void
 nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
 {
-       struct drm_device *dev = gpuobj->dev;
-       nv_wi32(dev, gpuobj->im_pramin->start + offset, val);
+       nv_wi32(gpuobj->dev, gpuobj->pinst + offset, val);
 }
index 435d2b727949e492a19d59bcbeba48ef49c63b65..6f89674ebb96e6262488cdf9dcdd03274b90a011 100644 (file)
@@ -113,8 +113,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
                return ret;
        }
 
-       ret = drm_mm_init(&chan->ramin_heap,
-                         chan->ramin->gpuobj->im_pramin->start, 32768);
+       ret = drm_mm_init(&chan->ramin_heap, 0, 32768);
        if (ret) {
                NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
                nv50_evo_channel_del(pchan);
index 38dbcda86196d2164ef513286bd6285ad6cebac9..9201f35d82776c88285eadf5524e2d3fe0f2768f 100644 (file)
@@ -228,19 +228,19 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
        NV_DEBUG(dev, "ch%d\n", chan->id);
 
        if (dev_priv->chipset == 0x50) {
-               uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start;
-               uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start;
-
-               ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset,
-                                             0x100, NVOBJ_FLAG_ZERO_ALLOC |
+               ret = nouveau_gpuobj_new_fake(dev, chan->ramin->gpuobj->pinst,
+                                             chan->ramin->gpuobj->vinst, 0x100,
+                                             NVOBJ_FLAG_ZERO_ALLOC |
                                              NVOBJ_FLAG_ZERO_FREE, &ramfc,
                                              &chan->ramfc);
                if (ret)
                        return ret;
 
-               ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400,
-                                             ramin_voffset + 0x0400, 4096,
-                                             0, NULL, &chan->cache);
+               ret = nouveau_gpuobj_new_fake(dev, chan->ramin->gpuobj->pinst +
+                                             0x0400,
+                                             chan->ramin->gpuobj->vinst +
+                                             0x0400, 4096, 0, NULL,
+                                             &chan->cache);
                if (ret)
                        return ret;
        } else {