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