diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 372adfdd9de03b102092b7d16ebd0e92f78095b3..b8511c122f5fb938d697be76a3563a3c73f6dd1f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -151,6 +151,10 @@ struct nouveau_gpuobj { uint32_t flags; int refcount; + u32 pinst; + u32 cinst; + u64 vinst; + uint32_t engine; uint32_t class; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 52db13cd75b2dbd8d0e44b05be441baa9f3a49c3..552f5131650f8cdca97fdee9f69337126438c1b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -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, /* 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); } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 435d2b727949e492a19d59bcbeba48ef49c63b65..6f89674ebb96e6262488cdf9dcdd03274b90a011 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 38dbcda86196d2164ef513286bd6285ad6cebac9..9201f35d82776c88285eadf5524e2d3fe0f2768f 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -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 {