diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-03-31 22:32:03 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-05-15 20:48:18 -0400 |
commit | a0b1de84fed49a055a3ecbfab67ff9cdea81aa6f (patch) | |
tree | 53d4e1014066beefca115d3567cb28708700c975 /drivers/gpu/drm | |
parent | 39c8d368273bca9b5f309f9feadfc8575c9fd993 (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.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv20_graph.c | 511 |
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[]; | |||
1167 | extern struct nouveau_bitfield nv10_graph_nstatus[]; | 1167 | extern struct nouveau_bitfield nv10_graph_nstatus[]; |
1168 | 1168 | ||
1169 | /* nv20_graph.c */ | 1169 | /* nv20_graph.c */ |
1170 | extern int nv20_graph_create_context(struct nouveau_channel *); | 1170 | extern int nv20_graph_create(struct drm_device *); |
1171 | extern void nv20_graph_destroy_context(struct nouveau_channel *); | ||
1172 | extern int nv20_graph_load_context(struct nouveau_channel *); | ||
1173 | extern int nv20_graph_unload_context(struct drm_device *); | ||
1174 | extern int nv20_graph_init(struct drm_device *); | ||
1175 | extern void nv20_graph_takedown(struct drm_device *); | ||
1176 | extern int nv30_graph_init(struct drm_device *); | ||
1177 | extern void nv20_graph_set_tile_region(struct drm_device *dev, int i); | 1171 | extern 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 | ||
27 | struct 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 | ||
35 | static int nv20_graph_register(struct drm_device *); | 43 | int |
36 | static int nv30_graph_register(struct drm_device *); | 44 | nv20_graph_unload_context(struct drm_device *dev) |
37 | static 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 | |||
70 | static void | ||
71 | nv20_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 | ||
39 | static void | 89 | static void |
40 | nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 90 | nv20_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 | ||
89 | static void | 139 | static void |
90 | nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 140 | nv25_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 | ||
148 | static void | 198 | static void |
149 | nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 199 | nv2a_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 | ||
198 | static void | 248 | static void |
199 | nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 249 | nv30_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 | ||
256 | static void | 306 | static void |
257 | nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 307 | nv34_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 | ||
314 | static void | 364 | static void |
315 | nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) | 365 | nv35_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 | ||
372 | int | 422 | int |
373 | nv20_graph_create_context(struct nouveau_channel *chan) | 423 | nv20_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 | ||
426 | void | 447 | void |
427 | nv20_graph_destroy_context(struct nouveau_channel *chan) | 448 | nv20_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 | |||
449 | int | ||
450 | nv20_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 | |||
468 | int | ||
469 | nv20_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 | |||
495 | static void | ||
496 | nv20_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 | ||
514 | void | 473 | void |
@@ -536,56 +495,22 @@ nv20_graph_set_tile_region(struct drm_device *dev, int i) | |||
536 | } | 495 | } |
537 | 496 | ||
538 | int | 497 | int |
539 | nv20_graph_init(struct drm_device *dev) | 498 | nv20_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 | ||
660 | void | ||
661 | nv20_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 | |||
672 | int | 585 | int |
673 | nv30_graph_init(struct drm_device *dev) | 586 | nv30_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 | ||
778 | static int | 656 | int |
779 | nv20_graph_register(struct drm_device *dev) | 657 | nv20_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 | |||
816 | static int | ||
817 | nv30_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 | |||
705 | static void | ||
706 | nv20_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 | |||
717 | int | ||
718 | nv20_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 | } | ||