diff --git a/linux-core/nouveau_sgdma.c b/linux-core/nouveau_sgdma.c index 1163baf..3bce3c9 100644 --- a/linux-core/nouveau_sgdma.c +++ b/linux-core/nouveau_sgdma.c @@ -90,6 +90,7 @@ static int nouveau_sgdma_bind(struct drm_ttm_backend *be, struct drm_bo_mem_reg *mem) { struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; + struct drm_device *dev = nvbe->dev; struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; uint64_t offset = (mem->mm_node->start << PAGE_SHIFT); @@ -128,6 +129,7 @@ static int nouveau_sgdma_unbind(struct drm_ttm_backend *be) { struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; + struct drm_device *dev = nvbe->dev; struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; DRM_DEBUG("\n"); diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 158d6fd..1eea607 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -615,7 +615,40 @@ extern void nouveau_fence_handler(struct drm_device *dev, int channel); #define NV_WI32(o,v) DRM_WRITE32(dev_priv->ramin, (o), (v)) #endif -#define INSTANCE_RD(o,i) NV_RI32((o)->im_pramin->start + ((i)<<2)) -#define INSTANCE_WR(o,i,v) NV_WI32((o)->im_pramin->start + ((i)<<2), (v)) +static inline uint32_t +gpuobj_rd32(struct drm_device *dev, struct nouveau_gpuobj *obj, + uint32_t index) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst, bop, val; + + inst = obj->im_pramin->start; + inst += (index << 2); + + bop = NV_READ(0x00001700); + NV_WRITE(0x00001700, (inst >> 16)); + val = NV_READ(0x00700000 + (inst & 0xffff)); + NV_WRITE(0x00001700, bop); + return val; +} + +static inline void +gpuobj_wr32(struct drm_device *dev, struct nouveau_gpuobj *obj, + uint32_t index, uint32_t val) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst, bop; + + inst = obj->im_pramin->start; + inst += (index << 2); + + bop = NV_READ(0x00001700); + NV_WRITE(0x00001700, (inst >> 16)); + NV_WRITE(0x00700000 + (inst & 0xffff), val); + NV_WRITE(0x00001700, bop); +} + +#define INSTANCE_RD(o,i) gpuobj_rd32(dev, (o), (i)) +#define INSTANCE_WR(o,i,v) gpuobj_wr32(dev, (o), (i), (v)) #endif /* __NOUVEAU_DRV_H__ */ diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 19325f3..66334e3 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -241,6 +241,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, } /* Allocate a chunk of the PRAMIN aperture */ +if (pramin != dev_priv->ramin_heap) { gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, drm_order(align), (struct drm_file *)-2, 0); @@ -248,6 +249,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, nouveau_gpuobj_del(dev, &gpuobj); return -ENOMEM; } +} else { + gpuobj->im_pramin = drm_calloc(1, sizeof(*gpuobj->im_pramin), DRM_MEM_DRIVER); + gpuobj->im_pramin->size = size; + gpuobj->im_pramin->start = gpuobj->im_backing->start; + gpuobj->flags |= NVOBJ_FLAG_FAKE; +} gpuobj->im_pramin->flags = NOUVEAU_MEM_INSTANCE; if (!chan && (ret = engine->instmem.bind(dev, gpuobj))) {