aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/Kconfig2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c3
-rw-r--r--drivers/gpu/drm/nouveau/nv40_fifo.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv40_graph.c12
-rw-r--r--drivers/gpu/drm/nouveau/nv50_graph.c49
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fbcon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fifo.c18
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_grctx.c46
14 files changed, 143 insertions, 79 deletions
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 72730e9ca06c..21d6c29c2d21 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -10,7 +10,7 @@ config DRM_NOUVEAU
10 select FB 10 select FB
11 select FRAMEBUFFER_CONSOLE if !EMBEDDED 11 select FRAMEBUFFER_CONSOLE if !EMBEDDED
12 select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT 12 select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
13 select ACPI_VIDEO if ACPI 13 select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT
14 help 14 help
15 Choose this option for open-source nVidia support. 15 Choose this option for open-source nVidia support.
16 16
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index e37977d02463..3960d66d7aba 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -121,7 +121,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
121 uint32_t vram_handle, uint32_t gart_handle) 121 uint32_t vram_handle, uint32_t gart_handle)
122{ 122{
123 struct drm_nouveau_private *dev_priv = dev->dev_private; 123 struct drm_nouveau_private *dev_priv = dev->dev_private;
124 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
125 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 124 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
126 struct nouveau_channel *chan; 125 struct nouveau_channel *chan;
127 unsigned long flags; 126 unsigned long flags;
@@ -202,15 +201,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
202 /* disable the fifo caches */ 201 /* disable the fifo caches */
203 pfifo->reassign(dev, false); 202 pfifo->reassign(dev, false);
204 203
205 /* Create a graphics context for new channel */
206 if (dev_priv->card_type < NV_50) {
207 ret = pgraph->create_context(chan);
208 if (ret) {
209 nouveau_channel_put(&chan);
210 return ret;
211 }
212 }
213
214 /* Construct inital RAMFC for new channel */ 204 /* Construct inital RAMFC for new channel */
215 ret = pfifo->create_context(chan); 205 ret = pfifo->create_context(chan);
216 if (ret) { 206 if (ret) {
@@ -253,6 +243,9 @@ nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id)
253 struct nouveau_channel *chan; 243 struct nouveau_channel *chan;
254 unsigned long flags; 244 unsigned long flags;
255 245
246 if (unlikely(id < 0 || id >= NOUVEAU_MAX_CHANNEL_NR))
247 return ERR_PTR(-EINVAL);
248
256 spin_lock_irqsave(&dev_priv->channels.lock, flags); 249 spin_lock_irqsave(&dev_priv->channels.lock, flags);
257 chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]); 250 chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]);
258 spin_unlock_irqrestore(&dev_priv->channels.lock, flags); 251 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
@@ -443,14 +436,20 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
443 else 436 else
444 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; 437 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
445 438
446 init->subchan[0].handle = NvM2MF; 439 if (dev_priv->card_type < NV_C0) {
447 if (dev_priv->card_type < NV_50) 440 init->subchan[0].handle = NvM2MF;
448 init->subchan[0].grclass = 0x0039; 441 if (dev_priv->card_type < NV_50)
449 else 442 init->subchan[0].grclass = 0x0039;
450 init->subchan[0].grclass = 0x5039; 443 else
451 init->subchan[1].handle = NvSw; 444 init->subchan[0].grclass = 0x5039;
452 init->subchan[1].grclass = NV_SW; 445 init->subchan[1].handle = NvSw;
453 init->nr_subchan = 2; 446 init->subchan[1].grclass = NV_SW;
447 init->nr_subchan = 2;
448 } else {
449 init->subchan[0].handle = 0x9039;
450 init->subchan[0].grclass = 0x9039;
451 init->nr_subchan = 1;
452 }
454 453
455 /* Named memory object area */ 454 /* Named memory object area */
456 ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, 455 ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index e59f5bcab1ad..46e32573b3a3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1191,6 +1191,7 @@ extern int nv50_graph_unload_context(struct drm_device *);
1191extern int nv50_grctx_init(struct nouveau_grctx *); 1191extern int nv50_grctx_init(struct nouveau_grctx *);
1192extern void nv50_graph_tlb_flush(struct drm_device *dev); 1192extern void nv50_graph_tlb_flush(struct drm_device *dev);
1193extern void nv86_graph_tlb_flush(struct drm_device *dev); 1193extern void nv86_graph_tlb_flush(struct drm_device *dev);
1194extern struct nouveau_enum nv50_data_error_names[];
1194 1195
1195/* nvc0_graph.c */ 1196/* nvc0_graph.c */
1196extern int nvc0_graph_init(struct drm_device *); 1197extern int nvc0_graph_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 88b2f29ca3e4..221b8462ea37 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -165,7 +165,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
165 if (dev_priv->card_type < NV_C0) 165 if (dev_priv->card_type < NV_C0)
166 BEGIN_RING(chan, NvSubSw, 0x0050, 1); 166 BEGIN_RING(chan, NvSubSw, 0x0050, 1);
167 else 167 else
168 BEGIN_NVC0(chan, 2, NvSubSw, 0x0050, 1); 168 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0050, 1);
169 } else { 169 } else {
170 BEGIN_RING(chan, NvSubSw, 0x0150, 1); 170 BEGIN_RING(chan, NvSubSw, 0x0150, 1);
171 } 171 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index d77b1fcd19d4..30b6544467ca 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -651,7 +651,8 @@ found:
651 } 651 }
652 break; 652 break;
653 case NVOBJ_ENGINE_GR: 653 case NVOBJ_ENGINE_GR:
654 if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { 654 if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) ||
655 (dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) {
655 struct nouveau_pgraph_engine *pgraph = 656 struct nouveau_pgraph_engine *pgraph =
656 &dev_priv->engine.graph; 657 &dev_priv->engine.graph;
657 658
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index d93814160bcf..fb846a3fef15 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -422,8 +422,7 @@ nouveau_hwmon_init(struct drm_device *dev)
422 return ret; 422 return ret;
423 } 423 }
424 dev_set_drvdata(hwmon_dev, dev); 424 dev_set_drvdata(hwmon_dev, dev);
425 ret = sysfs_create_group(&hwmon_dev->kobj, 425 ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup);
426 &hwmon_attrgroup);
427 if (ret) { 426 if (ret) {
428 NV_ERROR(dev, 427 NV_ERROR(dev,
429 "Unable to create hwmon sysfs file: %d\n", ret); 428 "Unable to create hwmon sysfs file: %d\n", ret);
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
index c86e4d4e9b96..49b9a35a9cd6 100644
--- a/drivers/gpu/drm/nouveau/nv40_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv40_fifo.c
@@ -64,7 +64,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
64 NV_PFIFO_CACHE1_BIG_ENDIAN | 64 NV_PFIFO_CACHE1_BIG_ENDIAN |
65#endif 65#endif
66 0x30000000 /* no idea.. */); 66 0x30000000 /* no idea.. */);
67 nv_wi32(dev, fc + 56, chan->ramin_grctx->pinst >> 4);
68 nv_wi32(dev, fc + 60, 0x0001FFFF); 67 nv_wi32(dev, fc + 60, 0x0001FFFF);
69 68
70 /* enable the fifo dma operation */ 69 /* enable the fifo dma operation */
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
index 0618846a97ce..19ef92a0375a 100644
--- a/drivers/gpu/drm/nouveau/nv40_graph.c
+++ b/drivers/gpu/drm/nouveau/nv40_graph.c
@@ -62,6 +62,7 @@ nv40_graph_create_context(struct nouveau_channel *chan)
62 struct drm_nouveau_private *dev_priv = dev->dev_private; 62 struct drm_nouveau_private *dev_priv = dev->dev_private;
63 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; 63 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
64 struct nouveau_grctx ctx = {}; 64 struct nouveau_grctx ctx = {};
65 unsigned long flags;
65 int ret; 66 int ret;
66 67
67 ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, 68 ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16,
@@ -76,6 +77,17 @@ nv40_graph_create_context(struct nouveau_channel *chan)
76 nv40_grctx_init(&ctx); 77 nv40_grctx_init(&ctx);
77 78
78 nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst); 79 nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst);
80
81 /* init grctx pointer in ramfc, and on PFIFO if channel is
82 * already active there
83 */
84 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
85 nv_wo32(chan->ramfc, 0x38, chan->ramin_grctx->pinst >> 4);
86 nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
87 if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id)
88 nv_wr32(dev, 0x0032e0, chan->ramin_grctx->pinst >> 4);
89 nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
90 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
79 return 0; 91 return 0;
80} 92}
81 93
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index c510e74acf4d..2d7ea75a09d4 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -554,13 +554,48 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = {
554}; 554};
555 555
556/* There must be a *lot* of these. Will take some time to gather them up. */ 556/* There must be a *lot* of these. Will take some time to gather them up. */
557static struct nouveau_enum nv50_data_error_names[] = { 557struct nouveau_enum nv50_data_error_names[] = {
558 { 4, "INVALID_VALUE" }, 558 { 0x00000003, "INVALID_QUERY_OR_TEXTURE" },
559 { 5, "INVALID_ENUM" }, 559 { 0x00000004, "INVALID_VALUE" },
560 { 8, "INVALID_OBJECT" }, 560 { 0x00000005, "INVALID_ENUM" },
561 { 0xc, "INVALID_BITFIELD" }, 561 { 0x00000008, "INVALID_OBJECT" },
562 { 0x28, "MP_NO_REG_SPACE" }, 562 { 0x00000009, "READ_ONLY_OBJECT" },
563 { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, 563 { 0x0000000a, "SUPERVISOR_OBJECT" },
564 { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT" },
565 { 0x0000000c, "INVALID_BITFIELD" },
566 { 0x0000000d, "BEGIN_END_ACTIVE" },
567 { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT" },
568 { 0x0000000f, "VIEWPORT_ID_NEEDS_GP" },
569 { 0x00000010, "RT_DOUBLE_BIND" },
570 { 0x00000011, "RT_TYPES_MISMATCH" },
571 { 0x00000012, "RT_LINEAR_WITH_ZETA" },
572 { 0x00000015, "FP_TOO_FEW_REGS" },
573 { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH" },
574 { 0x00000017, "RT_LINEAR_WITH_MSAA" },
575 { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT" },
576 { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT" },
577 { 0x0000001a, "RT_INVALID_ALIGNMENT" },
578 { 0x0000001b, "SAMPLER_OVER_LIMIT" },
579 { 0x0000001c, "TEXTURE_OVER_LIMIT" },
580 { 0x0000001e, "GP_TOO_MANY_OUTPUTS" },
581 { 0x0000001f, "RT_BPP128_WITH_MS8" },
582 { 0x00000021, "Z_OUT_OF_BOUNDS" },
583 { 0x00000023, "XY_OUT_OF_BOUNDS" },
584 { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED" },
585 { 0x00000028, "CP_NO_REG_SPACE_STRIPED" },
586 { 0x00000029, "CP_NO_REG_SPACE_PACKED" },
587 { 0x0000002a, "CP_NOT_ENOUGH_WARPS" },
588 { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH" },
589 { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS" },
590 { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS" },
591 { 0x0000002e, "CP_NO_BLOCKDIM_LATCH" },
592 { 0x00000031, "ENG2D_FORMAT_MISMATCH" },
593 { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP" },
594 { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT" },
595 { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT" },
596 { 0x00000046, "LAYER_ID_NEEDS_GP" },
597 { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT" },
598 { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT" },
564 {} 599 {}
565}; 600};
566 601
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
index cbb4a1ae20b1..fa5d4c234383 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
@@ -200,8 +200,6 @@ nvc0_fbcon_accel_init(struct fb_info *info)
200 return ret; 200 return ret;
201 } 201 }
202 202
203 printk(KERN_ERR "fb vma 0x%010llx\n", nvbo->vma.offset);
204
205 BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1); 203 BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1);
206 OUT_RING (chan, 0x0000902d); 204 OUT_RING (chan, 0x0000902d);
207 BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2); 205 BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2);
diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c
index 82a4ded5dae8..e6f92c541dba 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fifo.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c
@@ -33,6 +33,7 @@ struct nvc0_fifo_priv {
33 struct nouveau_gpuobj *playlist[2]; 33 struct nouveau_gpuobj *playlist[2];
34 int cur_playlist; 34 int cur_playlist;
35 struct nouveau_vma user_vma; 35 struct nouveau_vma user_vma;
36 int spoon_nr;
36}; 37};
37 38
38struct nvc0_fifo_chan { 39struct nvc0_fifo_chan {
@@ -324,13 +325,18 @@ nvc0_fifo_init(struct drm_device *dev)
324 nv_wr32(dev, 0x000204, 0xffffffff); 325 nv_wr32(dev, 0x000204, 0xffffffff);
325 nv_wr32(dev, 0x002204, 0xffffffff); 326 nv_wr32(dev, 0x002204, 0xffffffff);
326 327
328 priv->spoon_nr = hweight32(nv_rd32(dev, 0x002204));
329 NV_DEBUG(dev, "PFIFO: %d subfifo(s)\n", priv->spoon_nr);
330
327 /* assign engines to subfifos */ 331 /* assign engines to subfifos */
328 nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */ 332 if (priv->spoon_nr >= 3) {
329 nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */ 333 nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */
330 nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */ 334 nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */
331 nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */ 335 nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */
332 nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */ 336 nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */
333 nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */ 337 nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */
338 nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */
339 }
334 340
335 /* PSUBFIFO[n] */ 341 /* PSUBFIFO[n] */
336 for (i = 0; i < 3; i++) { 342 for (i = 0; i < 3; i++) {
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
index cf2f6aa920b4..5feacd5d5fa4 100644
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
@@ -244,7 +244,6 @@ nvc0_graph_load_context(struct nouveau_channel *chan)
244 if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) 244 if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
245 NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); 245 NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
246 246
247 printk(KERN_ERR "load_ctx 0x%08x\n", nv_rd32(dev, 0x409b00));
248 return 0; 247 return 0;
249} 248}
250 249
@@ -334,8 +333,6 @@ nvc0_graph_create(struct drm_device *dev)
334 case 0xc0: 333 case 0xc0:
335 if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ 334 if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
336 priv->magic_not_rop_nr = 0x07; 335 priv->magic_not_rop_nr = 0x07;
337 priv->magic419bd0 = 0x0a360000;
338 priv->magic419be4 = 0x04c33a54;
339 /* filled values up to tp_total, the rest 0 */ 336 /* filled values up to tp_total, the rest 0 */
340 priv->magicgpc980[0] = 0x22111000; 337 priv->magicgpc980[0] = 0x22111000;
341 priv->magicgpc980[1] = 0x00000233; 338 priv->magicgpc980[1] = 0x00000233;
@@ -345,8 +342,6 @@ nvc0_graph_create(struct drm_device *dev)
345 } else 342 } else
346 if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ 343 if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
347 priv->magic_not_rop_nr = 0x05; 344 priv->magic_not_rop_nr = 0x05;
348 priv->magic419bd0 = 0x043c0000;
349 priv->magic419be4 = 0x09041208;
350 priv->magicgpc980[0] = 0x11110000; 345 priv->magicgpc980[0] = 0x11110000;
351 priv->magicgpc980[1] = 0x00233222; 346 priv->magicgpc980[1] = 0x00233222;
352 priv->magicgpc980[2] = 0x00000000; 347 priv->magicgpc980[2] = 0x00000000;
@@ -355,8 +350,6 @@ nvc0_graph_create(struct drm_device *dev)
355 } else 350 } else
356 if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ 351 if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
357 priv->magic_not_rop_nr = 0x06; 352 priv->magic_not_rop_nr = 0x06;
358 priv->magic419bd0 = 0x023e0000;
359 priv->magic419be4 = 0x10414104;
360 priv->magicgpc980[0] = 0x11110000; 353 priv->magicgpc980[0] = 0x11110000;
361 priv->magicgpc980[1] = 0x03332222; 354 priv->magicgpc980[1] = 0x03332222;
362 priv->magicgpc980[2] = 0x00000000; 355 priv->magicgpc980[2] = 0x00000000;
@@ -366,8 +359,6 @@ nvc0_graph_create(struct drm_device *dev)
366 break; 359 break;
367 case 0xc3: /* 450, 4/0/0/0, 2 */ 360 case 0xc3: /* 450, 4/0/0/0, 2 */
368 priv->magic_not_rop_nr = 0x03; 361 priv->magic_not_rop_nr = 0x03;
369 priv->magic419bd0 = 0x00500000;
370 priv->magic419be4 = 0x00000000;
371 priv->magicgpc980[0] = 0x00003210; 362 priv->magicgpc980[0] = 0x00003210;
372 priv->magicgpc980[1] = 0x00000000; 363 priv->magicgpc980[1] = 0x00000000;
373 priv->magicgpc980[2] = 0x00000000; 364 priv->magicgpc980[2] = 0x00000000;
@@ -376,8 +367,6 @@ nvc0_graph_create(struct drm_device *dev)
376 break; 367 break;
377 case 0xc4: /* 460, 3/4/0/0, 4 */ 368 case 0xc4: /* 460, 3/4/0/0, 4 */
378 priv->magic_not_rop_nr = 0x01; 369 priv->magic_not_rop_nr = 0x01;
379 priv->magic419bd0 = 0x045c0000;
380 priv->magic419be4 = 0x09041208;
381 priv->magicgpc980[0] = 0x02321100; 370 priv->magicgpc980[0] = 0x02321100;
382 priv->magicgpc980[1] = 0x00000000; 371 priv->magicgpc980[1] = 0x00000000;
383 priv->magicgpc980[2] = 0x00000000; 372 priv->magicgpc980[2] = 0x00000000;
@@ -386,14 +375,12 @@ nvc0_graph_create(struct drm_device *dev)
386 break; 375 break;
387 } 376 }
388 377
389 if (!priv->magic419bd0) { 378 if (!priv->magic_not_rop_nr) {
390 NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", 379 NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
391 priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], 380 priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
392 priv->tp_nr[3], priv->rop_nr); 381 priv->tp_nr[3], priv->rop_nr);
393 /* use 0xc3's values... */ 382 /* use 0xc3's values... */
394 priv->magic_not_rop_nr = 0x03; 383 priv->magic_not_rop_nr = 0x03;
395 priv->magic419bd0 = 0x00500000;
396 priv->magic419be4 = 0x00000000;
397 priv->magicgpc980[0] = 0x00003210; 384 priv->magicgpc980[0] = 0x00003210;
398 priv->magicgpc980[1] = 0x00000000; 385 priv->magicgpc980[1] = 0x00000000;
399 priv->magicgpc980[2] = 0x00000000; 386 priv->magicgpc980[2] = 0x00000000;
@@ -597,7 +584,7 @@ nvc0_graph_init_ctxctl(struct drm_device *dev)
597 r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); 584 r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
598 ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d"); 585 ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d");
599 if (ret == 0) 586 if (ret == 0)
600 nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad"); 587 ret = nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad");
601 nv_wr32(dev, 0x000260, r000260); 588 nv_wr32(dev, 0x000260, r000260);
602 589
603 if (ret) 590 if (ret)
@@ -699,18 +686,11 @@ nvc0_graph_init(struct drm_device *dev)
699 nv_wr32(dev, 0x400054, 0x34ce3464); 686 nv_wr32(dev, 0x400054, 0x34ce3464);
700 687
701 ret = nvc0_graph_init_ctxctl(dev); 688 ret = nvc0_graph_init_ctxctl(dev);
702 if (ret) 689 if (ret == 0)
703 return ret; 690 dev_priv->engine.graph.accel_blocked = false;
704
705 dev_priv->engine.graph.accel_blocked = false;
706 return 0; 691 return 0;
707} 692}
708 693
709static struct nouveau_enum nvc0_graph_data_error[] = {
710 { 5, "INVALID_ENUM" },
711 {}
712};
713
714static int 694static int
715nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) 695nvc0_graph_isr_chid(struct drm_device *dev, u64 inst)
716{ 696{
@@ -753,9 +733,17 @@ nvc0_graph_isr(struct drm_device *dev)
753 stat &= ~0x00000010; 733 stat &= ~0x00000010;
754 } 734 }
755 735
736 if (stat & 0x00000020) {
737 NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
738 "class 0x%04x mthd 0x%04x data 0x%08x\n",
739 chid, inst, subc, class, mthd, data);
740 nv_wr32(dev, 0x400100, 0x00000020);
741 stat &= ~0x00000020;
742 }
743
756 if (stat & 0x00100000) { 744 if (stat & 0x00100000) {
757 NV_INFO(dev, "PGRAPH: DATA_ERROR ["); 745 NV_INFO(dev, "PGRAPH: DATA_ERROR [");
758 nouveau_enum_print(nvc0_graph_data_error, code); 746 nouveau_enum_print(nv50_data_error_names, code);
759 printk("] ch %d [0x%010llx] subc %d class 0x%04x " 747 printk("] ch %d [0x%010llx] subc %d class 0x%04x "
760 "mthd 0x%04x data 0x%08x\n", 748 "mthd 0x%04x data 0x%08x\n",
761 chid, inst, subc, class, mthd, data); 749 chid, inst, subc, class, mthd, data);
@@ -763,6 +751,14 @@ nvc0_graph_isr(struct drm_device *dev)
763 stat &= ~0x00100000; 751 stat &= ~0x00100000;
764 } 752 }
765 753
754 if (stat & 0x00200000) {
755 u32 trap = nv_rd32(dev, 0x400108);
756 NV_INFO(dev, "PGRAPH: TRAP ch %d status 0x%08x\n", chid, trap);
757 nv_wr32(dev, 0x400108, trap);
758 nv_wr32(dev, 0x400100, 0x00200000);
759 stat &= ~0x00200000;
760 }
761
766 if (stat & 0x00080000) { 762 if (stat & 0x00080000) {
767 u32 ustat = nv_rd32(dev, 0x409c18); 763 u32 ustat = nv_rd32(dev, 0x409c18);
768 764
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h
index 1e1f24f3fd34..40e26f9c56c4 100644
--- a/drivers/gpu/drm/nouveau/nvc0_graph.h
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.h
@@ -46,8 +46,6 @@ struct nvc0_graph_priv {
46 struct nouveau_gpuobj *unk4188b8; 46 struct nouveau_gpuobj *unk4188b8;
47 47
48 u8 magic_not_rop_nr; 48 u8 magic_not_rop_nr;
49 u32 magic419bd0;
50 u32 magic419be4;
51 u32 magicgpc980[4]; 49 u32 magicgpc980[4];
52 u32 magicgpc918; 50 u32 magicgpc918;
53}; 51};
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c
index 88fa6211ac19..b9e68b2d30aa 100644
--- a/drivers/gpu/drm/nouveau/nvc0_grctx.c
+++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c
@@ -1557,7 +1557,7 @@ nvc0_grctx_generate_unk47xx(struct drm_device *dev)
1557} 1557}
1558 1558
1559static void 1559static void
1560nvc0_grctx_generate_unk58xx(struct drm_device *dev) 1560nvc0_grctx_generate_shaders(struct drm_device *dev)
1561{ 1561{
1562 nv_wr32(dev, 0x405800, 0x078000bf); 1562 nv_wr32(dev, 0x405800, 0x078000bf);
1563 nv_wr32(dev, 0x405830, 0x02180000); 1563 nv_wr32(dev, 0x405830, 0x02180000);
@@ -1593,7 +1593,7 @@ nvc0_grctx_generate_unk64xx(struct drm_device *dev)
1593} 1593}
1594 1594
1595static void 1595static void
1596nvc0_grctx_generate_unk78xx(struct drm_device *dev) 1596nvc0_grctx_generate_tpbus(struct drm_device *dev)
1597{ 1597{
1598 nv_wr32(dev, 0x407804, 0x00000023); 1598 nv_wr32(dev, 0x407804, 0x00000023);
1599 nv_wr32(dev, 0x40780c, 0x0a418820); 1599 nv_wr32(dev, 0x40780c, 0x0a418820);
@@ -1606,7 +1606,7 @@ nvc0_grctx_generate_unk78xx(struct drm_device *dev)
1606} 1606}
1607 1607
1608static void 1608static void
1609nvc0_grctx_generate_unk80xx(struct drm_device *dev) 1609nvc0_grctx_generate_ccache(struct drm_device *dev)
1610{ 1610{
1611 nv_wr32(dev, 0x408000, 0x00000000); 1611 nv_wr32(dev, 0x408000, 0x00000000);
1612 nv_wr32(dev, 0x408004, 0x00000000); 1612 nv_wr32(dev, 0x408004, 0x00000000);
@@ -1801,7 +1801,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1801 struct nvc0_graph_chan *grch = chan->pgraph_ctx; 1801 struct nvc0_graph_chan *grch = chan->pgraph_ctx;
1802 struct drm_device *dev = chan->dev; 1802 struct drm_device *dev = chan->dev;
1803 int i, gpc, tp, id; 1803 int i, gpc, tp, id;
1804 u32 r000260; 1804 u32 r000260, tmp;
1805 1805
1806 r000260 = nv_rd32(dev, 0x000260); 1806 r000260 = nv_rd32(dev, 0x000260);
1807 nv_wr32(dev, 0x000260, r000260 & ~1); 1807 nv_wr32(dev, 0x000260, r000260 & ~1);
@@ -1811,11 +1811,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1811 nvc0_grctx_generate_macro(dev); 1811 nvc0_grctx_generate_macro(dev);
1812 nvc0_grctx_generate_m2mf(dev); 1812 nvc0_grctx_generate_m2mf(dev);
1813 nvc0_grctx_generate_unk47xx(dev); 1813 nvc0_grctx_generate_unk47xx(dev);
1814 nvc0_grctx_generate_unk58xx(dev); 1814 nvc0_grctx_generate_shaders(dev);
1815 nvc0_grctx_generate_unk60xx(dev); 1815 nvc0_grctx_generate_unk60xx(dev);
1816 nvc0_grctx_generate_unk64xx(dev); 1816 nvc0_grctx_generate_unk64xx(dev);
1817 nvc0_grctx_generate_unk78xx(dev); 1817 nvc0_grctx_generate_tpbus(dev);
1818 nvc0_grctx_generate_unk80xx(dev); 1818 nvc0_grctx_generate_ccache(dev);
1819 nvc0_grctx_generate_rop(dev); 1819 nvc0_grctx_generate_rop(dev);
1820 nvc0_grctx_generate_gpc(dev); 1820 nvc0_grctx_generate_gpc(dev);
1821 nvc0_grctx_generate_tp(dev); 1821 nvc0_grctx_generate_tp(dev);
@@ -1843,8 +1843,12 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1843 } 1843 }
1844 } 1844 }
1845 1845
1846 nv_wr32(dev, 0x406028, 0x00000443); 1846 tmp = 0;
1847 nv_wr32(dev, 0x405870, 0x00000443); 1847 for (i = 0; i < priv->gpc_nr; i++)
1848 tmp |= priv->tp_nr[i] << (i * 4);
1849 nv_wr32(dev, 0x406028, tmp);
1850 nv_wr32(dev, 0x405870, tmp);
1851
1848 nv_wr32(dev, 0x40602c, 0x00000000); 1852 nv_wr32(dev, 0x40602c, 0x00000000);
1849 nv_wr32(dev, 0x405874, 0x00000000); 1853 nv_wr32(dev, 0x405874, 0x00000000);
1850 nv_wr32(dev, 0x406030, 0x00000000); 1854 nv_wr32(dev, 0x406030, 0x00000000);
@@ -1875,9 +1879,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1875 } 1879 }
1876 1880
1877 if (1) { 1881 if (1) {
1878 u32 data[6] = {}; 1882 u32 data[6] = {}, data2[2] = {};
1879 u8 tpnr[GPC_MAX]; 1883 u8 tpnr[GPC_MAX];
1884 u8 shift, ntpcv;
1880 1885
1886 /* calculate first set of magics */
1881 memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); 1887 memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
1882 1888
1883 for (tp = 0; tp < priv->tp_total; tp++) { 1889 for (tp = 0; tp < priv->tp_total; tp++) {
@@ -1892,6 +1898,20 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1892 for (; tp < 32; tp++) 1898 for (; tp < 32; tp++)
1893 data[tp / 6] |= 7 << ((tp % 6) * 5); 1899 data[tp / 6] |= 7 << ((tp % 6) * 5);
1894 1900
1901 /* and the second... */
1902 shift = 0;
1903 ntpcv = priv->tp_total;
1904 while (!(ntpcv & (1 << 4))) {
1905 ntpcv <<= 1;
1906 shift++;
1907 }
1908
1909 data2[0] = (ntpcv << 16);
1910 data2[0] |= (shift << 21);
1911 data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
1912 for (i = 1; i < 7; i++)
1913 data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
1914
1895 // GPC_BROADCAST 1915 // GPC_BROADCAST
1896 nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | 1916 nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) |
1897 priv->magic_not_rop_nr); 1917 priv->magic_not_rop_nr);
@@ -1900,9 +1920,9 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
1900 1920
1901 // GPC_BROADCAST.TP_BROADCAST 1921 // GPC_BROADCAST.TP_BROADCAST
1902 nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | 1922 nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) |
1903 priv->magic_not_rop_nr | 1923 priv->magic_not_rop_nr |
1904 priv->magic419bd0); 1924 data2[0]);
1905 nv_wr32(dev, 0x419be4, priv->magic419be4); 1925 nv_wr32(dev, 0x419be4, data2[1]);
1906 for (i = 0; i < 6; i++) 1926 for (i = 0; i < 6; i++)
1907 nv_wr32(dev, 0x419b00 + (i * 4), data[i]); 1927 nv_wr32(dev, 0x419b00 + (i * 4), data[i]);
1908 1928