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 "nv50.h" 25 #include "head.h" 26 #include "ior.h" 27 #include "rootnv50.h" 28 29 #include <core/client.h> 30 #include <core/enum.h> 31 #include <core/gpuobj.h> 32 #include <subdev/bios.h> 33 #include <subdev/bios/disp.h> 34 #include <subdev/bios/init.h> 35 #include <subdev/bios/pll.h> 36 #include <subdev/devinit.h> 37 #include <subdev/timer.h> 38 39 static const struct nvkm_disp_oclass * 40 nv50_disp_root_(struct nvkm_disp *base) 41 { 42 return nv50_disp(base)->func->root; 43 } 44 45 static void 46 nv50_disp_intr_(struct nvkm_disp *base) 47 { 48 struct nv50_disp *disp = nv50_disp(base); 49 disp->func->intr(disp); 50 } 51 52 static void * 53 nv50_disp_dtor_(struct nvkm_disp *base) 54 { 55 struct nv50_disp *disp = nv50_disp(base); 56 nvkm_event_fini(&disp->uevent); 57 if (disp->wq) 58 destroy_workqueue(disp->wq); 59 return disp; 60 } 61 62 static const struct nvkm_disp_func 63 nv50_disp_ = { 64 .dtor = nv50_disp_dtor_, 65 .intr = nv50_disp_intr_, 66 .root = nv50_disp_root_, 67 }; 68 69 int 70 nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, 71 int index, int heads, struct nvkm_disp **pdisp) 72 { 73 struct nv50_disp *disp; 74 int ret, i; 75 76 if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL))) 77 return -ENOMEM; 78 disp->func = func; 79 *pdisp = &disp->base; 80 81 ret = nvkm_disp_ctor(&nv50_disp_, device, index, &disp->base); 82 if (ret) 83 return ret; 84 85 disp->wq = create_singlethread_workqueue("nvkm-disp"); 86 if (!disp->wq) 87 return -ENOMEM; 88 INIT_WORK(&disp->supervisor, func->super); 89 90 for (i = 0; func->head.new && i < heads; i++) { 91 ret = func->head.new(&disp->base, i); 92 if (ret) 93 return ret; 94 } 95 96 for (i = 0; func->dac.new && i < func->dac.nr; i++) { 97 ret = func->dac.new(&disp->base, i); 98 if (ret) 99 return ret; 100 } 101 102 for (i = 0; func->pior.new && i < func->pior.nr; i++) { 103 ret = func->pior.new(&disp->base, i); 104 if (ret) 105 return ret; 106 } 107 108 for (i = 0; func->sor.new && i < func->sor.nr; i++) { 109 ret = func->sor.new(&disp->base, i); 110 if (ret) 111 return ret; 112 } 113 114 return nvkm_event_init(func->uevent, 1, 1 + (heads * 4), &disp->uevent); 115 } 116 117 static u32 118 nv50_disp_super_iedt(struct nvkm_head *head, struct nvkm_outp *outp, 119 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, 120 struct nvbios_outp *iedt) 121 { 122 struct nvkm_bios *bios = head->disp->engine.subdev.device->bios; 123 const u8 l = ffs(outp->info.link); 124 const u16 t = outp->info.hasht; 125 const u16 m = (0x0100 << head->id) | (l << 6) | outp->info.or; 126 u32 data = nvbios_outp_match(bios, t, m, ver, hdr, cnt, len, iedt); 127 if (!data) 128 OUTP_DBG(outp, "missing IEDT for %04x:%04x", t, m); 129 return data; 130 } 131 132 static void 133 nv50_disp_super_ied_on(struct nvkm_head *head, 134 struct nvkm_ior *ior, int id, u32 khz) 135 { 136 struct nvkm_subdev *subdev = &head->disp->engine.subdev; 137 struct nvkm_bios *bios = subdev->device->bios; 138 struct nvkm_outp *outp = ior->asy.outp; 139 struct nvbios_ocfg iedtrs; 140 struct nvbios_outp iedt; 141 u8 ver, hdr, cnt, len, flags = 0x00; 142 u32 data; 143 144 if (!outp) { 145 IOR_DBG(ior, "nothing to attach"); 146 return; 147 } 148 149 /* Lookup IED table for the device. */ 150 data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt); 151 if (!data) 152 return; 153 154 /* Lookup IEDT runtime settings for the current configuration. */ 155 if (ior->type == SOR) { 156 if (ior->asy.proto == LVDS) { 157 if (head->asy.or.depth == 24) 158 flags |= 0x02; 159 } 160 if (ior->asy.link == 3) 161 flags |= 0x01; 162 } 163 164 data = nvbios_ocfg_match(bios, data, ior->asy.proto_evo, flags, 165 &ver, &hdr, &cnt, &len, &iedtrs); 166 if (!data) { 167 OUTP_DBG(outp, "missing IEDT RS for %02x:%02x", 168 ior->asy.proto_evo, flags); 169 return; 170 } 171 172 /* Execute the OnInt[23] script for the current frequency. */ 173 data = nvbios_oclk_match(bios, iedtrs.clkcmp[id], khz); 174 if (!data) { 175 OUTP_DBG(outp, "missing IEDT RSS %d for %02x:%02x %d khz", 176 id, ior->asy.proto_evo, flags, khz); 177 return; 178 } 179 180 nvbios_init(subdev, data, 181 init.outp = &outp->info; 182 init.or = ior->id; 183 init.link = ior->asy.link; 184 init.head = head->id; 185 ); 186 } 187 188 static void 189 nv50_disp_super_ied_off(struct nvkm_head *head, struct nvkm_ior *ior, int id) 190 { 191 struct nvkm_outp *outp = ior->arm.outp; 192 struct nvbios_outp iedt; 193 u8 ver, hdr, cnt, len; 194 u32 data; 195 196 if (!outp) { 197 IOR_DBG(ior, "nothing attached"); 198 return; 199 } 200 201 data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt); 202 if (!data) 203 return; 204 205 nvbios_init(&head->disp->engine.subdev, iedt.script[id], 206 init.outp = &outp->info; 207 init.or = ior->id; 208 init.link = ior->arm.link; 209 init.head = head->id; 210 ); 211 } 212 213 static struct nvkm_ior * 214 nv50_disp_super_ior_asy(struct nvkm_head *head) 215 { 216 struct nvkm_ior *ior; 217 list_for_each_entry(ior, &head->disp->ior, head) { 218 if (ior->asy.head & (1 << head->id)) { 219 HEAD_DBG(head, "to %s", ior->name); 220 return ior; 221 } 222 } 223 HEAD_DBG(head, "nothing to attach"); 224 return NULL; 225 } 226 227 static struct nvkm_ior * 228 nv50_disp_super_ior_arm(struct nvkm_head *head) 229 { 230 struct nvkm_ior *ior; 231 list_for_each_entry(ior, &head->disp->ior, head) { 232 if (ior->arm.head & (1 << head->id)) { 233 HEAD_DBG(head, "on %s", ior->name); 234 return ior; 235 } 236 } 237 HEAD_DBG(head, "nothing attached"); 238 return NULL; 239 } 240 241 void 242 nv50_disp_super_3_0(struct nv50_disp *disp, struct nvkm_head *head) 243 { 244 struct nvkm_ior *ior; 245 246 /* Determine which OR, if any, we're attaching to the head. */ 247 HEAD_DBG(head, "supervisor 3.0"); 248 ior = nv50_disp_super_ior_asy(head); 249 if (!ior) 250 return; 251 252 /* Execute OnInt3 IED script. */ 253 nv50_disp_super_ied_on(head, ior, 1, head->asy.hz / 1000); 254 255 /* OR-specific handling. */ 256 if (ior->func->war_3) 257 ior->func->war_3(ior); 258 } 259 260 static void 261 nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior) 262 { 263 struct nvkm_subdev *subdev = &head->disp->engine.subdev; 264 const u32 khz = head->asy.hz / 1000; 265 const u32 linkKBps = ior->dp.bw * 27000; 266 const u32 symbol = 100000; 267 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0; 268 int TU, VTUi, VTUf, VTUa; 269 u64 link_data_rate, link_ratio, unk; 270 u32 best_diff = 64 * symbol; 271 u64 h, v; 272 273 /* symbols/hblank - algorithm taken from comments in tegra driver */ 274 h = head->asy.hblanke + head->asy.htotal - head->asy.hblanks - 7; 275 h = h * linkKBps; 276 do_div(h, khz); 277 h = h - (3 * ior->dp.ef) - (12 / ior->dp.nr); 278 279 /* symbols/vblank - algorithm taken from comments in tegra driver */ 280 v = head->asy.vblanks - head->asy.vblanke - 25; 281 v = v * linkKBps; 282 do_div(v, khz); 283 v = v - ((36 / ior->dp.nr) + 3) - 1; 284 285 ior->func->dp.audio_sym(ior, head->id, h, v); 286 287 /* watermark / activesym */ 288 link_data_rate = (khz * head->asy.or.depth / 8) / ior->dp.nr; 289 290 /* calculate ratio of packed data rate to link symbol rate */ 291 link_ratio = link_data_rate * symbol; 292 do_div(link_ratio, linkKBps); 293 294 for (TU = 64; ior->func->dp.activesym && TU >= 32; TU--) { 295 /* calculate average number of valid symbols in each TU */ 296 u32 tu_valid = link_ratio * TU; 297 u32 calc, diff; 298 299 /* find a hw representation for the fraction.. */ 300 VTUi = tu_valid / symbol; 301 calc = VTUi * symbol; 302 diff = tu_valid - calc; 303 if (diff) { 304 if (diff >= (symbol / 2)) { 305 VTUf = symbol / (symbol - diff); 306 if (symbol - (VTUf * diff)) 307 VTUf++; 308 309 if (VTUf <= 15) { 310 VTUa = 1; 311 calc += symbol - (symbol / VTUf); 312 } else { 313 VTUa = 0; 314 VTUf = 1; 315 calc += symbol; 316 } 317 } else { 318 VTUa = 0; 319 VTUf = min((int)(symbol / diff), 15); 320 calc += symbol / VTUf; 321 } 322 323 diff = calc - tu_valid; 324 } else { 325 /* no remainder, but the hw doesn't like the fractional 326 * part to be zero. decrement the integer part and 327 * have the fraction add a whole symbol back 328 */ 329 VTUa = 0; 330 VTUf = 1; 331 VTUi--; 332 } 333 334 if (diff < best_diff) { 335 best_diff = diff; 336 bestTU = TU; 337 bestVTUa = VTUa; 338 bestVTUf = VTUf; 339 bestVTUi = VTUi; 340 if (diff == 0) 341 break; 342 } 343 } 344 345 if (ior->func->dp.activesym) { 346 if (!bestTU) { 347 nvkm_error(subdev, "unable to determine dp config\n"); 348 return; 349 } 350 ior->func->dp.activesym(ior, head->id, bestTU, 351 bestVTUa, bestVTUf, bestVTUi); 352 } else { 353 bestTU = 64; 354 } 355 356 /* XXX close to vbios numbers, but not right */ 357 unk = (symbol - link_ratio) * bestTU; 358 unk *= link_ratio; 359 do_div(unk, symbol); 360 do_div(unk, symbol); 361 unk += 6; 362 363 ior->func->dp.watermark(ior, head->id, unk); 364 } 365 366 void 367 nv50_disp_super_2_2(struct nv50_disp *disp, struct nvkm_head *head) 368 { 369 const u32 khz = head->asy.hz / 1000; 370 struct nvkm_outp *outp; 371 struct nvkm_ior *ior; 372 373 /* Determine which OR, if any, we're attaching from the head. */ 374 HEAD_DBG(head, "supervisor 2.2"); 375 ior = nv50_disp_super_ior_asy(head); 376 if (!ior) 377 return; 378 379 /* For some reason, NVIDIA decided not to: 380 * 381 * A) Give dual-link LVDS a separate EVO protocol, like for TMDS. 382 * and 383 * B) Use SetControlOutputResource.PixelDepth on LVDS. 384 * 385 * Override the values we usually read from HW with the same 386 * data we pass though an ioctl instead. 387 */ 388 if (ior->type == SOR && ior->asy.proto == LVDS) { 389 head->asy.or.depth = (disp->sor.lvdsconf & 0x0200) ? 24 : 18; 390 ior->asy.link = (disp->sor.lvdsconf & 0x0100) ? 3 : 1; 391 } 392 393 /* Handle any link training, etc. */ 394 if ((outp = ior->asy.outp) && outp->func->acquire) 395 outp->func->acquire(outp); 396 397 /* Execute OnInt2 IED script. */ 398 nv50_disp_super_ied_on(head, ior, 0, khz); 399 400 /* Program RG clock divider. */ 401 head->func->rgclk(head, ior->asy.rgdiv); 402 403 /* Mode-specific internal DP configuration. */ 404 if (ior->type == SOR && ior->asy.proto == DP) 405 nv50_disp_super_2_2_dp(head, ior); 406 407 /* OR-specific handling. */ 408 ior->func->clock(ior); 409 if (ior->func->war_2) 410 ior->func->war_2(ior); 411 } 412 413 void 414 nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head) 415 { 416 struct nvkm_devinit *devinit = disp->base.engine.subdev.device->devinit; 417 const u32 khz = head->asy.hz / 1000; 418 HEAD_DBG(head, "supervisor 2.1 - %d khz", khz); 419 if (khz) 420 nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head->id, khz); 421 } 422 423 void 424 nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head) 425 { 426 struct nvkm_outp *outp; 427 struct nvkm_ior *ior; 428 429 /* Determine which OR, if any, we're detaching from the head. */ 430 HEAD_DBG(head, "supervisor 2.0"); 431 ior = nv50_disp_super_ior_arm(head); 432 if (!ior) 433 return; 434 435 /* Execute OffInt2 IED script. */ 436 nv50_disp_super_ied_off(head, ior, 2); 437 438 /* If we're shutting down the OR's only active head, execute 439 * the output path's release function. 440 */ 441 if (ior->arm.head == (1 << head->id)) { 442 if ((outp = ior->arm.outp) && outp->func->release) 443 outp->func->release(outp, ior); 444 } 445 } 446 447 void 448 nv50_disp_super_1_0(struct nv50_disp *disp, struct nvkm_head *head) 449 { 450 struct nvkm_ior *ior; 451 452 /* Determine which OR, if any, we're detaching from the head. */ 453 HEAD_DBG(head, "supervisor 1.0"); 454 ior = nv50_disp_super_ior_arm(head); 455 if (!ior) 456 return; 457 458 /* Execute OffInt1 IED script. */ 459 nv50_disp_super_ied_off(head, ior, 1); 460 } 461 462 void 463 nv50_disp_super_1(struct nv50_disp *disp) 464 { 465 struct nvkm_head *head; 466 struct nvkm_ior *ior; 467 468 list_for_each_entry(head, &disp->base.head, head) { 469 head->func->state(head, &head->arm); 470 head->func->state(head, &head->asy); 471 } 472 473 list_for_each_entry(ior, &disp->base.ior, head) { 474 ior->func->state(ior, &ior->arm); 475 ior->func->state(ior, &ior->asy); 476 } 477 } 478 479 void 480 nv50_disp_super(struct work_struct *work) 481 { 482 struct nv50_disp *disp = 483 container_of(work, struct nv50_disp, supervisor); 484 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 485 struct nvkm_device *device = subdev->device; 486 struct nvkm_head *head; 487 u32 super = nvkm_rd32(device, 0x610030); 488 489 nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super); 490 491 if (disp->super & 0x00000010) { 492 nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG); 493 nv50_disp_super_1(disp); 494 list_for_each_entry(head, &disp->base.head, head) { 495 if (!(super & (0x00000020 << head->id))) 496 continue; 497 if (!(super & (0x00000080 << head->id))) 498 continue; 499 nv50_disp_super_1_0(disp, head); 500 } 501 } else 502 if (disp->super & 0x00000020) { 503 list_for_each_entry(head, &disp->base.head, head) { 504 if (!(super & (0x00000080 << head->id))) 505 continue; 506 nv50_disp_super_2_0(disp, head); 507 } 508 nvkm_outp_route(&disp->base); 509 list_for_each_entry(head, &disp->base.head, head) { 510 if (!(super & (0x00000200 << head->id))) 511 continue; 512 nv50_disp_super_2_1(disp, head); 513 } 514 list_for_each_entry(head, &disp->base.head, head) { 515 if (!(super & (0x00000080 << head->id))) 516 continue; 517 nv50_disp_super_2_2(disp, head); 518 } 519 } else 520 if (disp->super & 0x00000040) { 521 list_for_each_entry(head, &disp->base.head, head) { 522 if (!(super & (0x00000080 << head->id))) 523 continue; 524 nv50_disp_super_3_0(disp, head); 525 } 526 } 527 528 nvkm_wr32(device, 0x610030, 0x80000000); 529 } 530 531 static const struct nvkm_enum 532 nv50_disp_intr_error_type[] = { 533 { 3, "ILLEGAL_MTHD" }, 534 { 4, "INVALID_VALUE" }, 535 { 5, "INVALID_STATE" }, 536 { 7, "INVALID_HANDLE" }, 537 {} 538 }; 539 540 static const struct nvkm_enum 541 nv50_disp_intr_error_code[] = { 542 { 0x00, "" }, 543 {} 544 }; 545 546 static void 547 nv50_disp_intr_error(struct nv50_disp *disp, int chid) 548 { 549 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 550 struct nvkm_device *device = subdev->device; 551 u32 data = nvkm_rd32(device, 0x610084 + (chid * 0x08)); 552 u32 addr = nvkm_rd32(device, 0x610080 + (chid * 0x08)); 553 u32 code = (addr & 0x00ff0000) >> 16; 554 u32 type = (addr & 0x00007000) >> 12; 555 u32 mthd = (addr & 0x00000ffc); 556 const struct nvkm_enum *ec, *et; 557 558 et = nvkm_enum_find(nv50_disp_intr_error_type, type); 559 ec = nvkm_enum_find(nv50_disp_intr_error_code, code); 560 561 nvkm_error(subdev, 562 "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n", 563 type, et ? et->name : "", code, ec ? ec->name : "", 564 chid, mthd, data); 565 566 if (chid < ARRAY_SIZE(disp->chan)) { 567 switch (mthd) { 568 case 0x0080: 569 nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR); 570 break; 571 default: 572 break; 573 } 574 } 575 576 nvkm_wr32(device, 0x610020, 0x00010000 << chid); 577 nvkm_wr32(device, 0x610080 + (chid * 0x08), 0x90000000); 578 } 579 580 void 581 nv50_disp_intr(struct nv50_disp *disp) 582 { 583 struct nvkm_device *device = disp->base.engine.subdev.device; 584 u32 intr0 = nvkm_rd32(device, 0x610020); 585 u32 intr1 = nvkm_rd32(device, 0x610024); 586 587 while (intr0 & 0x001f0000) { 588 u32 chid = __ffs(intr0 & 0x001f0000) - 16; 589 nv50_disp_intr_error(disp, chid); 590 intr0 &= ~(0x00010000 << chid); 591 } 592 593 while (intr0 & 0x0000001f) { 594 u32 chid = __ffs(intr0 & 0x0000001f); 595 nv50_disp_chan_uevent_send(disp, chid); 596 intr0 &= ~(0x00000001 << chid); 597 } 598 599 if (intr1 & 0x00000004) { 600 nvkm_disp_vblank(&disp->base, 0); 601 nvkm_wr32(device, 0x610024, 0x00000004); 602 } 603 604 if (intr1 & 0x00000008) { 605 nvkm_disp_vblank(&disp->base, 1); 606 nvkm_wr32(device, 0x610024, 0x00000008); 607 } 608 609 if (intr1 & 0x00000070) { 610 disp->super = (intr1 & 0x00000070); 611 queue_work(disp->wq, &disp->supervisor); 612 nvkm_wr32(device, 0x610024, disp->super); 613 } 614 } 615 616 static const struct nv50_disp_func 617 nv50_disp = { 618 .intr = nv50_disp_intr, 619 .uevent = &nv50_disp_chan_uevent, 620 .super = nv50_disp_super, 621 .root = &nv50_disp_root_oclass, 622 .head.new = nv50_head_new, 623 .dac = { .nr = 3, .new = nv50_dac_new }, 624 .sor = { .nr = 2, .new = nv50_sor_new }, 625 .pior = { .nr = 3, .new = nv50_pior_new }, 626 }; 627 628 int 629 nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) 630 { 631 return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp); 632 } 633