diff options
author | Francisco Jerez <currojerez@riseup.net> | 2011-11-19 05:57:52 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-12-21 04:01:46 -0500 |
commit | 4e03b4af6dd3cff445fc0455805b43b101647bfc (patch) | |
tree | 8ef57180b317b6a37b13031dd1151d455a49c99e | |
parent | 045da4e55581d9b4de135bbdbdd1b7fa98dc18a9 (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dma.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fifo.c | 6 |
5 files changed, 17 insertions, 10 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index bb6ec9ef8676..a018defb7621 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -187,6 +187,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
187 | nouveau_dma_pre_init(chan); | 187 | nouveau_dma_pre_init(chan); |
188 | chan->user_put = 0x40; | 188 | chan->user_put = 0x40; |
189 | chan->user_get = 0x44; | 189 | chan->user_get = 0x44; |
190 | if (dev_priv->card_type >= NV_50) | ||
191 | chan->user_get_hi = 0x60; | ||
190 | 192 | ||
191 | /* disable the fifo caches */ | 193 | /* disable the fifo caches */ |
192 | pfifo->reassign(dev, false); | 194 | pfifo->reassign(dev, false); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index f52c2db3529e..fa2ec491f6a7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c | |||
@@ -44,7 +44,7 @@ nouveau_debugfs_channel_info(struct seq_file *m, void *data) | |||
44 | seq_printf(m, "channel id : %d\n", chan->id); | 44 | seq_printf(m, "channel id : %d\n", chan->id); |
45 | 45 | ||
46 | seq_printf(m, "cpu fifo state:\n"); | 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 | seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2); | 48 | seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2); |
49 | seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); | 49 | seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); |
50 | seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); | 50 | seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 00bc6eaad558..4c2e4e5925fe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -134,11 +134,13 @@ OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) | |||
134 | * -EBUSY if timeout exceeded | 134 | * -EBUSY if timeout exceeded |
135 | */ | 135 | */ |
136 | static inline int | 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 | val = nvchan_rd32(chan, chan->user_get); | 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 | /* reset counter as long as GET is still advancing, this is | 145 | /* reset counter as long as GET is still advancing, this is |
144 | * to avoid misdetecting a GPU lockup if the GPU happens to | 146 | * to avoid misdetecting a GPU lockup if the GPU happens to |
@@ -218,8 +220,8 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count) | |||
218 | static int | 220 | static int |
219 | nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) | 221 | nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) |
220 | { | 222 | { |
221 | uint32_t cnt = 0, prev_get = 0; | 223 | uint64_t prev_get = 0; |
222 | int ret; | 224 | int ret, cnt = 0; |
223 | 225 | ||
224 | ret = nv50_dma_push_wait(chan, slots + 1); | 226 | ret = nv50_dma_push_wait(chan, slots + 1); |
225 | if (unlikely(ret)) | 227 | if (unlikely(ret)) |
@@ -261,8 +263,8 @@ nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) | |||
261 | int | 263 | int |
262 | nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) | 264 | nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) |
263 | { | 265 | { |
264 | uint32_t prev_get = 0, cnt = 0; | 266 | uint64_t prev_get = 0; |
265 | int get; | 267 | int cnt = 0, get; |
266 | 268 | ||
267 | if (chan->dma.ib_max) | 269 | if (chan->dma.ib_max) |
268 | return nv50_dma_wait(chan, slots, size); | 270 | return nv50_dma_wait(chan, slots, size); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 0af525820347..38134a9c7578 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -232,6 +232,7 @@ struct nouveau_channel { | |||
232 | /* mapping of the regs controlling the fifo */ | 232 | /* mapping of the regs controlling the fifo */ |
233 | void __iomem *user; | 233 | void __iomem *user; |
234 | uint32_t user_get; | 234 | uint32_t user_get; |
235 | uint32_t user_get_hi; | ||
235 | uint32_t user_put; | 236 | uint32_t user_put; |
236 | 237 | ||
237 | /* Fencing */ | 238 | /* Fencing */ |
@@ -249,7 +250,7 @@ struct nouveau_channel { | |||
249 | struct nouveau_gpuobj *pushbuf; | 250 | struct nouveau_gpuobj *pushbuf; |
250 | struct nouveau_bo *pushbuf_bo; | 251 | struct nouveau_bo *pushbuf_bo; |
251 | struct nouveau_vma pushbuf_vma; | 252 | struct nouveau_vma pushbuf_vma; |
252 | uint32_t pushbuf_base; | 253 | uint64_t pushbuf_base; |
253 | 254 | ||
254 | /* Notifier memory */ | 255 | /* Notifier memory */ |
255 | struct nouveau_bo *notifier_bo; | 256 | struct nouveau_bo *notifier_bo; |
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index c34a074f7ea1..3bc2a565c20b 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -230,6 +230,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
230 | struct drm_device *dev = chan->dev; | 230 | struct drm_device *dev = chan->dev; |
231 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 231 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
232 | struct nouveau_gpuobj *ramfc = NULL; | 232 | struct nouveau_gpuobj *ramfc = NULL; |
233 | uint64_t ib_offset = chan->pushbuf_base + chan->dma.ib_base * 4; | ||
233 | unsigned long flags; | 234 | unsigned long flags; |
234 | int ret; | 235 | int ret; |
235 | 236 | ||
@@ -280,8 +281,9 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
280 | nv_wo32(ramfc, 0x7c, 0x30000001); | 281 | nv_wo32(ramfc, 0x7c, 0x30000001); |
281 | nv_wo32(ramfc, 0x78, 0x00000000); | 282 | nv_wo32(ramfc, 0x78, 0x00000000); |
282 | nv_wo32(ramfc, 0x3c, 0x403f6078); | 283 | nv_wo32(ramfc, 0x3c, 0x403f6078); |
283 | nv_wo32(ramfc, 0x50, chan->pushbuf_base + chan->dma.ib_base * 4); | 284 | nv_wo32(ramfc, 0x50, lower_32_bits(ib_offset)); |
284 | nv_wo32(ramfc, 0x54, drm_order(chan->dma.ib_max + 1) << 16); | 285 | nv_wo32(ramfc, 0x54, upper_32_bits(ib_offset) | |
286 | drm_order(chan->dma.ib_max + 1) << 16); | ||
285 | 287 | ||
286 | if (dev_priv->chipset != 0x50) { | 288 | if (dev_priv->chipset != 0x50) { |
287 | nv_wo32(chan->ramin, 0, chan->id); | 289 | nv_wo32(chan->ramin, 0, chan->id); |