aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2011-11-19 05:57:52 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:46 -0500
commit4e03b4af6dd3cff445fc0455805b43b101647bfc (patch)
tree8ef57180b317b6a37b13031dd1151d455a49c99e /drivers/gpu/drm/nouveau
parent045da4e55581d9b4de135bbdbdd1b7fa98dc18a9 (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>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_debugfs.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fifo.c6
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 bb6ec9ef867..a018defb762 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 f52c2db3529..fa2ec491f6a 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 00bc6eaad55..4c2e4e5925f 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 */
136static inline int 136static inline int
137READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout) 137READ_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)
218static int 220static int
219nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) 221nv50_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)
261int 263int
262nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) 264nouveau_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 0af52582034..38134a9c757 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 c34a074f7ea..3bc2a565c20 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);