Explorar o código

drm/nv50: make pushbuf dma object cover entire vm

This allows us to submit push buffers from any memtype to the hardware.
We'll need this ability for VRAM index buffers at some point.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs %!s(int64=15) %!d(string=hai) anos
pai
achega
d87897d4c8

+ 9 - 4
drivers/gpu/drm/nouveau/nouveau_channel.c

@@ -35,22 +35,27 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_bo *pb = chan->pushbuf_bo;
 	struct nouveau_bo *pb = chan->pushbuf_bo;
 	struct nouveau_gpuobj *pushbuf = NULL;
 	struct nouveau_gpuobj *pushbuf = NULL;
-	uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	int ret;
 	int ret;
 
 
+	if (dev_priv->card_type >= NV_50) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
+					     dev_priv->vm_end, NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_AGP, &pushbuf);
+		chan->pushbuf_base = pb->bo.offset;
+	} else
 	if (pb->bo.mem.mem_type == TTM_PL_TT) {
 	if (pb->bo.mem.mem_type == TTM_PL_TT) {
 		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
 		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
 						  dev_priv->gart_info.aper_size,
 						  dev_priv->gart_info.aper_size,
 						  NV_DMA_ACCESS_RO, &pushbuf,
 						  NV_DMA_ACCESS_RO, &pushbuf,
 						  NULL);
 						  NULL);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	} else
 	} else
 	if (dev_priv->card_type != NV_04) {
 	if (dev_priv->card_type != NV_04) {
 		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
 		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
 					     dev_priv->fb_available_size,
 					     dev_priv->fb_available_size,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_TARGET_VIDMEM, &pushbuf);
 					     NV_DMA_TARGET_VIDMEM, &pushbuf);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	} else {
 	} else {
 		/* NV04 cmdbuf hack, from original ddx.. not sure of it's
 		/* NV04 cmdbuf hack, from original ddx.. not sure of it's
 		 * exact reason for existing :)  PCI access to cmdbuf in
 		 * exact reason for existing :)  PCI access to cmdbuf in
@@ -61,7 +66,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
 					     dev_priv->fb_available_size,
 					     dev_priv->fb_available_size,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_ACCESS_RO,
 					     NV_DMA_TARGET_PCI, &pushbuf);
 					     NV_DMA_TARGET_PCI, &pushbuf);
-		chan->pushbuf_base = start;
+		chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
 	}
 	}
 
 
 	ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
 	ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);

+ 3 - 3
drivers/gpu/drm/nouveau/nouveau_dma.c

@@ -182,12 +182,12 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
 	      int delta, int dwords)
 	      int delta, int dwords)
 {
 {
 	struct nouveau_bo *pb = chan->pushbuf_bo;
 	struct nouveau_bo *pb = chan->pushbuf_bo;
-	uint64_t offset = (bo->bo.mem.mm_node->start << PAGE_SHIFT) + delta;
+	uint64_t offset = bo->bo.offset + delta;
 	int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
 	int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
 
 
 	BUG_ON(chan->dma.ib_free < 1);
 	BUG_ON(chan->dma.ib_free < 1);
-	nouveau_bo_wr32(pb, ip++, offset);
-	nouveau_bo_wr32(pb, ip++, dwords << 10);
+	nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
+	nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | dwords << 10);
 
 
 	chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
 	chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
 	nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
 	nvchan_wr32(chan, 0x8c, chan->dma.ib_put);