aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-03-31 22:32:03 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-05-15 20:48:18 -0400
commita0b1de84fed49a055a3ecbfab67ff9cdea81aa6f (patch)
tree53d4e1014066beefca115d3567cb28708700c975 /drivers/gpu/drm
parent39c8d368273bca9b5f309f9feadfc8575c9fd993 (diff)
drm/nv20-nv30/gr: move to exec engine interface
A bit of cleanup done along the way, but, like nv40/nv50, needs more. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c32
-rw-r--r--drivers/gpu/drm/nouveau/nv20_graph.c511
3 files changed, 239 insertions, 312 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a20e49d36209..5641d2e40d29 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1167,13 +1167,7 @@ extern struct nouveau_bitfield nv10_graph_intr[];
1167extern struct nouveau_bitfield nv10_graph_nstatus[]; 1167extern struct nouveau_bitfield nv10_graph_nstatus[];
1168 1168
1169/* nv20_graph.c */ 1169/* nv20_graph.c */
1170extern int nv20_graph_create_context(struct nouveau_channel *); 1170extern int nv20_graph_create(struct drm_device *);
1171extern void nv20_graph_destroy_context(struct nouveau_channel *);
1172extern int nv20_graph_load_context(struct nouveau_channel *);
1173extern int nv20_graph_unload_context(struct drm_device *);
1174extern int nv20_graph_init(struct drm_device *);
1175extern void nv20_graph_takedown(struct drm_device *);
1176extern int nv30_graph_init(struct drm_device *);
1177extern void nv20_graph_set_tile_region(struct drm_device *dev, int i); 1171extern void nv20_graph_set_tile_region(struct drm_device *dev, int i);
1178 1172
1179/* nv40_graph.c */ 1173/* nv40_graph.c */
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index d8852edc60cb..7bb2433013df 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -180,15 +180,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
180 engine->fb.init_tile_region = nv10_fb_init_tile_region; 180 engine->fb.init_tile_region = nv10_fb_init_tile_region;
181 engine->fb.set_tile_region = nv10_fb_set_tile_region; 181 engine->fb.set_tile_region = nv10_fb_set_tile_region;
182 engine->fb.free_tile_region = nv10_fb_free_tile_region; 182 engine->fb.free_tile_region = nv10_fb_free_tile_region;
183 engine->graph.init = nv20_graph_init; 183 engine->graph.init = nouveau_stub_init;
184 engine->graph.takedown = nv20_graph_takedown; 184 engine->graph.takedown = nouveau_stub_takedown;
185 engine->graph.channel = nv10_graph_channel; 185 engine->graph.channel = nvc0_graph_channel;
186 engine->graph.create_context = nv20_graph_create_context; 186 engine->graph.fifo_access = nvc0_graph_fifo_access;
187 engine->graph.destroy_context = nv20_graph_destroy_context;
188 engine->graph.fifo_access = nv04_graph_fifo_access;
189 engine->graph.load_context = nv20_graph_load_context;
190 engine->graph.unload_context = nv20_graph_unload_context;
191 engine->graph.object_new = nv04_graph_object_new;
192 engine->graph.set_tile_region = nv20_graph_set_tile_region; 187 engine->graph.set_tile_region = nv20_graph_set_tile_region;
193 engine->fifo.channels = 32; 188 engine->fifo.channels = 32;
194 engine->fifo.init = nv10_fifo_init; 189 engine->fifo.init = nv10_fifo_init;
@@ -238,15 +233,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
238 engine->fb.init_tile_region = nv30_fb_init_tile_region; 233 engine->fb.init_tile_region = nv30_fb_init_tile_region;
239 engine->fb.set_tile_region = nv10_fb_set_tile_region; 234 engine->fb.set_tile_region = nv10_fb_set_tile_region;
240 engine->fb.free_tile_region = nv30_fb_free_tile_region; 235 engine->fb.free_tile_region = nv30_fb_free_tile_region;
241 engine->graph.init = nv30_graph_init; 236 engine->graph.init = nouveau_stub_init;
242 engine->graph.takedown = nv20_graph_takedown; 237 engine->graph.takedown = nouveau_stub_takedown;
243 engine->graph.fifo_access = nv04_graph_fifo_access; 238 engine->graph.channel = nvc0_graph_channel;
244 engine->graph.channel = nv10_graph_channel; 239 engine->graph.fifo_access = nvc0_graph_fifo_access;
245 engine->graph.create_context = nv20_graph_create_context;
246 engine->graph.destroy_context = nv20_graph_destroy_context;
247 engine->graph.load_context = nv20_graph_load_context;
248 engine->graph.unload_context = nv20_graph_unload_context;
249 engine->graph.object_new = nv04_graph_object_new;
250 engine->graph.set_tile_region = nv20_graph_set_tile_region; 240 engine->graph.set_tile_region = nv20_graph_set_tile_region;
251 engine->fifo.channels = 32; 241 engine->fifo.channels = 32;
252 engine->fifo.init = nv10_fifo_init; 242 engine->fifo.init = nv10_fifo_init;
@@ -614,6 +604,10 @@ nouveau_card_init(struct drm_device *dev)
614 goto out_timer; 604 goto out_timer;
615 605
616 switch (dev_priv->card_type) { 606 switch (dev_priv->card_type) {
607 case NV_20:
608 case NV_30:
609 nv20_graph_create(dev);
610 break;
617 case NV_40: 611 case NV_40:
618 nv40_graph_create(dev); 612 nv40_graph_create(dev);
619 break; 613 break;
@@ -623,6 +617,8 @@ nouveau_card_init(struct drm_device *dev)
623 case NV_C0: 617 case NV_C0:
624 nvc0_graph_create(dev); 618 nvc0_graph_create(dev);
625 break; 619 break;
620 default:
621 break;
626 } 622 }
627 623
628 switch (dev_priv->chipset) { 624 switch (dev_priv->chipset) {
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c
index 8464b76798d5..ce83f02b06dd 100644
--- a/drivers/gpu/drm/nouveau/nv20_graph.c
+++ b/drivers/gpu/drm/nouveau/nv20_graph.c
@@ -24,6 +24,14 @@
24 * 24 *
25 */ 25 */
26 26
27struct nv20_graph_engine {
28 struct nouveau_exec_engine base;
29 struct nouveau_gpuobj *ctxtab;
30 void (*grctx_init)(struct nouveau_gpuobj *);
31 u32 grctx_size;
32 u32 grctx_user;
33};
34
27#define NV20_GRCTX_SIZE (3580*4) 35#define NV20_GRCTX_SIZE (3580*4)
28#define NV25_GRCTX_SIZE (3529*4) 36#define NV25_GRCTX_SIZE (3529*4)
29#define NV2A_GRCTX_SIZE (3500*4) 37#define NV2A_GRCTX_SIZE (3500*4)
@@ -32,12 +40,54 @@
32#define NV34_GRCTX_SIZE (18140) 40#define NV34_GRCTX_SIZE (18140)
33#define NV35_36_GRCTX_SIZE (22396) 41#define NV35_36_GRCTX_SIZE (22396)
34 42
35static int nv20_graph_register(struct drm_device *); 43int
36static int nv30_graph_register(struct drm_device *); 44nv20_graph_unload_context(struct drm_device *dev)
37static void nv20_graph_isr(struct drm_device *); 45{
46 struct drm_nouveau_private *dev_priv = dev->dev_private;
47 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
48 struct nouveau_channel *chan;
49 struct nouveau_gpuobj *grctx;
50 u32 tmp;
51
52 chan = nv10_graph_channel(dev);
53 if (!chan)
54 return 0;
55 grctx = chan->engctx[NVOBJ_ENGINE_GR];
56
57 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, grctx->pinst >> 4);
58 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
59 NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
60
61 nouveau_wait_for_idle(dev);
62
63 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
64 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
65 tmp |= (pfifo->channels - 1) << 24;
66 nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
67 return 0;
68}
69
70static void
71nv20_graph_rdi(struct drm_device *dev)
72{
73 struct drm_nouveau_private *dev_priv = dev->dev_private;
74 int i, writecount = 32;
75 uint32_t rdi_index = 0x2c80000;
76
77 if (dev_priv->chipset == 0x20) {
78 rdi_index = 0x3d0000;
79 writecount = 15;
80 }
81
82 nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
83 for (i = 0; i < writecount; i++)
84 nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
85
86 nouveau_wait_for_idle(dev);
87}
38 88
39static void 89static void
40nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 90nv20_graph_context_init(struct nouveau_gpuobj *ctx)
41{ 91{
42 int i; 92 int i;
43 93
@@ -87,7 +137,7 @@ nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
87} 137}
88 138
89static void 139static void
90nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 140nv25_graph_context_init(struct nouveau_gpuobj *ctx)
91{ 141{
92 int i; 142 int i;
93 143
@@ -146,7 +196,7 @@ nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
146} 196}
147 197
148static void 198static void
149nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 199nv2a_graph_context_init(struct nouveau_gpuobj *ctx)
150{ 200{
151 int i; 201 int i;
152 202
@@ -196,7 +246,7 @@ nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
196} 246}
197 247
198static void 248static void
199nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 249nv30_31_graph_context_init(struct nouveau_gpuobj *ctx)
200{ 250{
201 int i; 251 int i;
202 252
@@ -254,7 +304,7 @@ nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
254} 304}
255 305
256static void 306static void
257nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 307nv34_graph_context_init(struct nouveau_gpuobj *ctx)
258{ 308{
259 int i; 309 int i;
260 310
@@ -312,7 +362,7 @@ nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
312} 362}
313 363
314static void 364static void
315nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) 365nv35_36_graph_context_init(struct nouveau_gpuobj *ctx)
316{ 366{
317 int i; 367 int i;
318 368
@@ -370,145 +420,54 @@ nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
370} 420}
371 421
372int 422int
373nv20_graph_create_context(struct nouveau_channel *chan) 423nv20_graph_context_new(struct nouveau_channel *chan, int engine)
374{ 424{
425 struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
426 struct nouveau_gpuobj *grctx = NULL;
375 struct drm_device *dev = chan->dev; 427 struct drm_device *dev = chan->dev;
376 struct drm_nouveau_private *dev_priv = dev->dev_private;
377 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
378 void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
379 unsigned int idoffs = 0x28;
380 int ret; 428 int ret;
381 429
382 switch (dev_priv->chipset) { 430 ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16,
383 case 0x20: 431 NVOBJ_FLAG_ZERO_ALLOC, &grctx);
384 ctx_init = nv20_graph_context_init;
385 idoffs = 0;
386 break;
387 case 0x25:
388 case 0x28:
389 ctx_init = nv25_graph_context_init;
390 break;
391 case 0x2a:
392 ctx_init = nv2a_graph_context_init;
393 idoffs = 0;
394 break;
395 case 0x30:
396 case 0x31:
397 ctx_init = nv30_31_graph_context_init;
398 break;
399 case 0x34:
400 ctx_init = nv34_graph_context_init;
401 break;
402 case 0x35:
403 case 0x36:
404 ctx_init = nv35_36_graph_context_init;
405 break;
406 default:
407 BUG_ON(1);
408 }
409
410 ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16,
411 NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx);
412 if (ret) 432 if (ret)
413 return ret; 433 return ret;
414 434
415 /* Initialise default context values */ 435 /* Initialise default context values */
416 ctx_init(dev, chan->ramin_grctx); 436 pgraph->grctx_init(grctx);
417 437
418 /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ 438 /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
419 nv_wo32(chan->ramin_grctx, idoffs, 439 /* CTX_USER */
420 (chan->id << 24) | 0x1); /* CTX_USER */ 440 nv_wo32(grctx, pgraph->grctx_user, (chan->id << 24) | 0x1);
421 441
422 nv_wo32(pgraph->ctx_table, chan->id * 4, chan->ramin_grctx->pinst >> 4); 442 nv_wo32(pgraph->ctxtab, chan->id * 4, grctx->pinst >> 4);
443 chan->engctx[engine] = grctx;
423 return 0; 444 return 0;
424} 445}
425 446
426void 447void
427nv20_graph_destroy_context(struct nouveau_channel *chan) 448nv20_graph_context_del(struct nouveau_channel *chan, int engine)
428{ 449{
450 struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
451 struct nouveau_gpuobj *grctx = chan->engctx[engine];
429 struct drm_device *dev = chan->dev; 452 struct drm_device *dev = chan->dev;
430 struct drm_nouveau_private *dev_priv = dev->dev_private; 453 struct drm_nouveau_private *dev_priv = dev->dev_private;
431 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
432 unsigned long flags; 454 unsigned long flags;
433 455
434 spin_lock_irqsave(&dev_priv->context_switch_lock, flags); 456 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
435 pgraph->fifo_access(dev, false); 457 nv04_graph_fifo_access(dev, false);
436 458
437 /* Unload the context if it's the currently active one */ 459 /* Unload the context if it's the currently active one */
438 if (pgraph->channel(dev) == chan) 460 if (nv10_graph_channel(dev) == chan)
439 pgraph->unload_context(dev); 461 nv20_graph_unload_context(dev);
440 462
441 pgraph->fifo_access(dev, true); 463 nv04_graph_fifo_access(dev, true);
442 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); 464 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
443 465
444 /* Free the context resources */ 466 /* Free the context resources */
445 nv_wo32(pgraph->ctx_table, chan->id * 4, 0); 467 nv_wo32(pgraph->ctxtab, chan->id * 4, 0);
446 nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
447}
448
449int
450nv20_graph_load_context(struct nouveau_channel *chan)
451{
452 struct drm_device *dev = chan->dev;
453 uint32_t inst;
454 468
455 if (!chan->ramin_grctx) 469 nouveau_gpuobj_ref(NULL, &grctx);
456 return -EINVAL; 470 chan->engctx[engine] = NULL;
457 inst = chan->ramin_grctx->pinst >> 4;
458
459 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
460 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
461 NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD);
462 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
463
464 nouveau_wait_for_idle(dev);
465 return 0;
466}
467
468int
469nv20_graph_unload_context(struct drm_device *dev)
470{
471 struct drm_nouveau_private *dev_priv = dev->dev_private;
472 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
473 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
474 struct nouveau_channel *chan;
475 uint32_t inst, tmp;
476
477 chan = pgraph->channel(dev);
478 if (!chan)
479 return 0;
480 inst = chan->ramin_grctx->pinst >> 4;
481
482 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
483 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
484 NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
485
486 nouveau_wait_for_idle(dev);
487
488 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
489 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
490 tmp |= (pfifo->channels - 1) << 24;
491 nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
492 return 0;
493}
494
495static void
496nv20_graph_rdi(struct drm_device *dev)
497{
498 struct drm_nouveau_private *dev_priv = dev->dev_private;
499 int i, writecount = 32;
500 uint32_t rdi_index = 0x2c80000;
501
502 if (dev_priv->chipset == 0x20) {
503 rdi_index = 0x3d0000;
504 writecount = 15;
505 }
506
507 nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
508 for (i = 0; i < writecount; i++)
509 nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
510
511 nouveau_wait_for_idle(dev);
512} 471}
513 472
514void 473void
@@ -536,56 +495,22 @@ nv20_graph_set_tile_region(struct drm_device *dev, int i)
536} 495}
537 496
538int 497int
539nv20_graph_init(struct drm_device *dev) 498nv20_graph_init(struct drm_device *dev, int engine)
540{ 499{
500 struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
541 struct drm_nouveau_private *dev_priv = dev->dev_private; 501 struct drm_nouveau_private *dev_priv = dev->dev_private;
542 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
543 uint32_t tmp, vramsz; 502 uint32_t tmp, vramsz;
544 int ret, i; 503 int i;
545
546 switch (dev_priv->chipset) {
547 case 0x20:
548 pgraph->grctx_size = NV20_GRCTX_SIZE;
549 break;
550 case 0x25:
551 case 0x28:
552 pgraph->grctx_size = NV25_GRCTX_SIZE;
553 break;
554 case 0x2a:
555 pgraph->grctx_size = NV2A_GRCTX_SIZE;
556 break;
557 default:
558 NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
559 pgraph->accel_blocked = true;
560 return 0;
561 }
562 504
563 nv_wr32(dev, NV03_PMC_ENABLE, 505 nv_wr32(dev, NV03_PMC_ENABLE,
564 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); 506 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
565 nv_wr32(dev, NV03_PMC_ENABLE, 507 nv_wr32(dev, NV03_PMC_ENABLE,
566 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); 508 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH);
567 509
568 if (!pgraph->ctx_table) { 510 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
569 /* Create Context Pointer Table */
570 ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16,
571 NVOBJ_FLAG_ZERO_ALLOC,
572 &pgraph->ctx_table);
573 if (ret)
574 return ret;
575 }
576
577 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
578 pgraph->ctx_table->pinst >> 4);
579 511
580 nv20_graph_rdi(dev); 512 nv20_graph_rdi(dev);
581 513
582 ret = nv20_graph_register(dev);
583 if (ret) {
584 nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
585 return ret;
586 }
587
588 nouveau_irq_register(dev, 12, nv20_graph_isr);
589 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); 514 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
590 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 515 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
591 516
@@ -657,67 +582,20 @@ nv20_graph_init(struct drm_device *dev)
657 return 0; 582 return 0;
658} 583}
659 584
660void
661nv20_graph_takedown(struct drm_device *dev)
662{
663 struct drm_nouveau_private *dev_priv = dev->dev_private;
664 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
665
666 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
667 nouveau_irq_unregister(dev, 12);
668
669 nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
670}
671
672int 585int
673nv30_graph_init(struct drm_device *dev) 586nv30_graph_init(struct drm_device *dev, int engine)
674{ 587{
588 struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
675 struct drm_nouveau_private *dev_priv = dev->dev_private; 589 struct drm_nouveau_private *dev_priv = dev->dev_private;
676 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; 590 int i;
677 int ret, i;
678
679 switch (dev_priv->chipset) {
680 case 0x30:
681 case 0x31:
682 pgraph->grctx_size = NV30_31_GRCTX_SIZE;
683 break;
684 case 0x34:
685 pgraph->grctx_size = NV34_GRCTX_SIZE;
686 break;
687 case 0x35:
688 case 0x36:
689 pgraph->grctx_size = NV35_36_GRCTX_SIZE;
690 break;
691 default:
692 NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
693 pgraph->accel_blocked = true;
694 return 0;
695 }
696 591
697 nv_wr32(dev, NV03_PMC_ENABLE, 592 nv_wr32(dev, NV03_PMC_ENABLE,
698 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); 593 nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
699 nv_wr32(dev, NV03_PMC_ENABLE, 594 nv_wr32(dev, NV03_PMC_ENABLE,
700 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); 595 nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH);
701 596
702 if (!pgraph->ctx_table) { 597 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
703 /* Create Context Pointer Table */
704 ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16,
705 NVOBJ_FLAG_ZERO_ALLOC,
706 &pgraph->ctx_table);
707 if (ret)
708 return ret;
709 }
710
711 ret = nv30_graph_register(dev);
712 if (ret) {
713 nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
714 return ret;
715 }
716 598
717 nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
718 pgraph->ctx_table->pinst >> 4);
719
720 nouveau_irq_register(dev, 12, nv20_graph_isr);
721 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); 599 nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
722 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 600 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
723 601
@@ -775,85 +653,11 @@ nv30_graph_init(struct drm_device *dev)
775 return 0; 653 return 0;
776} 654}
777 655
778static int 656int
779nv20_graph_register(struct drm_device *dev) 657nv20_graph_fini(struct drm_device *dev, int engine)
780{
781 struct drm_nouveau_private *dev_priv = dev->dev_private;
782
783 if (dev_priv->engine.graph.registered)
784 return 0;
785
786 NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
787 NVOBJ_CLASS(dev, 0x0030, GR); /* null */
788 NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
789 NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
790 NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
791 NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
792 NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
793 NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
794 NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
795 NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
796 NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
797 NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
798 NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
799 NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */
800 NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */
801
802 /* kelvin */
803 if (dev_priv->chipset < 0x25)
804 NVOBJ_CLASS(dev, 0x0097, GR);
805 else
806 NVOBJ_CLASS(dev, 0x0597, GR);
807
808 /* nvsw */
809 NVOBJ_CLASS(dev, 0x506e, SW);
810 NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
811
812 dev_priv->engine.graph.registered = true;
813 return 0;
814}
815
816static int
817nv30_graph_register(struct drm_device *dev)
818{ 658{
819 struct drm_nouveau_private *dev_priv = dev->dev_private; 659 nv20_graph_unload_context(dev);
820 660 nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
821 if (dev_priv->engine.graph.registered)
822 return 0;
823
824 NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
825 NVOBJ_CLASS(dev, 0x0030, GR); /* null */
826 NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
827 NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
828 NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
829 NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
830 NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */
831 NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
832 NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */
833 NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
834 NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */
835 NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
836 NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
837 NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
838 NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
839 NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
840 NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */
841
842 /* rankine */
843 if (0x00000003 & (1 << (dev_priv->chipset & 0x0f)))
844 NVOBJ_CLASS(dev, 0x0397, GR);
845 else
846 if (0x00000010 & (1 << (dev_priv->chipset & 0x0f)))
847 NVOBJ_CLASS(dev, 0x0697, GR);
848 else
849 if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f)))
850 NVOBJ_CLASS(dev, 0x0497, GR);
851
852 /* nvsw */
853 NVOBJ_CLASS(dev, 0x506e, SW);
854 NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
855
856 dev_priv->engine.graph.registered = true;
857 return 0; 661 return 0;
858} 662}
859 663
@@ -897,3 +701,136 @@ nv20_graph_isr(struct drm_device *dev)
897 } 701 }
898 } 702 }
899} 703}
704
705static void
706nv20_graph_destroy(struct drm_device *dev, int engine)
707{
708 struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
709
710 nouveau_irq_unregister(dev, 12);
711 nouveau_gpuobj_ref(NULL, &pgraph->ctxtab);
712
713 NVOBJ_ENGINE_DEL(dev, GR);
714 kfree(pgraph);
715}
716
717int
718nv20_graph_create(struct drm_device *dev)
719{
720 struct drm_nouveau_private *dev_priv = dev->dev_private;
721 struct nv20_graph_engine *pgraph;
722 int ret;
723
724 pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
725 if (!pgraph)
726 return -ENOMEM;
727
728 pgraph->base.destroy = nv20_graph_destroy;
729 pgraph->base.fini = nv20_graph_fini;
730 pgraph->base.context_new = nv20_graph_context_new;
731 pgraph->base.context_del = nv20_graph_context_del;
732 pgraph->base.object_new = nv04_graph_object_new;
733
734 pgraph->grctx_user = 0x0028;
735 if (dev_priv->card_type == NV_20) {
736 pgraph->base.init = nv20_graph_init;
737 switch (dev_priv->chipset) {
738 case 0x20:
739 pgraph->grctx_init = nv20_graph_context_init;
740 pgraph->grctx_size = NV20_GRCTX_SIZE;
741 pgraph->grctx_user = 0x0000;
742 break;
743 case 0x25:
744 case 0x28:
745 pgraph->grctx_init = nv25_graph_context_init;
746 pgraph->grctx_size = NV25_GRCTX_SIZE;
747 break;
748 case 0x2a:
749 pgraph->grctx_init = nv2a_graph_context_init;
750 pgraph->grctx_size = NV2A_GRCTX_SIZE;
751 pgraph->grctx_user = 0x0000;
752 break;
753 default:
754 NV_ERROR(dev, "unknown nv20, disabling acceleration\n");
755 dev_priv->engine.graph.accel_blocked = true;
756 return 0;
757 }
758 } else {
759 pgraph->base.init = nv30_graph_init;
760 switch (dev_priv->chipset) {
761 case 0x30:
762 case 0x31:
763 pgraph->grctx_init = nv30_31_graph_context_init;
764 pgraph->grctx_size = NV30_31_GRCTX_SIZE;
765 break;
766 case 0x34:
767 pgraph->grctx_init = nv34_graph_context_init;
768 pgraph->grctx_size = NV34_GRCTX_SIZE;
769 break;
770 case 0x35:
771 case 0x36:
772 pgraph->grctx_init = nv35_36_graph_context_init;
773 pgraph->grctx_size = NV35_36_GRCTX_SIZE;
774 break;
775 default:
776 NV_ERROR(dev, "unknown nv30, disabling acceleration\n");
777 dev_priv->engine.graph.accel_blocked = true;
778 return 0;
779 }
780 }
781
782 /* Create Context Pointer Table */
783 ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC,
784 &pgraph->ctxtab);
785 if (ret) {
786 kfree(pgraph);
787 return ret;
788 }
789
790 NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
791 nouveau_irq_register(dev, 12, nv20_graph_isr);
792
793 /* nvsw */
794 NVOBJ_CLASS(dev, 0x506e, SW);
795 NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
796
797 NVOBJ_CLASS(dev, 0x0030, GR); /* null */
798 NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
799 NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
800 NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
801 NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
802 NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
803 NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
804 NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
805 NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
806 NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
807 NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
808 NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
809 if (dev_priv->card_type == NV_20) {
810 NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */
811 NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */
812
813 /* kelvin */
814 if (dev_priv->chipset < 0x25)
815 NVOBJ_CLASS(dev, 0x0097, GR);
816 else
817 NVOBJ_CLASS(dev, 0x0597, GR);
818 } else {
819 NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */
820 NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */
821 NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */
822 NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */
823
824 /* rankine */
825 if (0x00000003 & (1 << (dev_priv->chipset & 0x0f)))
826 NVOBJ_CLASS(dev, 0x0397, GR);
827 else
828 if (0x00000010 & (1 << (dev_priv->chipset & 0x0f)))
829 NVOBJ_CLASS(dev, 0x0697, GR);
830 else
831 if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f)))
832 NVOBJ_CLASS(dev, 0x0497, GR);
833 }
834
835 return 0;
836}