1/* 2 * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr> 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include "drmP.h" 26#include "drm.h" 27#include "nouveau_drm.h" 28#include "nouveau_drv.h" 29 30#define NV10_FIFO_NUMBER 32 31 32struct pipe_state { 33 uint32_t pipe_0x0000[0x040/4]; 34 uint32_t pipe_0x0040[0x010/4]; 35 uint32_t pipe_0x0200[0x0c0/4]; 36 uint32_t pipe_0x4400[0x080/4]; 37 uint32_t pipe_0x6400[0x3b0/4]; 38 uint32_t pipe_0x6800[0x2f0/4]; 39 uint32_t pipe_0x6c00[0x030/4]; 40 uint32_t pipe_0x7000[0x130/4]; 41 uint32_t pipe_0x7400[0x0c0/4]; 42 uint32_t pipe_0x7800[0x0c0/4]; 43}; 44 45static int nv10_graph_ctx_regs [] = { 46NV10_PGRAPH_CTX_SWITCH1, 47NV10_PGRAPH_CTX_SWITCH2, 48NV10_PGRAPH_CTX_SWITCH3, 49NV10_PGRAPH_CTX_SWITCH4, 50NV10_PGRAPH_CTX_SWITCH5, 51NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ 52NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ 53NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ 54NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ 55NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ 560x00400164, 570x00400184, 580x004001a4, 590x004001c4, 600x004001e4, 610x00400168, 620x00400188, 630x004001a8, 640x004001c8, 650x004001e8, 660x0040016c, 670x0040018c, 680x004001ac, 690x004001cc, 700x004001ec, 710x00400170, 720x00400190, 730x004001b0, 740x004001d0, 750x004001f0, 760x00400174, 770x00400194, 780x004001b4, 790x004001d4, 800x004001f4, 810x00400178, 820x00400198, 830x004001b8, 840x004001d8, 850x004001f8, 860x0040017c, 870x0040019c, 880x004001bc, 890x004001dc, 900x004001fc, 91NV10_PGRAPH_CTX_USER, 92NV04_PGRAPH_DMA_START_0, 93NV04_PGRAPH_DMA_START_1, 94NV04_PGRAPH_DMA_LENGTH, 95NV04_PGRAPH_DMA_MISC, 96NV10_PGRAPH_DMA_PITCH, 97NV04_PGRAPH_BOFFSET0, 98NV04_PGRAPH_BBASE0, 99NV04_PGRAPH_BLIMIT0, 100NV04_PGRAPH_BOFFSET1, 101NV04_PGRAPH_BBASE1, 102NV04_PGRAPH_BLIMIT1, 103NV04_PGRAPH_BOFFSET2, 104NV04_PGRAPH_BBASE2, 105NV04_PGRAPH_BLIMIT2, 106NV04_PGRAPH_BOFFSET3, 107NV04_PGRAPH_BBASE3, 108NV04_PGRAPH_BLIMIT3, 109NV04_PGRAPH_BOFFSET4, 110NV04_PGRAPH_BBASE4, 111NV04_PGRAPH_BLIMIT4, 112NV04_PGRAPH_BOFFSET5, 113NV04_PGRAPH_BBASE5, 114NV04_PGRAPH_BLIMIT5, 115NV04_PGRAPH_BPITCH0, 116NV04_PGRAPH_BPITCH1, 117NV04_PGRAPH_BPITCH2, 118NV04_PGRAPH_BPITCH3, 119NV04_PGRAPH_BPITCH4, 120NV10_PGRAPH_SURFACE, 121NV10_PGRAPH_STATE, 122NV04_PGRAPH_BSWIZZLE2, 123NV04_PGRAPH_BSWIZZLE5, 124NV04_PGRAPH_BPIXEL, 125NV10_PGRAPH_NOTIFY, 126NV04_PGRAPH_PATT_COLOR0, 127NV04_PGRAPH_PATT_COLOR1, 128NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ 1290x00400904, 1300x00400908, 1310x0040090c, 1320x00400910, 1330x00400914, 1340x00400918, 1350x0040091c, 1360x00400920, 1370x00400924, 1380x00400928, 1390x0040092c, 1400x00400930, 1410x00400934, 1420x00400938, 1430x0040093c, 1440x00400940, 1450x00400944, 1460x00400948, 1470x0040094c, 1480x00400950, 1490x00400954, 1500x00400958, 1510x0040095c, 1520x00400960, 1530x00400964, 1540x00400968, 1550x0040096c, 1560x00400970, 1570x00400974, 1580x00400978, 1590x0040097c, 1600x00400980, 1610x00400984, 1620x00400988, 1630x0040098c, 1640x00400990, 1650x00400994, 1660x00400998, 1670x0040099c, 1680x004009a0, 1690x004009a4, 1700x004009a8, 1710x004009ac, 1720x004009b0, 1730x004009b4, 1740x004009b8, 1750x004009bc, 1760x004009c0, 1770x004009c4, 1780x004009c8, 1790x004009cc, 1800x004009d0, 1810x004009d4, 1820x004009d8, 1830x004009dc, 1840x004009e0, 1850x004009e4, 1860x004009e8, 1870x004009ec, 1880x004009f0, 1890x004009f4, 1900x004009f8, 1910x004009fc, 192NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ 1930x0040080c, 194NV04_PGRAPH_PATTERN_SHAPE, 195NV03_PGRAPH_MONO_COLOR0, 196NV04_PGRAPH_ROP3, 197NV04_PGRAPH_CHROMA, 198NV04_PGRAPH_BETA_AND, 199NV04_PGRAPH_BETA_PREMULT, 2000x00400e70, 2010x00400e74, 2020x00400e78, 2030x00400e7c, 2040x00400e80, 2050x00400e84, 2060x00400e88, 2070x00400e8c, 2080x00400ea0, 2090x00400ea4, 2100x00400ea8, 2110x00400e90, 2120x00400e94, 2130x00400e98, 2140x00400e9c, 215NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00 to 0x400f1c */ 216NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20 to 0x400f3c */ 2170x00400f04, 2180x00400f24, 2190x00400f08, 2200x00400f28, 2210x00400f0c, 2220x00400f2c, 2230x00400f10, 2240x00400f30, 2250x00400f14, 2260x00400f34, 2270x00400f18, 2280x00400f38, 2290x00400f1c, 2300x00400f3c, 231NV10_PGRAPH_XFMODE0, 232NV10_PGRAPH_XFMODE1, 233NV10_PGRAPH_GLOBALSTATE0, 234NV10_PGRAPH_GLOBALSTATE1, 235NV04_PGRAPH_STORED_FMT, 236NV04_PGRAPH_SOURCE_COLOR, 237NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ 238NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ 2390x00400404, 2400x00400484, 2410x00400408, 2420x00400488, 2430x0040040c, 2440x0040048c, 2450x00400410, 2460x00400490, 2470x00400414, 2480x00400494, 2490x00400418, 2500x00400498, 2510x0040041c, 2520x0040049c, 2530x00400420, 2540x004004a0, 2550x00400424, 2560x004004a4, 2570x00400428, 2580x004004a8, 2590x0040042c, 2600x004004ac, 2610x00400430, 2620x004004b0, 2630x00400434, 2640x004004b4, 2650x00400438, 2660x004004b8, 2670x0040043c, 2680x004004bc, 2690x00400440, 2700x004004c0, 2710x00400444, 2720x004004c4, 2730x00400448, 2740x004004c8, 2750x0040044c, 2760x004004cc, 2770x00400450, 2780x004004d0, 2790x00400454, 2800x004004d4, 2810x00400458, 2820x004004d8, 2830x0040045c, 2840x004004dc, 2850x00400460, 2860x004004e0, 2870x00400464, 2880x004004e4, 2890x00400468, 2900x004004e8, 2910x0040046c, 2920x004004ec, 2930x00400470, 2940x004004f0, 2950x00400474, 2960x004004f4, 2970x00400478, 2980x004004f8, 2990x0040047c, 3000x004004fc, 301NV03_PGRAPH_ABS_UCLIP_XMIN, 302NV03_PGRAPH_ABS_UCLIP_XMAX, 303NV03_PGRAPH_ABS_UCLIP_YMIN, 304NV03_PGRAPH_ABS_UCLIP_YMAX, 3050x00400550, 3060x00400558, 3070x00400554, 3080x0040055c, 309NV03_PGRAPH_ABS_UCLIPA_XMIN, 310NV03_PGRAPH_ABS_UCLIPA_XMAX, 311NV03_PGRAPH_ABS_UCLIPA_YMIN, 312NV03_PGRAPH_ABS_UCLIPA_YMAX, 313NV03_PGRAPH_ABS_ICLIP_XMAX, 314NV03_PGRAPH_ABS_ICLIP_YMAX, 315NV03_PGRAPH_XY_LOGIC_MISC0, 316NV03_PGRAPH_XY_LOGIC_MISC1, 317NV03_PGRAPH_XY_LOGIC_MISC2, 318NV03_PGRAPH_XY_LOGIC_MISC3, 319NV03_PGRAPH_CLIPX_0, 320NV03_PGRAPH_CLIPX_1, 321NV03_PGRAPH_CLIPY_0, 322NV03_PGRAPH_CLIPY_1, 323NV10_PGRAPH_COMBINER0_IN_ALPHA, 324NV10_PGRAPH_COMBINER1_IN_ALPHA, 325NV10_PGRAPH_COMBINER0_IN_RGB, 326NV10_PGRAPH_COMBINER1_IN_RGB, 327NV10_PGRAPH_COMBINER_COLOR0, 328NV10_PGRAPH_COMBINER_COLOR1, 329NV10_PGRAPH_COMBINER0_OUT_ALPHA, 330NV10_PGRAPH_COMBINER1_OUT_ALPHA, 331NV10_PGRAPH_COMBINER0_OUT_RGB, 332NV10_PGRAPH_COMBINER1_OUT_RGB, 333NV10_PGRAPH_COMBINER_FINAL0, 334NV10_PGRAPH_COMBINER_FINAL1, 3350x00400e00, 3360x00400e04, 3370x00400e08, 3380x00400e0c, 3390x00400e10, 3400x00400e14, 3410x00400e18, 3420x00400e1c, 3430x00400e20, 3440x00400e24, 3450x00400e28, 3460x00400e2c, 3470x00400e30, 3480x00400e34, 3490x00400e38, 3500x00400e3c, 351NV04_PGRAPH_PASSTHRU_0, 352NV04_PGRAPH_PASSTHRU_1, 353NV04_PGRAPH_PASSTHRU_2, 354NV10_PGRAPH_DIMX_TEXTURE, 355NV10_PGRAPH_WDIMX_TEXTURE, 356NV10_PGRAPH_DVD_COLORFMT, 357NV10_PGRAPH_SCALED_FORMAT, 358NV04_PGRAPH_MISC24_0, 359NV04_PGRAPH_MISC24_1, 360NV04_PGRAPH_MISC24_2, 361NV03_PGRAPH_X_MISC, 362NV03_PGRAPH_Y_MISC, 363NV04_PGRAPH_VALID1, 364NV04_PGRAPH_VALID2, 365}; 366 367static int nv17_graph_ctx_regs [] = { 368NV10_PGRAPH_DEBUG_4, 3690x004006b0, 3700x00400eac, 3710x00400eb0, 3720x00400eb4, 3730x00400eb8, 3740x00400ebc, 3750x00400ec0, 3760x00400ec4, 3770x00400ec8, 3780x00400ecc, 3790x00400ed0, 3800x00400ed4, 3810x00400ed8, 3820x00400edc, 3830x00400ee0, 3840x00400a00, 3850x00400a04, 386}; 387 388struct graph_state { 389 int nv10[sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0])]; 390 int nv17[sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0])]; 391 struct pipe_state pipe_state; 392}; 393 394static void nv10_graph_save_pipe(struct nouveau_channel *chan) { 395 struct drm_device *dev = chan->dev; 396 struct drm_nouveau_private *dev_priv = dev->dev_private; 397 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 398 struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; 399 int i; 400#define PIPE_SAVE(addr) \ 401 do { \ 402 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, addr); \ 403 for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ 404 fifo_pipe_state->pipe_##addr[i] = NV_READ(NV10_PGRAPH_PIPE_DATA); \ 405 } while (0) 406 407 PIPE_SAVE(0x4400); 408 PIPE_SAVE(0x0200); 409 PIPE_SAVE(0x6400); 410 PIPE_SAVE(0x6800); 411 PIPE_SAVE(0x6c00); 412 PIPE_SAVE(0x7000); 413 PIPE_SAVE(0x7400); 414 PIPE_SAVE(0x7800); 415 PIPE_SAVE(0x0040); 416 PIPE_SAVE(0x0000); 417 418#undef PIPE_SAVE 419} 420 421static void nv10_graph_load_pipe(struct nouveau_channel *chan) { 422 struct drm_device *dev = chan->dev; 423 struct drm_nouveau_private *dev_priv = dev->dev_private; 424 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 425 struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; 426 int i; 427 uint32_t xfmode0, xfmode1; 428#define PIPE_RESTORE(addr) \ 429 do { \ 430 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, addr); \ 431 for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ 432 NV_WRITE(NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ 433 } while (0) 434 435 436 nouveau_wait_for_idle(dev); 437 /* XXX check haiku comments */ 438 xfmode0 = NV_READ(NV10_PGRAPH_XFMODE0); 439 xfmode1 = NV_READ(NV10_PGRAPH_XFMODE1); 440 NV_WRITE(NV10_PGRAPH_XFMODE0, 0x10000000); 441 NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000); 442 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); 443 for (i = 0; i < 4; i++) 444 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); 445 for (i = 0; i < 4; i++) 446 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); 447 448 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); 449 for (i = 0; i < 3; i++) 450 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); 451 452 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); 453 for (i = 0; i < 3; i++) 454 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); 455 456 NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); 457 NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000008); 458 459 460 PIPE_RESTORE(0x0200); 461 nouveau_wait_for_idle(dev); 462 463 /* restore XFMODE */ 464 NV_WRITE(NV10_PGRAPH_XFMODE0, xfmode0); 465 NV_WRITE(NV10_PGRAPH_XFMODE1, xfmode1); 466 PIPE_RESTORE(0x6400); 467 PIPE_RESTORE(0x6800); 468 PIPE_RESTORE(0x6c00); 469 PIPE_RESTORE(0x7000); 470 PIPE_RESTORE(0x7400); 471 PIPE_RESTORE(0x7800); 472 PIPE_RESTORE(0x4400); 473 PIPE_RESTORE(0x0000); 474 PIPE_RESTORE(0x0040); 475 nouveau_wait_for_idle(dev); 476 477#undef PIPE_RESTORE 478} 479 480static void nv10_graph_create_pipe(struct nouveau_channel *chan) { 481 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 482 struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; 483 uint32_t *fifo_pipe_state_addr; 484 int i; 485#define PIPE_INIT(addr) \ 486 do { \ 487 fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \ 488 } while (0) 489#define PIPE_INIT_END(addr) \ 490 do { \ 491 if (fifo_pipe_state_addr != \ 492 sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr) \ 493 DRM_ERROR("incomplete pipe init for 0x%x : %p/%p\n", addr, fifo_pipe_state_addr, \ 494 sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr); \ 495 } while (0) 496#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value 497 498 PIPE_INIT(0x0200); 499 for (i = 0; i < 48; i++) 500 NV_WRITE_PIPE_INIT(0x00000000); 501 PIPE_INIT_END(0x0200); 502 503 PIPE_INIT(0x6400); 504 for (i = 0; i < 211; i++) 505 NV_WRITE_PIPE_INIT(0x00000000); 506 NV_WRITE_PIPE_INIT(0x3f800000); 507 NV_WRITE_PIPE_INIT(0x40000000); 508 NV_WRITE_PIPE_INIT(0x40000000); 509 NV_WRITE_PIPE_INIT(0x40000000); 510 NV_WRITE_PIPE_INIT(0x40000000); 511 NV_WRITE_PIPE_INIT(0x00000000); 512 NV_WRITE_PIPE_INIT(0x00000000); 513 NV_WRITE_PIPE_INIT(0x3f800000); 514 NV_WRITE_PIPE_INIT(0x00000000); 515 NV_WRITE_PIPE_INIT(0x3f000000); 516 NV_WRITE_PIPE_INIT(0x3f000000); 517 NV_WRITE_PIPE_INIT(0x00000000); 518 NV_WRITE_PIPE_INIT(0x00000000); 519 NV_WRITE_PIPE_INIT(0x00000000); 520 NV_WRITE_PIPE_INIT(0x00000000); 521 NV_WRITE_PIPE_INIT(0x3f800000); 522 NV_WRITE_PIPE_INIT(0x00000000); 523 NV_WRITE_PIPE_INIT(0x00000000); 524 NV_WRITE_PIPE_INIT(0x00000000); 525 NV_WRITE_PIPE_INIT(0x00000000); 526 NV_WRITE_PIPE_INIT(0x00000000); 527 NV_WRITE_PIPE_INIT(0x3f800000); 528 NV_WRITE_PIPE_INIT(0x3f800000); 529 NV_WRITE_PIPE_INIT(0x3f800000); 530 NV_WRITE_PIPE_INIT(0x3f800000); 531 PIPE_INIT_END(0x6400); 532 533 PIPE_INIT(0x6800); 534 for (i = 0; i < 162; i++) 535 NV_WRITE_PIPE_INIT(0x00000000); 536 NV_WRITE_PIPE_INIT(0x3f800000); 537 for (i = 0; i < 25; i++) 538 NV_WRITE_PIPE_INIT(0x00000000); 539 PIPE_INIT_END(0x6800); 540 541 PIPE_INIT(0x6c00); 542 NV_WRITE_PIPE_INIT(0x00000000); 543 NV_WRITE_PIPE_INIT(0x00000000); 544 NV_WRITE_PIPE_INIT(0x00000000); 545 NV_WRITE_PIPE_INIT(0x00000000); 546 NV_WRITE_PIPE_INIT(0xbf800000); 547 NV_WRITE_PIPE_INIT(0x00000000); 548 NV_WRITE_PIPE_INIT(0x00000000); 549 NV_WRITE_PIPE_INIT(0x00000000); 550 NV_WRITE_PIPE_INIT(0x00000000); 551 NV_WRITE_PIPE_INIT(0x00000000); 552 NV_WRITE_PIPE_INIT(0x00000000); 553 NV_WRITE_PIPE_INIT(0x00000000); 554 PIPE_INIT_END(0x6c00); 555 556 PIPE_INIT(0x7000); 557 NV_WRITE_PIPE_INIT(0x00000000); 558 NV_WRITE_PIPE_INIT(0x00000000); 559 NV_WRITE_PIPE_INIT(0x00000000); 560 NV_WRITE_PIPE_INIT(0x00000000); 561 NV_WRITE_PIPE_INIT(0x00000000); 562 NV_WRITE_PIPE_INIT(0x00000000); 563 NV_WRITE_PIPE_INIT(0x00000000); 564 NV_WRITE_PIPE_INIT(0x00000000); 565 NV_WRITE_PIPE_INIT(0x00000000); 566 NV_WRITE_PIPE_INIT(0x00000000); 567 NV_WRITE_PIPE_INIT(0x00000000); 568 NV_WRITE_PIPE_INIT(0x00000000); 569 NV_WRITE_PIPE_INIT(0x7149f2ca); 570 NV_WRITE_PIPE_INIT(0x00000000); 571 NV_WRITE_PIPE_INIT(0x00000000); 572 NV_WRITE_PIPE_INIT(0x00000000); 573 NV_WRITE_PIPE_INIT(0x7149f2ca); 574 NV_WRITE_PIPE_INIT(0x00000000); 575 NV_WRITE_PIPE_INIT(0x00000000); 576 NV_WRITE_PIPE_INIT(0x00000000); 577 NV_WRITE_PIPE_INIT(0x7149f2ca); 578 NV_WRITE_PIPE_INIT(0x00000000); 579 NV_WRITE_PIPE_INIT(0x00000000); 580 NV_WRITE_PIPE_INIT(0x00000000); 581 NV_WRITE_PIPE_INIT(0x7149f2ca); 582 NV_WRITE_PIPE_INIT(0x00000000); 583 NV_WRITE_PIPE_INIT(0x00000000); 584 NV_WRITE_PIPE_INIT(0x00000000); 585 NV_WRITE_PIPE_INIT(0x7149f2ca); 586 NV_WRITE_PIPE_INIT(0x00000000); 587 NV_WRITE_PIPE_INIT(0x00000000); 588 NV_WRITE_PIPE_INIT(0x00000000); 589 NV_WRITE_PIPE_INIT(0x7149f2ca); 590 NV_WRITE_PIPE_INIT(0x00000000); 591 NV_WRITE_PIPE_INIT(0x00000000); 592 NV_WRITE_PIPE_INIT(0x00000000); 593 NV_WRITE_PIPE_INIT(0x7149f2ca); 594 NV_WRITE_PIPE_INIT(0x00000000); 595 NV_WRITE_PIPE_INIT(0x00000000); 596 NV_WRITE_PIPE_INIT(0x00000000); 597 NV_WRITE_PIPE_INIT(0x7149f2ca); 598 for (i = 0; i < 35; i++) 599 NV_WRITE_PIPE_INIT(0x00000000); 600 PIPE_INIT_END(0x7000); 601 602 PIPE_INIT(0x7400); 603 for (i = 0; i < 48; i++) 604 NV_WRITE_PIPE_INIT(0x00000000); 605 PIPE_INIT_END(0x7400); 606 607 PIPE_INIT(0x7800); 608 for (i = 0; i < 48; i++) 609 NV_WRITE_PIPE_INIT(0x00000000); 610 PIPE_INIT_END(0x7800); 611 612 PIPE_INIT(0x4400); 613 for (i = 0; i < 32; i++) 614 NV_WRITE_PIPE_INIT(0x00000000); 615 PIPE_INIT_END(0x4400); 616 617 PIPE_INIT(0x0000); 618 for (i = 0; i < 16; i++) 619 NV_WRITE_PIPE_INIT(0x00000000); 620 PIPE_INIT_END(0x0000); 621 622 PIPE_INIT(0x0040); 623 for (i = 0; i < 4; i++) 624 NV_WRITE_PIPE_INIT(0x00000000); 625 PIPE_INIT_END(0x0040); 626 627#undef PIPE_INIT 628#undef PIPE_INIT_END 629#undef NV_WRITE_PIPE_INIT 630} 631 632static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) 633{ 634 int i; 635 for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) { 636 if (nv10_graph_ctx_regs[i] == reg) 637 return i; 638 } 639 DRM_ERROR("unknow offset nv10_ctx_regs %d\n", reg); 640 return -1; 641} 642 643static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) 644{ 645 int i; 646 for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) { 647 if (nv17_graph_ctx_regs[i] == reg) 648 return i; 649 } 650 DRM_ERROR("unknow offset nv17_ctx_regs %d\n", reg); 651 return -1; 652} 653 654int nv10_graph_load_context(struct nouveau_channel *chan) 655{ 656 struct drm_device *dev = chan->dev; 657 struct drm_nouveau_private *dev_priv = dev->dev_private; 658 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 659 int i; 660 661 for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) 662 NV_WRITE(nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]); 663 if (dev_priv->chipset>=0x17) { 664 for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) 665 NV_WRITE(nv17_graph_ctx_regs[i], pgraph_ctx->nv17[i]); 666 } 667 668 nv10_graph_load_pipe(chan); 669 670 return 0; 671} 672 673int nv10_graph_save_context(struct nouveau_channel *chan) 674{ 675 struct drm_device *dev = chan->dev; 676 struct drm_nouveau_private *dev_priv = dev->dev_private; 677 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 678 int i; 679 680 for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) 681 pgraph_ctx->nv10[i] = NV_READ(nv10_graph_ctx_regs[i]); 682 if (dev_priv->chipset>=0x17) { 683 for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) 684 pgraph_ctx->nv17[i] = NV_READ(nv17_graph_ctx_regs[i]); 685 } 686 687 nv10_graph_save_pipe(chan); 688 689 return 0; 690} 691 692void nouveau_nv10_context_switch(struct drm_device *dev) 693{ 694 struct drm_nouveau_private *dev_priv; 695 struct nouveau_engine *engine; 696 struct nouveau_channel *next, *last; 697 int chid; 698 699 if (!dev) { 700 DRM_DEBUG("Invalid drm_device\n"); 701 return; 702 } 703 dev_priv = dev->dev_private; 704 if (!dev_priv) { 705 DRM_DEBUG("Invalid drm_nouveau_private\n"); 706 return; 707 } 708 if (!dev_priv->fifos) { 709 DRM_DEBUG("Invalid drm_nouveau_private->fifos\n"); 710 return; 711 } 712 engine = &dev_priv->Engine; 713 714 chid = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 715 (engine->fifo.channels - 1); 716 next = dev_priv->fifos[chid]; 717 718 if (!next) { 719 DRM_ERROR("Invalid next channel\n"); 720 return; 721 } 722 723 chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & 724 (engine->fifo.channels - 1); 725 last = dev_priv->fifos[chid]; 726 727 if (!last) { 728 DRM_INFO("WARNING: Invalid last channel, switch to %x\n", 729 next->id); 730 } else { 731 DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n", 732 last->id, next->id); 733 } 734 735 NV_WRITE(NV04_PGRAPH_FIFO,0x0); 736 if (last) { 737 nouveau_wait_for_idle(dev); 738 nv10_graph_save_context(last); 739 } 740 741 nouveau_wait_for_idle(dev); 742 743 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000); 744 745 nouveau_wait_for_idle(dev); 746 747 nv10_graph_load_context(next); 748 749 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); 750 NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); 751 NV_WRITE(NV04_PGRAPH_FIFO,0x1); 752} 753 754#define NV_WRITE_CTX(reg, val) do { \ 755 int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ 756 if (offset > 0) \ 757 pgraph_ctx->nv10[offset] = val; \ 758 } while (0) 759 760#define NV17_WRITE_CTX(reg, val) do { \ 761 int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \ 762 if (offset > 0) \ 763 pgraph_ctx->nv17[offset] = val; \ 764 } while (0) 765 766int nv10_graph_create_context(struct nouveau_channel *chan) { 767 struct drm_device *dev = chan->dev; 768 struct drm_nouveau_private *dev_priv = dev->dev_private; 769 struct graph_state* pgraph_ctx; 770 771 DRM_DEBUG("nv10_graph_context_create %d\n", chan->id); 772 773 chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx), 774 DRM_MEM_DRIVER); 775 776 if (pgraph_ctx == NULL) 777 return -ENOMEM; 778 779 /* mmio trace suggest that should be done in ddx with methods/objects */ 780#if 0 781 uint32_t tmp, vramsz; 782 /* per channel init from ddx */ 783 tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; 784 /*XXX the original ddx code, does this in 2 steps : 785 * tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; 786 * NV_WRITE(NV10_PGRAPH_SURFACE, tmp); 787 * tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; 788 * NV_WRITE(NV10_PGRAPH_SURFACE, tmp); 789 */ 790 tmp |= 0x00020100; 791 NV_WRITE_CTX(NV10_PGRAPH_SURFACE, tmp); 792 793 vramsz = drm_get_resource_len(dev, 0) - 1; 794 NV_WRITE_CTX(NV04_PGRAPH_BOFFSET0, 0); 795 NV_WRITE_CTX(NV04_PGRAPH_BOFFSET1, 0); 796 NV_WRITE_CTX(NV04_PGRAPH_BLIMIT0 , vramsz); 797 NV_WRITE_CTX(NV04_PGRAPH_BLIMIT1 , vramsz); 798 799 NV_WRITE_CTX(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); 800 NV_WRITE_CTX(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); 801 802 NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); 803 NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); 804 NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); 805 NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); 806#endif 807 808 NV_WRITE_CTX(0x00400e88, 0x08000000); 809 NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); 810 NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); 811 NV_WRITE_CTX(0x00400e10, 0x00001000); 812 NV_WRITE_CTX(0x00400e14, 0x00001000); 813 NV_WRITE_CTX(0x00400e30, 0x00080008); 814 NV_WRITE_CTX(0x00400e34, 0x00080008); 815 if (dev_priv->chipset>=0x17) { 816 /* is it really needed ??? */ 817 NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4)); 818 NV17_WRITE_CTX(0x004006b0, NV_READ(0x004006b0)); 819 NV17_WRITE_CTX(0x00400eac, 0x0fff0000); 820 NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); 821 NV17_WRITE_CTX(0x00400ec0, 0x00000080); 822 NV17_WRITE_CTX(0x00400ed0, 0x00000080); 823 } 824 NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24); 825 826 nv10_graph_create_pipe(chan); 827 return 0; 828} 829 830void nv10_graph_destroy_context(struct nouveau_channel *chan) 831{ 832 struct drm_device *dev = chan->dev; 833 struct drm_nouveau_private *dev_priv = dev->dev_private; 834 struct nouveau_engine *engine = &dev_priv->Engine; 835 struct graph_state* pgraph_ctx = chan->pgraph_ctx; 836 int chid; 837 838 drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); 839 chan->pgraph_ctx = NULL; 840 841 chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1); 842 843 /* This code seems to corrupt the 3D pipe, but blob seems to do similar things ???? 844 */ 845#if 0 846 /* does this avoid a potential context switch while we are written graph 847 * reg, or we should mask graph interrupt ??? 848 */ 849 NV_WRITE(NV04_PGRAPH_FIFO,0x0); 850 if (chid == chan->id) { 851 DRM_INFO("cleanning a channel with graph in current context\n"); 852 nouveau_wait_for_idle(dev); 853 DRM_INFO("reseting current graph context\n"); 854 /* can't be call here because of dynamic mem alloc */ 855 //nv10_graph_create_context(chan); 856 nv10_graph_load_context(chan); 857 } 858 NV_WRITE(NV04_PGRAPH_FIFO, 0x1); 859#else 860 if (chid == chan->id) { 861 DRM_INFO("cleanning a channel with graph in current context\n"); 862 } 863#endif 864} 865 866int nv10_graph_init(struct drm_device *dev) { 867 struct drm_nouveau_private *dev_priv = dev->dev_private; 868 int i; 869 870 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & 871 ~NV_PMC_ENABLE_PGRAPH); 872 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | 873 NV_PMC_ENABLE_PGRAPH); 874 875 NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); 876 NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 877 878 NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); 879 NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); 880 NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700); 881 //NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810); /* 0x25f92ad9 */ 882 NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x25f92ad9); 883 NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0830 | 884 (1<<29) | 885 (1<<31)); 886 if (dev_priv->chipset>=0x17) { 887 NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x1f000000); 888 NV_WRITE(0x004006b0, 0x40000020); 889 } 890 else 891 NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000); 892 893 /* copy tile info from PFB */ 894 for (i=0; i<NV10_PFB_TILE__SIZE; i++) { 895 NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); 896 NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); 897 NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); 898 NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); 899 } 900 901 NV_WRITE(NV10_PGRAPH_CTX_SWITCH1, 0x00000000); 902 NV_WRITE(NV10_PGRAPH_CTX_SWITCH2, 0x00000000); 903 NV_WRITE(NV10_PGRAPH_CTX_SWITCH3, 0x00000000); 904 NV_WRITE(NV10_PGRAPH_CTX_SWITCH4, 0x00000000); 905 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); 906 NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); 907 NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); 908 909 return 0; 910} 911 912void nv10_graph_takedown(struct drm_device *dev) 913{ 914} 915