Commit 7ad7f87b authored by Dave Airlie's avatar Dave Airlie

Merge remote branch 'nouveau/drm-nouveau-next' of ../drm-nouveau-next into drm-core-next

* 'nouveau/drm-nouveau-next' of ../drm-nouveau-next:
  drm/nouveau: fix hwmon device binding
  drm/nouveau: create grctx on the fly on all chipsets
  drm/nvc0: fix init without firmware present
  drm/nvc0/pgraph: fix 0x406028/0x405870 init
  drm/nvc0/pgraph: more unit names
  drm/nvc0/pfifo: support for chipsets with only one PSUBFIFO (0xc1)
  drm/nvc0: reserve only subc 0 for kernel use
  drm/nv50: sync up gr data error names with rnn, use for nvc0 also
  drm/nvc0: parse a couple more PGRAPH_INTR
  drm/nvc0: nuke left-over debug messages
  drm/nvc0: kill off a couple more magics
  drm/nouveau: Validate channel indices passed from userspace.
  drm/nouveau: Only select ACPI_VIDEO if its dependencies are met
parents fea6f330 07cfe0e7
...@@ -10,7 +10,7 @@ config DRM_NOUVEAU ...@@ -10,7 +10,7 @@ config DRM_NOUVEAU
select FB select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED select FRAMEBUFFER_CONSOLE if !EMBEDDED
select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
select ACPI_VIDEO if ACPI select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT
help help
Choose this option for open-source nVidia support. Choose this option for open-source nVidia support.
......
...@@ -121,7 +121,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ...@@ -121,7 +121,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
uint32_t vram_handle, uint32_t gart_handle) uint32_t vram_handle, uint32_t gart_handle)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_channel *chan; struct nouveau_channel *chan;
unsigned long flags; unsigned long flags;
...@@ -202,15 +201,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ...@@ -202,15 +201,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
/* disable the fifo caches */ /* disable the fifo caches */
pfifo->reassign(dev, false); pfifo->reassign(dev, false);
/* Create a graphics context for new channel */
if (dev_priv->card_type < NV_50) {
ret = pgraph->create_context(chan);
if (ret) {
nouveau_channel_put(&chan);
return ret;
}
}
/* Construct inital RAMFC for new channel */ /* Construct inital RAMFC for new channel */
ret = pfifo->create_context(chan); ret = pfifo->create_context(chan);
if (ret) { if (ret) {
...@@ -253,6 +243,9 @@ nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) ...@@ -253,6 +243,9 @@ nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id)
struct nouveau_channel *chan; struct nouveau_channel *chan;
unsigned long flags; unsigned long flags;
if (unlikely(id < 0 || id >= NOUVEAU_MAX_CHANNEL_NR))
return ERR_PTR(-EINVAL);
spin_lock_irqsave(&dev_priv->channels.lock, flags); spin_lock_irqsave(&dev_priv->channels.lock, flags);
chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]); chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]);
spin_unlock_irqrestore(&dev_priv->channels.lock, flags); spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
...@@ -443,14 +436,20 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, ...@@ -443,14 +436,20 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
else else
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
init->subchan[0].handle = NvM2MF; if (dev_priv->card_type < NV_C0) {
if (dev_priv->card_type < NV_50) init->subchan[0].handle = NvM2MF;
init->subchan[0].grclass = 0x0039; if (dev_priv->card_type < NV_50)
else init->subchan[0].grclass = 0x0039;
init->subchan[0].grclass = 0x5039; else
init->subchan[1].handle = NvSw; init->subchan[0].grclass = 0x5039;
init->subchan[1].grclass = NV_SW; init->subchan[1].handle = NvSw;
init->nr_subchan = 2; init->subchan[1].grclass = NV_SW;
init->nr_subchan = 2;
} else {
init->subchan[0].handle = 0x9039;
init->subchan[0].grclass = 0x9039;
init->nr_subchan = 1;
}
/* Named memory object area */ /* Named memory object area */
ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
......
...@@ -1191,6 +1191,7 @@ extern int nv50_graph_unload_context(struct drm_device *); ...@@ -1191,6 +1191,7 @@ extern int nv50_graph_unload_context(struct drm_device *);
extern int nv50_grctx_init(struct nouveau_grctx *); extern int nv50_grctx_init(struct nouveau_grctx *);
extern void nv50_graph_tlb_flush(struct drm_device *dev); extern void nv50_graph_tlb_flush(struct drm_device *dev);
extern void nv86_graph_tlb_flush(struct drm_device *dev); extern void nv86_graph_tlb_flush(struct drm_device *dev);
extern struct nouveau_enum nv50_data_error_names[];
/* nvc0_graph.c */ /* nvc0_graph.c */
extern int nvc0_graph_init(struct drm_device *); extern int nvc0_graph_init(struct drm_device *);
......
...@@ -165,7 +165,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) ...@@ -165,7 +165,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
if (dev_priv->card_type < NV_C0) if (dev_priv->card_type < NV_C0)
BEGIN_RING(chan, NvSubSw, 0x0050, 1); BEGIN_RING(chan, NvSubSw, 0x0050, 1);
else else
BEGIN_NVC0(chan, 2, NvSubSw, 0x0050, 1); BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0050, 1);
} else { } else {
BEGIN_RING(chan, NvSubSw, 0x0150, 1); BEGIN_RING(chan, NvSubSw, 0x0150, 1);
} }
......
...@@ -651,7 +651,8 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) ...@@ -651,7 +651,8 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
} }
break; break;
case NVOBJ_ENGINE_GR: case NVOBJ_ENGINE_GR:
if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) ||
(dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) {
struct nouveau_pgraph_engine *pgraph = struct nouveau_pgraph_engine *pgraph =
&dev_priv->engine.graph; &dev_priv->engine.graph;
......
...@@ -422,8 +422,7 @@ nouveau_hwmon_init(struct drm_device *dev) ...@@ -422,8 +422,7 @@ nouveau_hwmon_init(struct drm_device *dev)
return ret; return ret;
} }
dev_set_drvdata(hwmon_dev, dev); dev_set_drvdata(hwmon_dev, dev);
ret = sysfs_create_group(&hwmon_dev->kobj, ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup);
&hwmon_attrgroup);
if (ret) { if (ret) {
NV_ERROR(dev, NV_ERROR(dev,
"Unable to create hwmon sysfs file: %d\n", ret); "Unable to create hwmon sysfs file: %d\n", ret);
......
...@@ -64,7 +64,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) ...@@ -64,7 +64,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
NV_PFIFO_CACHE1_BIG_ENDIAN | NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif #endif
0x30000000 /* no idea.. */); 0x30000000 /* no idea.. */);
nv_wi32(dev, fc + 56, chan->ramin_grctx->pinst >> 4);
nv_wi32(dev, fc + 60, 0x0001FFFF); nv_wi32(dev, fc + 60, 0x0001FFFF);
/* enable the fifo dma operation */ /* enable the fifo dma operation */
......
...@@ -62,6 +62,7 @@ nv40_graph_create_context(struct nouveau_channel *chan) ...@@ -62,6 +62,7 @@ nv40_graph_create_context(struct nouveau_channel *chan)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_grctx ctx = {}; struct nouveau_grctx ctx = {};
unsigned long flags;
int ret; int ret;
ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16,
...@@ -76,6 +77,17 @@ nv40_graph_create_context(struct nouveau_channel *chan) ...@@ -76,6 +77,17 @@ nv40_graph_create_context(struct nouveau_channel *chan)
nv40_grctx_init(&ctx); nv40_grctx_init(&ctx);
nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst); nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst);
/* init grctx pointer in ramfc, and on PFIFO if channel is
* already active there
*/
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
nv_wo32(chan->ramfc, 0x38, chan->ramin_grctx->pinst >> 4);
nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id)
nv_wr32(dev, 0x0032e0, chan->ramin_grctx->pinst >> 4);
nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
return 0; return 0;
} }
......
...@@ -554,13 +554,48 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = { ...@@ -554,13 +554,48 @@ static struct nouveau_bitfield nv50_graph_trap_ccache[] = {
}; };
/* There must be a *lot* of these. Will take some time to gather them up. */ /* There must be a *lot* of these. Will take some time to gather them up. */
static struct nouveau_enum nv50_data_error_names[] = { struct nouveau_enum nv50_data_error_names[] = {
{ 4, "INVALID_VALUE" }, { 0x00000003, "INVALID_QUERY_OR_TEXTURE" },
{ 5, "INVALID_ENUM" }, { 0x00000004, "INVALID_VALUE" },
{ 8, "INVALID_OBJECT" }, { 0x00000005, "INVALID_ENUM" },
{ 0xc, "INVALID_BITFIELD" }, { 0x00000008, "INVALID_OBJECT" },
{ 0x28, "MP_NO_REG_SPACE" }, { 0x00000009, "READ_ONLY_OBJECT" },
{ 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, { 0x0000000a, "SUPERVISOR_OBJECT" },
{ 0x0000000b, "INVALID_ADDRESS_ALIGNMENT" },
{ 0x0000000c, "INVALID_BITFIELD" },
{ 0x0000000d, "BEGIN_END_ACTIVE" },
{ 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT" },
{ 0x0000000f, "VIEWPORT_ID_NEEDS_GP" },
{ 0x00000010, "RT_DOUBLE_BIND" },
{ 0x00000011, "RT_TYPES_MISMATCH" },
{ 0x00000012, "RT_LINEAR_WITH_ZETA" },
{ 0x00000015, "FP_TOO_FEW_REGS" },
{ 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH" },
{ 0x00000017, "RT_LINEAR_WITH_MSAA" },
{ 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT" },
{ 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT" },
{ 0x0000001a, "RT_INVALID_ALIGNMENT" },
{ 0x0000001b, "SAMPLER_OVER_LIMIT" },
{ 0x0000001c, "TEXTURE_OVER_LIMIT" },
{ 0x0000001e, "GP_TOO_MANY_OUTPUTS" },
{ 0x0000001f, "RT_BPP128_WITH_MS8" },
{ 0x00000021, "Z_OUT_OF_BOUNDS" },
{ 0x00000023, "XY_OUT_OF_BOUNDS" },
{ 0x00000027, "CP_MORE_PARAMS_THAN_SHARED" },
{ 0x00000028, "CP_NO_REG_SPACE_STRIPED" },
{ 0x00000029, "CP_NO_REG_SPACE_PACKED" },
{ 0x0000002a, "CP_NOT_ENOUGH_WARPS" },
{ 0x0000002b, "CP_BLOCK_SIZE_MISMATCH" },
{ 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS" },
{ 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS" },
{ 0x0000002e, "CP_NO_BLOCKDIM_LATCH" },
{ 0x00000031, "ENG2D_FORMAT_MISMATCH" },
{ 0x0000003f, "PRIMITIVE_ID_NEEDS_GP" },
{ 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT" },
{ 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT" },
{ 0x00000046, "LAYER_ID_NEEDS_GP" },
{ 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT" },
{ 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT" },
{} {}
}; };
......
...@@ -200,8 +200,6 @@ nvc0_fbcon_accel_init(struct fb_info *info) ...@@ -200,8 +200,6 @@ nvc0_fbcon_accel_init(struct fb_info *info)
return ret; return ret;
} }
printk(KERN_ERR "fb vma 0x%010llx\n", nvbo->vma.offset);
BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1); BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1);
OUT_RING (chan, 0x0000902d); OUT_RING (chan, 0x0000902d);
BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2); BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2);
......
...@@ -33,6 +33,7 @@ struct nvc0_fifo_priv { ...@@ -33,6 +33,7 @@ struct nvc0_fifo_priv {
struct nouveau_gpuobj *playlist[2]; struct nouveau_gpuobj *playlist[2];
int cur_playlist; int cur_playlist;
struct nouveau_vma user_vma; struct nouveau_vma user_vma;
int spoon_nr;
}; };
struct nvc0_fifo_chan { struct nvc0_fifo_chan {
...@@ -324,13 +325,18 @@ nvc0_fifo_init(struct drm_device *dev) ...@@ -324,13 +325,18 @@ nvc0_fifo_init(struct drm_device *dev)
nv_wr32(dev, 0x000204, 0xffffffff); nv_wr32(dev, 0x000204, 0xffffffff);
nv_wr32(dev, 0x002204, 0xffffffff); nv_wr32(dev, 0x002204, 0xffffffff);
priv->spoon_nr = hweight32(nv_rd32(dev, 0x002204));
NV_DEBUG(dev, "PFIFO: %d subfifo(s)\n", priv->spoon_nr);
/* assign engines to subfifos */ /* assign engines to subfifos */
nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */ if (priv->spoon_nr >= 3) {
nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */ nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */
nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */ nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */
nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */ nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */
nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */ nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */
nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */ nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */
nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */
}
/* PSUBFIFO[n] */ /* PSUBFIFO[n] */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
......
...@@ -244,7 +244,6 @@ nvc0_graph_load_context(struct nouveau_channel *chan) ...@@ -244,7 +244,6 @@ nvc0_graph_load_context(struct nouveau_channel *chan)
if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
printk(KERN_ERR "load_ctx 0x%08x\n", nv_rd32(dev, 0x409b00));
return 0; return 0;
} }
...@@ -334,8 +333,6 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -334,8 +333,6 @@ nvc0_graph_create(struct drm_device *dev)
case 0xc0: case 0xc0:
if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
priv->magic_not_rop_nr = 0x07; priv->magic_not_rop_nr = 0x07;
priv->magic419bd0 = 0x0a360000;
priv->magic419be4 = 0x04c33a54;
/* filled values up to tp_total, the rest 0 */ /* filled values up to tp_total, the rest 0 */
priv->magicgpc980[0] = 0x22111000; priv->magicgpc980[0] = 0x22111000;
priv->magicgpc980[1] = 0x00000233; priv->magicgpc980[1] = 0x00000233;
...@@ -345,8 +342,6 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -345,8 +342,6 @@ nvc0_graph_create(struct drm_device *dev)
} else } else
if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
priv->magic_not_rop_nr = 0x05; priv->magic_not_rop_nr = 0x05;
priv->magic419bd0 = 0x043c0000;
priv->magic419be4 = 0x09041208;
priv->magicgpc980[0] = 0x11110000; priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x00233222; priv->magicgpc980[1] = 0x00233222;
priv->magicgpc980[2] = 0x00000000; priv->magicgpc980[2] = 0x00000000;
...@@ -355,8 +350,6 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -355,8 +350,6 @@ nvc0_graph_create(struct drm_device *dev)
} else } else
if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
priv->magic_not_rop_nr = 0x06; priv->magic_not_rop_nr = 0x06;
priv->magic419bd0 = 0x023e0000;
priv->magic419be4 = 0x10414104;
priv->magicgpc980[0] = 0x11110000; priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x03332222; priv->magicgpc980[1] = 0x03332222;
priv->magicgpc980[2] = 0x00000000; priv->magicgpc980[2] = 0x00000000;
...@@ -366,8 +359,6 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -366,8 +359,6 @@ nvc0_graph_create(struct drm_device *dev)
break; break;
case 0xc3: /* 450, 4/0/0/0, 2 */ case 0xc3: /* 450, 4/0/0/0, 2 */
priv->magic_not_rop_nr = 0x03; priv->magic_not_rop_nr = 0x03;
priv->magic419bd0 = 0x00500000;
priv->magic419be4 = 0x00000000;
priv->magicgpc980[0] = 0x00003210; priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000; priv->magicgpc980[2] = 0x00000000;
...@@ -376,8 +367,6 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -376,8 +367,6 @@ nvc0_graph_create(struct drm_device *dev)
break; break;
case 0xc4: /* 460, 3/4/0/0, 4 */ case 0xc4: /* 460, 3/4/0/0, 4 */
priv->magic_not_rop_nr = 0x01; priv->magic_not_rop_nr = 0x01;
priv->magic419bd0 = 0x045c0000;
priv->magic419be4 = 0x09041208;
priv->magicgpc980[0] = 0x02321100; priv->magicgpc980[0] = 0x02321100;
priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000; priv->magicgpc980[2] = 0x00000000;
...@@ -386,14 +375,12 @@ nvc0_graph_create(struct drm_device *dev) ...@@ -386,14 +375,12 @@ nvc0_graph_create(struct drm_device *dev)
break; break;
} }
if (!priv->magic419bd0) { if (!priv->magic_not_rop_nr) {
NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
priv->tp_nr[3], priv->rop_nr); priv->tp_nr[3], priv->rop_nr);
/* use 0xc3's values... */ /* use 0xc3's values... */
priv->magic_not_rop_nr = 0x03; priv->magic_not_rop_nr = 0x03;
priv->magic419bd0 = 0x00500000;
priv->magic419be4 = 0x00000000;
priv->magicgpc980[0] = 0x00003210; priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000; priv->magicgpc980[2] = 0x00000000;
...@@ -597,7 +584,7 @@ nvc0_graph_init_ctxctl(struct drm_device *dev) ...@@ -597,7 +584,7 @@ nvc0_graph_init_ctxctl(struct drm_device *dev)
r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d"); ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d");
if (ret == 0) if (ret == 0)
nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad"); ret = nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad");
nv_wr32(dev, 0x000260, r000260); nv_wr32(dev, 0x000260, r000260);
if (ret) if (ret)
...@@ -699,18 +686,11 @@ nvc0_graph_init(struct drm_device *dev) ...@@ -699,18 +686,11 @@ nvc0_graph_init(struct drm_device *dev)
nv_wr32(dev, 0x400054, 0x34ce3464); nv_wr32(dev, 0x400054, 0x34ce3464);
ret = nvc0_graph_init_ctxctl(dev); ret = nvc0_graph_init_ctxctl(dev);
if (ret) if (ret == 0)
return ret; dev_priv->engine.graph.accel_blocked = false;
dev_priv->engine.graph.accel_blocked = false;
return 0; return 0;
} }
static struct nouveau_enum nvc0_graph_data_error[] = {
{ 5, "INVALID_ENUM" },
{}
};
static int static int
nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) nvc0_graph_isr_chid(struct drm_device *dev, u64 inst)
{ {
...@@ -753,9 +733,17 @@ nvc0_graph_isr(struct drm_device *dev) ...@@ -753,9 +733,17 @@ nvc0_graph_isr(struct drm_device *dev)
stat &= ~0x00000010; stat &= ~0x00000010;
} }
if (stat & 0x00000020) {
NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
"class 0x%04x mthd 0x%04x data 0x%08x\n",
chid, inst, subc, class, mthd, data);
nv_wr32(dev, 0x400100, 0x00000020);
stat &= ~0x00000020;
}
if (stat & 0x00100000) { if (stat & 0x00100000) {
NV_INFO(dev, "PGRAPH: DATA_ERROR ["); NV_INFO(dev, "PGRAPH: DATA_ERROR [");
nouveau_enum_print(nvc0_graph_data_error, code); nouveau_enum_print(nv50_data_error_names, code);
printk("] ch %d [0x%010llx] subc %d class 0x%04x " printk("] ch %d [0x%010llx] subc %d class 0x%04x "
"mthd 0x%04x data 0x%08x\n", "mthd 0x%04x data 0x%08x\n",
chid, inst, subc, class, mthd, data); chid, inst, subc, class, mthd, data);
...@@ -763,6 +751,14 @@ nvc0_graph_isr(struct drm_device *dev) ...@@ -763,6 +751,14 @@ nvc0_graph_isr(struct drm_device *dev)
stat &= ~0x00100000; stat &= ~0x00100000;
} }
if (stat & 0x00200000) {
u32 trap = nv_rd32(dev, 0x400108);
NV_INFO(dev, "PGRAPH: TRAP ch %d status 0x%08x\n", chid, trap);
nv_wr32(dev, 0x400108, trap);
nv_wr32(dev, 0x400100, 0x00200000);
stat &= ~0x00200000;
}
if (stat & 0x00080000) { if (stat & 0x00080000) {
u32 ustat = nv_rd32(dev, 0x409c18); u32 ustat = nv_rd32(dev, 0x409c18);
......
...@@ -46,8 +46,6 @@ struct nvc0_graph_priv { ...@@ -46,8 +46,6 @@ struct nvc0_graph_priv {
struct nouveau_gpuobj *unk4188b8; struct nouveau_gpuobj *unk4188b8;
u8 magic_not_rop_nr; u8 magic_not_rop_nr;
u32 magic419bd0;
u32 magic419be4;
u32 magicgpc980[4]; u32 magicgpc980[4];
u32 magicgpc918; u32 magicgpc918;
}; };
......
...@@ -1557,7 +1557,7 @@ nvc0_grctx_generate_unk47xx(struct drm_device *dev) ...@@ -1557,7 +1557,7 @@ nvc0_grctx_generate_unk47xx(struct drm_device *dev)
} }
static void static void
nvc0_grctx_generate_unk58xx(struct drm_device *dev) nvc0_grctx_generate_shaders(struct drm_device *dev)
{ {
nv_wr32(dev, 0x405800, 0x078000bf); nv_wr32(dev, 0x405800, 0x078000bf);
nv_wr32(dev, 0x405830, 0x02180000); nv_wr32(dev, 0x405830, 0x02180000);
...@@ -1593,7 +1593,7 @@ nvc0_grctx_generate_unk64xx(struct drm_device *dev) ...@@ -1593,7 +1593,7 @@ nvc0_grctx_generate_unk64xx(struct drm_device *dev)
} }
static void static void
nvc0_grctx_generate_unk78xx(struct drm_device *dev) nvc0_grctx_generate_tpbus(struct drm_device *dev)
{ {
nv_wr32(dev, 0x407804, 0x00000023); nv_wr32(dev, 0x407804, 0x00000023);
nv_wr32(dev, 0x40780c, 0x0a418820); nv_wr32(dev, 0x40780c, 0x0a418820);
...@@ -1606,7 +1606,7 @@ nvc0_grctx_generate_unk78xx(struct drm_device *dev) ...@@ -1606,7 +1606,7 @@ nvc0_grctx_generate_unk78xx(struct drm_device *dev)
} }
static void static void
nvc0_grctx_generate_unk80xx(struct drm_device *dev) nvc0_grctx_generate_ccache(struct drm_device *dev)
{ {
nv_wr32(dev, 0x408000, 0x00000000); nv_wr32(dev, 0x408000, 0x00000000);
nv_wr32(dev, 0x408004, 0x00000000); nv_wr32(dev, 0x408004, 0x00000000);
...@@ -1801,7 +1801,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1801,7 +1801,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
struct nvc0_graph_chan *grch = chan->pgraph_ctx; struct nvc0_graph_chan *grch = chan->pgraph_ctx;
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
int i, gpc, tp, id; int i, gpc, tp, id;
u32 r000260; u32 r000260, tmp;
r000260 = nv_rd32(dev, 0x000260); r000260 = nv_rd32(dev, 0x000260);
nv_wr32(dev, 0x000260, r000260 & ~1); nv_wr32(dev, 0x000260, r000260 & ~1);
...@@ -1811,11 +1811,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1811,11 +1811,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
nvc0_grctx_generate_macro(dev); nvc0_grctx_generate_macro(dev);
nvc0_grctx_generate_m2mf(dev); nvc0_grctx_generate_m2mf(dev);
nvc0_grctx_generate_unk47xx(dev); nvc0_grctx_generate_unk47xx(dev);
nvc0_grctx_generate_unk58xx(dev); nvc0_grctx_generate_shaders(dev);
nvc0_grctx_generate_unk60xx(dev); nvc0_grctx_generate_unk60xx(dev);
nvc0_grctx_generate_unk64xx(dev); nvc0_grctx_generate_unk64xx(dev);
nvc0_grctx_generate_unk78xx(dev); nvc0_grctx_generate_tpbus(dev);
nvc0_grctx_generate_unk80xx(dev); nvc0_grctx_generate_ccache(dev);
nvc0_grctx_generate_rop(dev); nvc0_grctx_generate_rop(dev);
nvc0_grctx_generate_gpc(dev); nvc0_grctx_generate_gpc(dev);
nvc0_grctx_generate_tp(dev); nvc0_grctx_generate_tp(dev);
...@@ -1843,8 +1843,12 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1843,8 +1843,12 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
} }
} }
nv_wr32(dev, 0x406028, 0x00000443); tmp = 0;
nv_wr32(dev, 0x405870, 0x00000443); for (i = 0; i < priv->gpc_nr; i++)
tmp |= priv->tp_nr[i] << (i * 4);
nv_wr32(dev, 0x406028, tmp);
nv_wr32(dev, 0x405870, tmp);
nv_wr32(dev, 0x40602c, 0x00000000); nv_wr32(dev, 0x40602c, 0x00000000);
nv_wr32(dev, 0x405874, 0x00000000); nv_wr32(dev, 0x405874, 0x00000000);
nv_wr32(dev, 0x406030, 0x00000000); nv_wr32(dev, 0x406030, 0x00000000);
...@@ -1875,9 +1879,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1875,9 +1879,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
} }
if (1) { if (1) {
u32 data[6] = {}; u32 data[6] = {}, data2[2] = {};
u8 tpnr[GPC_MAX]; u8 tpnr[GPC_MAX];
u8 shift, ntpcv;
/* calculate first set of magics */
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
for (tp = 0; tp < priv->tp_total; tp++) { for (tp = 0; tp < priv->tp_total; tp++) {
...@@ -1892,6 +1898,20 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1892,6 +1898,20 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
for (; tp < 32; tp++) for (; tp < 32; tp++)
data[tp / 6] |= 7 << ((tp % 6) * 5); data[tp / 6] |= 7 << ((tp % 6) * 5);
/* and the second... */
shift = 0;
ntpcv = priv->tp_total;
while (!(ntpcv & (1 << 4))) {
ntpcv <<= 1;
shift++;
}
data2[0] = (ntpcv << 16);
data2[0] |= (shift << 21);
data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
for (i = 1; i < 7; i++)
data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
// GPC_BROADCAST // GPC_BROADCAST
nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) |
priv->magic_not_rop_nr); priv->magic_not_rop_nr);
...@@ -1900,9 +1920,9 @@ nvc0_grctx_generate(struct nouveau_channel *chan) ...@@ -1900,9 +1920,9 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
// GPC_BROADCAST.TP_BROADCAST // GPC_BROADCAST.TP_BROADCAST
nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) |
priv->magic_not_rop_nr | priv->magic_not_rop_nr |
priv->magic419bd0); data2[0]);
nv_wr32(dev, 0x419be4, priv->magic419be4); nv_wr32(dev, 0x419be4, data2[1]);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
nv_wr32(dev, 0x419b00 + (i * 4), data[i]); nv_wr32(dev, 0x419b00 + (i * 4), data[i]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment