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