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