aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_graph.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_graph.c91
1 files changed, 61 insertions, 30 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index 01a598917e3c..84ca90e91811 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -30,6 +30,8 @@
30#include "nouveau_ramht.h" 30#include "nouveau_ramht.h"
31#include "nouveau_grctx.h" 31#include "nouveau_grctx.h"
32 32
33static int nv50_graph_register(struct drm_device *);
34
33static void 35static void
34nv50_graph_init_reset(struct drm_device *dev) 36nv50_graph_init_reset(struct drm_device *dev)
35{ 37{
@@ -145,12 +147,15 @@ nv50_graph_init(struct drm_device *dev)
145 nv50_graph_init_reset(dev); 147 nv50_graph_init_reset(dev);
146 nv50_graph_init_regs__nv(dev); 148 nv50_graph_init_regs__nv(dev);
147 nv50_graph_init_regs(dev); 149 nv50_graph_init_regs(dev);
148 nv50_graph_init_intr(dev);
149 150
150 ret = nv50_graph_init_ctxctl(dev); 151 ret = nv50_graph_init_ctxctl(dev);
151 if (ret) 152 if (ret)
152 return ret; 153 return ret;
153 154
155 ret = nv50_graph_register(dev);
156 if (ret)
157 return ret;
158 nv50_graph_init_intr(dev);
154 return 0; 159 return 0;
155} 160}
156 161
@@ -333,8 +338,8 @@ nv50_graph_context_switch(struct drm_device *dev)
333} 338}
334 339
335static int 340static int
336nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, 341nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan,
337 int mthd, uint32_t data) 342 u32 class, u32 mthd, u32 data)
338{ 343{
339 struct nouveau_gpuobj *gpuobj; 344 struct nouveau_gpuobj *gpuobj;
340 345
@@ -351,8 +356,8 @@ nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass,
351} 356}
352 357
353static int 358static int
354nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass, 359nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan,
355 int mthd, uint32_t data) 360 u32 class, u32 mthd, u32 data)
356{ 361{
357 if (nouveau_notifier_offset(chan->nvsw.vblsem, &data)) 362 if (nouveau_notifier_offset(chan->nvsw.vblsem, &data))
358 return -ERANGE; 363 return -ERANGE;
@@ -362,16 +367,16 @@ nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass,
362} 367}
363 368
364static int 369static int
365nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass, 370nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan,
366 int mthd, uint32_t data) 371 u32 class, u32 mthd, u32 data)
367{ 372{
368 chan->nvsw.vblsem_rval = data; 373 chan->nvsw.vblsem_rval = data;
369 return 0; 374 return 0;
370} 375}
371 376
372static int 377static int
373nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass, 378nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan,
374 int mthd, uint32_t data) 379 u32 class, u32 mthd, u32 data)
375{ 380{
376 struct drm_device *dev = chan->dev; 381 struct drm_device *dev = chan->dev;
377 struct drm_nouveau_private *dev_priv = dev->dev_private; 382 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -392,27 +397,53 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass,
392 return 0; 397 return 0;
393} 398}
394 399
395static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = { 400static int
396 { 0x018c, nv50_graph_nvsw_dma_vblsem }, 401nv50_graph_register(struct drm_device *dev)
397 { 0x0400, nv50_graph_nvsw_vblsem_offset }, 402{
398 { 0x0404, nv50_graph_nvsw_vblsem_release_val }, 403 struct drm_nouveau_private *dev_priv = dev->dev_private;
399 { 0x0408, nv50_graph_nvsw_vblsem_release }, 404
400 {} 405 if (dev_priv->engine.graph.registered)
401}; 406 return 0;
402 407
403struct nouveau_pgraph_object_class nv50_graph_grclass[] = { 408 NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
404 { 0x506e, NVOBJ_ENGINE_SW, nv50_graph_nvsw_methods }, /* nvsw */ 409 NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem);
405 { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ 410 NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset);
406 { 0x5039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ 411 NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val);
407 { 0x502d, NVOBJ_ENGINE_GR, NULL }, /* 2d */ 412 NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release);
408 { 0x50c0, NVOBJ_ENGINE_GR, NULL }, /* compute */ 413
409 { 0x85c0, NVOBJ_ENGINE_GR, NULL }, /* compute (nva3, nva5, nva8) */ 414 NVOBJ_CLASS(dev, 0x0030, GR); /* null */
410 { 0x5097, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv50) */ 415 NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */
411 { 0x8297, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv8x/nv9x) */ 416 NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */
412 { 0x8397, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva0, nvaa, nvac) */ 417 NVOBJ_CLASS(dev, 0x50c0, GR); /* compute */
413 { 0x8597, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva3, nva5, nva8) */ 418 NVOBJ_CLASS(dev, 0x85c0, GR); /* compute (nva3, nva5, nva8) */
414 {} 419
415}; 420 /* tesla */
421 if (dev_priv->chipset == 0x50)
422 NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */
423 else
424 if (dev_priv->chipset < 0xa0)
425 NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */
426 else {
427 switch (dev_priv->chipset) {
428 case 0xa0:
429 case 0xaa:
430 case 0xac:
431 NVOBJ_CLASS(dev, 0x8397, GR);
432 break;
433 case 0xa3:
434 case 0xa5:
435 case 0xa8:
436 NVOBJ_CLASS(dev, 0x8597, GR);
437 break;
438 case 0xaf:
439 NVOBJ_CLASS(dev, 0x8697, GR);
440 break;
441 }
442 }
443
444 dev_priv->engine.graph.registered = true;
445 return 0;
446}
416 447
417void 448void
418nv50_graph_tlb_flush(struct drm_device *dev) 449nv50_graph_tlb_flush(struct drm_device *dev)