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