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 * paragr) 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 <core/client.h> 26 #include <core/os.h> 27 #include <core/handle.h> 28 29 #include <subdev/fb.h> 30 31 #include <engine/fifo.h> 32 #include <engine/gr.h> 33 34 #include "regs.h" 35 36 struct pipe_state { 37 u32 pipe_0x0000[0x040/4]; 38 u32 pipe_0x0040[0x010/4]; 39 u32 pipe_0x0200[0x0c0/4]; 40 u32 pipe_0x4400[0x080/4]; 41 u32 pipe_0x6400[0x3b0/4]; 42 u32 pipe_0x6800[0x2f0/4]; 43 u32 pipe_0x6c00[0x030/4]; 44 u32 pipe_0x7000[0x130/4]; 45 u32 pipe_0x7400[0x0c0/4]; 46 u32 pipe_0x7800[0x0c0/4]; 47 }; 48 49 static int nv10_gr_ctx_regs[] = { 50 NV10_PGRAPH_CTX_SWITCH(0), 51 NV10_PGRAPH_CTX_SWITCH(1), 52 NV10_PGRAPH_CTX_SWITCH(2), 53 NV10_PGRAPH_CTX_SWITCH(3), 54 NV10_PGRAPH_CTX_SWITCH(4), 55 NV10_PGRAPH_CTX_CACHE(0, 0), 56 NV10_PGRAPH_CTX_CACHE(0, 1), 57 NV10_PGRAPH_CTX_CACHE(0, 2), 58 NV10_PGRAPH_CTX_CACHE(0, 3), 59 NV10_PGRAPH_CTX_CACHE(0, 4), 60 NV10_PGRAPH_CTX_CACHE(1, 0), 61 NV10_PGRAPH_CTX_CACHE(1, 1), 62 NV10_PGRAPH_CTX_CACHE(1, 2), 63 NV10_PGRAPH_CTX_CACHE(1, 3), 64 NV10_PGRAPH_CTX_CACHE(1, 4), 65 NV10_PGRAPH_CTX_CACHE(2, 0), 66 NV10_PGRAPH_CTX_CACHE(2, 1), 67 NV10_PGRAPH_CTX_CACHE(2, 2), 68 NV10_PGRAPH_CTX_CACHE(2, 3), 69 NV10_PGRAPH_CTX_CACHE(2, 4), 70 NV10_PGRAPH_CTX_CACHE(3, 0), 71 NV10_PGRAPH_CTX_CACHE(3, 1), 72 NV10_PGRAPH_CTX_CACHE(3, 2), 73 NV10_PGRAPH_CTX_CACHE(3, 3), 74 NV10_PGRAPH_CTX_CACHE(3, 4), 75 NV10_PGRAPH_CTX_CACHE(4, 0), 76 NV10_PGRAPH_CTX_CACHE(4, 1), 77 NV10_PGRAPH_CTX_CACHE(4, 2), 78 NV10_PGRAPH_CTX_CACHE(4, 3), 79 NV10_PGRAPH_CTX_CACHE(4, 4), 80 NV10_PGRAPH_CTX_CACHE(5, 0), 81 NV10_PGRAPH_CTX_CACHE(5, 1), 82 NV10_PGRAPH_CTX_CACHE(5, 2), 83 NV10_PGRAPH_CTX_CACHE(5, 3), 84 NV10_PGRAPH_CTX_CACHE(5, 4), 85 NV10_PGRAPH_CTX_CACHE(6, 0), 86 NV10_PGRAPH_CTX_CACHE(6, 1), 87 NV10_PGRAPH_CTX_CACHE(6, 2), 88 NV10_PGRAPH_CTX_CACHE(6, 3), 89 NV10_PGRAPH_CTX_CACHE(6, 4), 90 NV10_PGRAPH_CTX_CACHE(7, 0), 91 NV10_PGRAPH_CTX_CACHE(7, 1), 92 NV10_PGRAPH_CTX_CACHE(7, 2), 93 NV10_PGRAPH_CTX_CACHE(7, 3), 94 NV10_PGRAPH_CTX_CACHE(7, 4), 95 NV10_PGRAPH_CTX_USER, 96 NV04_PGRAPH_DMA_START_0, 97 NV04_PGRAPH_DMA_START_1, 98 NV04_PGRAPH_DMA_LENGTH, 99 NV04_PGRAPH_DMA_MISC, 100 NV10_PGRAPH_DMA_PITCH, 101 NV04_PGRAPH_BOFFSET0, 102 NV04_PGRAPH_BBASE0, 103 NV04_PGRAPH_BLIMIT0, 104 NV04_PGRAPH_BOFFSET1, 105 NV04_PGRAPH_BBASE1, 106 NV04_PGRAPH_BLIMIT1, 107 NV04_PGRAPH_BOFFSET2, 108 NV04_PGRAPH_BBASE2, 109 NV04_PGRAPH_BLIMIT2, 110 NV04_PGRAPH_BOFFSET3, 111 NV04_PGRAPH_BBASE3, 112 NV04_PGRAPH_BLIMIT3, 113 NV04_PGRAPH_BOFFSET4, 114 NV04_PGRAPH_BBASE4, 115 NV04_PGRAPH_BLIMIT4, 116 NV04_PGRAPH_BOFFSET5, 117 NV04_PGRAPH_BBASE5, 118 NV04_PGRAPH_BLIMIT5, 119 NV04_PGRAPH_BPITCH0, 120 NV04_PGRAPH_BPITCH1, 121 NV04_PGRAPH_BPITCH2, 122 NV04_PGRAPH_BPITCH3, 123 NV04_PGRAPH_BPITCH4, 124 NV10_PGRAPH_SURFACE, 125 NV10_PGRAPH_STATE, 126 NV04_PGRAPH_BSWIZZLE2, 127 NV04_PGRAPH_BSWIZZLE5, 128 NV04_PGRAPH_BPIXEL, 129 NV10_PGRAPH_NOTIFY, 130 NV04_PGRAPH_PATT_COLOR0, 131 NV04_PGRAPH_PATT_COLOR1, 132 NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ 133 0x00400904, 134 0x00400908, 135 0x0040090c, 136 0x00400910, 137 0x00400914, 138 0x00400918, 139 0x0040091c, 140 0x00400920, 141 0x00400924, 142 0x00400928, 143 0x0040092c, 144 0x00400930, 145 0x00400934, 146 0x00400938, 147 0x0040093c, 148 0x00400940, 149 0x00400944, 150 0x00400948, 151 0x0040094c, 152 0x00400950, 153 0x00400954, 154 0x00400958, 155 0x0040095c, 156 0x00400960, 157 0x00400964, 158 0x00400968, 159 0x0040096c, 160 0x00400970, 161 0x00400974, 162 0x00400978, 163 0x0040097c, 164 0x00400980, 165 0x00400984, 166 0x00400988, 167 0x0040098c, 168 0x00400990, 169 0x00400994, 170 0x00400998, 171 0x0040099c, 172 0x004009a0, 173 0x004009a4, 174 0x004009a8, 175 0x004009ac, 176 0x004009b0, 177 0x004009b4, 178 0x004009b8, 179 0x004009bc, 180 0x004009c0, 181 0x004009c4, 182 0x004009c8, 183 0x004009cc, 184 0x004009d0, 185 0x004009d4, 186 0x004009d8, 187 0x004009dc, 188 0x004009e0, 189 0x004009e4, 190 0x004009e8, 191 0x004009ec, 192 0x004009f0, 193 0x004009f4, 194 0x004009f8, 195 0x004009fc, 196 NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ 197 0x0040080c, 198 NV04_PGRAPH_PATTERN_SHAPE, 199 NV03_PGRAPH_MONO_COLOR0, 200 NV04_PGRAPH_ROP3, 201 NV04_PGRAPH_CHROMA, 202 NV04_PGRAPH_BETA_AND, 203 NV04_PGRAPH_BETA_PREMULT, 204 0x00400e70, 205 0x00400e74, 206 0x00400e78, 207 0x00400e7c, 208 0x00400e80, 209 0x00400e84, 210 0x00400e88, 211 0x00400e8c, 212 0x00400ea0, 213 0x00400ea4, 214 0x00400ea8, 215 0x00400e90, 216 0x00400e94, 217 0x00400e98, 218 0x00400e9c, 219 NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */ 220 NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */ 221 0x00400f04, 222 0x00400f24, 223 0x00400f08, 224 0x00400f28, 225 0x00400f0c, 226 0x00400f2c, 227 0x00400f10, 228 0x00400f30, 229 0x00400f14, 230 0x00400f34, 231 0x00400f18, 232 0x00400f38, 233 0x00400f1c, 234 0x00400f3c, 235 NV10_PGRAPH_XFMODE0, 236 NV10_PGRAPH_XFMODE1, 237 NV10_PGRAPH_GLOBALSTATE0, 238 NV10_PGRAPH_GLOBALSTATE1, 239 NV04_PGRAPH_STORED_FMT, 240 NV04_PGRAPH_SOURCE_COLOR, 241 NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ 242 NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ 243 0x00400404, 244 0x00400484, 245 0x00400408, 246 0x00400488, 247 0x0040040c, 248 0x0040048c, 249 0x00400410, 250 0x00400490, 251 0x00400414, 252 0x00400494, 253 0x00400418, 254 0x00400498, 255 0x0040041c, 256 0x0040049c, 257 0x00400420, 258 0x004004a0, 259 0x00400424, 260 0x004004a4, 261 0x00400428, 262 0x004004a8, 263 0x0040042c, 264 0x004004ac, 265 0x00400430, 266 0x004004b0, 267 0x00400434, 268 0x004004b4, 269 0x00400438, 270 0x004004b8, 271 0x0040043c, 272 0x004004bc, 273 0x00400440, 274 0x004004c0, 275 0x00400444, 276 0x004004c4, 277 0x00400448, 278 0x004004c8, 279 0x0040044c, 280 0x004004cc, 281 0x00400450, 282 0x004004d0, 283 0x00400454, 284 0x004004d4, 285 0x00400458, 286 0x004004d8, 287 0x0040045c, 288 0x004004dc, 289 0x00400460, 290 0x004004e0, 291 0x00400464, 292 0x004004e4, 293 0x00400468, 294 0x004004e8, 295 0x0040046c, 296 0x004004ec, 297 0x00400470, 298 0x004004f0, 299 0x00400474, 300 0x004004f4, 301 0x00400478, 302 0x004004f8, 303 0x0040047c, 304 0x004004fc, 305 NV03_PGRAPH_ABS_UCLIP_XMIN, 306 NV03_PGRAPH_ABS_UCLIP_XMAX, 307 NV03_PGRAPH_ABS_UCLIP_YMIN, 308 NV03_PGRAPH_ABS_UCLIP_YMAX, 309 0x00400550, 310 0x00400558, 311 0x00400554, 312 0x0040055c, 313 NV03_PGRAPH_ABS_UCLIPA_XMIN, 314 NV03_PGRAPH_ABS_UCLIPA_XMAX, 315 NV03_PGRAPH_ABS_UCLIPA_YMIN, 316 NV03_PGRAPH_ABS_UCLIPA_YMAX, 317 NV03_PGRAPH_ABS_ICLIP_XMAX, 318 NV03_PGRAPH_ABS_ICLIP_YMAX, 319 NV03_PGRAPH_XY_LOGIC_MISC0, 320 NV03_PGRAPH_XY_LOGIC_MISC1, 321 NV03_PGRAPH_XY_LOGIC_MISC2, 322 NV03_PGRAPH_XY_LOGIC_MISC3, 323 NV03_PGRAPH_CLIPX_0, 324 NV03_PGRAPH_CLIPX_1, 325 NV03_PGRAPH_CLIPY_0, 326 NV03_PGRAPH_CLIPY_1, 327 NV10_PGRAPH_COMBINER0_IN_ALPHA, 328 NV10_PGRAPH_COMBINER1_IN_ALPHA, 329 NV10_PGRAPH_COMBINER0_IN_RGB, 330 NV10_PGRAPH_COMBINER1_IN_RGB, 331 NV10_PGRAPH_COMBINER_COLOR0, 332 NV10_PGRAPH_COMBINER_COLOR1, 333 NV10_PGRAPH_COMBINER0_OUT_ALPHA, 334 NV10_PGRAPH_COMBINER1_OUT_ALPHA, 335 NV10_PGRAPH_COMBINER0_OUT_RGB, 336 NV10_PGRAPH_COMBINER1_OUT_RGB, 337 NV10_PGRAPH_COMBINER_FINAL0, 338 NV10_PGRAPH_COMBINER_FINAL1, 339 0x00400e00, 340 0x00400e04, 341 0x00400e08, 342 0x00400e0c, 343 0x00400e10, 344 0x00400e14, 345 0x00400e18, 346 0x00400e1c, 347 0x00400e20, 348 0x00400e24, 349 0x00400e28, 350 0x00400e2c, 351 0x00400e30, 352 0x00400e34, 353 0x00400e38, 354 0x00400e3c, 355 NV04_PGRAPH_PASSTHRU_0, 356 NV04_PGRAPH_PASSTHRU_1, 357 NV04_PGRAPH_PASSTHRU_2, 358 NV10_PGRAPH_DIMX_TEXTURE, 359 NV10_PGRAPH_WDIMX_TEXTURE, 360 NV10_PGRAPH_DVD_COLORFMT, 361 NV10_PGRAPH_SCALED_FORMAT, 362 NV04_PGRAPH_MISC24_0, 363 NV04_PGRAPH_MISC24_1, 364 NV04_PGRAPH_MISC24_2, 365 NV03_PGRAPH_X_MISC, 366 NV03_PGRAPH_Y_MISC, 367 NV04_PGRAPH_VALID1, 368 NV04_PGRAPH_VALID2, 369 }; 370 371 static int nv17_gr_ctx_regs[] = { 372 NV10_PGRAPH_DEBUG_4, 373 0x004006b0, 374 0x00400eac, 375 0x00400eb0, 376 0x00400eb4, 377 0x00400eb8, 378 0x00400ebc, 379 0x00400ec0, 380 0x00400ec4, 381 0x00400ec8, 382 0x00400ecc, 383 0x00400ed0, 384 0x00400ed4, 385 0x00400ed8, 386 0x00400edc, 387 0x00400ee0, 388 0x00400a00, 389 0x00400a04, 390 }; 391 392 struct nv10_gr_priv { 393 struct nouveau_gr base; 394 struct nv10_gr_chan *chan[32]; 395 spinlock_t lock; 396 }; 397 398 struct nv10_gr_chan { 399 struct nouveau_object base; 400 int chid; 401 int nv10[ARRAY_SIZE(nv10_gr_ctx_regs)]; 402 int nv17[ARRAY_SIZE(nv17_gr_ctx_regs)]; 403 struct pipe_state pipe_state; 404 u32 lma_window[4]; 405 }; 406 407 408 static inline struct nv10_gr_priv * 409 nv10_gr_priv(struct nv10_gr_chan *chan) 410 { 411 return (void *)nv_object(chan)->engine; 412 } 413 414 /******************************************************************************* 415 * Graphics object classes 416 ******************************************************************************/ 417 418 #define PIPE_SAVE(priv, state, addr) \ 419 do { \ 420 int __i; \ 421 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \ 422 for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ 423 state[__i] = nv_rd32(priv, NV10_PGRAPH_PIPE_DATA); \ 424 } while (0) 425 426 #define PIPE_RESTORE(priv, state, addr) \ 427 do { \ 428 int __i; \ 429 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \ 430 for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ 431 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, state[__i]); \ 432 } while (0) 433 434 static struct nouveau_oclass 435 nv10_gr_sclass[] = { 436 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */ 437 { 0x0019, &nv04_gr_ofuncs }, /* clip */ 438 { 0x0030, &nv04_gr_ofuncs }, /* null */ 439 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */ 440 { 0x0043, &nv04_gr_ofuncs }, /* rop */ 441 { 0x0044, &nv04_gr_ofuncs }, /* pattern */ 442 { 0x004a, &nv04_gr_ofuncs }, /* gdi */ 443 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */ 444 { 0x005f, &nv04_gr_ofuncs }, /* blit */ 445 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */ 446 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */ 447 { 0x0089, &nv04_gr_ofuncs }, /* sifm */ 448 { 0x008a, &nv04_gr_ofuncs }, /* ifc */ 449 { 0x009f, &nv04_gr_ofuncs }, /* blit */ 450 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */ 451 { 0x0094, &nv04_gr_ofuncs }, /* ttri */ 452 { 0x0095, &nv04_gr_ofuncs }, /* mtri */ 453 { 0x0056, &nv04_gr_ofuncs }, /* celcius */ 454 {}, 455 }; 456 457 static struct nouveau_oclass 458 nv15_gr_sclass[] = { 459 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */ 460 { 0x0019, &nv04_gr_ofuncs }, /* clip */ 461 { 0x0030, &nv04_gr_ofuncs }, /* null */ 462 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */ 463 { 0x0043, &nv04_gr_ofuncs }, /* rop */ 464 { 0x0044, &nv04_gr_ofuncs }, /* pattern */ 465 { 0x004a, &nv04_gr_ofuncs }, /* gdi */ 466 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */ 467 { 0x005f, &nv04_gr_ofuncs }, /* blit */ 468 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */ 469 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */ 470 { 0x0089, &nv04_gr_ofuncs }, /* sifm */ 471 { 0x008a, &nv04_gr_ofuncs }, /* ifc */ 472 { 0x009f, &nv04_gr_ofuncs }, /* blit */ 473 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */ 474 { 0x0094, &nv04_gr_ofuncs }, /* ttri */ 475 { 0x0095, &nv04_gr_ofuncs }, /* mtri */ 476 { 0x0096, &nv04_gr_ofuncs }, /* celcius */ 477 {}, 478 }; 479 480 static int 481 nv17_gr_mthd_lma_window(struct nouveau_object *object, u32 mthd, 482 void *args, u32 size) 483 { 484 struct nv10_gr_chan *chan = (void *)object->parent; 485 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 486 struct pipe_state *pipe = &chan->pipe_state; 487 u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; 488 u32 xfmode0, xfmode1; 489 u32 data = *(u32 *)args; 490 int i; 491 492 chan->lma_window[(mthd - 0x1638) / 4] = data; 493 494 if (mthd != 0x1644) 495 return 0; 496 497 nv04_gr_idle(priv); 498 499 PIPE_SAVE(priv, pipe_0x0040, 0x0040); 500 PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200); 501 502 PIPE_RESTORE(priv, chan->lma_window, 0x6790); 503 504 nv04_gr_idle(priv); 505 506 xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0); 507 xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1); 508 509 PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400); 510 PIPE_SAVE(priv, pipe_0x64c0, 0x64c0); 511 PIPE_SAVE(priv, pipe_0x6ab0, 0x6ab0); 512 PIPE_SAVE(priv, pipe_0x6a80, 0x6a80); 513 514 nv04_gr_idle(priv); 515 516 nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000); 517 nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000); 518 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); 519 for (i = 0; i < 4; i++) 520 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); 521 for (i = 0; i < 4; i++) 522 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); 523 524 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); 525 for (i = 0; i < 3; i++) 526 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); 527 528 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); 529 for (i = 0; i < 3; i++) 530 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); 531 532 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); 533 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008); 534 535 PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200); 536 537 nv04_gr_idle(priv); 538 539 PIPE_RESTORE(priv, pipe_0x0040, 0x0040); 540 541 nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0); 542 nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1); 543 544 PIPE_RESTORE(priv, pipe_0x64c0, 0x64c0); 545 PIPE_RESTORE(priv, pipe_0x6ab0, 0x6ab0); 546 PIPE_RESTORE(priv, pipe_0x6a80, 0x6a80); 547 PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400); 548 549 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0); 550 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); 551 552 nv04_gr_idle(priv); 553 554 return 0; 555 } 556 557 static int 558 nv17_gr_mthd_lma_enable(struct nouveau_object *object, u32 mthd, 559 void *args, u32 size) 560 { 561 struct nv10_gr_chan *chan = (void *)object->parent; 562 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 563 564 nv04_gr_idle(priv); 565 566 nv_mask(priv, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100); 567 nv_mask(priv, 0x4006b0, 0x08000000, 0x08000000); 568 return 0; 569 } 570 571 static struct nouveau_omthds 572 nv17_celcius_omthds[] = { 573 { 0x1638, 0x1638, nv17_gr_mthd_lma_window }, 574 { 0x163c, 0x163c, nv17_gr_mthd_lma_window }, 575 { 0x1640, 0x1640, nv17_gr_mthd_lma_window }, 576 { 0x1644, 0x1644, nv17_gr_mthd_lma_window }, 577 { 0x1658, 0x1658, nv17_gr_mthd_lma_enable }, 578 {} 579 }; 580 581 static struct nouveau_oclass 582 nv17_gr_sclass[] = { 583 { 0x0012, &nv04_gr_ofuncs }, /* beta1 */ 584 { 0x0019, &nv04_gr_ofuncs }, /* clip */ 585 { 0x0030, &nv04_gr_ofuncs }, /* null */ 586 { 0x0039, &nv04_gr_ofuncs }, /* m2mf */ 587 { 0x0043, &nv04_gr_ofuncs }, /* rop */ 588 { 0x0044, &nv04_gr_ofuncs }, /* pattern */ 589 { 0x004a, &nv04_gr_ofuncs }, /* gdi */ 590 { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */ 591 { 0x005f, &nv04_gr_ofuncs }, /* blit */ 592 { 0x0062, &nv04_gr_ofuncs }, /* surf2d */ 593 { 0x0072, &nv04_gr_ofuncs }, /* beta4 */ 594 { 0x0089, &nv04_gr_ofuncs }, /* sifm */ 595 { 0x008a, &nv04_gr_ofuncs }, /* ifc */ 596 { 0x009f, &nv04_gr_ofuncs }, /* blit */ 597 { 0x0093, &nv04_gr_ofuncs }, /* surf3d */ 598 { 0x0094, &nv04_gr_ofuncs }, /* ttri */ 599 { 0x0095, &nv04_gr_ofuncs }, /* mtri */ 600 { 0x0099, &nv04_gr_ofuncs, nv17_celcius_omthds }, 601 {}, 602 }; 603 604 /******************************************************************************* 605 * PGRAPH context 606 ******************************************************************************/ 607 608 static struct nv10_gr_chan * 609 nv10_gr_channel(struct nv10_gr_priv *priv) 610 { 611 struct nv10_gr_chan *chan = NULL; 612 if (nv_rd32(priv, 0x400144) & 0x00010000) { 613 int chid = nv_rd32(priv, 0x400148) >> 24; 614 if (chid < ARRAY_SIZE(priv->chan)) 615 chan = priv->chan[chid]; 616 } 617 return chan; 618 } 619 620 static void 621 nv10_gr_save_pipe(struct nv10_gr_chan *chan) 622 { 623 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 624 struct pipe_state *pipe = &chan->pipe_state; 625 626 PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400); 627 PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200); 628 PIPE_SAVE(priv, pipe->pipe_0x6400, 0x6400); 629 PIPE_SAVE(priv, pipe->pipe_0x6800, 0x6800); 630 PIPE_SAVE(priv, pipe->pipe_0x6c00, 0x6c00); 631 PIPE_SAVE(priv, pipe->pipe_0x7000, 0x7000); 632 PIPE_SAVE(priv, pipe->pipe_0x7400, 0x7400); 633 PIPE_SAVE(priv, pipe->pipe_0x7800, 0x7800); 634 PIPE_SAVE(priv, pipe->pipe_0x0040, 0x0040); 635 PIPE_SAVE(priv, pipe->pipe_0x0000, 0x0000); 636 } 637 638 static void 639 nv10_gr_load_pipe(struct nv10_gr_chan *chan) 640 { 641 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 642 struct pipe_state *pipe = &chan->pipe_state; 643 u32 xfmode0, xfmode1; 644 int i; 645 646 nv04_gr_idle(priv); 647 /* XXX check haiku comments */ 648 xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0); 649 xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1); 650 nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000); 651 nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000); 652 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); 653 for (i = 0; i < 4; i++) 654 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); 655 for (i = 0; i < 4; i++) 656 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); 657 658 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); 659 for (i = 0; i < 3; i++) 660 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); 661 662 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); 663 for (i = 0; i < 3; i++) 664 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); 665 666 nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); 667 nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008); 668 669 670 PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200); 671 nv04_gr_idle(priv); 672 673 /* restore XFMODE */ 674 nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0); 675 nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1); 676 PIPE_RESTORE(priv, pipe->pipe_0x6400, 0x6400); 677 PIPE_RESTORE(priv, pipe->pipe_0x6800, 0x6800); 678 PIPE_RESTORE(priv, pipe->pipe_0x6c00, 0x6c00); 679 PIPE_RESTORE(priv, pipe->pipe_0x7000, 0x7000); 680 PIPE_RESTORE(priv, pipe->pipe_0x7400, 0x7400); 681 PIPE_RESTORE(priv, pipe->pipe_0x7800, 0x7800); 682 PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400); 683 PIPE_RESTORE(priv, pipe->pipe_0x0000, 0x0000); 684 PIPE_RESTORE(priv, pipe->pipe_0x0040, 0x0040); 685 nv04_gr_idle(priv); 686 } 687 688 static void 689 nv10_gr_create_pipe(struct nv10_gr_chan *chan) 690 { 691 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 692 struct pipe_state *pipe_state = &chan->pipe_state; 693 u32 *pipe_state_addr; 694 int i; 695 #define PIPE_INIT(addr) \ 696 do { \ 697 pipe_state_addr = pipe_state->pipe_##addr; \ 698 } while (0) 699 #define PIPE_INIT_END(addr) \ 700 do { \ 701 u32 *__end_addr = pipe_state->pipe_##addr + \ 702 ARRAY_SIZE(pipe_state->pipe_##addr); \ 703 if (pipe_state_addr != __end_addr) \ 704 nv_error(priv, "incomplete pipe init for 0x%x : %p/%p\n", \ 705 addr, pipe_state_addr, __end_addr); \ 706 } while (0) 707 #define NV_WRITE_PIPE_INIT(value) *(pipe_state_addr++) = value 708 709 PIPE_INIT(0x0200); 710 for (i = 0; i < 48; i++) 711 NV_WRITE_PIPE_INIT(0x00000000); 712 PIPE_INIT_END(0x0200); 713 714 PIPE_INIT(0x6400); 715 for (i = 0; i < 211; i++) 716 NV_WRITE_PIPE_INIT(0x00000000); 717 NV_WRITE_PIPE_INIT(0x3f800000); 718 NV_WRITE_PIPE_INIT(0x40000000); 719 NV_WRITE_PIPE_INIT(0x40000000); 720 NV_WRITE_PIPE_INIT(0x40000000); 721 NV_WRITE_PIPE_INIT(0x40000000); 722 NV_WRITE_PIPE_INIT(0x00000000); 723 NV_WRITE_PIPE_INIT(0x00000000); 724 NV_WRITE_PIPE_INIT(0x3f800000); 725 NV_WRITE_PIPE_INIT(0x00000000); 726 NV_WRITE_PIPE_INIT(0x3f000000); 727 NV_WRITE_PIPE_INIT(0x3f000000); 728 NV_WRITE_PIPE_INIT(0x00000000); 729 NV_WRITE_PIPE_INIT(0x00000000); 730 NV_WRITE_PIPE_INIT(0x00000000); 731 NV_WRITE_PIPE_INIT(0x00000000); 732 NV_WRITE_PIPE_INIT(0x3f800000); 733 NV_WRITE_PIPE_INIT(0x00000000); 734 NV_WRITE_PIPE_INIT(0x00000000); 735 NV_WRITE_PIPE_INIT(0x00000000); 736 NV_WRITE_PIPE_INIT(0x00000000); 737 NV_WRITE_PIPE_INIT(0x00000000); 738 NV_WRITE_PIPE_INIT(0x3f800000); 739 NV_WRITE_PIPE_INIT(0x3f800000); 740 NV_WRITE_PIPE_INIT(0x3f800000); 741 NV_WRITE_PIPE_INIT(0x3f800000); 742 PIPE_INIT_END(0x6400); 743 744 PIPE_INIT(0x6800); 745 for (i = 0; i < 162; i++) 746 NV_WRITE_PIPE_INIT(0x00000000); 747 NV_WRITE_PIPE_INIT(0x3f800000); 748 for (i = 0; i < 25; i++) 749 NV_WRITE_PIPE_INIT(0x00000000); 750 PIPE_INIT_END(0x6800); 751 752 PIPE_INIT(0x6c00); 753 NV_WRITE_PIPE_INIT(0x00000000); 754 NV_WRITE_PIPE_INIT(0x00000000); 755 NV_WRITE_PIPE_INIT(0x00000000); 756 NV_WRITE_PIPE_INIT(0x00000000); 757 NV_WRITE_PIPE_INIT(0xbf800000); 758 NV_WRITE_PIPE_INIT(0x00000000); 759 NV_WRITE_PIPE_INIT(0x00000000); 760 NV_WRITE_PIPE_INIT(0x00000000); 761 NV_WRITE_PIPE_INIT(0x00000000); 762 NV_WRITE_PIPE_INIT(0x00000000); 763 NV_WRITE_PIPE_INIT(0x00000000); 764 NV_WRITE_PIPE_INIT(0x00000000); 765 PIPE_INIT_END(0x6c00); 766 767 PIPE_INIT(0x7000); 768 NV_WRITE_PIPE_INIT(0x00000000); 769 NV_WRITE_PIPE_INIT(0x00000000); 770 NV_WRITE_PIPE_INIT(0x00000000); 771 NV_WRITE_PIPE_INIT(0x00000000); 772 NV_WRITE_PIPE_INIT(0x00000000); 773 NV_WRITE_PIPE_INIT(0x00000000); 774 NV_WRITE_PIPE_INIT(0x00000000); 775 NV_WRITE_PIPE_INIT(0x00000000); 776 NV_WRITE_PIPE_INIT(0x00000000); 777 NV_WRITE_PIPE_INIT(0x00000000); 778 NV_WRITE_PIPE_INIT(0x00000000); 779 NV_WRITE_PIPE_INIT(0x00000000); 780 NV_WRITE_PIPE_INIT(0x7149f2ca); 781 NV_WRITE_PIPE_INIT(0x00000000); 782 NV_WRITE_PIPE_INIT(0x00000000); 783 NV_WRITE_PIPE_INIT(0x00000000); 784 NV_WRITE_PIPE_INIT(0x7149f2ca); 785 NV_WRITE_PIPE_INIT(0x00000000); 786 NV_WRITE_PIPE_INIT(0x00000000); 787 NV_WRITE_PIPE_INIT(0x00000000); 788 NV_WRITE_PIPE_INIT(0x7149f2ca); 789 NV_WRITE_PIPE_INIT(0x00000000); 790 NV_WRITE_PIPE_INIT(0x00000000); 791 NV_WRITE_PIPE_INIT(0x00000000); 792 NV_WRITE_PIPE_INIT(0x7149f2ca); 793 NV_WRITE_PIPE_INIT(0x00000000); 794 NV_WRITE_PIPE_INIT(0x00000000); 795 NV_WRITE_PIPE_INIT(0x00000000); 796 NV_WRITE_PIPE_INIT(0x7149f2ca); 797 NV_WRITE_PIPE_INIT(0x00000000); 798 NV_WRITE_PIPE_INIT(0x00000000); 799 NV_WRITE_PIPE_INIT(0x00000000); 800 NV_WRITE_PIPE_INIT(0x7149f2ca); 801 NV_WRITE_PIPE_INIT(0x00000000); 802 NV_WRITE_PIPE_INIT(0x00000000); 803 NV_WRITE_PIPE_INIT(0x00000000); 804 NV_WRITE_PIPE_INIT(0x7149f2ca); 805 NV_WRITE_PIPE_INIT(0x00000000); 806 NV_WRITE_PIPE_INIT(0x00000000); 807 NV_WRITE_PIPE_INIT(0x00000000); 808 NV_WRITE_PIPE_INIT(0x7149f2ca); 809 for (i = 0; i < 35; i++) 810 NV_WRITE_PIPE_INIT(0x00000000); 811 PIPE_INIT_END(0x7000); 812 813 PIPE_INIT(0x7400); 814 for (i = 0; i < 48; i++) 815 NV_WRITE_PIPE_INIT(0x00000000); 816 PIPE_INIT_END(0x7400); 817 818 PIPE_INIT(0x7800); 819 for (i = 0; i < 48; i++) 820 NV_WRITE_PIPE_INIT(0x00000000); 821 PIPE_INIT_END(0x7800); 822 823 PIPE_INIT(0x4400); 824 for (i = 0; i < 32; i++) 825 NV_WRITE_PIPE_INIT(0x00000000); 826 PIPE_INIT_END(0x4400); 827 828 PIPE_INIT(0x0000); 829 for (i = 0; i < 16; i++) 830 NV_WRITE_PIPE_INIT(0x00000000); 831 PIPE_INIT_END(0x0000); 832 833 PIPE_INIT(0x0040); 834 for (i = 0; i < 4; i++) 835 NV_WRITE_PIPE_INIT(0x00000000); 836 PIPE_INIT_END(0x0040); 837 838 #undef PIPE_INIT 839 #undef PIPE_INIT_END 840 #undef NV_WRITE_PIPE_INIT 841 } 842 843 static int 844 nv10_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg) 845 { 846 int i; 847 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) { 848 if (nv10_gr_ctx_regs[i] == reg) 849 return i; 850 } 851 nv_error(priv, "unknow offset nv10_ctx_regs %d\n", reg); 852 return -1; 853 } 854 855 static int 856 nv17_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg) 857 { 858 int i; 859 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) { 860 if (nv17_gr_ctx_regs[i] == reg) 861 return i; 862 } 863 nv_error(priv, "unknow offset nv17_ctx_regs %d\n", reg); 864 return -1; 865 } 866 867 static void 868 nv10_gr_load_dma_vtxbuf(struct nv10_gr_chan *chan, int chid, u32 inst) 869 { 870 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 871 u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; 872 u32 ctx_user, ctx_switch[5]; 873 int i, subchan = -1; 874 875 /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state 876 * that cannot be restored via MMIO. Do it through the FIFO 877 * instead. 878 */ 879 880 /* Look for a celsius object */ 881 for (i = 0; i < 8; i++) { 882 int class = nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff; 883 884 if (class == 0x56 || class == 0x96 || class == 0x99) { 885 subchan = i; 886 break; 887 } 888 } 889 890 if (subchan < 0 || !inst) 891 return; 892 893 /* Save the current ctx object */ 894 ctx_user = nv_rd32(priv, NV10_PGRAPH_CTX_USER); 895 for (i = 0; i < 5; i++) 896 ctx_switch[i] = nv_rd32(priv, NV10_PGRAPH_CTX_SWITCH(i)); 897 898 /* Save the FIFO state */ 899 st2 = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2); 900 st2_dl = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DL); 901 st2_dh = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DH); 902 fifo_ptr = nv_rd32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR); 903 904 for (i = 0; i < ARRAY_SIZE(fifo); i++) 905 fifo[i] = nv_rd32(priv, 0x4007a0 + 4 * i); 906 907 /* Switch to the celsius subchannel */ 908 for (i = 0; i < 5; i++) 909 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), 910 nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(subchan, i))); 911 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13); 912 913 /* Inject NV10TCL_DMA_VTXBUF */ 914 nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0); 915 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, 916 0x2c000000 | chid << 20 | subchan << 16 | 0x18c); 917 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, inst); 918 nv_mask(priv, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); 919 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); 920 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); 921 922 /* Restore the FIFO state */ 923 for (i = 0; i < ARRAY_SIZE(fifo); i++) 924 nv_wr32(priv, 0x4007a0 + 4 * i, fifo[i]); 925 926 nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr); 927 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, st2); 928 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl); 929 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh); 930 931 /* Restore the current ctx object */ 932 for (i = 0; i < 5; i++) 933 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]); 934 nv_wr32(priv, NV10_PGRAPH_CTX_USER, ctx_user); 935 } 936 937 static int 938 nv10_gr_load_context(struct nv10_gr_chan *chan, int chid) 939 { 940 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 941 u32 inst; 942 int i; 943 944 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) 945 nv_wr32(priv, nv10_gr_ctx_regs[i], chan->nv10[i]); 946 947 if (nv_device(priv)->card_type >= NV_11 && 948 nv_device(priv)->chipset >= 0x17) { 949 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) 950 nv_wr32(priv, nv17_gr_ctx_regs[i], chan->nv17[i]); 951 } 952 953 nv10_gr_load_pipe(chan); 954 955 inst = nv_rd32(priv, NV10_PGRAPH_GLOBALSTATE1) & 0xffff; 956 nv10_gr_load_dma_vtxbuf(chan, chid, inst); 957 958 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100); 959 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24); 960 nv_mask(priv, NV10_PGRAPH_FFINTFC_ST2, 0x30000000, 0x00000000); 961 return 0; 962 } 963 964 static int 965 nv10_gr_unload_context(struct nv10_gr_chan *chan) 966 { 967 struct nv10_gr_priv *priv = nv10_gr_priv(chan); 968 int i; 969 970 for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) 971 chan->nv10[i] = nv_rd32(priv, nv10_gr_ctx_regs[i]); 972 973 if (nv_device(priv)->card_type >= NV_11 && 974 nv_device(priv)->chipset >= 0x17) { 975 for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) 976 chan->nv17[i] = nv_rd32(priv, nv17_gr_ctx_regs[i]); 977 } 978 979 nv10_gr_save_pipe(chan); 980 981 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000000); 982 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000); 983 return 0; 984 } 985 986 static void 987 nv10_gr_context_switch(struct nv10_gr_priv *priv) 988 { 989 struct nv10_gr_chan *prev = NULL; 990 struct nv10_gr_chan *next = NULL; 991 unsigned long flags; 992 int chid; 993 994 spin_lock_irqsave(&priv->lock, flags); 995 nv04_gr_idle(priv); 996 997 /* If previous context is valid, we need to save it */ 998 prev = nv10_gr_channel(priv); 999 if (prev) 1000 nv10_gr_unload_context(prev); 1001 1002 /* load context for next channel */ 1003 chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; 1004 next = priv->chan[chid]; 1005 if (next) 1006 nv10_gr_load_context(next, chid); 1007 1008 spin_unlock_irqrestore(&priv->lock, flags); 1009 } 1010 1011 #define NV_WRITE_CTX(reg, val) do { \ 1012 int offset = nv10_gr_ctx_regs_find_offset(priv, reg); \ 1013 if (offset > 0) \ 1014 chan->nv10[offset] = val; \ 1015 } while (0) 1016 1017 #define NV17_WRITE_CTX(reg, val) do { \ 1018 int offset = nv17_gr_ctx_regs_find_offset(priv, reg); \ 1019 if (offset > 0) \ 1020 chan->nv17[offset] = val; \ 1021 } while (0) 1022 1023 static int 1024 nv10_gr_context_ctor(struct nouveau_object *parent, 1025 struct nouveau_object *engine, 1026 struct nouveau_oclass *oclass, void *data, u32 size, 1027 struct nouveau_object **pobject) 1028 { 1029 struct nouveau_fifo_chan *fifo = (void *)parent; 1030 struct nv10_gr_priv *priv = (void *)engine; 1031 struct nv10_gr_chan *chan; 1032 unsigned long flags; 1033 int ret; 1034 1035 ret = nouveau_object_create(parent, engine, oclass, 0, &chan); 1036 *pobject = nv_object(chan); 1037 if (ret) 1038 return ret; 1039 1040 spin_lock_irqsave(&priv->lock, flags); 1041 if (priv->chan[fifo->chid]) { 1042 *pobject = nv_object(priv->chan[fifo->chid]); 1043 atomic_inc(&(*pobject)->refcount); 1044 spin_unlock_irqrestore(&priv->lock, flags); 1045 nouveau_object_destroy(&chan->base); 1046 return 1; 1047 } 1048 1049 NV_WRITE_CTX(0x00400e88, 0x08000000); 1050 NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); 1051 NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); 1052 NV_WRITE_CTX(0x00400e10, 0x00001000); 1053 NV_WRITE_CTX(0x00400e14, 0x00001000); 1054 NV_WRITE_CTX(0x00400e30, 0x00080008); 1055 NV_WRITE_CTX(0x00400e34, 0x00080008); 1056 if (nv_device(priv)->card_type >= NV_11 && 1057 nv_device(priv)->chipset >= 0x17) { 1058 /* is it really needed ??? */ 1059 NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, 1060 nv_rd32(priv, NV10_PGRAPH_DEBUG_4)); 1061 NV17_WRITE_CTX(0x004006b0, nv_rd32(priv, 0x004006b0)); 1062 NV17_WRITE_CTX(0x00400eac, 0x0fff0000); 1063 NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); 1064 NV17_WRITE_CTX(0x00400ec0, 0x00000080); 1065 NV17_WRITE_CTX(0x00400ed0, 0x00000080); 1066 } 1067 NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24); 1068 1069 nv10_gr_create_pipe(chan); 1070 1071 priv->chan[fifo->chid] = chan; 1072 chan->chid = fifo->chid; 1073 spin_unlock_irqrestore(&priv->lock, flags); 1074 return 0; 1075 } 1076 1077 static void 1078 nv10_gr_context_dtor(struct nouveau_object *object) 1079 { 1080 struct nv10_gr_priv *priv = (void *)object->engine; 1081 struct nv10_gr_chan *chan = (void *)object; 1082 unsigned long flags; 1083 1084 spin_lock_irqsave(&priv->lock, flags); 1085 priv->chan[chan->chid] = NULL; 1086 spin_unlock_irqrestore(&priv->lock, flags); 1087 1088 nouveau_object_destroy(&chan->base); 1089 } 1090 1091 static int 1092 nv10_gr_context_fini(struct nouveau_object *object, bool suspend) 1093 { 1094 struct nv10_gr_priv *priv = (void *)object->engine; 1095 struct nv10_gr_chan *chan = (void *)object; 1096 unsigned long flags; 1097 1098 spin_lock_irqsave(&priv->lock, flags); 1099 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); 1100 if (nv10_gr_channel(priv) == chan) 1101 nv10_gr_unload_context(chan); 1102 nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); 1103 spin_unlock_irqrestore(&priv->lock, flags); 1104 1105 return nouveau_object_fini(&chan->base, suspend); 1106 } 1107 1108 static struct nouveau_oclass 1109 nv10_gr_cclass = { 1110 .handle = NV_ENGCTX(GR, 0x10), 1111 .ofuncs = &(struct nouveau_ofuncs) { 1112 .ctor = nv10_gr_context_ctor, 1113 .dtor = nv10_gr_context_dtor, 1114 .init = nouveau_object_init, 1115 .fini = nv10_gr_context_fini, 1116 }, 1117 }; 1118 1119 /******************************************************************************* 1120 * PGRAPH engine/subdev functions 1121 ******************************************************************************/ 1122 1123 static void 1124 nv10_gr_tile_prog(struct nouveau_engine *engine, int i) 1125 { 1126 struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i]; 1127 struct nouveau_fifo *pfifo = nouveau_fifo(engine); 1128 struct nv10_gr_priv *priv = (void *)engine; 1129 unsigned long flags; 1130 1131 pfifo->pause(pfifo, &flags); 1132 nv04_gr_idle(priv); 1133 1134 nv_wr32(priv, NV10_PGRAPH_TLIMIT(i), tile->limit); 1135 nv_wr32(priv, NV10_PGRAPH_TSIZE(i), tile->pitch); 1136 nv_wr32(priv, NV10_PGRAPH_TILE(i), tile->addr); 1137 1138 pfifo->start(pfifo, &flags); 1139 } 1140 1141 const struct nouveau_bitfield nv10_gr_intr_name[] = { 1142 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, 1143 { NV_PGRAPH_INTR_ERROR, "ERROR" }, 1144 {} 1145 }; 1146 1147 const struct nouveau_bitfield nv10_gr_nstatus[] = { 1148 { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, 1149 { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, 1150 { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, 1151 { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, 1152 {} 1153 }; 1154 1155 static void 1156 nv10_gr_intr(struct nouveau_subdev *subdev) 1157 { 1158 struct nv10_gr_priv *priv = (void *)subdev; 1159 struct nv10_gr_chan *chan = NULL; 1160 struct nouveau_namedb *namedb = NULL; 1161 struct nouveau_handle *handle = NULL; 1162 u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); 1163 u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); 1164 u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); 1165 u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); 1166 u32 chid = (addr & 0x01f00000) >> 20; 1167 u32 subc = (addr & 0x00070000) >> 16; 1168 u32 mthd = (addr & 0x00001ffc); 1169 u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); 1170 u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff; 1171 u32 show = stat; 1172 unsigned long flags; 1173 1174 spin_lock_irqsave(&priv->lock, flags); 1175 chan = priv->chan[chid]; 1176 if (chan) 1177 namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS); 1178 spin_unlock_irqrestore(&priv->lock, flags); 1179 1180 if (stat & NV_PGRAPH_INTR_ERROR) { 1181 if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { 1182 handle = nouveau_namedb_get_class(namedb, class); 1183 if (handle && !nv_call(handle->object, mthd, data)) 1184 show &= ~NV_PGRAPH_INTR_ERROR; 1185 } 1186 } 1187 1188 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { 1189 nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); 1190 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; 1191 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; 1192 nv10_gr_context_switch(priv); 1193 } 1194 1195 nv_wr32(priv, NV03_PGRAPH_INTR, stat); 1196 nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); 1197 1198 if (show) { 1199 nv_error(priv, "%s", ""); 1200 nouveau_bitfield_print(nv10_gr_intr_name, show); 1201 pr_cont(" nsource:"); 1202 nouveau_bitfield_print(nv04_gr_nsource, nsource); 1203 pr_cont(" nstatus:"); 1204 nouveau_bitfield_print(nv10_gr_nstatus, nstatus); 1205 pr_cont("\n"); 1206 nv_error(priv, 1207 "ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", 1208 chid, nouveau_client_name(chan), subc, class, mthd, 1209 data); 1210 } 1211 1212 nouveau_namedb_put(handle); 1213 } 1214 1215 static int 1216 nv10_gr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 1217 struct nouveau_oclass *oclass, void *data, u32 size, 1218 struct nouveau_object **pobject) 1219 { 1220 struct nv10_gr_priv *priv; 1221 int ret; 1222 1223 ret = nouveau_gr_create(parent, engine, oclass, true, &priv); 1224 *pobject = nv_object(priv); 1225 if (ret) 1226 return ret; 1227 1228 nv_subdev(priv)->unit = 0x00001000; 1229 nv_subdev(priv)->intr = nv10_gr_intr; 1230 nv_engine(priv)->cclass = &nv10_gr_cclass; 1231 1232 if (nv_device(priv)->chipset <= 0x10) 1233 nv_engine(priv)->sclass = nv10_gr_sclass; 1234 else 1235 if (nv_device(priv)->chipset < 0x17 || 1236 nv_device(priv)->card_type < NV_11) 1237 nv_engine(priv)->sclass = nv15_gr_sclass; 1238 else 1239 nv_engine(priv)->sclass = nv17_gr_sclass; 1240 1241 nv_engine(priv)->tile_prog = nv10_gr_tile_prog; 1242 spin_lock_init(&priv->lock); 1243 return 0; 1244 } 1245 1246 static void 1247 nv10_gr_dtor(struct nouveau_object *object) 1248 { 1249 struct nv10_gr_priv *priv = (void *)object; 1250 nouveau_gr_destroy(&priv->base); 1251 } 1252 1253 static int 1254 nv10_gr_init(struct nouveau_object *object) 1255 { 1256 struct nouveau_engine *engine = nv_engine(object); 1257 struct nouveau_fb *pfb = nouveau_fb(object); 1258 struct nv10_gr_priv *priv = (void *)engine; 1259 int ret, i; 1260 1261 ret = nouveau_gr_init(&priv->base); 1262 if (ret) 1263 return ret; 1264 1265 nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF); 1266 nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 1267 1268 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); 1269 nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000); 1270 nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700); 1271 /* nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */ 1272 nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9); 1273 nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31)); 1274 1275 if (nv_device(priv)->card_type >= NV_11 && 1276 nv_device(priv)->chipset >= 0x17) { 1277 nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000); 1278 nv_wr32(priv, 0x400a10, 0x03ff3fb6); 1279 nv_wr32(priv, 0x400838, 0x002f8684); 1280 nv_wr32(priv, 0x40083c, 0x00115f3f); 1281 nv_wr32(priv, 0x4006b0, 0x40000020); 1282 } else { 1283 nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000); 1284 } 1285 1286 /* Turn all the tiling regions off. */ 1287 for (i = 0; i < pfb->tile.regions; i++) 1288 engine->tile_prog(engine, i); 1289 1290 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000); 1291 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000); 1292 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000); 1293 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000); 1294 nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000); 1295 nv_wr32(priv, NV10_PGRAPH_STATE, 0xFFFFFFFF); 1296 1297 nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000); 1298 nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100); 1299 nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, 0x08000000); 1300 return 0; 1301 } 1302 1303 static int 1304 nv10_gr_fini(struct nouveau_object *object, bool suspend) 1305 { 1306 struct nv10_gr_priv *priv = (void *)object; 1307 return nouveau_gr_fini(&priv->base, suspend); 1308 } 1309 1310 struct nouveau_oclass 1311 nv10_gr_oclass = { 1312 .handle = NV_ENGINE(GR, 0x10), 1313 .ofuncs = &(struct nouveau_ofuncs) { 1314 .ctor = nv10_gr_ctor, 1315 .dtor = nv10_gr_dtor, 1316 .init = nv10_gr_init, 1317 .fini = nv10_gr_fini, 1318 }, 1319 }; 1320