diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_graph.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_graph.c | 91 |
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 | ||
33 | static int nv50_graph_register(struct drm_device *); | ||
34 | |||
33 | static void | 35 | static void |
34 | nv50_graph_init_reset(struct drm_device *dev) | 36 | nv50_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 | ||
335 | static int | 340 | static int |
336 | nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, | 341 | nv50_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 | ||
353 | static int | 358 | static int |
354 | nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass, | 359 | nv50_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 | ||
364 | static int | 369 | static int |
365 | nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass, | 370 | nv50_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 | ||
372 | static int | 377 | static int |
373 | nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass, | 378 | nv50_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 | ||
395 | static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = { | 400 | static int |
396 | { 0x018c, nv50_graph_nvsw_dma_vblsem }, | 401 | nv50_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 | ||
403 | struct 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 | ||
417 | void | 448 | void |
418 | nv50_graph_tlb_flush(struct drm_device *dev) | 449 | nv50_graph_tlb_flush(struct drm_device *dev) |