nouveau_nvkm_engine_disp_nv50.c revision 1.3
1/* $NetBSD: nouveau_nvkm_engine_disp_nv50.c,v 1.3 2020/02/14 14:34:59 maya Exp $ */ 2 3/* 4 * Copyright 2012 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs 25 */ 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_disp_nv50.c,v 1.3 2020/02/14 14:34:59 maya Exp $"); 28 29#include "nv50.h" 30#include "rootnv50.h" 31 32#include <core/client.h> 33#include <core/enum.h> 34#include <core/gpuobj.h> 35#include <subdev/bios.h> 36#include <subdev/bios/disp.h> 37#include <subdev/bios/init.h> 38#include <subdev/bios/pll.h> 39#include <subdev/devinit.h> 40 41static const struct nvkm_disp_oclass * 42nv50_disp_root_(struct nvkm_disp *base) 43{ 44 return nv50_disp(base)->func->root; 45} 46 47static int 48nv50_disp_outp_internal_crt_(struct nvkm_disp *base, int index, 49 struct dcb_output *dcb, struct nvkm_output **poutp) 50{ 51 struct nv50_disp *disp = nv50_disp(base); 52 return disp->func->outp.internal.crt(base, index, dcb, poutp); 53} 54 55static int 56nv50_disp_outp_internal_tmds_(struct nvkm_disp *base, int index, 57 struct dcb_output *dcb, 58 struct nvkm_output **poutp) 59{ 60 struct nv50_disp *disp = nv50_disp(base); 61 return disp->func->outp.internal.tmds(base, index, dcb, poutp); 62} 63 64static int 65nv50_disp_outp_internal_lvds_(struct nvkm_disp *base, int index, 66 struct dcb_output *dcb, 67 struct nvkm_output **poutp) 68{ 69 struct nv50_disp *disp = nv50_disp(base); 70 return disp->func->outp.internal.lvds(base, index, dcb, poutp); 71} 72 73static int 74nv50_disp_outp_internal_dp_(struct nvkm_disp *base, int index, 75 struct dcb_output *dcb, struct nvkm_output **poutp) 76{ 77 struct nv50_disp *disp = nv50_disp(base); 78 if (disp->func->outp.internal.dp) 79 return disp->func->outp.internal.dp(base, index, dcb, poutp); 80 return -ENODEV; 81} 82 83static int 84nv50_disp_outp_external_tmds_(struct nvkm_disp *base, int index, 85 struct dcb_output *dcb, 86 struct nvkm_output **poutp) 87{ 88 struct nv50_disp *disp = nv50_disp(base); 89 if (disp->func->outp.external.tmds) 90 return disp->func->outp.external.tmds(base, index, dcb, poutp); 91 return -ENODEV; 92} 93 94static int 95nv50_disp_outp_external_dp_(struct nvkm_disp *base, int index, 96 struct dcb_output *dcb, struct nvkm_output **poutp) 97{ 98 struct nv50_disp *disp = nv50_disp(base); 99 if (disp->func->outp.external.dp) 100 return disp->func->outp.external.dp(base, index, dcb, poutp); 101 return -ENODEV; 102} 103 104static void 105nv50_disp_vblank_fini_(struct nvkm_disp *base, int head) 106{ 107 struct nv50_disp *disp = nv50_disp(base); 108 disp->func->head.vblank_fini(disp, head); 109} 110 111static void 112nv50_disp_vblank_init_(struct nvkm_disp *base, int head) 113{ 114 struct nv50_disp *disp = nv50_disp(base); 115 disp->func->head.vblank_init(disp, head); 116} 117 118static void 119nv50_disp_intr_(struct nvkm_disp *base) 120{ 121 struct nv50_disp *disp = nv50_disp(base); 122 disp->func->intr(disp); 123} 124 125static void * 126nv50_disp_dtor_(struct nvkm_disp *base) 127{ 128 struct nv50_disp *disp = nv50_disp(base); 129 nvkm_event_fini(&disp->uevent); 130 return disp; 131} 132 133static const struct nvkm_disp_func 134nv50_disp_ = { 135 .dtor = nv50_disp_dtor_, 136 .intr = nv50_disp_intr_, 137 .root = nv50_disp_root_, 138 .outp.internal.crt = nv50_disp_outp_internal_crt_, 139 .outp.internal.tmds = nv50_disp_outp_internal_tmds_, 140 .outp.internal.lvds = nv50_disp_outp_internal_lvds_, 141 .outp.internal.dp = nv50_disp_outp_internal_dp_, 142 .outp.external.tmds = nv50_disp_outp_external_tmds_, 143 .outp.external.dp = nv50_disp_outp_external_dp_, 144 .head.vblank_init = nv50_disp_vblank_init_, 145 .head.vblank_fini = nv50_disp_vblank_fini_, 146}; 147 148int 149nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, 150 int index, int heads, struct nvkm_disp **pdisp) 151{ 152 struct nv50_disp *disp; 153 int ret; 154 155 if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL))) 156 return -ENOMEM; 157 INIT_WORK(&disp->supervisor, func->super); 158 disp->func = func; 159 *pdisp = &disp->base; 160 161 ret = nvkm_disp_ctor(&nv50_disp_, device, index, heads, &disp->base); 162 if (ret) 163 return ret; 164 165 return nvkm_event_init(func->uevent, 1, 1 + (heads * 4), &disp->uevent); 166} 167 168void 169nv50_disp_vblank_fini(struct nv50_disp *disp, int head) 170{ 171 struct nvkm_device *device = disp->base.engine.subdev.device; 172 nvkm_mask(device, 0x61002c, (4 << head), 0); 173} 174 175void 176nv50_disp_vblank_init(struct nv50_disp *disp, int head) 177{ 178 struct nvkm_device *device = disp->base.engine.subdev.device; 179 nvkm_mask(device, 0x61002c, (4 << head), (4 << head)); 180} 181 182static const struct nvkm_enum 183nv50_disp_intr_error_type[] = { 184 { 3, "ILLEGAL_MTHD" }, 185 { 4, "INVALID_VALUE" }, 186 { 5, "INVALID_STATE" }, 187 { 7, "INVALID_HANDLE" }, 188 {} 189}; 190 191static const struct nvkm_enum 192nv50_disp_intr_error_code[] = { 193 { 0x00, "" }, 194 {} 195}; 196 197static void 198nv50_disp_intr_error(struct nv50_disp *disp, int chid) 199{ 200 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 201 struct nvkm_device *device = subdev->device; 202 u32 data = nvkm_rd32(device, 0x610084 + (chid * 0x08)); 203 u32 addr = nvkm_rd32(device, 0x610080 + (chid * 0x08)); 204 u32 code = (addr & 0x00ff0000) >> 16; 205 u32 type = (addr & 0x00007000) >> 12; 206 u32 mthd = (addr & 0x00000ffc); 207 const struct nvkm_enum *ec, *et; 208 209 et = nvkm_enum_find(nv50_disp_intr_error_type, type); 210 ec = nvkm_enum_find(nv50_disp_intr_error_code, code); 211 212 nvkm_error(subdev, 213 "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n", 214 type, et ? et->name : "", code, ec ? ec->name : "", 215 chid, mthd, data); 216 217 if (chid < ARRAY_SIZE(disp->chan)) { 218 switch (mthd) { 219 case 0x0080: 220 nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR); 221 break; 222 default: 223 break; 224 } 225 } 226 227 nvkm_wr32(device, 0x610020, 0x00010000 << chid); 228 nvkm_wr32(device, 0x610080 + (chid * 0x08), 0x90000000); 229} 230 231static struct nvkm_output * 232exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl, 233 u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, 234 struct nvbios_outp *info) 235{ 236 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 237 struct nvkm_bios *bios = subdev->device->bios; 238 struct nvkm_output *outp; 239 u16 mask, type; 240 241 if (or < 4) { 242 type = DCB_OUTPUT_ANALOG; 243 mask = 0; 244 } else 245 if (or < 8) { 246 switch (ctrl & 0x00000f00) { 247 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; 248 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; 249 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break; 250 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break; 251 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break; 252 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; 253 default: 254 nvkm_error(subdev, "unknown SOR mc %08x\n", ctrl); 255 return NULL; 256 } 257 or -= 4; 258 } else { 259 or = or - 8; 260 type = 0x0010; 261 mask = 0; 262 switch (ctrl & 0x00000f00) { 263 case 0x00000000: type |= disp->pior.type[or]; break; 264 default: 265 nvkm_error(subdev, "unknown PIOR mc %08x\n", ctrl); 266 return NULL; 267 } 268 } 269 270 mask = 0x00c0 & (mask << 6); 271 mask |= 0x0001 << or; 272 mask |= 0x0100 << head; 273 274 list_for_each_entry(outp, &disp->base.outp, head) { 275 if ((outp->info.hasht & 0xff) == type && 276 (outp->info.hashm & mask) == mask) { 277 *data = nvbios_outp_match(bios, outp->info.hasht, 278 outp->info.hashm, 279 ver, hdr, cnt, len, info); 280 if (!*data) 281 return NULL; 282 return outp; 283 } 284 } 285 286 return NULL; 287} 288 289static struct nvkm_output * 290exec_script(struct nv50_disp *disp, int head, int id) 291{ 292 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 293 struct nvkm_device *device = subdev->device; 294 struct nvkm_bios *bios = device->bios; 295 struct nvkm_output *outp; 296 struct nvbios_outp info; 297 u8 ver, hdr, cnt, len; 298 u32 data, ctrl = 0; 299 u32 reg; 300 int i; 301 302 /* DAC */ 303 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->dac.nr; i++) 304 ctrl = nvkm_rd32(device, 0x610b5c + (i * 8)); 305 306 /* SOR */ 307 if (!(ctrl & (1 << head))) { 308 if (device->chipset < 0x90 || 309 device->chipset == 0x92 || 310 device->chipset == 0xa0) { 311 reg = 0x610b74; 312 } else { 313 reg = 0x610798; 314 } 315 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->sor.nr; i++) 316 ctrl = nvkm_rd32(device, reg + (i * 8)); 317 i += 4; 318 } 319 320 /* PIOR */ 321 if (!(ctrl & (1 << head))) { 322 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->pior.nr; i++) 323 ctrl = nvkm_rd32(device, 0x610b84 + (i * 8)); 324 i += 8; 325 } 326 327 if (!(ctrl & (1 << head))) 328 return NULL; 329 i--; 330 331 outp = exec_lookup(disp, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info); 332 if (outp) { 333 struct nvbios_init init = { 334 .subdev = subdev, 335 .bios = bios, 336 .offset = info.script[id], 337 .outp = &outp->info, 338 .crtc = head, 339 .execute = 1, 340 }; 341 342 nvbios_exec(&init); 343 } 344 345 return outp; 346} 347 348static struct nvkm_output * 349exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) 350{ 351 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 352 struct nvkm_device *device = subdev->device; 353 struct nvkm_bios *bios = device->bios; 354 struct nvkm_output *outp; 355 struct nvbios_outp info1; 356 struct nvbios_ocfg info2; 357 u8 ver, hdr, cnt, len; 358 u32 data, ctrl = 0; 359 u32 reg; 360 int i; 361 362 /* DAC */ 363 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->dac.nr; i++) 364 ctrl = nvkm_rd32(device, 0x610b58 + (i * 8)); 365 366 /* SOR */ 367 if (!(ctrl & (1 << head))) { 368 if (device->chipset < 0x90 || 369 device->chipset == 0x92 || 370 device->chipset == 0xa0) { 371 reg = 0x610b70; 372 } else { 373 reg = 0x610794; 374 } 375 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->sor.nr; i++) 376 ctrl = nvkm_rd32(device, reg + (i * 8)); 377 i += 4; 378 } 379 380 /* PIOR */ 381 if (!(ctrl & (1 << head))) { 382 for (i = 0; !(ctrl & (1 << head)) && i < disp->func->pior.nr; i++) 383 ctrl = nvkm_rd32(device, 0x610b80 + (i * 8)); 384 i += 8; 385 } 386 387 if (!(ctrl & (1 << head))) 388 return NULL; 389 i--; 390 391 outp = exec_lookup(disp, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1); 392 if (!outp) 393 return NULL; 394 395 if (outp->info.location == 0) { 396 switch (outp->info.type) { 397 case DCB_OUTPUT_TMDS: 398 *conf = (ctrl & 0x00000f00) >> 8; 399 if (pclk >= 165000) 400 *conf |= 0x0100; 401 break; 402 case DCB_OUTPUT_LVDS: 403 *conf = disp->sor.lvdsconf; 404 break; 405 case DCB_OUTPUT_DP: 406 *conf = (ctrl & 0x00000f00) >> 8; 407 break; 408 case DCB_OUTPUT_ANALOG: 409 default: 410 *conf = 0x00ff; 411 break; 412 } 413 } else { 414 *conf = (ctrl & 0x00000f00) >> 8; 415 pclk = pclk / 2; 416 } 417 418 data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); 419 if (data && id < 0xff) { 420 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); 421 if (data) { 422 struct nvbios_init init = { 423 .subdev = subdev, 424 .bios = bios, 425 .offset = data, 426 .outp = &outp->info, 427 .crtc = head, 428 .execute = 1, 429 }; 430 431 nvbios_exec(&init); 432 } 433 } 434 435 return outp; 436} 437 438static void 439nv50_disp_intr_unk10_0(struct nv50_disp *disp, int head) 440{ 441 exec_script(disp, head, 1); 442} 443 444static void 445nv50_disp_intr_unk20_0(struct nv50_disp *disp, int head) 446{ 447 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 448 struct nvkm_output *outp = exec_script(disp, head, 2); 449 450 /* the binary driver does this outside of the supervisor handling 451 * (after the third supervisor from a detach). we (currently?) 452 * allow both detach/attach to happen in the same set of 453 * supervisor interrupts, so it would make sense to execute this 454 * (full power down?) script after all the detach phases of the 455 * supervisor handling. like with training if needed from the 456 * second supervisor, nvidia doesn't do this, so who knows if it's 457 * entirely safe, but it does appear to work.. 458 * 459 * without this script being run, on some configurations i've 460 * seen, switching from DP to TMDS on a DP connector may result 461 * in a blank screen (SOR_PWR off/on can restore it) 462 */ 463 if (outp && outp->info.type == DCB_OUTPUT_DP) { 464 struct nvkm_output_dp *outpdp = nvkm_output_dp(outp); 465 struct nvbios_init init = { 466 .subdev = subdev, 467 .bios = subdev->device->bios, 468 .outp = &outp->info, 469 .crtc = head, 470 .offset = outpdp->info.script[4], 471 .execute = 1, 472 }; 473 474 nvbios_exec(&init); 475 atomic_set(&outpdp->lt.done, 0); 476 } 477} 478 479static void 480nv50_disp_intr_unk20_1(struct nv50_disp *disp, int head) 481{ 482 struct nvkm_device *device = disp->base.engine.subdev.device; 483 struct nvkm_devinit *devinit = device->devinit; 484 u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff; 485 if (pclk) 486 nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk); 487} 488 489static void 490nv50_disp_intr_unk20_2_dp(struct nv50_disp *disp, int head, 491 struct dcb_output *outp, u32 pclk) 492{ 493 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 494 struct nvkm_device *device = subdev->device; 495 const int link = !(outp->sorconf.link & 1); 496 const int or = ffs(outp->or) - 1; 497 const u32 soff = ( or * 0x800); 498 const u32 loff = (link * 0x080) + soff; 499 const u32 ctrl = nvkm_rd32(device, 0x610794 + (or * 8)); 500 const u32 symbol = 100000; 501 const s32 vactive = nvkm_rd32(device, 0x610af8 + (head * 0x540)) & 0xffff; 502 const s32 vblanke = nvkm_rd32(device, 0x610ae8 + (head * 0x540)) & 0xffff; 503 const s32 vblanks = nvkm_rd32(device, 0x610af0 + (head * 0x540)) & 0xffff; 504 u32 dpctrl = nvkm_rd32(device, 0x61c10c + loff); 505 u32 clksor = nvkm_rd32(device, 0x614300 + soff); 506 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0; 507 int TU, VTUi, VTUf, VTUa; 508 u64 link_data_rate, link_ratio, unk; 509 u32 best_diff = 64 * symbol; 510 u32 link_nr, link_bw, bits; 511 u64 value; 512 513 link_bw = (clksor & 0x000c0000) ? 270000 : 162000; 514 link_nr = hweight32(dpctrl & 0x000f0000); 515 516 /* symbols/hblank - algorithm taken from comments in tegra driver */ 517 value = vblanke + vactive - vblanks - 7; 518 value = value * link_bw; 519 do_div(value, pclk); 520 value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr); 521 nvkm_mask(device, 0x61c1e8 + soff, 0x0000ffff, value); 522 523 /* symbols/vblank - algorithm taken from comments in tegra driver */ 524 value = vblanks - vblanke - 25; 525 value = value * link_bw; 526 do_div(value, pclk); 527 value = value - ((36 / link_nr) + 3) - 1; 528 nvkm_mask(device, 0x61c1ec + soff, 0x00ffffff, value); 529 530 /* watermark / activesym */ 531 if ((ctrl & 0xf0000) == 0x60000) bits = 30; 532 else if ((ctrl & 0xf0000) == 0x50000) bits = 24; 533 else bits = 18; 534 535 link_data_rate = (pclk * bits / 8) / link_nr; 536 537 /* calculate ratio of packed data rate to link symbol rate */ 538 link_ratio = link_data_rate * symbol; 539 do_div(link_ratio, link_bw); 540 541 for (TU = 64; TU >= 32; TU--) { 542 /* calculate average number of valid symbols in each TU */ 543 u32 tu_valid = link_ratio * TU; 544 u32 calc, diff; 545 546 /* find a hw representation for the fraction.. */ 547 VTUi = tu_valid / symbol; 548 calc = VTUi * symbol; 549 diff = tu_valid - calc; 550 if (diff) { 551 if (diff >= (symbol / 2)) { 552 VTUf = symbol / (symbol - diff); 553 if (symbol - (VTUf * diff)) 554 VTUf++; 555 556 if (VTUf <= 15) { 557 VTUa = 1; 558 calc += symbol - (symbol / VTUf); 559 } else { 560 VTUa = 0; 561 VTUf = 1; 562 calc += symbol; 563 } 564 } else { 565 VTUa = 0; 566 VTUf = min((int)(symbol / diff), 15); 567 calc += symbol / VTUf; 568 } 569 570 diff = calc - tu_valid; 571 } else { 572 /* no remainder, but the hw doesn't like the fractional 573 * part to be zero. decrement the integer part and 574 * have the fraction add a whole symbol back 575 */ 576 VTUa = 0; 577 VTUf = 1; 578 VTUi--; 579 } 580 581 if (diff < best_diff) { 582 best_diff = diff; 583 bestTU = TU; 584 bestVTUa = VTUa; 585 bestVTUf = VTUf; 586 bestVTUi = VTUi; 587 if (diff == 0) 588 break; 589 } 590 } 591 592 if (!bestTU) { 593 nvkm_error(subdev, "unable to find suitable dp config\n"); 594 return; 595 } 596 597 /* XXX close to vbios numbers, but not right */ 598 unk = (symbol - link_ratio) * bestTU; 599 unk *= link_ratio; 600 do_div(unk, symbol); 601 do_div(unk, symbol); 602 unk += 6; 603 604 nvkm_mask(device, 0x61c10c + loff, 0x000001fc, bestTU << 2); 605 nvkm_mask(device, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 | 606 bestVTUf << 16 | 607 bestVTUi << 8 | unk); 608} 609 610static void 611nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head) 612{ 613 struct nvkm_device *device = disp->base.engine.subdev.device; 614 struct nvkm_output *outp; 615 u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff; 616 u32 hval, hreg = 0x614200 + (head * 0x800); 617 u32 oval, oreg; 618 u32 mask, conf; 619 620 outp = exec_clkcmp(disp, head, 0xff, pclk, &conf); 621 if (!outp) 622 return; 623 624 /* we allow both encoder attach and detach operations to occur 625 * within a single supervisor (ie. modeset) sequence. the 626 * encoder detach scripts quite often switch off power to the 627 * lanes, which requires the link to be re-trained. 628 * 629 * this is not generally an issue as the sink "must" (heh) 630 * signal an irq when it's lost sync so the driver can 631 * re-train. 632 * 633 * however, on some boards, if one does not configure at least 634 * the gpu side of the link *before* attaching, then various 635 * things can go horribly wrong (PDISP disappearing from mmio, 636 * third supervisor never happens, etc). 637 * 638 * the solution is simply to retrain here, if necessary. last 639 * i checked, the binary driver userspace does not appear to 640 * trigger this situation (it forces an UPDATE between steps). 641 */ 642 if (outp->info.type == DCB_OUTPUT_DP) { 643 u32 soff = (ffs(outp->info.or) - 1) * 0x08; 644 u32 ctrl, datarate; 645 646 if (outp->info.location == 0) { 647 ctrl = nvkm_rd32(device, 0x610794 + soff); 648 soff = 1; 649 } else { 650 ctrl = nvkm_rd32(device, 0x610b80 + soff); 651 soff = 2; 652 } 653 654 switch ((ctrl & 0x000f0000) >> 16) { 655 case 6: datarate = pclk * 30; break; 656 case 5: datarate = pclk * 24; break; 657 case 2: 658 default: 659 datarate = pclk * 18; 660 break; 661 } 662 663 if (nvkm_output_dp_train(outp, datarate / soff, true)) 664 OUTP_ERR(outp, "link not trained before attach"); 665 } 666 667 exec_clkcmp(disp, head, 0, pclk, &conf); 668 669 if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) { 670 oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800; 671 oval = 0x00000000; 672 hval = 0x00000000; 673 mask = 0xffffffff; 674 } else 675 if (!outp->info.location) { 676 if (outp->info.type == DCB_OUTPUT_DP) 677 nv50_disp_intr_unk20_2_dp(disp, head, &outp->info, pclk); 678 oreg = 0x614300 + (ffs(outp->info.or) - 1) * 0x800; 679 oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; 680 hval = 0x00000000; 681 mask = 0x00000707; 682 } else { 683 oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800; 684 oval = 0x00000001; 685 hval = 0x00000001; 686 mask = 0x00000707; 687 } 688 689 nvkm_mask(device, hreg, 0x0000000f, hval); 690 nvkm_mask(device, oreg, mask, oval); 691} 692 693/* If programming a TMDS output on a SOR that can also be configured for 694 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. 695 * 696 * It looks like the VBIOS TMDS scripts make an attempt at this, however, 697 * the VBIOS scripts on at least one board I have only switch it off on 698 * link 0, causing a blank display if the output has previously been 699 * programmed for DisplayPort. 700 */ 701static void 702nv50_disp_intr_unk40_0_tmds(struct nv50_disp *disp, 703 struct dcb_output *outp) 704{ 705 struct nvkm_device *device = disp->base.engine.subdev.device; 706 struct nvkm_bios *bios = device->bios; 707 const int link = !(outp->sorconf.link & 1); 708 const int or = ffs(outp->or) - 1; 709 const u32 loff = (or * 0x800) + (link * 0x80); 710 const u16 mask = (outp->sorconf.link << 6) | outp->or; 711 struct dcb_output match; 712 u8 ver, hdr; 713 714 if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, &match)) 715 nvkm_mask(device, 0x61c10c + loff, 0x00000001, 0x00000000); 716} 717 718static void 719nv50_disp_intr_unk40_0(struct nv50_disp *disp, int head) 720{ 721 struct nvkm_device *device = disp->base.engine.subdev.device; 722 struct nvkm_output *outp; 723 u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff; 724 u32 conf; 725 726 outp = exec_clkcmp(disp, head, 1, pclk, &conf); 727 if (!outp) 728 return; 729 730 if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS) 731 nv50_disp_intr_unk40_0_tmds(disp, &outp->info); 732} 733 734void 735nv50_disp_intr_supervisor(struct work_struct *work) 736{ 737 struct nv50_disp *disp = 738 container_of(work, struct nv50_disp, supervisor); 739 struct nvkm_subdev *subdev = &disp->base.engine.subdev; 740 struct nvkm_device *device = subdev->device; 741 u32 super = nvkm_rd32(device, 0x610030); 742 int head; 743 744 nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super); 745 746 if (disp->super & 0x00000010) { 747 nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG); 748 for (head = 0; head < disp->base.head.nr; head++) { 749 if (!(super & (0x00000020 << head))) 750 continue; 751 if (!(super & (0x00000080 << head))) 752 continue; 753 nv50_disp_intr_unk10_0(disp, head); 754 } 755 } else 756 if (disp->super & 0x00000020) { 757 for (head = 0; head < disp->base.head.nr; head++) { 758 if (!(super & (0x00000080 << head))) 759 continue; 760 nv50_disp_intr_unk20_0(disp, head); 761 } 762 for (head = 0; head < disp->base.head.nr; head++) { 763 if (!(super & (0x00000200 << head))) 764 continue; 765 nv50_disp_intr_unk20_1(disp, head); 766 } 767 for (head = 0; head < disp->base.head.nr; head++) { 768 if (!(super & (0x00000080 << head))) 769 continue; 770 nv50_disp_intr_unk20_2(disp, head); 771 } 772 } else 773 if (disp->super & 0x00000040) { 774 for (head = 0; head < disp->base.head.nr; head++) { 775 if (!(super & (0x00000080 << head))) 776 continue; 777 nv50_disp_intr_unk40_0(disp, head); 778 } 779 } 780 781 nvkm_wr32(device, 0x610030, 0x80000000); 782} 783 784void 785nv50_disp_intr(struct nv50_disp *disp) 786{ 787 struct nvkm_device *device = disp->base.engine.subdev.device; 788 u32 intr0 = nvkm_rd32(device, 0x610020); 789 u32 intr1 = nvkm_rd32(device, 0x610024); 790 791 while (intr0 & 0x001f0000) { 792 u32 chid = __ffs(intr0 & 0x001f0000) - 16; 793 nv50_disp_intr_error(disp, chid); 794 intr0 &= ~(0x00010000 << chid); 795 } 796 797 while (intr0 & 0x0000001f) { 798 u32 chid = __ffs(intr0 & 0x0000001f); 799 nv50_disp_chan_uevent_send(disp, chid); 800 intr0 &= ~(0x00000001 << chid); 801 } 802 803 if (intr1 & 0x00000004) { 804 nvkm_disp_vblank(&disp->base, 0); 805 nvkm_wr32(device, 0x610024, 0x00000004); 806 } 807 808 if (intr1 & 0x00000008) { 809 nvkm_disp_vblank(&disp->base, 1); 810 nvkm_wr32(device, 0x610024, 0x00000008); 811 } 812 813 if (intr1 & 0x00000070) { 814 disp->super = (intr1 & 0x00000070); 815 schedule_work(&disp->supervisor); 816 nvkm_wr32(device, 0x610024, disp->super); 817 } 818} 819 820static const struct nv50_disp_func 821nv50_disp = { 822 .intr = nv50_disp_intr, 823 .uevent = &nv50_disp_chan_uevent, 824 .super = nv50_disp_intr_supervisor, 825 .root = &nv50_disp_root_oclass, 826 .head.vblank_init = nv50_disp_vblank_init, 827 .head.vblank_fini = nv50_disp_vblank_fini, 828 .head.scanoutpos = nv50_disp_root_scanoutpos, 829 .outp.internal.crt = nv50_dac_output_new, 830 .outp.internal.tmds = nv50_sor_output_new, 831 .outp.internal.lvds = nv50_sor_output_new, 832 .outp.external.tmds = nv50_pior_output_new, 833 .outp.external.dp = nv50_pior_dp_new, 834 .dac.nr = 3, 835 .dac.power = nv50_dac_power, 836 .dac.sense = nv50_dac_sense, 837 .sor.nr = 2, 838 .sor.power = nv50_sor_power, 839 .pior.nr = 3, 840 .pior.power = nv50_pior_power, 841}; 842 843int 844nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) 845{ 846 return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp); 847} 848