Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/nouveau: Fix pushbufs over the 4GB mark.

Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Tested-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

authored by

Francisco Jerez and committed by
Ben Skeggs
4e03b4af 045da4e5

+17 -10
+2
drivers/gpu/drm/nouveau/nouveau_channel.c
··· 187 187 nouveau_dma_pre_init(chan); 188 188 chan->user_put = 0x40; 189 189 chan->user_get = 0x44; 190 + if (dev_priv->card_type >= NV_50) 191 + chan->user_get_hi = 0x60; 190 192 191 193 /* disable the fifo caches */ 192 194 pfifo->reassign(dev, false);
+1 -1
drivers/gpu/drm/nouveau/nouveau_debugfs.c
··· 44 44 seq_printf(m, "channel id : %d\n", chan->id); 45 45 46 46 seq_printf(m, "cpu fifo state:\n"); 47 - seq_printf(m, " base: 0x%08x\n", chan->pushbuf_base); 47 + seq_printf(m, " base: 0x%10llx\n", chan->pushbuf_base); 48 48 seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2); 49 49 seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); 50 50 seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2);
+8 -6
drivers/gpu/drm/nouveau/nouveau_dma.c
··· 134 134 * -EBUSY if timeout exceeded 135 135 */ 136 136 static inline int 137 - READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout) 137 + READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) 138 138 { 139 - uint32_t val; 139 + uint64_t val; 140 140 141 141 val = nvchan_rd32(chan, chan->user_get); 142 + if (chan->user_get_hi) 143 + val |= (uint64_t)nvchan_rd32(chan, chan->user_get_hi) << 32; 142 144 143 145 /* reset counter as long as GET is still advancing, this is 144 146 * to avoid misdetecting a GPU lockup if the GPU happens to ··· 220 218 static int 221 219 nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) 222 220 { 223 - uint32_t cnt = 0, prev_get = 0; 224 - int ret; 221 + uint64_t prev_get = 0; 222 + int ret, cnt = 0; 225 223 226 224 ret = nv50_dma_push_wait(chan, slots + 1); 227 225 if (unlikely(ret)) ··· 263 261 int 264 262 nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) 265 263 { 266 - uint32_t prev_get = 0, cnt = 0; 267 - int get; 264 + uint64_t prev_get = 0; 265 + int cnt = 0, get; 268 266 269 267 if (chan->dma.ib_max) 270 268 return nv50_dma_wait(chan, slots, size);
+2 -1
drivers/gpu/drm/nouveau/nouveau_drv.h
··· 232 232 /* mapping of the regs controlling the fifo */ 233 233 void __iomem *user; 234 234 uint32_t user_get; 235 + uint32_t user_get_hi; 235 236 uint32_t user_put; 236 237 237 238 /* Fencing */ ··· 250 249 struct nouveau_gpuobj *pushbuf; 251 250 struct nouveau_bo *pushbuf_bo; 252 251 struct nouveau_vma pushbuf_vma; 253 - uint32_t pushbuf_base; 252 + uint64_t pushbuf_base; 254 253 255 254 /* Notifier memory */ 256 255 struct nouveau_bo *notifier_bo;
+4 -2
drivers/gpu/drm/nouveau/nv50_fifo.c
··· 230 230 struct drm_device *dev = chan->dev; 231 231 struct drm_nouveau_private *dev_priv = dev->dev_private; 232 232 struct nouveau_gpuobj *ramfc = NULL; 233 + uint64_t ib_offset = chan->pushbuf_base + chan->dma.ib_base * 4; 233 234 unsigned long flags; 234 235 int ret; 235 236 ··· 281 280 nv_wo32(ramfc, 0x7c, 0x30000001); 282 281 nv_wo32(ramfc, 0x78, 0x00000000); 283 282 nv_wo32(ramfc, 0x3c, 0x403f6078); 284 - nv_wo32(ramfc, 0x50, chan->pushbuf_base + chan->dma.ib_base * 4); 285 - nv_wo32(ramfc, 0x54, drm_order(chan->dma.ib_max + 1) << 16); 283 + nv_wo32(ramfc, 0x50, lower_32_bits(ib_offset)); 284 + nv_wo32(ramfc, 0x54, upper_32_bits(ib_offset) | 285 + drm_order(chan->dma.ib_max + 1) << 16); 286 286 287 287 if (dev_priv->chipset != 0x50) { 288 288 nv_wo32(chan->ramin, 0, chan->id);