nouveau_nvkm_engine_gr_nv04.c revision 1.4
1/* $NetBSD: nouveau_nvkm_engine_gr_nv04.c,v 1.4 2021/12/19 11:34:45 riastradh Exp $ */ 2 3/* 4 * Copyright 2007 Stephane Marchesin 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragr) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 */ 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_gr_nv04.c,v 1.4 2021/12/19 11:34:45 riastradh Exp $"); 28 29#include "priv.h" 30#include "regs.h" 31 32#include <core/client.h> 33#include <core/gpuobj.h> 34#include <engine/fifo.h> 35#include <engine/fifo/chan.h> 36#include <subdev/instmem.h> 37#include <subdev/timer.h> 38 39static u32 40nv04_gr_ctx_regs[] = { 41 0x0040053c, 42 0x00400544, 43 0x00400540, 44 0x00400548, 45 NV04_PGRAPH_CTX_SWITCH1, 46 NV04_PGRAPH_CTX_SWITCH2, 47 NV04_PGRAPH_CTX_SWITCH3, 48 NV04_PGRAPH_CTX_SWITCH4, 49 NV04_PGRAPH_CTX_CACHE1, 50 NV04_PGRAPH_CTX_CACHE2, 51 NV04_PGRAPH_CTX_CACHE3, 52 NV04_PGRAPH_CTX_CACHE4, 53 0x00400184, 54 0x004001a4, 55 0x004001c4, 56 0x004001e4, 57 0x00400188, 58 0x004001a8, 59 0x004001c8, 60 0x004001e8, 61 0x0040018c, 62 0x004001ac, 63 0x004001cc, 64 0x004001ec, 65 0x00400190, 66 0x004001b0, 67 0x004001d0, 68 0x004001f0, 69 0x00400194, 70 0x004001b4, 71 0x004001d4, 72 0x004001f4, 73 0x00400198, 74 0x004001b8, 75 0x004001d8, 76 0x004001f8, 77 0x0040019c, 78 0x004001bc, 79 0x004001dc, 80 0x004001fc, 81 0x00400174, 82 NV04_PGRAPH_DMA_START_0, 83 NV04_PGRAPH_DMA_START_1, 84 NV04_PGRAPH_DMA_LENGTH, 85 NV04_PGRAPH_DMA_MISC, 86 NV04_PGRAPH_DMA_PITCH, 87 NV04_PGRAPH_BOFFSET0, 88 NV04_PGRAPH_BBASE0, 89 NV04_PGRAPH_BLIMIT0, 90 NV04_PGRAPH_BOFFSET1, 91 NV04_PGRAPH_BBASE1, 92 NV04_PGRAPH_BLIMIT1, 93 NV04_PGRAPH_BOFFSET2, 94 NV04_PGRAPH_BBASE2, 95 NV04_PGRAPH_BLIMIT2, 96 NV04_PGRAPH_BOFFSET3, 97 NV04_PGRAPH_BBASE3, 98 NV04_PGRAPH_BLIMIT3, 99 NV04_PGRAPH_BOFFSET4, 100 NV04_PGRAPH_BBASE4, 101 NV04_PGRAPH_BLIMIT4, 102 NV04_PGRAPH_BOFFSET5, 103 NV04_PGRAPH_BBASE5, 104 NV04_PGRAPH_BLIMIT5, 105 NV04_PGRAPH_BPITCH0, 106 NV04_PGRAPH_BPITCH1, 107 NV04_PGRAPH_BPITCH2, 108 NV04_PGRAPH_BPITCH3, 109 NV04_PGRAPH_BPITCH4, 110 NV04_PGRAPH_SURFACE, 111 NV04_PGRAPH_STATE, 112 NV04_PGRAPH_BSWIZZLE2, 113 NV04_PGRAPH_BSWIZZLE5, 114 NV04_PGRAPH_BPIXEL, 115 NV04_PGRAPH_NOTIFY, 116 NV04_PGRAPH_PATT_COLOR0, 117 NV04_PGRAPH_PATT_COLOR1, 118 NV04_PGRAPH_PATT_COLORRAM+0x00, 119 NV04_PGRAPH_PATT_COLORRAM+0x04, 120 NV04_PGRAPH_PATT_COLORRAM+0x08, 121 NV04_PGRAPH_PATT_COLORRAM+0x0c, 122 NV04_PGRAPH_PATT_COLORRAM+0x10, 123 NV04_PGRAPH_PATT_COLORRAM+0x14, 124 NV04_PGRAPH_PATT_COLORRAM+0x18, 125 NV04_PGRAPH_PATT_COLORRAM+0x1c, 126 NV04_PGRAPH_PATT_COLORRAM+0x20, 127 NV04_PGRAPH_PATT_COLORRAM+0x24, 128 NV04_PGRAPH_PATT_COLORRAM+0x28, 129 NV04_PGRAPH_PATT_COLORRAM+0x2c, 130 NV04_PGRAPH_PATT_COLORRAM+0x30, 131 NV04_PGRAPH_PATT_COLORRAM+0x34, 132 NV04_PGRAPH_PATT_COLORRAM+0x38, 133 NV04_PGRAPH_PATT_COLORRAM+0x3c, 134 NV04_PGRAPH_PATT_COLORRAM+0x40, 135 NV04_PGRAPH_PATT_COLORRAM+0x44, 136 NV04_PGRAPH_PATT_COLORRAM+0x48, 137 NV04_PGRAPH_PATT_COLORRAM+0x4c, 138 NV04_PGRAPH_PATT_COLORRAM+0x50, 139 NV04_PGRAPH_PATT_COLORRAM+0x54, 140 NV04_PGRAPH_PATT_COLORRAM+0x58, 141 NV04_PGRAPH_PATT_COLORRAM+0x5c, 142 NV04_PGRAPH_PATT_COLORRAM+0x60, 143 NV04_PGRAPH_PATT_COLORRAM+0x64, 144 NV04_PGRAPH_PATT_COLORRAM+0x68, 145 NV04_PGRAPH_PATT_COLORRAM+0x6c, 146 NV04_PGRAPH_PATT_COLORRAM+0x70, 147 NV04_PGRAPH_PATT_COLORRAM+0x74, 148 NV04_PGRAPH_PATT_COLORRAM+0x78, 149 NV04_PGRAPH_PATT_COLORRAM+0x7c, 150 NV04_PGRAPH_PATT_COLORRAM+0x80, 151 NV04_PGRAPH_PATT_COLORRAM+0x84, 152 NV04_PGRAPH_PATT_COLORRAM+0x88, 153 NV04_PGRAPH_PATT_COLORRAM+0x8c, 154 NV04_PGRAPH_PATT_COLORRAM+0x90, 155 NV04_PGRAPH_PATT_COLORRAM+0x94, 156 NV04_PGRAPH_PATT_COLORRAM+0x98, 157 NV04_PGRAPH_PATT_COLORRAM+0x9c, 158 NV04_PGRAPH_PATT_COLORRAM+0xa0, 159 NV04_PGRAPH_PATT_COLORRAM+0xa4, 160 NV04_PGRAPH_PATT_COLORRAM+0xa8, 161 NV04_PGRAPH_PATT_COLORRAM+0xac, 162 NV04_PGRAPH_PATT_COLORRAM+0xb0, 163 NV04_PGRAPH_PATT_COLORRAM+0xb4, 164 NV04_PGRAPH_PATT_COLORRAM+0xb8, 165 NV04_PGRAPH_PATT_COLORRAM+0xbc, 166 NV04_PGRAPH_PATT_COLORRAM+0xc0, 167 NV04_PGRAPH_PATT_COLORRAM+0xc4, 168 NV04_PGRAPH_PATT_COLORRAM+0xc8, 169 NV04_PGRAPH_PATT_COLORRAM+0xcc, 170 NV04_PGRAPH_PATT_COLORRAM+0xd0, 171 NV04_PGRAPH_PATT_COLORRAM+0xd4, 172 NV04_PGRAPH_PATT_COLORRAM+0xd8, 173 NV04_PGRAPH_PATT_COLORRAM+0xdc, 174 NV04_PGRAPH_PATT_COLORRAM+0xe0, 175 NV04_PGRAPH_PATT_COLORRAM+0xe4, 176 NV04_PGRAPH_PATT_COLORRAM+0xe8, 177 NV04_PGRAPH_PATT_COLORRAM+0xec, 178 NV04_PGRAPH_PATT_COLORRAM+0xf0, 179 NV04_PGRAPH_PATT_COLORRAM+0xf4, 180 NV04_PGRAPH_PATT_COLORRAM+0xf8, 181 NV04_PGRAPH_PATT_COLORRAM+0xfc, 182 NV04_PGRAPH_PATTERN, 183 0x0040080c, 184 NV04_PGRAPH_PATTERN_SHAPE, 185 0x00400600, 186 NV04_PGRAPH_ROP3, 187 NV04_PGRAPH_CHROMA, 188 NV04_PGRAPH_BETA_AND, 189 NV04_PGRAPH_BETA_PREMULT, 190 NV04_PGRAPH_CONTROL0, 191 NV04_PGRAPH_CONTROL1, 192 NV04_PGRAPH_CONTROL2, 193 NV04_PGRAPH_BLEND, 194 NV04_PGRAPH_STORED_FMT, 195 NV04_PGRAPH_SOURCE_COLOR, 196 0x00400560, 197 0x00400568, 198 0x00400564, 199 0x0040056c, 200 0x00400400, 201 0x00400480, 202 0x00400404, 203 0x00400484, 204 0x00400408, 205 0x00400488, 206 0x0040040c, 207 0x0040048c, 208 0x00400410, 209 0x00400490, 210 0x00400414, 211 0x00400494, 212 0x00400418, 213 0x00400498, 214 0x0040041c, 215 0x0040049c, 216 0x00400420, 217 0x004004a0, 218 0x00400424, 219 0x004004a4, 220 0x00400428, 221 0x004004a8, 222 0x0040042c, 223 0x004004ac, 224 0x00400430, 225 0x004004b0, 226 0x00400434, 227 0x004004b4, 228 0x00400438, 229 0x004004b8, 230 0x0040043c, 231 0x004004bc, 232 0x00400440, 233 0x004004c0, 234 0x00400444, 235 0x004004c4, 236 0x00400448, 237 0x004004c8, 238 0x0040044c, 239 0x004004cc, 240 0x00400450, 241 0x004004d0, 242 0x00400454, 243 0x004004d4, 244 0x00400458, 245 0x004004d8, 246 0x0040045c, 247 0x004004dc, 248 0x00400460, 249 0x004004e0, 250 0x00400464, 251 0x004004e4, 252 0x00400468, 253 0x004004e8, 254 0x0040046c, 255 0x004004ec, 256 0x00400470, 257 0x004004f0, 258 0x00400474, 259 0x004004f4, 260 0x00400478, 261 0x004004f8, 262 0x0040047c, 263 0x004004fc, 264 0x00400534, 265 0x00400538, 266 0x00400514, 267 0x00400518, 268 0x0040051c, 269 0x00400520, 270 0x00400524, 271 0x00400528, 272 0x0040052c, 273 0x00400530, 274 0x00400d00, 275 0x00400d40, 276 0x00400d80, 277 0x00400d04, 278 0x00400d44, 279 0x00400d84, 280 0x00400d08, 281 0x00400d48, 282 0x00400d88, 283 0x00400d0c, 284 0x00400d4c, 285 0x00400d8c, 286 0x00400d10, 287 0x00400d50, 288 0x00400d90, 289 0x00400d14, 290 0x00400d54, 291 0x00400d94, 292 0x00400d18, 293 0x00400d58, 294 0x00400d98, 295 0x00400d1c, 296 0x00400d5c, 297 0x00400d9c, 298 0x00400d20, 299 0x00400d60, 300 0x00400da0, 301 0x00400d24, 302 0x00400d64, 303 0x00400da4, 304 0x00400d28, 305 0x00400d68, 306 0x00400da8, 307 0x00400d2c, 308 0x00400d6c, 309 0x00400dac, 310 0x00400d30, 311 0x00400d70, 312 0x00400db0, 313 0x00400d34, 314 0x00400d74, 315 0x00400db4, 316 0x00400d38, 317 0x00400d78, 318 0x00400db8, 319 0x00400d3c, 320 0x00400d7c, 321 0x00400dbc, 322 0x00400590, 323 0x00400594, 324 0x00400598, 325 0x0040059c, 326 0x004005a8, 327 0x004005ac, 328 0x004005b0, 329 0x004005b4, 330 0x004005c0, 331 0x004005c4, 332 0x004005c8, 333 0x004005cc, 334 0x004005d0, 335 0x004005d4, 336 0x004005d8, 337 0x004005dc, 338 0x004005e0, 339 NV04_PGRAPH_PASSTHRU_0, 340 NV04_PGRAPH_PASSTHRU_1, 341 NV04_PGRAPH_PASSTHRU_2, 342 NV04_PGRAPH_DVD_COLORFMT, 343 NV04_PGRAPH_SCALED_FORMAT, 344 NV04_PGRAPH_MISC24_0, 345 NV04_PGRAPH_MISC24_1, 346 NV04_PGRAPH_MISC24_2, 347 0x00400500, 348 0x00400504, 349 NV04_PGRAPH_VALID1, 350 NV04_PGRAPH_VALID2, 351 NV04_PGRAPH_DEBUG_3 352}; 353 354#define nv04_gr(p) container_of((p), struct nv04_gr, base) 355 356struct nv04_gr { 357 struct nvkm_gr base; 358 struct nv04_gr_chan *chan[16]; 359 spinlock_t lock; 360}; 361 362#define nv04_gr_chan(p) container_of((p), struct nv04_gr_chan, object) 363 364struct nv04_gr_chan { 365 struct nvkm_object object; 366 struct nv04_gr *gr; 367 int chid; 368 u32 nv04[ARRAY_SIZE(nv04_gr_ctx_regs)]; 369}; 370 371/******************************************************************************* 372 * Graphics object classes 373 ******************************************************************************/ 374 375/* 376 * Software methods, why they are needed, and how they all work: 377 * 378 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some 379 * 2d engine settings are kept inside the grobjs themselves. The grobjs are 380 * 3 words long on both. grobj format on NV04 is: 381 * 382 * word 0: 383 * - bits 0-7: class 384 * - bit 12: color key active 385 * - bit 13: clip rect active 386 * - bit 14: if set, destination surface is swizzled and taken from buffer 5 387 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken 388 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or 389 * NV03_CONTEXT_SURFACE_DST]. 390 * - bits 15-17: 2d operation [aka patch config] 391 * - bit 24: patch valid [enables rendering using this object] 392 * - bit 25: surf3d valid [for tex_tri and multitex_tri only] 393 * word 1: 394 * - bits 0-1: mono format 395 * - bits 8-13: color format 396 * - bits 16-31: DMA_NOTIFY instance 397 * word 2: 398 * - bits 0-15: DMA_A instance 399 * - bits 16-31: DMA_B instance 400 * 401 * On NV05 it's: 402 * 403 * word 0: 404 * - bits 0-7: class 405 * - bit 12: color key active 406 * - bit 13: clip rect active 407 * - bit 14: if set, destination surface is swizzled and taken from buffer 5 408 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken 409 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or 410 * NV03_CONTEXT_SURFACE_DST]. 411 * - bits 15-17: 2d operation [aka patch config] 412 * - bits 20-22: dither mode 413 * - bit 24: patch valid [enables rendering using this object] 414 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid 415 * - bit 26: surface_src/surface_zeta valid 416 * - bit 27: pattern valid 417 * - bit 28: rop valid 418 * - bit 29: beta1 valid 419 * - bit 30: beta4 valid 420 * word 1: 421 * - bits 0-1: mono format 422 * - bits 8-13: color format 423 * - bits 16-31: DMA_NOTIFY instance 424 * word 2: 425 * - bits 0-15: DMA_A instance 426 * - bits 16-31: DMA_B instance 427 * 428 * NV05 will set/unset the relevant valid bits when you poke the relevant 429 * object-binding methods with object of the proper type, or with the NULL 430 * type. It'll only allow rendering using the grobj if all needed objects 431 * are bound. The needed set of objects depends on selected operation: for 432 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND. 433 * 434 * NV04 doesn't have these methods implemented at all, and doesn't have the 435 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24 436 * is set. So we have to emulate them in software, internally keeping the 437 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04, 438 * but the last word isn't actually used for anything, we abuse it for this 439 * purpose. 440 * 441 * Actually, NV05 can optionally check bit 24 too, but we disable this since 442 * there's no use for it. 443 * 444 * For unknown reasons, NV04 implements surf3d binding in hardware as an 445 * exception. Also for unknown reasons, NV04 doesn't implement the clipping 446 * methods on the surf3d object, so we have to emulate them too. 447 */ 448 449static void 450nv04_gr_set_ctx1(struct nvkm_device *device, u32 inst, u32 mask, u32 value) 451{ 452 int subc = (nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; 453 u32 tmp; 454 455 tmp = nvkm_rd32(device, 0x700000 + inst); 456 tmp &= ~mask; 457 tmp |= value; 458 nvkm_wr32(device, 0x700000 + inst, tmp); 459 460 nvkm_wr32(device, NV04_PGRAPH_CTX_SWITCH1, tmp); 461 nvkm_wr32(device, NV04_PGRAPH_CTX_CACHE1 + (subc << 2), tmp); 462} 463 464static void 465nv04_gr_set_ctx_val(struct nvkm_device *device, u32 inst, u32 mask, u32 value) 466{ 467 int class, op, valid = 1; 468 u32 tmp, ctx1; 469 470 ctx1 = nvkm_rd32(device, 0x700000 + inst); 471 class = ctx1 & 0xff; 472 op = (ctx1 >> 15) & 7; 473 474 tmp = nvkm_rd32(device, 0x70000c + inst); 475 tmp &= ~mask; 476 tmp |= value; 477 nvkm_wr32(device, 0x70000c + inst, tmp); 478 479 /* check for valid surf2d/surf_dst/surf_color */ 480 if (!(tmp & 0x02000000)) 481 valid = 0; 482 /* check for valid surf_src/surf_zeta */ 483 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000)) 484 valid = 0; 485 486 switch (op) { 487 /* SRCCOPY_AND, SRCCOPY: no extra objects required */ 488 case 0: 489 case 3: 490 break; 491 /* ROP_AND: requires pattern and rop */ 492 case 1: 493 if (!(tmp & 0x18000000)) 494 valid = 0; 495 break; 496 /* BLEND_AND: requires beta1 */ 497 case 2: 498 if (!(tmp & 0x20000000)) 499 valid = 0; 500 break; 501 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */ 502 case 4: 503 case 5: 504 if (!(tmp & 0x40000000)) 505 valid = 0; 506 break; 507 } 508 509 nv04_gr_set_ctx1(device, inst, 0x01000000, valid << 24); 510} 511 512static bool 513nv04_gr_mthd_set_operation(struct nvkm_device *device, u32 inst, u32 data) 514{ 515 u8 class = nvkm_rd32(device, 0x700000) & 0x000000ff; 516 if (data > 5) 517 return false; 518 /* Old versions of the objects only accept first three operations. */ 519 if (data > 2 && class < 0x40) 520 return false; 521 nv04_gr_set_ctx1(device, inst, 0x00038000, data << 15); 522 /* changing operation changes set of objects needed for validation */ 523 nv04_gr_set_ctx_val(device, inst, 0, 0); 524 return true; 525} 526 527static bool 528nv04_gr_mthd_surf3d_clip_h(struct nvkm_device *device, u32 inst, u32 data) 529{ 530 u32 min = data & 0xffff, max; 531 u32 w = data >> 16; 532 if (min & 0x8000) 533 /* too large */ 534 return false; 535 if (w & 0x8000) 536 /* yes, it accepts negative for some reason. */ 537 w |= 0xffff0000; 538 max = min + w; 539 max &= 0x3ffff; 540 nvkm_wr32(device, 0x40053c, min); 541 nvkm_wr32(device, 0x400544, max); 542 return true; 543} 544 545static bool 546nv04_gr_mthd_surf3d_clip_v(struct nvkm_device *device, u32 inst, u32 data) 547{ 548 u32 min = data & 0xffff, max; 549 u32 w = data >> 16; 550 if (min & 0x8000) 551 /* too large */ 552 return false; 553 if (w & 0x8000) 554 /* yes, it accepts negative for some reason. */ 555 w |= 0xffff0000; 556 max = min + w; 557 max &= 0x3ffff; 558 nvkm_wr32(device, 0x400540, min); 559 nvkm_wr32(device, 0x400548, max); 560 return true; 561} 562 563static u8 564nv04_gr_mthd_bind_class(struct nvkm_device *device, u32 inst) 565{ 566 return nvkm_rd32(device, 0x700000 + (inst << 4)); 567} 568 569static bool 570nv04_gr_mthd_bind_surf2d(struct nvkm_device *device, u32 inst, u32 data) 571{ 572 switch (nv04_gr_mthd_bind_class(device, data)) { 573 case 0x30: 574 nv04_gr_set_ctx1(device, inst, 0x00004000, 0); 575 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0); 576 return true; 577 case 0x42: 578 nv04_gr_set_ctx1(device, inst, 0x00004000, 0); 579 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000); 580 return true; 581 } 582 return false; 583} 584 585static bool 586nv04_gr_mthd_bind_surf2d_swzsurf(struct nvkm_device *device, u32 inst, u32 data) 587{ 588 switch (nv04_gr_mthd_bind_class(device, data)) { 589 case 0x30: 590 nv04_gr_set_ctx1(device, inst, 0x00004000, 0); 591 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0); 592 return true; 593 case 0x42: 594 nv04_gr_set_ctx1(device, inst, 0x00004000, 0); 595 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000); 596 return true; 597 case 0x52: 598 nv04_gr_set_ctx1(device, inst, 0x00004000, 0x00004000); 599 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000); 600 return true; 601 } 602 return false; 603} 604 605static bool 606nv01_gr_mthd_bind_patt(struct nvkm_device *device, u32 inst, u32 data) 607{ 608 switch (nv04_gr_mthd_bind_class(device, data)) { 609 case 0x30: 610 nv04_gr_set_ctx_val(device, inst, 0x08000000, 0); 611 return true; 612 case 0x18: 613 nv04_gr_set_ctx_val(device, inst, 0x08000000, 0x08000000); 614 return true; 615 } 616 return false; 617} 618 619static bool 620nv04_gr_mthd_bind_patt(struct nvkm_device *device, u32 inst, u32 data) 621{ 622 switch (nv04_gr_mthd_bind_class(device, data)) { 623 case 0x30: 624 nv04_gr_set_ctx_val(device, inst, 0x08000000, 0); 625 return true; 626 case 0x44: 627 nv04_gr_set_ctx_val(device, inst, 0x08000000, 0x08000000); 628 return true; 629 } 630 return false; 631} 632 633static bool 634nv04_gr_mthd_bind_rop(struct nvkm_device *device, u32 inst, u32 data) 635{ 636 switch (nv04_gr_mthd_bind_class(device, data)) { 637 case 0x30: 638 nv04_gr_set_ctx_val(device, inst, 0x10000000, 0); 639 return true; 640 case 0x43: 641 nv04_gr_set_ctx_val(device, inst, 0x10000000, 0x10000000); 642 return true; 643 } 644 return false; 645} 646 647static bool 648nv04_gr_mthd_bind_beta1(struct nvkm_device *device, u32 inst, u32 data) 649{ 650 switch (nv04_gr_mthd_bind_class(device, data)) { 651 case 0x30: 652 nv04_gr_set_ctx_val(device, inst, 0x20000000, 0); 653 return true; 654 case 0x12: 655 nv04_gr_set_ctx_val(device, inst, 0x20000000, 0x20000000); 656 return true; 657 } 658 return false; 659} 660 661static bool 662nv04_gr_mthd_bind_beta4(struct nvkm_device *device, u32 inst, u32 data) 663{ 664 switch (nv04_gr_mthd_bind_class(device, data)) { 665 case 0x30: 666 nv04_gr_set_ctx_val(device, inst, 0x40000000, 0); 667 return true; 668 case 0x72: 669 nv04_gr_set_ctx_val(device, inst, 0x40000000, 0x40000000); 670 return true; 671 } 672 return false; 673} 674 675static bool 676nv04_gr_mthd_bind_surf_dst(struct nvkm_device *device, u32 inst, u32 data) 677{ 678 switch (nv04_gr_mthd_bind_class(device, data)) { 679 case 0x30: 680 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0); 681 return true; 682 case 0x58: 683 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000); 684 return true; 685 } 686 return false; 687} 688 689static bool 690nv04_gr_mthd_bind_surf_src(struct nvkm_device *device, u32 inst, u32 data) 691{ 692 switch (nv04_gr_mthd_bind_class(device, data)) { 693 case 0x30: 694 nv04_gr_set_ctx_val(device, inst, 0x04000000, 0); 695 return true; 696 case 0x59: 697 nv04_gr_set_ctx_val(device, inst, 0x04000000, 0x04000000); 698 return true; 699 } 700 return false; 701} 702 703static bool 704nv04_gr_mthd_bind_surf_color(struct nvkm_device *device, u32 inst, u32 data) 705{ 706 switch (nv04_gr_mthd_bind_class(device, data)) { 707 case 0x30: 708 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0); 709 return true; 710 case 0x5a: 711 nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000); 712 return true; 713 } 714 return false; 715} 716 717static bool 718nv04_gr_mthd_bind_surf_zeta(struct nvkm_device *device, u32 inst, u32 data) 719{ 720 switch (nv04_gr_mthd_bind_class(device, data)) { 721 case 0x30: 722 nv04_gr_set_ctx_val(device, inst, 0x04000000, 0); 723 return true; 724 case 0x5b: 725 nv04_gr_set_ctx_val(device, inst, 0x04000000, 0x04000000); 726 return true; 727 } 728 return false; 729} 730 731static bool 732nv01_gr_mthd_bind_clip(struct nvkm_device *device, u32 inst, u32 data) 733{ 734 switch (nv04_gr_mthd_bind_class(device, data)) { 735 case 0x30: 736 nv04_gr_set_ctx1(device, inst, 0x2000, 0); 737 return true; 738 case 0x19: 739 nv04_gr_set_ctx1(device, inst, 0x2000, 0x2000); 740 return true; 741 } 742 return false; 743} 744 745static bool 746nv01_gr_mthd_bind_chroma(struct nvkm_device *device, u32 inst, u32 data) 747{ 748 switch (nv04_gr_mthd_bind_class(device, data)) { 749 case 0x30: 750 nv04_gr_set_ctx1(device, inst, 0x1000, 0); 751 return true; 752 /* Yes, for some reason even the old versions of objects 753 * accept 0x57 and not 0x17. Consistency be damned. 754 */ 755 case 0x57: 756 nv04_gr_set_ctx1(device, inst, 0x1000, 0x1000); 757 return true; 758 } 759 return false; 760} 761 762static bool 763nv03_gr_mthd_gdi(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 764{ 765 bool (*func)(struct nvkm_device *, u32, u32); 766 switch (mthd) { 767 case 0x0184: func = nv01_gr_mthd_bind_patt; break; 768 case 0x0188: func = nv04_gr_mthd_bind_rop; break; 769 case 0x018c: func = nv04_gr_mthd_bind_beta1; break; 770 case 0x0190: func = nv04_gr_mthd_bind_surf_dst; break; 771 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 772 default: 773 return false; 774 } 775 return func(device, inst, data); 776} 777 778static bool 779nv04_gr_mthd_gdi(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 780{ 781 bool (*func)(struct nvkm_device *, u32, u32); 782 switch (mthd) { 783 case 0x0188: func = nv04_gr_mthd_bind_patt; break; 784 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 785 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 786 case 0x0194: func = nv04_gr_mthd_bind_beta4; break; 787 case 0x0198: func = nv04_gr_mthd_bind_surf2d; break; 788 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 789 default: 790 return false; 791 } 792 return func(device, inst, data); 793} 794 795static bool 796nv01_gr_mthd_blit(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 797{ 798 bool (*func)(struct nvkm_device *, u32, u32); 799 switch (mthd) { 800 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 801 case 0x0188: func = nv01_gr_mthd_bind_clip; break; 802 case 0x018c: func = nv01_gr_mthd_bind_patt; break; 803 case 0x0190: func = nv04_gr_mthd_bind_rop; break; 804 case 0x0194: func = nv04_gr_mthd_bind_beta1; break; 805 case 0x0198: func = nv04_gr_mthd_bind_surf_dst; break; 806 case 0x019c: func = nv04_gr_mthd_bind_surf_src; break; 807 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 808 default: 809 return false; 810 } 811 return func(device, inst, data); 812} 813 814static bool 815nv04_gr_mthd_blit(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 816{ 817 bool (*func)(struct nvkm_device *, u32, u32); 818 switch (mthd) { 819 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 820 case 0x0188: func = nv01_gr_mthd_bind_clip; break; 821 case 0x018c: func = nv04_gr_mthd_bind_patt; break; 822 case 0x0190: func = nv04_gr_mthd_bind_rop; break; 823 case 0x0194: func = nv04_gr_mthd_bind_beta1; break; 824 case 0x0198: func = nv04_gr_mthd_bind_beta4; break; 825 case 0x019c: func = nv04_gr_mthd_bind_surf2d; break; 826 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 827 default: 828 return false; 829 } 830 return func(device, inst, data); 831} 832 833static bool 834nv04_gr_mthd_iifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 835{ 836 bool (*func)(struct nvkm_device *, u32, u32); 837 switch (mthd) { 838 case 0x0188: func = nv01_gr_mthd_bind_chroma; break; 839 case 0x018c: func = nv01_gr_mthd_bind_clip; break; 840 case 0x0190: func = nv04_gr_mthd_bind_patt; break; 841 case 0x0194: func = nv04_gr_mthd_bind_rop; break; 842 case 0x0198: func = nv04_gr_mthd_bind_beta1; break; 843 case 0x019c: func = nv04_gr_mthd_bind_beta4; break; 844 case 0x01a0: func = nv04_gr_mthd_bind_surf2d_swzsurf; break; 845 case 0x03e4: func = nv04_gr_mthd_set_operation; break; 846 default: 847 return false; 848 } 849 return func(device, inst, data); 850} 851 852static bool 853nv01_gr_mthd_ifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 854{ 855 bool (*func)(struct nvkm_device *, u32, u32); 856 switch (mthd) { 857 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 858 case 0x0188: func = nv01_gr_mthd_bind_clip; break; 859 case 0x018c: func = nv01_gr_mthd_bind_patt; break; 860 case 0x0190: func = nv04_gr_mthd_bind_rop; break; 861 case 0x0194: func = nv04_gr_mthd_bind_beta1; break; 862 case 0x0198: func = nv04_gr_mthd_bind_surf_dst; break; 863 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 864 default: 865 return false; 866 } 867 return func(device, inst, data); 868} 869 870static bool 871nv04_gr_mthd_ifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 872{ 873 bool (*func)(struct nvkm_device *, u32, u32); 874 switch (mthd) { 875 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 876 case 0x0188: func = nv01_gr_mthd_bind_clip; break; 877 case 0x018c: func = nv04_gr_mthd_bind_patt; break; 878 case 0x0190: func = nv04_gr_mthd_bind_rop; break; 879 case 0x0194: func = nv04_gr_mthd_bind_beta1; break; 880 case 0x0198: func = nv04_gr_mthd_bind_beta4; break; 881 case 0x019c: func = nv04_gr_mthd_bind_surf2d; break; 882 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 883 default: 884 return false; 885 } 886 return func(device, inst, data); 887} 888 889static bool 890nv03_gr_mthd_sifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 891{ 892 bool (*func)(struct nvkm_device *, u32, u32); 893 switch (mthd) { 894 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 895 case 0x0188: func = nv01_gr_mthd_bind_patt; break; 896 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 897 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 898 case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break; 899 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 900 default: 901 return false; 902 } 903 return func(device, inst, data); 904} 905 906static bool 907nv04_gr_mthd_sifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 908{ 909 bool (*func)(struct nvkm_device *, u32, u32); 910 switch (mthd) { 911 case 0x0184: func = nv01_gr_mthd_bind_chroma; break; 912 case 0x0188: func = nv04_gr_mthd_bind_patt; break; 913 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 914 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 915 case 0x0194: func = nv04_gr_mthd_bind_beta4; break; 916 case 0x0198: func = nv04_gr_mthd_bind_surf2d; break; 917 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 918 default: 919 return false; 920 } 921 return func(device, inst, data); 922} 923 924static bool 925nv03_gr_mthd_sifm(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 926{ 927 bool (*func)(struct nvkm_device *, u32, u32); 928 switch (mthd) { 929 case 0x0188: func = nv01_gr_mthd_bind_patt; break; 930 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 931 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 932 case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break; 933 case 0x0304: func = nv04_gr_mthd_set_operation; break; 934 default: 935 return false; 936 } 937 return func(device, inst, data); 938} 939 940static bool 941nv04_gr_mthd_sifm(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 942{ 943 bool (*func)(struct nvkm_device *, u32, u32); 944 switch (mthd) { 945 case 0x0188: func = nv04_gr_mthd_bind_patt; break; 946 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 947 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 948 case 0x0194: func = nv04_gr_mthd_bind_beta4; break; 949 case 0x0198: func = nv04_gr_mthd_bind_surf2d; break; 950 case 0x0304: func = nv04_gr_mthd_set_operation; break; 951 default: 952 return false; 953 } 954 return func(device, inst, data); 955} 956 957static bool 958nv04_gr_mthd_surf3d(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 959{ 960 bool (*func)(struct nvkm_device *, u32, u32); 961 switch (mthd) { 962 case 0x02f8: func = nv04_gr_mthd_surf3d_clip_h; break; 963 case 0x02fc: func = nv04_gr_mthd_surf3d_clip_v; break; 964 default: 965 return false; 966 } 967 return func(device, inst, data); 968} 969 970static bool 971nv03_gr_mthd_ttri(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 972{ 973 bool (*func)(struct nvkm_device *, u32, u32); 974 switch (mthd) { 975 case 0x0188: func = nv01_gr_mthd_bind_clip; break; 976 case 0x018c: func = nv04_gr_mthd_bind_surf_color; break; 977 case 0x0190: func = nv04_gr_mthd_bind_surf_zeta; break; 978 default: 979 return false; 980 } 981 return func(device, inst, data); 982} 983 984static bool 985nv01_gr_mthd_prim(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 986{ 987 bool (*func)(struct nvkm_device *, u32, u32); 988 switch (mthd) { 989 case 0x0184: func = nv01_gr_mthd_bind_clip; break; 990 case 0x0188: func = nv01_gr_mthd_bind_patt; break; 991 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 992 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 993 case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break; 994 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 995 default: 996 return false; 997 } 998 return func(device, inst, data); 999} 1000 1001static bool 1002nv04_gr_mthd_prim(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 1003{ 1004 bool (*func)(struct nvkm_device *, u32, u32); 1005 switch (mthd) { 1006 case 0x0184: func = nv01_gr_mthd_bind_clip; break; 1007 case 0x0188: func = nv04_gr_mthd_bind_patt; break; 1008 case 0x018c: func = nv04_gr_mthd_bind_rop; break; 1009 case 0x0190: func = nv04_gr_mthd_bind_beta1; break; 1010 case 0x0194: func = nv04_gr_mthd_bind_beta4; break; 1011 case 0x0198: func = nv04_gr_mthd_bind_surf2d; break; 1012 case 0x02fc: func = nv04_gr_mthd_set_operation; break; 1013 default: 1014 return false; 1015 } 1016 return func(device, inst, data); 1017} 1018 1019static bool 1020nv04_gr_mthd(struct nvkm_device *device, u32 inst, u32 mthd, u32 data) 1021{ 1022 bool (*func)(struct nvkm_device *, u32, u32, u32); 1023 switch (nvkm_rd32(device, 0x700000 + inst) & 0x000000ff) { 1024 case 0x1c ... 0x1e: 1025 func = nv01_gr_mthd_prim; break; 1026 case 0x1f: func = nv01_gr_mthd_blit; break; 1027 case 0x21: func = nv01_gr_mthd_ifc; break; 1028 case 0x36: func = nv03_gr_mthd_sifc; break; 1029 case 0x37: func = nv03_gr_mthd_sifm; break; 1030 case 0x48: func = nv03_gr_mthd_ttri; break; 1031 case 0x4a: func = nv04_gr_mthd_gdi; break; 1032 case 0x4b: func = nv03_gr_mthd_gdi; break; 1033 case 0x53: func = nv04_gr_mthd_surf3d; break; 1034 case 0x5c ... 0x5e: 1035 func = nv04_gr_mthd_prim; break; 1036 case 0x5f: func = nv04_gr_mthd_blit; break; 1037 case 0x60: func = nv04_gr_mthd_iifc; break; 1038 case 0x61: func = nv04_gr_mthd_ifc; break; 1039 case 0x76: func = nv04_gr_mthd_sifc; break; 1040 case 0x77: func = nv04_gr_mthd_sifm; break; 1041 default: 1042 return false; 1043 } 1044 return func(device, inst, mthd, data); 1045} 1046 1047static int 1048nv04_gr_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent, 1049 int align, struct nvkm_gpuobj **pgpuobj) 1050{ 1051 int ret = nvkm_gpuobj_new(object->engine->subdev.device, 16, align, 1052 false, parent, pgpuobj); 1053 if (ret == 0) { 1054 nvkm_kmap(*pgpuobj); 1055 nvkm_wo32(*pgpuobj, 0x00, object->oclass); 1056#ifdef __BIG_ENDIAN 1057 nvkm_mo32(*pgpuobj, 0x00, 0x00080000, 0x00080000); 1058#endif 1059 nvkm_wo32(*pgpuobj, 0x04, 0x00000000); 1060 nvkm_wo32(*pgpuobj, 0x08, 0x00000000); 1061 nvkm_wo32(*pgpuobj, 0x0c, 0x00000000); 1062 nvkm_done(*pgpuobj); 1063 } 1064 return ret; 1065} 1066 1067const struct nvkm_object_func 1068nv04_gr_object = { 1069 .bind = nv04_gr_object_bind, 1070}; 1071 1072/******************************************************************************* 1073 * PGRAPH context 1074 ******************************************************************************/ 1075 1076static struct nv04_gr_chan * 1077nv04_gr_channel(struct nv04_gr *gr) 1078{ 1079 struct nvkm_device *device = gr->base.engine.subdev.device; 1080 struct nv04_gr_chan *chan = NULL; 1081 if (nvkm_rd32(device, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) { 1082 int chid = nvkm_rd32(device, NV04_PGRAPH_CTX_USER) >> 24; 1083 if (chid < ARRAY_SIZE(gr->chan)) 1084 chan = gr->chan[chid]; 1085 } 1086 return chan; 1087} 1088 1089static int 1090nv04_gr_load_context(struct nv04_gr_chan *chan, int chid) 1091{ 1092 struct nvkm_device *device = chan->gr->base.engine.subdev.device; 1093 int i; 1094 1095 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++) 1096 nvkm_wr32(device, nv04_gr_ctx_regs[i], chan->nv04[i]); 1097 1098 nvkm_wr32(device, NV04_PGRAPH_CTX_CONTROL, 0x10010100); 1099 nvkm_mask(device, NV04_PGRAPH_CTX_USER, 0xff000000, chid << 24); 1100 nvkm_mask(device, NV04_PGRAPH_FFINTFC_ST2, 0xfff00000, 0x00000000); 1101 return 0; 1102} 1103 1104static int 1105nv04_gr_unload_context(struct nv04_gr_chan *chan) 1106{ 1107 struct nvkm_device *device = chan->gr->base.engine.subdev.device; 1108 int i; 1109 1110 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++) 1111 chan->nv04[i] = nvkm_rd32(device, nv04_gr_ctx_regs[i]); 1112 1113 nvkm_wr32(device, NV04_PGRAPH_CTX_CONTROL, 0x10000000); 1114 nvkm_mask(device, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000); 1115 return 0; 1116} 1117 1118static void 1119nv04_gr_context_switch(struct nv04_gr *gr) 1120{ 1121 struct nvkm_device *device = gr->base.engine.subdev.device; 1122 struct nv04_gr_chan *prev = NULL; 1123 struct nv04_gr_chan *next = NULL; 1124 int chid; 1125 1126 nv04_gr_idle(&gr->base); 1127 1128 /* If previous context is valid, we need to save it */ 1129 prev = nv04_gr_channel(gr); 1130 if (prev) 1131 nv04_gr_unload_context(prev); 1132 1133 /* load context for next channel */ 1134 chid = (nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0x0f; 1135 next = gr->chan[chid]; 1136 if (next) 1137 nv04_gr_load_context(next, chid); 1138} 1139 1140static u32 *ctx_reg(struct nv04_gr_chan *chan, u32 reg) 1141{ 1142 int i; 1143 1144 for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++) { 1145 if (nv04_gr_ctx_regs[i] == reg) 1146 return &chan->nv04[i]; 1147 } 1148 1149 return NULL; 1150} 1151 1152static void * 1153nv04_gr_chan_dtor(struct nvkm_object *object) 1154{ 1155 struct nv04_gr_chan *chan = nv04_gr_chan(object); 1156 struct nv04_gr *gr = chan->gr; 1157 unsigned long flags; 1158 1159 spin_lock_irqsave(&gr->lock, flags); 1160 gr->chan[chan->chid] = NULL; 1161 spin_unlock_irqrestore(&gr->lock, flags); 1162 return chan; 1163} 1164 1165static int 1166nv04_gr_chan_fini(struct nvkm_object *object, bool suspend) 1167{ 1168 struct nv04_gr_chan *chan = nv04_gr_chan(object); 1169 struct nv04_gr *gr = chan->gr; 1170 struct nvkm_device *device = gr->base.engine.subdev.device; 1171 unsigned long flags; 1172 1173 spin_lock_irqsave(&gr->lock, flags); 1174 nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); 1175 if (nv04_gr_channel(gr) == chan) 1176 nv04_gr_unload_context(chan); 1177 nvkm_mask(device, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); 1178 spin_unlock_irqrestore(&gr->lock, flags); 1179 return 0; 1180} 1181 1182static const struct nvkm_object_func 1183nv04_gr_chan = { 1184 .dtor = nv04_gr_chan_dtor, 1185 .fini = nv04_gr_chan_fini, 1186}; 1187 1188static int 1189nv04_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, 1190 const struct nvkm_oclass *oclass, struct nvkm_object **pobject) 1191{ 1192 struct nv04_gr *gr = nv04_gr(base); 1193 struct nv04_gr_chan *chan; 1194 unsigned long flags; 1195 1196 if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) 1197 return -ENOMEM; 1198 nvkm_object_ctor(&nv04_gr_chan, oclass, &chan->object); 1199 chan->gr = gr; 1200 chan->chid = fifoch->chid; 1201 *pobject = &chan->object; 1202 1203 *ctx_reg(chan, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; 1204 1205 spin_lock_irqsave(&gr->lock, flags); 1206 gr->chan[chan->chid] = chan; 1207 spin_unlock_irqrestore(&gr->lock, flags); 1208 return 0; 1209} 1210 1211/******************************************************************************* 1212 * PGRAPH engine/subdev functions 1213 ******************************************************************************/ 1214 1215bool 1216nv04_gr_idle(struct nvkm_gr *gr) 1217{ 1218 struct nvkm_subdev *subdev = &gr->engine.subdev; 1219 struct nvkm_device *device = subdev->device; 1220 u32 mask = 0xffffffff; 1221 1222 if (device->card_type == NV_40) 1223 mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL; 1224 1225 if (nvkm_msec(device, 2000, 1226 if (!(nvkm_rd32(device, NV04_PGRAPH_STATUS) & mask)) 1227 break; 1228 ) < 0) { 1229 nvkm_error(subdev, "idle timed out with status %08x\n", 1230 nvkm_rd32(device, NV04_PGRAPH_STATUS)); 1231 return false; 1232 } 1233 1234 return true; 1235} 1236 1237static const struct nvkm_bitfield 1238nv04_gr_intr_name[] = { 1239 { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, 1240 {} 1241}; 1242 1243static const struct nvkm_bitfield 1244nv04_gr_nstatus[] = { 1245 { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, 1246 { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, 1247 { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, 1248 { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, 1249 {} 1250}; 1251 1252const struct nvkm_bitfield 1253nv04_gr_nsource[] = { 1254 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, 1255 { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, 1256 { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, 1257 { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, 1258 { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, 1259 { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, 1260 { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, 1261 { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, 1262 { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, 1263 { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, 1264 { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, 1265 { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, 1266 { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, 1267 { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, 1268 { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, 1269 { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, 1270 { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, 1271 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, 1272 { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, 1273 {} 1274}; 1275 1276static void 1277nv04_gr_intr(struct nvkm_gr *base) 1278{ 1279 struct nv04_gr *gr = nv04_gr(base); 1280 struct nvkm_subdev *subdev = &gr->base.engine.subdev; 1281 struct nvkm_device *device = subdev->device; 1282 u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR); 1283 u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE); 1284 u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS); 1285 u32 addr = nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR); 1286 u32 chid = (addr & 0x0f000000) >> 24; 1287 u32 subc = (addr & 0x0000e000) >> 13; 1288 u32 mthd = (addr & 0x00001ffc); 1289 u32 data = nvkm_rd32(device, NV04_PGRAPH_TRAPPED_DATA); 1290 u32 class = nvkm_rd32(device, 0x400180 + subc * 4) & 0xff; 1291 u32 inst = (nvkm_rd32(device, 0x40016c) & 0xffff) << 4; 1292 u32 show = stat; 1293 char msg[128], src[128], sta[128]; 1294 struct nv04_gr_chan *chan; 1295 unsigned long flags; 1296 1297 spin_lock_irqsave(&gr->lock, flags); 1298 chan = gr->chan[chid]; 1299 1300 if (stat & NV_PGRAPH_INTR_NOTIFY) { 1301 if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { 1302 if (!nv04_gr_mthd(device, inst, mthd, data)) 1303 show &= ~NV_PGRAPH_INTR_NOTIFY; 1304 } 1305 } 1306 1307 if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { 1308 nvkm_wr32(device, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); 1309 stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; 1310 show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; 1311 nv04_gr_context_switch(gr); 1312 } 1313 1314 nvkm_wr32(device, NV03_PGRAPH_INTR, stat); 1315 nvkm_wr32(device, NV04_PGRAPH_FIFO, 0x00000001); 1316 1317 if (show) { 1318 nvkm_snprintbf(msg, sizeof(msg), nv04_gr_intr_name, show); 1319 nvkm_snprintbf(src, sizeof(src), nv04_gr_nsource, nsource); 1320 nvkm_snprintbf(sta, sizeof(sta), nv04_gr_nstatus, nstatus); 1321 nvkm_error(subdev, "intr %08x [%s] nsource %08x [%s] " 1322 "nstatus %08x [%s] ch %d [%s] subc %d " 1323 "class %04x mthd %04x data %08x\n", 1324 show, msg, nsource, src, nstatus, sta, chid, 1325 chan ? chan->object.client->name : "unknown", 1326 subc, class, mthd, data); 1327 } 1328 1329 spin_unlock_irqrestore(&gr->lock, flags); 1330} 1331 1332static int 1333nv04_gr_init(struct nvkm_gr *base) 1334{ 1335 struct nv04_gr *gr = nv04_gr(base); 1336 struct nvkm_device *device = gr->base.engine.subdev.device; 1337 1338 /* Enable PGRAPH interrupts */ 1339 nvkm_wr32(device, NV03_PGRAPH_INTR, 0xFFFFFFFF); 1340 nvkm_wr32(device, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); 1341 1342 nvkm_wr32(device, NV04_PGRAPH_VALID1, 0); 1343 nvkm_wr32(device, NV04_PGRAPH_VALID2, 0); 1344 /*nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x000001FF); 1345 nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ 1346 nvkm_wr32(device, NV04_PGRAPH_DEBUG_0, 0x1231c000); 1347 /*1231C000 blob, 001 haiku*/ 1348 /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ 1349 nvkm_wr32(device, NV04_PGRAPH_DEBUG_1, 0x72111100); 1350 /*0x72111100 blob , 01 haiku*/ 1351 /*nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ 1352 nvkm_wr32(device, NV04_PGRAPH_DEBUG_2, 0x11d5f071); 1353 /*haiku same*/ 1354 1355 /*nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ 1356 nvkm_wr32(device, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31); 1357 /*haiku and blob 10d4*/ 1358 1359 nvkm_wr32(device, NV04_PGRAPH_STATE , 0xFFFFFFFF); 1360 nvkm_wr32(device, NV04_PGRAPH_CTX_CONTROL , 0x10000100); 1361 nvkm_mask(device, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000); 1362 1363 /* These don't belong here, they're part of a per-channel context */ 1364 nvkm_wr32(device, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); 1365 nvkm_wr32(device, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); 1366 return 0; 1367} 1368 1369static void * 1370nv04_gr_dtor(struct nvkm_gr *gr) 1371{ 1372 spin_lock_destroy(&nv04_gr(gr)->lock); 1373 return gr; 1374} 1375 1376static const struct nvkm_gr_func 1377nv04_gr = { 1378 .init = nv04_gr_init, 1379 .dtor = nv04_gr_dtor, 1380 .intr = nv04_gr_intr, 1381 .chan_new = nv04_gr_chan_new, 1382 .sclass = { 1383 { -1, -1, 0x0012, &nv04_gr_object }, /* beta1 */ 1384 { -1, -1, 0x0017, &nv04_gr_object }, /* chroma */ 1385 { -1, -1, 0x0018, &nv04_gr_object }, /* pattern (nv01) */ 1386 { -1, -1, 0x0019, &nv04_gr_object }, /* clip */ 1387 { -1, -1, 0x001c, &nv04_gr_object }, /* line */ 1388 { -1, -1, 0x001d, &nv04_gr_object }, /* tri */ 1389 { -1, -1, 0x001e, &nv04_gr_object }, /* rect */ 1390 { -1, -1, 0x001f, &nv04_gr_object }, 1391 { -1, -1, 0x0021, &nv04_gr_object }, 1392 { -1, -1, 0x0030, &nv04_gr_object }, /* null */ 1393 { -1, -1, 0x0036, &nv04_gr_object }, 1394 { -1, -1, 0x0037, &nv04_gr_object }, 1395 { -1, -1, 0x0038, &nv04_gr_object }, /* dvd subpicture */ 1396 { -1, -1, 0x0039, &nv04_gr_object }, /* m2mf */ 1397 { -1, -1, 0x0042, &nv04_gr_object }, /* surf2d */ 1398 { -1, -1, 0x0043, &nv04_gr_object }, /* rop */ 1399 { -1, -1, 0x0044, &nv04_gr_object }, /* pattern */ 1400 { -1, -1, 0x0048, &nv04_gr_object }, 1401 { -1, -1, 0x004a, &nv04_gr_object }, 1402 { -1, -1, 0x004b, &nv04_gr_object }, 1403 { -1, -1, 0x0052, &nv04_gr_object }, /* swzsurf */ 1404 { -1, -1, 0x0053, &nv04_gr_object }, 1405 { -1, -1, 0x0054, &nv04_gr_object }, /* ttri */ 1406 { -1, -1, 0x0055, &nv04_gr_object }, /* mtri */ 1407 { -1, -1, 0x0057, &nv04_gr_object }, /* chroma */ 1408 { -1, -1, 0x0058, &nv04_gr_object }, /* surf_dst */ 1409 { -1, -1, 0x0059, &nv04_gr_object }, /* surf_src */ 1410 { -1, -1, 0x005a, &nv04_gr_object }, /* surf_color */ 1411 { -1, -1, 0x005b, &nv04_gr_object }, /* surf_zeta */ 1412 { -1, -1, 0x005c, &nv04_gr_object }, /* line */ 1413 { -1, -1, 0x005d, &nv04_gr_object }, /* tri */ 1414 { -1, -1, 0x005e, &nv04_gr_object }, /* rect */ 1415 { -1, -1, 0x005f, &nv04_gr_object }, 1416 { -1, -1, 0x0060, &nv04_gr_object }, 1417 { -1, -1, 0x0061, &nv04_gr_object }, 1418 { -1, -1, 0x0064, &nv04_gr_object }, /* iifc (nv05) */ 1419 { -1, -1, 0x0065, &nv04_gr_object }, /* ifc (nv05) */ 1420 { -1, -1, 0x0066, &nv04_gr_object }, /* sifc (nv05) */ 1421 { -1, -1, 0x0072, &nv04_gr_object }, /* beta4 */ 1422 { -1, -1, 0x0076, &nv04_gr_object }, 1423 { -1, -1, 0x0077, &nv04_gr_object }, 1424 {} 1425 } 1426}; 1427 1428int 1429nv04_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) 1430{ 1431 struct nv04_gr *gr; 1432 1433 if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) 1434 return -ENOMEM; 1435 spin_lock_init(&gr->lock); 1436 *pgr = &gr->base; 1437 1438 return nvkm_gr_ctor(&nv04_gr, device, index, true, &gr->base); 1439} 1440