diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 35 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv40_fifo.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv40_graph.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_graph.c | 49 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_fbcon.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_fifo.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_graph.c | 46 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_graph.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_grctx.c | 46 |
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 *); | |||
| 1191 | extern int nv50_grctx_init(struct nouveau_grctx *); | 1191 | extern int nv50_grctx_init(struct nouveau_grctx *); |
| 1192 | extern void nv50_graph_tlb_flush(struct drm_device *dev); | 1192 | extern void nv50_graph_tlb_flush(struct drm_device *dev); |
| 1193 | extern void nv86_graph_tlb_flush(struct drm_device *dev); | 1193 | extern void nv86_graph_tlb_flush(struct drm_device *dev); |
| 1194 | extern struct nouveau_enum nv50_data_error_names[]; | ||
| 1194 | 1195 | ||
| 1195 | /* nvc0_graph.c */ | 1196 | /* nvc0_graph.c */ |
| 1196 | extern int nvc0_graph_init(struct drm_device *); | 1197 | extern 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. */ |
| 557 | static struct nouveau_enum nv50_data_error_names[] = { | 557 | struct 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 | ||
| 38 | struct nvc0_fifo_chan { | 39 | struct 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 | ||
| 709 | static struct nouveau_enum nvc0_graph_data_error[] = { | ||
| 710 | { 5, "INVALID_ENUM" }, | ||
| 711 | {} | ||
| 712 | }; | ||
| 713 | |||
| 714 | static int | 694 | static int |
| 715 | nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) | 695 | nvc0_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 | ||
| 1559 | static void | 1559 | static void |
| 1560 | nvc0_grctx_generate_unk58xx(struct drm_device *dev) | 1560 | nvc0_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 | ||
| 1595 | static void | 1595 | static void |
| 1596 | nvc0_grctx_generate_unk78xx(struct drm_device *dev) | 1596 | nvc0_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 | ||
| 1608 | static void | 1608 | static void |
| 1609 | nvc0_grctx_generate_unk80xx(struct drm_device *dev) | 1609 | nvc0_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 | ||
