1 /* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 #include "gf100.h" 25 #include "ctxgf100.h" 26 #include "fuc/os.h" 27 28 #include <core/client.h> 29 #include <core/handle.h> 30 #include <core/option.h> 31 #include <engine/fifo.h> 32 #include <subdev/fb.h> 33 #include <subdev/mc.h> 34 #include <subdev/timer.h> 35 36 #include <nvif/class.h> 37 #include <nvif/unpack.h> 38 39 /******************************************************************************* 40 * Zero Bandwidth Clear 41 ******************************************************************************/ 42 43 static void 44 gf100_gr_zbc_clear_color(struct gf100_gr_priv *priv, int zbc) 45 { 46 if (priv->zbc_color[zbc].format) { 47 nv_wr32(priv, 0x405804, priv->zbc_color[zbc].ds[0]); 48 nv_wr32(priv, 0x405808, priv->zbc_color[zbc].ds[1]); 49 nv_wr32(priv, 0x40580c, priv->zbc_color[zbc].ds[2]); 50 nv_wr32(priv, 0x405810, priv->zbc_color[zbc].ds[3]); 51 } 52 nv_wr32(priv, 0x405814, priv->zbc_color[zbc].format); 53 nv_wr32(priv, 0x405820, zbc); 54 nv_wr32(priv, 0x405824, 0x00000004); /* TRIGGER | WRITE | COLOR */ 55 } 56 57 static int 58 gf100_gr_zbc_color_get(struct gf100_gr_priv *priv, int format, 59 const u32 ds[4], const u32 l2[4]) 60 { 61 struct nvkm_ltc *ltc = nvkm_ltc(priv); 62 int zbc = -ENOSPC, i; 63 64 for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { 65 if (priv->zbc_color[i].format) { 66 if (priv->zbc_color[i].format != format) 67 continue; 68 if (memcmp(priv->zbc_color[i].ds, ds, sizeof( 69 priv->zbc_color[i].ds))) 70 continue; 71 if (memcmp(priv->zbc_color[i].l2, l2, sizeof( 72 priv->zbc_color[i].l2))) { 73 WARN_ON(1); 74 return -EINVAL; 75 } 76 return i; 77 } else { 78 zbc = (zbc < 0) ? i : zbc; 79 } 80 } 81 82 if (zbc < 0) 83 return zbc; 84 85 memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds)); 86 memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2)); 87 priv->zbc_color[zbc].format = format; 88 ltc->zbc_color_get(ltc, zbc, l2); 89 gf100_gr_zbc_clear_color(priv, zbc); 90 return zbc; 91 } 92 93 static void 94 gf100_gr_zbc_clear_depth(struct gf100_gr_priv *priv, int zbc) 95 { 96 if (priv->zbc_depth[zbc].format) 97 nv_wr32(priv, 0x405818, priv->zbc_depth[zbc].ds); 98 nv_wr32(priv, 0x40581c, priv->zbc_depth[zbc].format); 99 nv_wr32(priv, 0x405820, zbc); 100 nv_wr32(priv, 0x405824, 0x00000005); /* TRIGGER | WRITE | DEPTH */ 101 } 102 103 static int 104 gf100_gr_zbc_depth_get(struct gf100_gr_priv *priv, int format, 105 const u32 ds, const u32 l2) 106 { 107 struct nvkm_ltc *ltc = nvkm_ltc(priv); 108 int zbc = -ENOSPC, i; 109 110 for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { 111 if (priv->zbc_depth[i].format) { 112 if (priv->zbc_depth[i].format != format) 113 continue; 114 if (priv->zbc_depth[i].ds != ds) 115 continue; 116 if (priv->zbc_depth[i].l2 != l2) { 117 WARN_ON(1); 118 return -EINVAL; 119 } 120 return i; 121 } else { 122 zbc = (zbc < 0) ? i : zbc; 123 } 124 } 125 126 if (zbc < 0) 127 return zbc; 128 129 priv->zbc_depth[zbc].format = format; 130 priv->zbc_depth[zbc].ds = ds; 131 priv->zbc_depth[zbc].l2 = l2; 132 ltc->zbc_depth_get(ltc, zbc, l2); 133 gf100_gr_zbc_clear_depth(priv, zbc); 134 return zbc; 135 } 136 137 /******************************************************************************* 138 * Graphics object classes 139 ******************************************************************************/ 140 141 static int 142 gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size) 143 { 144 struct gf100_gr_priv *priv = (void *)object->engine; 145 union { 146 struct fermi_a_zbc_color_v0 v0; 147 } *args = data; 148 int ret; 149 150 if (nvif_unpack(args->v0, 0, 0, false)) { 151 switch (args->v0.format) { 152 case FERMI_A_ZBC_COLOR_V0_FMT_ZERO: 153 case FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE: 154 case FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32: 155 case FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16: 156 case FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16: 157 case FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16: 158 case FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16: 159 case FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16: 160 case FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8: 161 case FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8: 162 case FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10: 163 case FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10: 164 case FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8: 165 case FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8: 166 case FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8: 167 case FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8: 168 case FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8: 169 case FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10: 170 case FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11: 171 ret = gf100_gr_zbc_color_get(priv, args->v0.format, 172 args->v0.ds, 173 args->v0.l2); 174 if (ret >= 0) { 175 args->v0.index = ret; 176 return 0; 177 } 178 break; 179 default: 180 return -EINVAL; 181 } 182 } 183 184 return ret; 185 } 186 187 static int 188 gf100_fermi_mthd_zbc_depth(struct nvkm_object *object, void *data, u32 size) 189 { 190 struct gf100_gr_priv *priv = (void *)object->engine; 191 union { 192 struct fermi_a_zbc_depth_v0 v0; 193 } *args = data; 194 int ret; 195 196 if (nvif_unpack(args->v0, 0, 0, false)) { 197 switch (args->v0.format) { 198 case FERMI_A_ZBC_DEPTH_V0_FMT_FP32: 199 ret = gf100_gr_zbc_depth_get(priv, args->v0.format, 200 args->v0.ds, 201 args->v0.l2); 202 return (ret >= 0) ? 0 : -ENOSPC; 203 default: 204 return -EINVAL; 205 } 206 } 207 208 return ret; 209 } 210 211 static int 212 gf100_fermi_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) 213 { 214 switch (mthd) { 215 case FERMI_A_ZBC_COLOR: 216 return gf100_fermi_mthd_zbc_color(object, data, size); 217 case FERMI_A_ZBC_DEPTH: 218 return gf100_fermi_mthd_zbc_depth(object, data, size); 219 default: 220 break; 221 } 222 return -EINVAL; 223 } 224 225 struct nvkm_ofuncs 226 gf100_fermi_ofuncs = { 227 .ctor = _nvkm_object_ctor, 228 .dtor = nvkm_object_destroy, 229 .init = nvkm_object_init, 230 .fini = nvkm_object_fini, 231 .mthd = gf100_fermi_mthd, 232 }; 233 234 static int 235 gf100_gr_set_shader_exceptions(struct nvkm_object *object, u32 mthd, 236 void *pdata, u32 size) 237 { 238 struct gf100_gr_priv *priv = (void *)object->engine; 239 if (size >= sizeof(u32)) { 240 u32 data = *(u32 *)pdata ? 0xffffffff : 0x00000000; 241 nv_wr32(priv, 0x419e44, data); 242 nv_wr32(priv, 0x419e4c, data); 243 return 0; 244 } 245 return -EINVAL; 246 } 247 248 struct nvkm_omthds 249 gf100_gr_9097_omthds[] = { 250 { 0x1528, 0x1528, gf100_gr_set_shader_exceptions }, 251 {} 252 }; 253 254 struct nvkm_omthds 255 gf100_gr_90c0_omthds[] = { 256 { 0x1528, 0x1528, gf100_gr_set_shader_exceptions }, 257 {} 258 }; 259 260 struct nvkm_oclass 261 gf100_gr_sclass[] = { 262 { FERMI_TWOD_A, &nvkm_object_ofuncs }, 263 { FERMI_MEMORY_TO_MEMORY_FORMAT_A, &nvkm_object_ofuncs }, 264 { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds }, 265 { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds }, 266 {} 267 }; 268 269 /******************************************************************************* 270 * PGRAPH context 271 ******************************************************************************/ 272 273 int 274 gf100_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 275 struct nvkm_oclass *oclass, void *args, u32 size, 276 struct nvkm_object **pobject) 277 { 278 struct nvkm_vm *vm = nvkm_client(parent)->vm; 279 struct gf100_gr_priv *priv = (void *)engine; 280 struct gf100_gr_data *data = priv->mmio_data; 281 struct gf100_gr_mmio *mmio = priv->mmio_list; 282 struct gf100_gr_chan *chan; 283 int ret, i; 284 285 /* allocate memory for context, and fill with default values */ 286 ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 287 priv->size, 0x100, 288 NVOBJ_FLAG_ZERO_ALLOC, &chan); 289 *pobject = nv_object(chan); 290 if (ret) 291 return ret; 292 293 /* allocate memory for a "mmio list" buffer that's used by the HUB 294 * fuc to modify some per-context register settings on first load 295 * of the context. 296 */ 297 ret = nvkm_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0, 298 &chan->mmio); 299 if (ret) 300 return ret; 301 302 ret = nvkm_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm, 303 NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, 304 &chan->mmio_vma); 305 if (ret) 306 return ret; 307 308 /* allocate buffers referenced by mmio list */ 309 for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) { 310 ret = nvkm_gpuobj_new(nv_object(chan), NULL, data->size, 311 data->align, 0, &chan->data[i].mem); 312 if (ret) 313 return ret; 314 315 ret = nvkm_gpuobj_map_vm(chan->data[i].mem, vm, data->access, 316 &chan->data[i].vma); 317 if (ret) 318 return ret; 319 320 data++; 321 } 322 323 /* finally, fill in the mmio list and point the context at it */ 324 for (i = 0; mmio->addr && i < ARRAY_SIZE(priv->mmio_list); i++) { 325 u32 addr = mmio->addr; 326 u32 data = mmio->data; 327 328 if (mmio->buffer >= 0) { 329 u64 info = chan->data[mmio->buffer].vma.offset; 330 data |= info >> mmio->shift; 331 } 332 333 nv_wo32(chan->mmio, chan->mmio_nr++ * 4, addr); 334 nv_wo32(chan->mmio, chan->mmio_nr++ * 4, data); 335 mmio++; 336 } 337 338 for (i = 0; i < priv->size; i += 4) 339 nv_wo32(chan, i, priv->data[i / 4]); 340 341 if (!priv->firmware) { 342 nv_wo32(chan, 0x00, chan->mmio_nr / 2); 343 nv_wo32(chan, 0x04, chan->mmio_vma.offset >> 8); 344 } else { 345 nv_wo32(chan, 0xf4, 0); 346 nv_wo32(chan, 0xf8, 0); 347 nv_wo32(chan, 0x10, chan->mmio_nr / 2); 348 nv_wo32(chan, 0x14, lower_32_bits(chan->mmio_vma.offset)); 349 nv_wo32(chan, 0x18, upper_32_bits(chan->mmio_vma.offset)); 350 nv_wo32(chan, 0x1c, 1); 351 nv_wo32(chan, 0x20, 0); 352 nv_wo32(chan, 0x28, 0); 353 nv_wo32(chan, 0x2c, 0); 354 } 355 356 return 0; 357 } 358 359 void 360 gf100_gr_context_dtor(struct nvkm_object *object) 361 { 362 struct gf100_gr_chan *chan = (void *)object; 363 int i; 364 365 for (i = 0; i < ARRAY_SIZE(chan->data); i++) { 366 nvkm_gpuobj_unmap(&chan->data[i].vma); 367 nvkm_gpuobj_ref(NULL, &chan->data[i].mem); 368 } 369 370 nvkm_gpuobj_unmap(&chan->mmio_vma); 371 nvkm_gpuobj_ref(NULL, &chan->mmio); 372 373 nvkm_gr_context_destroy(&chan->base); 374 } 375 376 /******************************************************************************* 377 * PGRAPH register lists 378 ******************************************************************************/ 379 380 const struct gf100_gr_init 381 gf100_gr_init_main_0[] = { 382 { 0x400080, 1, 0x04, 0x003083c2 }, 383 { 0x400088, 1, 0x04, 0x00006fe7 }, 384 { 0x40008c, 1, 0x04, 0x00000000 }, 385 { 0x400090, 1, 0x04, 0x00000030 }, 386 { 0x40013c, 1, 0x04, 0x013901f7 }, 387 { 0x400140, 1, 0x04, 0x00000100 }, 388 { 0x400144, 1, 0x04, 0x00000000 }, 389 { 0x400148, 1, 0x04, 0x00000110 }, 390 { 0x400138, 1, 0x04, 0x00000000 }, 391 { 0x400130, 2, 0x04, 0x00000000 }, 392 { 0x400124, 1, 0x04, 0x00000002 }, 393 {} 394 }; 395 396 const struct gf100_gr_init 397 gf100_gr_init_fe_0[] = { 398 { 0x40415c, 1, 0x04, 0x00000000 }, 399 { 0x404170, 1, 0x04, 0x00000000 }, 400 {} 401 }; 402 403 const struct gf100_gr_init 404 gf100_gr_init_pri_0[] = { 405 { 0x404488, 2, 0x04, 0x00000000 }, 406 {} 407 }; 408 409 const struct gf100_gr_init 410 gf100_gr_init_rstr2d_0[] = { 411 { 0x407808, 1, 0x04, 0x00000000 }, 412 {} 413 }; 414 415 const struct gf100_gr_init 416 gf100_gr_init_pd_0[] = { 417 { 0x406024, 1, 0x04, 0x00000000 }, 418 {} 419 }; 420 421 const struct gf100_gr_init 422 gf100_gr_init_ds_0[] = { 423 { 0x405844, 1, 0x04, 0x00ffffff }, 424 { 0x405850, 1, 0x04, 0x00000000 }, 425 { 0x405908, 1, 0x04, 0x00000000 }, 426 {} 427 }; 428 429 const struct gf100_gr_init 430 gf100_gr_init_scc_0[] = { 431 { 0x40803c, 1, 0x04, 0x00000000 }, 432 {} 433 }; 434 435 const struct gf100_gr_init 436 gf100_gr_init_prop_0[] = { 437 { 0x4184a0, 1, 0x04, 0x00000000 }, 438 {} 439 }; 440 441 const struct gf100_gr_init 442 gf100_gr_init_gpc_unk_0[] = { 443 { 0x418604, 1, 0x04, 0x00000000 }, 444 { 0x418680, 1, 0x04, 0x00000000 }, 445 { 0x418714, 1, 0x04, 0x80000000 }, 446 { 0x418384, 1, 0x04, 0x00000000 }, 447 {} 448 }; 449 450 const struct gf100_gr_init 451 gf100_gr_init_setup_0[] = { 452 { 0x418814, 3, 0x04, 0x00000000 }, 453 {} 454 }; 455 456 const struct gf100_gr_init 457 gf100_gr_init_crstr_0[] = { 458 { 0x418b04, 1, 0x04, 0x00000000 }, 459 {} 460 }; 461 462 const struct gf100_gr_init 463 gf100_gr_init_setup_1[] = { 464 { 0x4188c8, 1, 0x04, 0x80000000 }, 465 { 0x4188cc, 1, 0x04, 0x00000000 }, 466 { 0x4188d0, 1, 0x04, 0x00010000 }, 467 { 0x4188d4, 1, 0x04, 0x00000001 }, 468 {} 469 }; 470 471 const struct gf100_gr_init 472 gf100_gr_init_zcull_0[] = { 473 { 0x418910, 1, 0x04, 0x00010001 }, 474 { 0x418914, 1, 0x04, 0x00000301 }, 475 { 0x418918, 1, 0x04, 0x00800000 }, 476 { 0x418980, 1, 0x04, 0x77777770 }, 477 { 0x418984, 3, 0x04, 0x77777777 }, 478 {} 479 }; 480 481 const struct gf100_gr_init 482 gf100_gr_init_gpm_0[] = { 483 { 0x418c04, 1, 0x04, 0x00000000 }, 484 { 0x418c88, 1, 0x04, 0x00000000 }, 485 {} 486 }; 487 488 const struct gf100_gr_init 489 gf100_gr_init_gpc_unk_1[] = { 490 { 0x418d00, 1, 0x04, 0x00000000 }, 491 { 0x418f08, 1, 0x04, 0x00000000 }, 492 { 0x418e00, 1, 0x04, 0x00000050 }, 493 { 0x418e08, 1, 0x04, 0x00000000 }, 494 {} 495 }; 496 497 const struct gf100_gr_init 498 gf100_gr_init_gcc_0[] = { 499 { 0x41900c, 1, 0x04, 0x00000000 }, 500 { 0x419018, 1, 0x04, 0x00000000 }, 501 {} 502 }; 503 504 const struct gf100_gr_init 505 gf100_gr_init_tpccs_0[] = { 506 { 0x419d08, 2, 0x04, 0x00000000 }, 507 { 0x419d10, 1, 0x04, 0x00000014 }, 508 {} 509 }; 510 511 const struct gf100_gr_init 512 gf100_gr_init_tex_0[] = { 513 { 0x419ab0, 1, 0x04, 0x00000000 }, 514 { 0x419ab8, 1, 0x04, 0x000000e7 }, 515 { 0x419abc, 2, 0x04, 0x00000000 }, 516 {} 517 }; 518 519 const struct gf100_gr_init 520 gf100_gr_init_pe_0[] = { 521 { 0x41980c, 3, 0x04, 0x00000000 }, 522 { 0x419844, 1, 0x04, 0x00000000 }, 523 { 0x41984c, 1, 0x04, 0x00005bc5 }, 524 { 0x419850, 4, 0x04, 0x00000000 }, 525 {} 526 }; 527 528 const struct gf100_gr_init 529 gf100_gr_init_l1c_0[] = { 530 { 0x419c98, 1, 0x04, 0x00000000 }, 531 { 0x419ca8, 1, 0x04, 0x80000000 }, 532 { 0x419cb4, 1, 0x04, 0x00000000 }, 533 { 0x419cb8, 1, 0x04, 0x00008bf4 }, 534 { 0x419cbc, 1, 0x04, 0x28137606 }, 535 { 0x419cc0, 2, 0x04, 0x00000000 }, 536 {} 537 }; 538 539 const struct gf100_gr_init 540 gf100_gr_init_wwdx_0[] = { 541 { 0x419bd4, 1, 0x04, 0x00800000 }, 542 { 0x419bdc, 1, 0x04, 0x00000000 }, 543 {} 544 }; 545 546 const struct gf100_gr_init 547 gf100_gr_init_tpccs_1[] = { 548 { 0x419d2c, 1, 0x04, 0x00000000 }, 549 {} 550 }; 551 552 const struct gf100_gr_init 553 gf100_gr_init_mpc_0[] = { 554 { 0x419c0c, 1, 0x04, 0x00000000 }, 555 {} 556 }; 557 558 static const struct gf100_gr_init 559 gf100_gr_init_sm_0[] = { 560 { 0x419e00, 1, 0x04, 0x00000000 }, 561 { 0x419ea0, 1, 0x04, 0x00000000 }, 562 { 0x419ea4, 1, 0x04, 0x00000100 }, 563 { 0x419ea8, 1, 0x04, 0x00001100 }, 564 { 0x419eac, 1, 0x04, 0x11100702 }, 565 { 0x419eb0, 1, 0x04, 0x00000003 }, 566 { 0x419eb4, 4, 0x04, 0x00000000 }, 567 { 0x419ec8, 1, 0x04, 0x06060618 }, 568 { 0x419ed0, 1, 0x04, 0x0eff0e38 }, 569 { 0x419ed4, 1, 0x04, 0x011104f1 }, 570 { 0x419edc, 1, 0x04, 0x00000000 }, 571 { 0x419f00, 1, 0x04, 0x00000000 }, 572 { 0x419f2c, 1, 0x04, 0x00000000 }, 573 {} 574 }; 575 576 const struct gf100_gr_init 577 gf100_gr_init_be_0[] = { 578 { 0x40880c, 1, 0x04, 0x00000000 }, 579 { 0x408910, 9, 0x04, 0x00000000 }, 580 { 0x408950, 1, 0x04, 0x00000000 }, 581 { 0x408954, 1, 0x04, 0x0000ffff }, 582 { 0x408984, 1, 0x04, 0x00000000 }, 583 { 0x408988, 1, 0x04, 0x08040201 }, 584 { 0x40898c, 1, 0x04, 0x80402010 }, 585 {} 586 }; 587 588 const struct gf100_gr_init 589 gf100_gr_init_fe_1[] = { 590 { 0x4040f0, 1, 0x04, 0x00000000 }, 591 {} 592 }; 593 594 const struct gf100_gr_init 595 gf100_gr_init_pe_1[] = { 596 { 0x419880, 1, 0x04, 0x00000002 }, 597 {} 598 }; 599 600 static const struct gf100_gr_pack 601 gf100_gr_pack_mmio[] = { 602 { gf100_gr_init_main_0 }, 603 { gf100_gr_init_fe_0 }, 604 { gf100_gr_init_pri_0 }, 605 { gf100_gr_init_rstr2d_0 }, 606 { gf100_gr_init_pd_0 }, 607 { gf100_gr_init_ds_0 }, 608 { gf100_gr_init_scc_0 }, 609 { gf100_gr_init_prop_0 }, 610 { gf100_gr_init_gpc_unk_0 }, 611 { gf100_gr_init_setup_0 }, 612 { gf100_gr_init_crstr_0 }, 613 { gf100_gr_init_setup_1 }, 614 { gf100_gr_init_zcull_0 }, 615 { gf100_gr_init_gpm_0 }, 616 { gf100_gr_init_gpc_unk_1 }, 617 { gf100_gr_init_gcc_0 }, 618 { gf100_gr_init_tpccs_0 }, 619 { gf100_gr_init_tex_0 }, 620 { gf100_gr_init_pe_0 }, 621 { gf100_gr_init_l1c_0 }, 622 { gf100_gr_init_wwdx_0 }, 623 { gf100_gr_init_tpccs_1 }, 624 { gf100_gr_init_mpc_0 }, 625 { gf100_gr_init_sm_0 }, 626 { gf100_gr_init_be_0 }, 627 { gf100_gr_init_fe_1 }, 628 { gf100_gr_init_pe_1 }, 629 {} 630 }; 631 632 /******************************************************************************* 633 * PGRAPH engine/subdev functions 634 ******************************************************************************/ 635 636 void 637 gf100_gr_zbc_init(struct gf100_gr_priv *priv) 638 { 639 const u32 zero[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 640 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; 641 const u32 one[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 642 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; 643 const u32 f32_0[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 644 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; 645 const u32 f32_1[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 646 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; 647 struct nvkm_ltc *ltc = nvkm_ltc(priv); 648 int index; 649 650 if (!priv->zbc_color[0].format) { 651 gf100_gr_zbc_color_get(priv, 1, & zero[0], &zero[4]); 652 gf100_gr_zbc_color_get(priv, 2, & one[0], &one[4]); 653 gf100_gr_zbc_color_get(priv, 4, &f32_0[0], &f32_0[4]); 654 gf100_gr_zbc_color_get(priv, 4, &f32_1[0], &f32_1[4]); 655 gf100_gr_zbc_depth_get(priv, 1, 0x00000000, 0x00000000); 656 gf100_gr_zbc_depth_get(priv, 1, 0x3f800000, 0x3f800000); 657 } 658 659 for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) 660 gf100_gr_zbc_clear_color(priv, index); 661 for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) 662 gf100_gr_zbc_clear_depth(priv, index); 663 } 664 665 /** 666 * Wait until GR goes idle. GR is considered idle if it is disabled by the 667 * MC (0x200) register, or GR is not busy and a context switch is not in 668 * progress. 669 */ 670 int 671 gf100_gr_wait_idle(struct gf100_gr_priv *priv) 672 { 673 unsigned long end_jiffies = jiffies + msecs_to_jiffies(2000); 674 bool gr_enabled, ctxsw_active, gr_busy; 675 676 do { 677 /* 678 * required to make sure FIFO_ENGINE_STATUS (0x2640) is 679 * up-to-date 680 */ 681 nv_rd32(priv, 0x400700); 682 683 gr_enabled = nv_rd32(priv, 0x200) & 0x1000; 684 ctxsw_active = nv_rd32(priv, 0x2640) & 0x8000; 685 gr_busy = nv_rd32(priv, 0x40060c) & 0x1; 686 687 if (!gr_enabled || (!gr_busy && !ctxsw_active)) 688 return 0; 689 } while (time_before(jiffies, end_jiffies)); 690 691 nv_error(priv, "wait for idle timeout (en: %d, ctxsw: %d, busy: %d)\n", 692 gr_enabled, ctxsw_active, gr_busy); 693 return -EAGAIN; 694 } 695 696 void 697 gf100_gr_mmio(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) 698 { 699 const struct gf100_gr_pack *pack; 700 const struct gf100_gr_init *init; 701 702 pack_for_each_init(init, pack, p) { 703 u32 next = init->addr + init->count * init->pitch; 704 u32 addr = init->addr; 705 while (addr < next) { 706 nv_wr32(priv, addr, init->data); 707 addr += init->pitch; 708 } 709 } 710 } 711 712 void 713 gf100_gr_icmd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) 714 { 715 const struct gf100_gr_pack *pack; 716 const struct gf100_gr_init *init; 717 u32 data = 0; 718 719 nv_wr32(priv, 0x400208, 0x80000000); 720 721 pack_for_each_init(init, pack, p) { 722 u32 next = init->addr + init->count * init->pitch; 723 u32 addr = init->addr; 724 725 if ((pack == p && init == p->init) || data != init->data) { 726 nv_wr32(priv, 0x400204, init->data); 727 data = init->data; 728 } 729 730 while (addr < next) { 731 nv_wr32(priv, 0x400200, addr); 732 /** 733 * Wait for GR to go idle after submitting a 734 * GO_IDLE bundle 735 */ 736 if ((addr & 0xffff) == 0xe100) 737 gf100_gr_wait_idle(priv); 738 nv_wait(priv, 0x400700, 0x00000004, 0x00000000); 739 addr += init->pitch; 740 } 741 } 742 743 nv_wr32(priv, 0x400208, 0x00000000); 744 } 745 746 void 747 gf100_gr_mthd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) 748 { 749 const struct gf100_gr_pack *pack; 750 const struct gf100_gr_init *init; 751 u32 data = 0; 752 753 pack_for_each_init(init, pack, p) { 754 u32 ctrl = 0x80000000 | pack->type; 755 u32 next = init->addr + init->count * init->pitch; 756 u32 addr = init->addr; 757 758 if ((pack == p && init == p->init) || data != init->data) { 759 nv_wr32(priv, 0x40448c, init->data); 760 data = init->data; 761 } 762 763 while (addr < next) { 764 nv_wr32(priv, 0x404488, ctrl | (addr << 14)); 765 addr += init->pitch; 766 } 767 } 768 } 769 770 u64 771 gf100_gr_units(struct nvkm_gr *gr) 772 { 773 struct gf100_gr_priv *priv = (void *)gr; 774 u64 cfg; 775 776 cfg = (u32)priv->gpc_nr; 777 cfg |= (u32)priv->tpc_total << 8; 778 cfg |= (u64)priv->rop_nr << 32; 779 780 return cfg; 781 } 782 783 static const struct nvkm_enum gk104_sked_error[] = { 784 { 7, "CONSTANT_BUFFER_SIZE" }, 785 { 9, "LOCAL_MEMORY_SIZE_POS" }, 786 { 10, "LOCAL_MEMORY_SIZE_NEG" }, 787 { 11, "WARP_CSTACK_SIZE" }, 788 { 12, "TOTAL_TEMP_SIZE" }, 789 { 13, "REGISTER_COUNT" }, 790 { 18, "TOTAL_THREADS" }, 791 { 20, "PROGRAM_OFFSET" }, 792 { 21, "SHARED_MEMORY_SIZE" }, 793 { 25, "SHARED_CONFIG_TOO_SMALL" }, 794 { 26, "TOTAL_REGISTER_COUNT" }, 795 {} 796 }; 797 798 static const struct nvkm_enum gf100_gpc_rop_error[] = { 799 { 1, "RT_PITCH_OVERRUN" }, 800 { 4, "RT_WIDTH_OVERRUN" }, 801 { 5, "RT_HEIGHT_OVERRUN" }, 802 { 7, "ZETA_STORAGE_TYPE_MISMATCH" }, 803 { 8, "RT_STORAGE_TYPE_MISMATCH" }, 804 { 10, "RT_LINEAR_MISMATCH" }, 805 {} 806 }; 807 808 static void 809 gf100_gr_trap_gpc_rop(struct gf100_gr_priv *priv, int gpc) 810 { 811 u32 trap[4]; 812 int i; 813 814 trap[0] = nv_rd32(priv, GPC_UNIT(gpc, 0x0420)); 815 trap[1] = nv_rd32(priv, GPC_UNIT(gpc, 0x0434)); 816 trap[2] = nv_rd32(priv, GPC_UNIT(gpc, 0x0438)); 817 trap[3] = nv_rd32(priv, GPC_UNIT(gpc, 0x043c)); 818 819 nv_error(priv, "GPC%d/PROP trap:", gpc); 820 for (i = 0; i <= 29; ++i) { 821 if (!(trap[0] & (1 << i))) 822 continue; 823 pr_cont(" "); 824 nvkm_enum_print(gf100_gpc_rop_error, i); 825 } 826 pr_cont("\n"); 827 828 nv_error(priv, "x = %u, y = %u, format = %x, storage type = %x\n", 829 trap[1] & 0xffff, trap[1] >> 16, (trap[2] >> 8) & 0x3f, 830 trap[3] & 0xff); 831 nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); 832 } 833 834 static const struct nvkm_enum gf100_mp_warp_error[] = { 835 { 0x00, "NO_ERROR" }, 836 { 0x01, "STACK_MISMATCH" }, 837 { 0x05, "MISALIGNED_PC" }, 838 { 0x08, "MISALIGNED_GPR" }, 839 { 0x09, "INVALID_OPCODE" }, 840 { 0x0d, "GPR_OUT_OF_BOUNDS" }, 841 { 0x0e, "MEM_OUT_OF_BOUNDS" }, 842 { 0x0f, "UNALIGNED_MEM_ACCESS" }, 843 { 0x11, "INVALID_PARAM" }, 844 {} 845 }; 846 847 static const struct nvkm_bitfield gf100_mp_global_error[] = { 848 { 0x00000004, "MULTIPLE_WARP_ERRORS" }, 849 { 0x00000008, "OUT_OF_STACK_SPACE" }, 850 {} 851 }; 852 853 static void 854 gf100_gr_trap_mp(struct gf100_gr_priv *priv, int gpc, int tpc) 855 { 856 u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648)); 857 u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650)); 858 859 nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc); 860 nvkm_bitfield_print(gf100_mp_global_error, gerr); 861 if (werr) { 862 pr_cont(" "); 863 nvkm_enum_print(gf100_mp_warp_error, werr & 0xffff); 864 } 865 pr_cont("\n"); 866 867 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x648), 0x00000000); 868 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x650), gerr); 869 } 870 871 static void 872 gf100_gr_trap_tpc(struct gf100_gr_priv *priv, int gpc, int tpc) 873 { 874 u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0508)); 875 876 if (stat & 0x00000001) { 877 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0224)); 878 nv_error(priv, "GPC%d/TPC%d/TEX: 0x%08x\n", gpc, tpc, trap); 879 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0224), 0xc0000000); 880 stat &= ~0x00000001; 881 } 882 883 if (stat & 0x00000002) { 884 gf100_gr_trap_mp(priv, gpc, tpc); 885 stat &= ~0x00000002; 886 } 887 888 if (stat & 0x00000004) { 889 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0084)); 890 nv_error(priv, "GPC%d/TPC%d/POLY: 0x%08x\n", gpc, tpc, trap); 891 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0084), 0xc0000000); 892 stat &= ~0x00000004; 893 } 894 895 if (stat & 0x00000008) { 896 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x048c)); 897 nv_error(priv, "GPC%d/TPC%d/L1C: 0x%08x\n", gpc, tpc, trap); 898 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x048c), 0xc0000000); 899 stat &= ~0x00000008; 900 } 901 902 if (stat) { 903 nv_error(priv, "GPC%d/TPC%d/0x%08x: unknown\n", gpc, tpc, stat); 904 } 905 } 906 907 static void 908 gf100_gr_trap_gpc(struct gf100_gr_priv *priv, int gpc) 909 { 910 u32 stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90)); 911 int tpc; 912 913 if (stat & 0x00000001) { 914 gf100_gr_trap_gpc_rop(priv, gpc); 915 stat &= ~0x00000001; 916 } 917 918 if (stat & 0x00000002) { 919 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900)); 920 nv_error(priv, "GPC%d/ZCULL: 0x%08x\n", gpc, trap); 921 nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); 922 stat &= ~0x00000002; 923 } 924 925 if (stat & 0x00000004) { 926 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028)); 927 nv_error(priv, "GPC%d/CCACHE: 0x%08x\n", gpc, trap); 928 nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); 929 stat &= ~0x00000004; 930 } 931 932 if (stat & 0x00000008) { 933 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824)); 934 nv_error(priv, "GPC%d/ESETUP: 0x%08x\n", gpc, trap); 935 nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); 936 stat &= ~0x00000009; 937 } 938 939 for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { 940 u32 mask = 0x00010000 << tpc; 941 if (stat & mask) { 942 gf100_gr_trap_tpc(priv, gpc, tpc); 943 nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), mask); 944 stat &= ~mask; 945 } 946 } 947 948 if (stat) { 949 nv_error(priv, "GPC%d/0x%08x: unknown\n", gpc, stat); 950 } 951 } 952 953 static void 954 gf100_gr_trap_intr(struct gf100_gr_priv *priv) 955 { 956 u32 trap = nv_rd32(priv, 0x400108); 957 int rop, gpc, i; 958 959 if (trap & 0x00000001) { 960 u32 stat = nv_rd32(priv, 0x404000); 961 nv_error(priv, "DISPATCH 0x%08x\n", stat); 962 nv_wr32(priv, 0x404000, 0xc0000000); 963 nv_wr32(priv, 0x400108, 0x00000001); 964 trap &= ~0x00000001; 965 } 966 967 if (trap & 0x00000002) { 968 u32 stat = nv_rd32(priv, 0x404600); 969 nv_error(priv, "M2MF 0x%08x\n", stat); 970 nv_wr32(priv, 0x404600, 0xc0000000); 971 nv_wr32(priv, 0x400108, 0x00000002); 972 trap &= ~0x00000002; 973 } 974 975 if (trap & 0x00000008) { 976 u32 stat = nv_rd32(priv, 0x408030); 977 nv_error(priv, "CCACHE 0x%08x\n", stat); 978 nv_wr32(priv, 0x408030, 0xc0000000); 979 nv_wr32(priv, 0x400108, 0x00000008); 980 trap &= ~0x00000008; 981 } 982 983 if (trap & 0x00000010) { 984 u32 stat = nv_rd32(priv, 0x405840); 985 nv_error(priv, "SHADER 0x%08x\n", stat); 986 nv_wr32(priv, 0x405840, 0xc0000000); 987 nv_wr32(priv, 0x400108, 0x00000010); 988 trap &= ~0x00000010; 989 } 990 991 if (trap & 0x00000040) { 992 u32 stat = nv_rd32(priv, 0x40601c); 993 nv_error(priv, "UNK6 0x%08x\n", stat); 994 nv_wr32(priv, 0x40601c, 0xc0000000); 995 nv_wr32(priv, 0x400108, 0x00000040); 996 trap &= ~0x00000040; 997 } 998 999 if (trap & 0x00000080) { 1000 u32 stat = nv_rd32(priv, 0x404490); 1001 nv_error(priv, "MACRO 0x%08x\n", stat); 1002 nv_wr32(priv, 0x404490, 0xc0000000); 1003 nv_wr32(priv, 0x400108, 0x00000080); 1004 trap &= ~0x00000080; 1005 } 1006 1007 if (trap & 0x00000100) { 1008 u32 stat = nv_rd32(priv, 0x407020); 1009 1010 nv_error(priv, "SKED:"); 1011 for (i = 0; i <= 29; ++i) { 1012 if (!(stat & (1 << i))) 1013 continue; 1014 pr_cont(" "); 1015 nvkm_enum_print(gk104_sked_error, i); 1016 } 1017 pr_cont("\n"); 1018 1019 if (stat & 0x3fffffff) 1020 nv_wr32(priv, 0x407020, 0x40000000); 1021 nv_wr32(priv, 0x400108, 0x00000100); 1022 trap &= ~0x00000100; 1023 } 1024 1025 if (trap & 0x01000000) { 1026 u32 stat = nv_rd32(priv, 0x400118); 1027 for (gpc = 0; stat && gpc < priv->gpc_nr; gpc++) { 1028 u32 mask = 0x00000001 << gpc; 1029 if (stat & mask) { 1030 gf100_gr_trap_gpc(priv, gpc); 1031 nv_wr32(priv, 0x400118, mask); 1032 stat &= ~mask; 1033 } 1034 } 1035 nv_wr32(priv, 0x400108, 0x01000000); 1036 trap &= ~0x01000000; 1037 } 1038 1039 if (trap & 0x02000000) { 1040 for (rop = 0; rop < priv->rop_nr; rop++) { 1041 u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); 1042 u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); 1043 nv_error(priv, "ROP%d 0x%08x 0x%08x\n", 1044 rop, statz, statc); 1045 nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); 1046 nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); 1047 } 1048 nv_wr32(priv, 0x400108, 0x02000000); 1049 trap &= ~0x02000000; 1050 } 1051 1052 if (trap) { 1053 nv_error(priv, "TRAP UNHANDLED 0x%08x\n", trap); 1054 nv_wr32(priv, 0x400108, trap); 1055 } 1056 } 1057 1058 static void 1059 gf100_gr_ctxctl_debug_unit(struct gf100_gr_priv *priv, u32 base) 1060 { 1061 nv_error(priv, "%06x - done 0x%08x\n", base, 1062 nv_rd32(priv, base + 0x400)); 1063 nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, 1064 nv_rd32(priv, base + 0x800), nv_rd32(priv, base + 0x804), 1065 nv_rd32(priv, base + 0x808), nv_rd32(priv, base + 0x80c)); 1066 nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, 1067 nv_rd32(priv, base + 0x810), nv_rd32(priv, base + 0x814), 1068 nv_rd32(priv, base + 0x818), nv_rd32(priv, base + 0x81c)); 1069 } 1070 1071 void 1072 gf100_gr_ctxctl_debug(struct gf100_gr_priv *priv) 1073 { 1074 u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff; 1075 u32 gpc; 1076 1077 gf100_gr_ctxctl_debug_unit(priv, 0x409000); 1078 for (gpc = 0; gpc < gpcnr; gpc++) 1079 gf100_gr_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000)); 1080 } 1081 1082 static void 1083 gf100_gr_ctxctl_isr(struct gf100_gr_priv *priv) 1084 { 1085 u32 stat = nv_rd32(priv, 0x409c18); 1086 1087 if (stat & 0x00000001) { 1088 u32 code = nv_rd32(priv, 0x409814); 1089 if (code == E_BAD_FWMTHD) { 1090 u32 class = nv_rd32(priv, 0x409808); 1091 u32 addr = nv_rd32(priv, 0x40980c); 1092 u32 subc = (addr & 0x00070000) >> 16; 1093 u32 mthd = (addr & 0x00003ffc); 1094 u32 data = nv_rd32(priv, 0x409810); 1095 1096 nv_error(priv, "FECS MTHD subc %d class 0x%04x " 1097 "mthd 0x%04x data 0x%08x\n", 1098 subc, class, mthd, data); 1099 1100 nv_wr32(priv, 0x409c20, 0x00000001); 1101 stat &= ~0x00000001; 1102 } else { 1103 nv_error(priv, "FECS ucode error %d\n", code); 1104 } 1105 } 1106 1107 if (stat & 0x00080000) { 1108 nv_error(priv, "FECS watchdog timeout\n"); 1109 gf100_gr_ctxctl_debug(priv); 1110 nv_wr32(priv, 0x409c20, 0x00080000); 1111 stat &= ~0x00080000; 1112 } 1113 1114 if (stat) { 1115 nv_error(priv, "FECS 0x%08x\n", stat); 1116 gf100_gr_ctxctl_debug(priv); 1117 nv_wr32(priv, 0x409c20, stat); 1118 } 1119 } 1120 1121 static void 1122 gf100_gr_intr(struct nvkm_subdev *subdev) 1123 { 1124 struct nvkm_fifo *pfifo = nvkm_fifo(subdev); 1125 struct nvkm_engine *engine = nv_engine(subdev); 1126 struct nvkm_object *engctx; 1127 struct nvkm_handle *handle; 1128 struct gf100_gr_priv *priv = (void *)subdev; 1129 u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff; 1130 u32 stat = nv_rd32(priv, 0x400100); 1131 u32 addr = nv_rd32(priv, 0x400704); 1132 u32 mthd = (addr & 0x00003ffc); 1133 u32 subc = (addr & 0x00070000) >> 16; 1134 u32 data = nv_rd32(priv, 0x400708); 1135 u32 code = nv_rd32(priv, 0x400110); 1136 u32 class; 1137 int chid; 1138 1139 if (nv_device(priv)->card_type < NV_E0 || subc < 4) 1140 class = nv_rd32(priv, 0x404200 + (subc * 4)); 1141 else 1142 class = 0x0000; 1143 1144 engctx = nvkm_engctx_get(engine, inst); 1145 chid = pfifo->chid(pfifo, engctx); 1146 1147 if (stat & 0x00000001) { 1148 /* 1149 * notifier interrupt, only needed for cyclestats 1150 * can be safely ignored 1151 */ 1152 nv_wr32(priv, 0x400100, 0x00000001); 1153 stat &= ~0x00000001; 1154 } 1155 1156 if (stat & 0x00000010) { 1157 handle = nvkm_handle_get_class(engctx, class); 1158 if (!handle || nv_call(handle->object, mthd, data)) { 1159 nv_error(priv, 1160 "ILLEGAL_MTHD ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", 1161 chid, inst << 12, nvkm_client_name(engctx), 1162 subc, class, mthd, data); 1163 } 1164 nvkm_handle_put(handle); 1165 nv_wr32(priv, 0x400100, 0x00000010); 1166 stat &= ~0x00000010; 1167 } 1168 1169 if (stat & 0x00000020) { 1170 nv_error(priv, 1171 "ILLEGAL_CLASS ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", 1172 chid, inst << 12, nvkm_client_name(engctx), subc, 1173 class, mthd, data); 1174 nv_wr32(priv, 0x400100, 0x00000020); 1175 stat &= ~0x00000020; 1176 } 1177 1178 if (stat & 0x00100000) { 1179 nv_error(priv, "DATA_ERROR ["); 1180 nvkm_enum_print(nv50_data_error_names, code); 1181 pr_cont("] ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n", 1182 chid, inst << 12, nvkm_client_name(engctx), subc, 1183 class, mthd, data); 1184 nv_wr32(priv, 0x400100, 0x00100000); 1185 stat &= ~0x00100000; 1186 } 1187 1188 if (stat & 0x00200000) { 1189 nv_error(priv, "TRAP ch %d [0x%010llx %s]\n", chid, inst << 12, 1190 nvkm_client_name(engctx)); 1191 gf100_gr_trap_intr(priv); 1192 nv_wr32(priv, 0x400100, 0x00200000); 1193 stat &= ~0x00200000; 1194 } 1195 1196 if (stat & 0x00080000) { 1197 gf100_gr_ctxctl_isr(priv); 1198 nv_wr32(priv, 0x400100, 0x00080000); 1199 stat &= ~0x00080000; 1200 } 1201 1202 if (stat) { 1203 nv_error(priv, "unknown stat 0x%08x\n", stat); 1204 nv_wr32(priv, 0x400100, stat); 1205 } 1206 1207 nv_wr32(priv, 0x400500, 0x00010001); 1208 nvkm_engctx_put(engctx); 1209 } 1210 1211 void 1212 gf100_gr_init_fw(struct gf100_gr_priv *priv, u32 fuc_base, 1213 struct gf100_gr_fuc *code, struct gf100_gr_fuc *data) 1214 { 1215 int i; 1216 1217 nv_wr32(priv, fuc_base + 0x01c0, 0x01000000); 1218 for (i = 0; i < data->size / 4; i++) 1219 nv_wr32(priv, fuc_base + 0x01c4, data->data[i]); 1220 1221 nv_wr32(priv, fuc_base + 0x0180, 0x01000000); 1222 for (i = 0; i < code->size / 4; i++) { 1223 if ((i & 0x3f) == 0) 1224 nv_wr32(priv, fuc_base + 0x0188, i >> 6); 1225 nv_wr32(priv, fuc_base + 0x0184, code->data[i]); 1226 } 1227 1228 /* code must be padded to 0x40 words */ 1229 for (; i & 0x3f; i++) 1230 nv_wr32(priv, fuc_base + 0x0184, 0); 1231 } 1232 1233 static void 1234 gf100_gr_init_csdata(struct gf100_gr_priv *priv, 1235 const struct gf100_gr_pack *pack, 1236 u32 falcon, u32 starstar, u32 base) 1237 { 1238 const struct gf100_gr_pack *iter; 1239 const struct gf100_gr_init *init; 1240 u32 addr = ~0, prev = ~0, xfer = 0; 1241 u32 star, temp; 1242 1243 nv_wr32(priv, falcon + 0x01c0, 0x02000000 + starstar); 1244 star = nv_rd32(priv, falcon + 0x01c4); 1245 temp = nv_rd32(priv, falcon + 0x01c4); 1246 if (temp > star) 1247 star = temp; 1248 nv_wr32(priv, falcon + 0x01c0, 0x01000000 + star); 1249 1250 pack_for_each_init(init, iter, pack) { 1251 u32 head = init->addr - base; 1252 u32 tail = head + init->count * init->pitch; 1253 while (head < tail) { 1254 if (head != prev + 4 || xfer >= 32) { 1255 if (xfer) { 1256 u32 data = ((--xfer << 26) | addr); 1257 nv_wr32(priv, falcon + 0x01c4, data); 1258 star += 4; 1259 } 1260 addr = head; 1261 xfer = 0; 1262 } 1263 prev = head; 1264 xfer = xfer + 1; 1265 head = head + init->pitch; 1266 } 1267 } 1268 1269 nv_wr32(priv, falcon + 0x01c4, (--xfer << 26) | addr); 1270 nv_wr32(priv, falcon + 0x01c0, 0x01000004 + starstar); 1271 nv_wr32(priv, falcon + 0x01c4, star + 4); 1272 } 1273 1274 int 1275 gf100_gr_init_ctxctl(struct gf100_gr_priv *priv) 1276 { 1277 struct gf100_gr_oclass *oclass = (void *)nv_object(priv)->oclass; 1278 struct gf100_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass; 1279 int i; 1280 1281 if (priv->firmware) { 1282 /* load fuc microcode */ 1283 nvkm_mc(priv)->unk260(nvkm_mc(priv), 0); 1284 gf100_gr_init_fw(priv, 0x409000, &priv->fuc409c, 1285 &priv->fuc409d); 1286 gf100_gr_init_fw(priv, 0x41a000, &priv->fuc41ac, 1287 &priv->fuc41ad); 1288 nvkm_mc(priv)->unk260(nvkm_mc(priv), 1); 1289 1290 /* start both of them running */ 1291 nv_wr32(priv, 0x409840, 0xffffffff); 1292 nv_wr32(priv, 0x41a10c, 0x00000000); 1293 nv_wr32(priv, 0x40910c, 0x00000000); 1294 nv_wr32(priv, 0x41a100, 0x00000002); 1295 nv_wr32(priv, 0x409100, 0x00000002); 1296 if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001)) 1297 nv_warn(priv, "0x409800 wait failed\n"); 1298 1299 nv_wr32(priv, 0x409840, 0xffffffff); 1300 nv_wr32(priv, 0x409500, 0x7fffffff); 1301 nv_wr32(priv, 0x409504, 0x00000021); 1302 1303 nv_wr32(priv, 0x409840, 0xffffffff); 1304 nv_wr32(priv, 0x409500, 0x00000000); 1305 nv_wr32(priv, 0x409504, 0x00000010); 1306 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1307 nv_error(priv, "fuc09 req 0x10 timeout\n"); 1308 return -EBUSY; 1309 } 1310 priv->size = nv_rd32(priv, 0x409800); 1311 1312 nv_wr32(priv, 0x409840, 0xffffffff); 1313 nv_wr32(priv, 0x409500, 0x00000000); 1314 nv_wr32(priv, 0x409504, 0x00000016); 1315 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1316 nv_error(priv, "fuc09 req 0x16 timeout\n"); 1317 return -EBUSY; 1318 } 1319 1320 nv_wr32(priv, 0x409840, 0xffffffff); 1321 nv_wr32(priv, 0x409500, 0x00000000); 1322 nv_wr32(priv, 0x409504, 0x00000025); 1323 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1324 nv_error(priv, "fuc09 req 0x25 timeout\n"); 1325 return -EBUSY; 1326 } 1327 1328 if (nv_device(priv)->chipset >= 0xe0) { 1329 nv_wr32(priv, 0x409800, 0x00000000); 1330 nv_wr32(priv, 0x409500, 0x00000001); 1331 nv_wr32(priv, 0x409504, 0x00000030); 1332 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1333 nv_error(priv, "fuc09 req 0x30 timeout\n"); 1334 return -EBUSY; 1335 } 1336 1337 nv_wr32(priv, 0x409810, 0xb00095c8); 1338 nv_wr32(priv, 0x409800, 0x00000000); 1339 nv_wr32(priv, 0x409500, 0x00000001); 1340 nv_wr32(priv, 0x409504, 0x00000031); 1341 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1342 nv_error(priv, "fuc09 req 0x31 timeout\n"); 1343 return -EBUSY; 1344 } 1345 1346 nv_wr32(priv, 0x409810, 0x00080420); 1347 nv_wr32(priv, 0x409800, 0x00000000); 1348 nv_wr32(priv, 0x409500, 0x00000001); 1349 nv_wr32(priv, 0x409504, 0x00000032); 1350 if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { 1351 nv_error(priv, "fuc09 req 0x32 timeout\n"); 1352 return -EBUSY; 1353 } 1354 1355 nv_wr32(priv, 0x409614, 0x00000070); 1356 nv_wr32(priv, 0x409614, 0x00000770); 1357 nv_wr32(priv, 0x40802c, 0x00000001); 1358 } 1359 1360 if (priv->data == NULL) { 1361 int ret = gf100_grctx_generate(priv); 1362 if (ret) { 1363 nv_error(priv, "failed to construct context\n"); 1364 return ret; 1365 } 1366 } 1367 1368 return 0; 1369 } else 1370 if (!oclass->fecs.ucode) { 1371 return -ENOSYS; 1372 } 1373 1374 /* load HUB microcode */ 1375 nvkm_mc(priv)->unk260(nvkm_mc(priv), 0); 1376 nv_wr32(priv, 0x4091c0, 0x01000000); 1377 for (i = 0; i < oclass->fecs.ucode->data.size / 4; i++) 1378 nv_wr32(priv, 0x4091c4, oclass->fecs.ucode->data.data[i]); 1379 1380 nv_wr32(priv, 0x409180, 0x01000000); 1381 for (i = 0; i < oclass->fecs.ucode->code.size / 4; i++) { 1382 if ((i & 0x3f) == 0) 1383 nv_wr32(priv, 0x409188, i >> 6); 1384 nv_wr32(priv, 0x409184, oclass->fecs.ucode->code.data[i]); 1385 } 1386 1387 /* load GPC microcode */ 1388 nv_wr32(priv, 0x41a1c0, 0x01000000); 1389 for (i = 0; i < oclass->gpccs.ucode->data.size / 4; i++) 1390 nv_wr32(priv, 0x41a1c4, oclass->gpccs.ucode->data.data[i]); 1391 1392 nv_wr32(priv, 0x41a180, 0x01000000); 1393 for (i = 0; i < oclass->gpccs.ucode->code.size / 4; i++) { 1394 if ((i & 0x3f) == 0) 1395 nv_wr32(priv, 0x41a188, i >> 6); 1396 nv_wr32(priv, 0x41a184, oclass->gpccs.ucode->code.data[i]); 1397 } 1398 nvkm_mc(priv)->unk260(nvkm_mc(priv), 1); 1399 1400 /* load register lists */ 1401 gf100_gr_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000); 1402 gf100_gr_init_csdata(priv, cclass->gpc, 0x41a000, 0x000, 0x418000); 1403 gf100_gr_init_csdata(priv, cclass->tpc, 0x41a000, 0x004, 0x419800); 1404 gf100_gr_init_csdata(priv, cclass->ppc, 0x41a000, 0x008, 0x41be00); 1405 1406 /* start HUB ucode running, it'll init the GPCs */ 1407 nv_wr32(priv, 0x40910c, 0x00000000); 1408 nv_wr32(priv, 0x409100, 0x00000002); 1409 if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) { 1410 nv_error(priv, "HUB_INIT timed out\n"); 1411 gf100_gr_ctxctl_debug(priv); 1412 return -EBUSY; 1413 } 1414 1415 priv->size = nv_rd32(priv, 0x409804); 1416 if (priv->data == NULL) { 1417 int ret = gf100_grctx_generate(priv); 1418 if (ret) { 1419 nv_error(priv, "failed to construct context\n"); 1420 return ret; 1421 } 1422 } 1423 1424 return 0; 1425 } 1426 1427 int 1428 gf100_gr_init(struct nvkm_object *object) 1429 { 1430 struct gf100_gr_oclass *oclass = (void *)object->oclass; 1431 struct gf100_gr_priv *priv = (void *)object; 1432 const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); 1433 u32 data[TPC_MAX / 8] = {}; 1434 u8 tpcnr[GPC_MAX]; 1435 int gpc, tpc, rop; 1436 int ret, i; 1437 1438 ret = nvkm_gr_init(&priv->base); 1439 if (ret) 1440 return ret; 1441 1442 nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000); 1443 nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000); 1444 nv_wr32(priv, GPC_BCAST(0x0888), 0x00000000); 1445 nv_wr32(priv, GPC_BCAST(0x088c), 0x00000000); 1446 nv_wr32(priv, GPC_BCAST(0x0890), 0x00000000); 1447 nv_wr32(priv, GPC_BCAST(0x0894), 0x00000000); 1448 nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); 1449 nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); 1450 1451 gf100_gr_mmio(priv, oclass->mmio); 1452 1453 memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); 1454 for (i = 0, gpc = -1; i < priv->tpc_total; i++) { 1455 do { 1456 gpc = (gpc + 1) % priv->gpc_nr; 1457 } while (!tpcnr[gpc]); 1458 tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; 1459 1460 data[i / 8] |= tpc << ((i % 8) * 4); 1461 } 1462 1463 nv_wr32(priv, GPC_BCAST(0x0980), data[0]); 1464 nv_wr32(priv, GPC_BCAST(0x0984), data[1]); 1465 nv_wr32(priv, GPC_BCAST(0x0988), data[2]); 1466 nv_wr32(priv, GPC_BCAST(0x098c), data[3]); 1467 1468 for (gpc = 0; gpc < priv->gpc_nr; gpc++) { 1469 nv_wr32(priv, GPC_UNIT(gpc, 0x0914), 1470 priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]); 1471 nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | 1472 priv->tpc_total); 1473 nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); 1474 } 1475 1476 if (nv_device(priv)->chipset != 0xd7) 1477 nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918); 1478 else 1479 nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918); 1480 1481 nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); 1482 1483 nv_wr32(priv, 0x400500, 0x00010001); 1484 1485 nv_wr32(priv, 0x400100, 0xffffffff); 1486 nv_wr32(priv, 0x40013c, 0xffffffff); 1487 1488 nv_wr32(priv, 0x409c24, 0x000f0000); 1489 nv_wr32(priv, 0x404000, 0xc0000000); 1490 nv_wr32(priv, 0x404600, 0xc0000000); 1491 nv_wr32(priv, 0x408030, 0xc0000000); 1492 nv_wr32(priv, 0x40601c, 0xc0000000); 1493 nv_wr32(priv, 0x404490, 0xc0000000); 1494 nv_wr32(priv, 0x406018, 0xc0000000); 1495 nv_wr32(priv, 0x405840, 0xc0000000); 1496 nv_wr32(priv, 0x405844, 0x00ffffff); 1497 nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); 1498 nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000); 1499 1500 for (gpc = 0; gpc < priv->gpc_nr; gpc++) { 1501 nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); 1502 nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); 1503 nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); 1504 nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); 1505 for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { 1506 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); 1507 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); 1508 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); 1509 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); 1510 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); 1511 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); 1512 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); 1513 } 1514 nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff); 1515 nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff); 1516 } 1517 1518 for (rop = 0; rop < priv->rop_nr; rop++) { 1519 nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); 1520 nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); 1521 nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff); 1522 nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff); 1523 } 1524 1525 nv_wr32(priv, 0x400108, 0xffffffff); 1526 nv_wr32(priv, 0x400138, 0xffffffff); 1527 nv_wr32(priv, 0x400118, 0xffffffff); 1528 nv_wr32(priv, 0x400130, 0xffffffff); 1529 nv_wr32(priv, 0x40011c, 0xffffffff); 1530 nv_wr32(priv, 0x400134, 0xffffffff); 1531 1532 nv_wr32(priv, 0x400054, 0x34ce3464); 1533 1534 gf100_gr_zbc_init(priv); 1535 1536 return gf100_gr_init_ctxctl(priv); 1537 } 1538 1539 void 1540 gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc) 1541 { 1542 kfree(fuc->data); 1543 fuc->data = NULL; 1544 } 1545 1546 int 1547 gf100_gr_ctor_fw(struct gf100_gr_priv *priv, const char *fwname, 1548 struct gf100_gr_fuc *fuc) 1549 { 1550 struct nvkm_device *device = nv_device(priv); 1551 const struct firmware *fw; 1552 char f[64]; 1553 char cname[16]; 1554 int ret; 1555 int i; 1556 1557 /* Convert device name to lowercase */ 1558 strncpy(cname, device->cname, sizeof(cname)); 1559 cname[sizeof(cname) - 1] = '\0'; 1560 i = strlen(cname); 1561 while (i) { 1562 --i; 1563 cname[i] = tolower(cname[i]); 1564 } 1565 1566 snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname); 1567 ret = request_firmware(&fw, f, nv_device_base(device)); 1568 if (ret) { 1569 nv_error(priv, "failed to load %s\n", fwname); 1570 return ret; 1571 } 1572 1573 fuc->size = fw->size; 1574 fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); 1575 release_firmware(fw); 1576 return (fuc->data != NULL) ? 0 : -ENOMEM; 1577 } 1578 1579 void 1580 gf100_gr_dtor(struct nvkm_object *object) 1581 { 1582 struct gf100_gr_priv *priv = (void *)object; 1583 1584 kfree(priv->data); 1585 1586 gf100_gr_dtor_fw(&priv->fuc409c); 1587 gf100_gr_dtor_fw(&priv->fuc409d); 1588 gf100_gr_dtor_fw(&priv->fuc41ac); 1589 gf100_gr_dtor_fw(&priv->fuc41ad); 1590 1591 nvkm_gpuobj_ref(NULL, &priv->unk4188b8); 1592 nvkm_gpuobj_ref(NULL, &priv->unk4188b4); 1593 1594 nvkm_gr_destroy(&priv->base); 1595 } 1596 1597 int 1598 gf100_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 1599 struct nvkm_oclass *bclass, void *data, u32 size, 1600 struct nvkm_object **pobject) 1601 { 1602 struct gf100_gr_oclass *oclass = (void *)bclass; 1603 struct nvkm_device *device = nv_device(parent); 1604 struct gf100_gr_priv *priv; 1605 bool use_ext_fw, enable; 1606 int ret, i, j; 1607 1608 use_ext_fw = nvkm_boolopt(device->cfgopt, "NvGrUseFW", 1609 oclass->fecs.ucode == NULL); 1610 enable = use_ext_fw || oclass->fecs.ucode != NULL; 1611 1612 ret = nvkm_gr_create(parent, engine, bclass, enable, &priv); 1613 *pobject = nv_object(priv); 1614 if (ret) 1615 return ret; 1616 1617 nv_subdev(priv)->unit = 0x08001000; 1618 nv_subdev(priv)->intr = gf100_gr_intr; 1619 1620 priv->base.units = gf100_gr_units; 1621 1622 if (use_ext_fw) { 1623 nv_info(priv, "using external firmware\n"); 1624 if (gf100_gr_ctor_fw(priv, "fecs_inst", &priv->fuc409c) || 1625 gf100_gr_ctor_fw(priv, "fecs_data", &priv->fuc409d) || 1626 gf100_gr_ctor_fw(priv, "gpccs_inst", &priv->fuc41ac) || 1627 gf100_gr_ctor_fw(priv, "gpccs_data", &priv->fuc41ad)) 1628 return -ENODEV; 1629 priv->firmware = true; 1630 } 1631 1632 ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0, 1633 &priv->unk4188b4); 1634 if (ret) 1635 return ret; 1636 1637 ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0, 1638 &priv->unk4188b8); 1639 if (ret) 1640 return ret; 1641 1642 for (i = 0; i < 0x1000; i += 4) { 1643 nv_wo32(priv->unk4188b4, i, 0x00000010); 1644 nv_wo32(priv->unk4188b8, i, 0x00000010); 1645 } 1646 1647 priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16; 1648 priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f; 1649 for (i = 0; i < priv->gpc_nr; i++) { 1650 priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608)); 1651 priv->tpc_total += priv->tpc_nr[i]; 1652 priv->ppc_nr[i] = oclass->ppc_nr; 1653 for (j = 0; j < priv->ppc_nr[i]; j++) { 1654 u8 mask = nv_rd32(priv, GPC_UNIT(i, 0x0c30 + (j * 4))); 1655 priv->ppc_tpc_nr[i][j] = hweight8(mask); 1656 } 1657 } 1658 1659 /*XXX: these need figuring out... though it might not even matter */ 1660 switch (nv_device(priv)->chipset) { 1661 case 0xc0: 1662 if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */ 1663 priv->magic_not_rop_nr = 0x07; 1664 } else 1665 if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */ 1666 priv->magic_not_rop_nr = 0x05; 1667 } else 1668 if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */ 1669 priv->magic_not_rop_nr = 0x06; 1670 } 1671 break; 1672 case 0xc3: /* 450, 4/0/0/0, 2 */ 1673 priv->magic_not_rop_nr = 0x03; 1674 break; 1675 case 0xc4: /* 460, 3/4/0/0, 4 */ 1676 priv->magic_not_rop_nr = 0x01; 1677 break; 1678 case 0xc1: /* 2/0/0/0, 1 */ 1679 priv->magic_not_rop_nr = 0x01; 1680 break; 1681 case 0xc8: /* 4/4/3/4, 5 */ 1682 priv->magic_not_rop_nr = 0x06; 1683 break; 1684 case 0xce: /* 4/4/0/0, 4 */ 1685 priv->magic_not_rop_nr = 0x03; 1686 break; 1687 case 0xcf: /* 4/0/0/0, 3 */ 1688 priv->magic_not_rop_nr = 0x03; 1689 break; 1690 case 0xd7: 1691 case 0xd9: /* 1/0/0/0, 1 */ 1692 case 0xea: /* gk20a */ 1693 case 0x12b: /* gm20b */ 1694 priv->magic_not_rop_nr = 0x01; 1695 break; 1696 } 1697 1698 nv_engine(priv)->cclass = *oclass->cclass; 1699 nv_engine(priv)->sclass = oclass->sclass; 1700 return 0; 1701 } 1702 1703 #include "fuc/hubgf100.fuc3.h" 1704 1705 struct gf100_gr_ucode 1706 gf100_gr_fecs_ucode = { 1707 .code.data = gf100_grhub_code, 1708 .code.size = sizeof(gf100_grhub_code), 1709 .data.data = gf100_grhub_data, 1710 .data.size = sizeof(gf100_grhub_data), 1711 }; 1712 1713 #include "fuc/gpcgf100.fuc3.h" 1714 1715 struct gf100_gr_ucode 1716 gf100_gr_gpccs_ucode = { 1717 .code.data = gf100_grgpc_code, 1718 .code.size = sizeof(gf100_grgpc_code), 1719 .data.data = gf100_grgpc_data, 1720 .data.size = sizeof(gf100_grgpc_data), 1721 }; 1722 1723 struct nvkm_oclass * 1724 gf100_gr_oclass = &(struct gf100_gr_oclass) { 1725 .base.handle = NV_ENGINE(GR, 0xc0), 1726 .base.ofuncs = &(struct nvkm_ofuncs) { 1727 .ctor = gf100_gr_ctor, 1728 .dtor = gf100_gr_dtor, 1729 .init = gf100_gr_init, 1730 .fini = _nvkm_gr_fini, 1731 }, 1732 .cclass = &gf100_grctx_oclass, 1733 .sclass = gf100_gr_sclass, 1734 .mmio = gf100_gr_pack_mmio, 1735 .fecs.ucode = &gf100_gr_fecs_ucode, 1736 .gpccs.ucode = &gf100_gr_gpccs_ucode, 1737 }.base; 1738