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 "outp.h" 26 #include "outpdp.h" 27 28 #include <core/client.h> 29 #include <core/device.h> 30 #include <core/engctx.h> 31 #include <core/enum.h> 32 #include <core/handle.h> 33 #include <core/ramht.h> 34 #include <engine/dmaobj.h> 35 #include <subdev/bios.h> 36 #include <subdev/bios/dcb.h> 37 #include <subdev/bios/disp.h> 38 #include <subdev/bios/init.h> 39 #include <subdev/bios/pll.h> 40 #include <subdev/devinit.h> 41 #include <subdev/fb.h> 42 #include <subdev/timer.h> 43 44 #include <nvif/class.h> 45 #include <nvif/event.h> 46 #include <nvif/unpack.h> 47 48 /******************************************************************************* 49 * EVO channel base class 50 ******************************************************************************/ 51 52 static int 53 nv50_disp_chan_create_(struct nvkm_object *parent, 54 struct nvkm_object *engine, 55 struct nvkm_oclass *oclass, int head, 56 int length, void **pobject) 57 { 58 const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs; 59 struct nv50_disp_base *base = (void *)parent; 60 struct nv50_disp_chan *chan; 61 int chid = impl->chid + head; 62 int ret; 63 64 if (base->chan & (1 << chid)) 65 return -EBUSY; 66 base->chan |= (1 << chid); 67 68 ret = nvkm_namedb_create_(parent, engine, oclass, 0, NULL, 69 (1ULL << NVDEV_ENGINE_DMAOBJ), 70 length, pobject); 71 chan = *pobject; 72 if (ret) 73 return ret; 74 chan->chid = chid; 75 76 nv_parent(chan)->object_attach = impl->attach; 77 nv_parent(chan)->object_detach = impl->detach; 78 return 0; 79 } 80 81 static void 82 nv50_disp_chan_destroy(struct nv50_disp_chan *chan) 83 { 84 struct nv50_disp_base *base = (void *)nv_object(chan)->parent; 85 base->chan &= ~(1 << chan->chid); 86 nvkm_namedb_destroy(&chan->base); 87 } 88 89 static void 90 nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index) 91 { 92 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 93 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index); 94 nv_wr32(priv, 0x610020, 0x00000001 << index); 95 } 96 97 static void 98 nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index) 99 { 100 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 101 nv_wr32(priv, 0x610020, 0x00000001 << index); 102 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index); 103 } 104 105 void 106 nv50_disp_chan_uevent_send(struct nv50_disp_priv *priv, int chid) 107 { 108 struct nvif_notify_uevent_rep { 109 } rep; 110 111 nvkm_event_send(&priv->uevent, 1, chid, &rep, sizeof(rep)); 112 } 113 114 int 115 nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size, 116 struct nvkm_notify *notify) 117 { 118 struct nv50_disp_dmac *dmac = (void *)object; 119 union { 120 struct nvif_notify_uevent_req none; 121 } *args = data; 122 int ret; 123 124 if (nvif_unvers(args->none)) { 125 notify->size = sizeof(struct nvif_notify_uevent_rep); 126 notify->types = 1; 127 notify->index = dmac->base.chid; 128 return 0; 129 } 130 131 return ret; 132 } 133 134 const struct nvkm_event_func 135 nv50_disp_chan_uevent = { 136 .ctor = nv50_disp_chan_uevent_ctor, 137 .init = nv50_disp_chan_uevent_init, 138 .fini = nv50_disp_chan_uevent_fini, 139 }; 140 141 int 142 nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type, 143 struct nvkm_event **pevent) 144 { 145 struct nv50_disp_priv *priv = (void *)object->engine; 146 switch (type) { 147 case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT: 148 *pevent = &priv->uevent; 149 return 0; 150 default: 151 break; 152 } 153 return -EINVAL; 154 } 155 156 int 157 nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size) 158 { 159 struct nv50_disp_chan *chan = (void *)object; 160 *addr = nv_device_resource_start(nv_device(object), 0) + 161 0x640000 + (chan->chid * 0x1000); 162 *size = 0x001000; 163 return 0; 164 } 165 166 u32 167 nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr) 168 { 169 struct nv50_disp_priv *priv = (void *)object->engine; 170 struct nv50_disp_chan *chan = (void *)object; 171 return nv_rd32(priv, 0x640000 + (chan->chid * 0x1000) + addr); 172 } 173 174 void 175 nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data) 176 { 177 struct nv50_disp_priv *priv = (void *)object->engine; 178 struct nv50_disp_chan *chan = (void *)object; 179 nv_wr32(priv, 0x640000 + (chan->chid * 0x1000) + addr, data); 180 } 181 182 /******************************************************************************* 183 * EVO DMA channel base class 184 ******************************************************************************/ 185 186 static int 187 nv50_disp_dmac_object_attach(struct nvkm_object *parent, 188 struct nvkm_object *object, u32 name) 189 { 190 struct nv50_disp_base *base = (void *)parent->parent; 191 struct nv50_disp_chan *chan = (void *)parent; 192 u32 addr = nv_gpuobj(object)->node->offset; 193 u32 chid = chan->chid; 194 u32 data = (chid << 28) | (addr << 10) | chid; 195 return nvkm_ramht_insert(base->ramht, chid, name, data); 196 } 197 198 static void 199 nv50_disp_dmac_object_detach(struct nvkm_object *parent, int cookie) 200 { 201 struct nv50_disp_base *base = (void *)parent->parent; 202 nvkm_ramht_remove(base->ramht, cookie); 203 } 204 205 static int 206 nv50_disp_dmac_create_(struct nvkm_object *parent, 207 struct nvkm_object *engine, 208 struct nvkm_oclass *oclass, u32 pushbuf, int head, 209 int length, void **pobject) 210 { 211 struct nv50_disp_dmac *dmac; 212 int ret; 213 214 ret = nv50_disp_chan_create_(parent, engine, oclass, head, 215 length, pobject); 216 dmac = *pobject; 217 if (ret) 218 return ret; 219 220 dmac->pushdma = (void *)nvkm_handle_ref(parent, pushbuf); 221 if (!dmac->pushdma) 222 return -ENOENT; 223 224 switch (nv_mclass(dmac->pushdma)) { 225 case 0x0002: 226 case 0x003d: 227 if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff) 228 return -EINVAL; 229 230 switch (dmac->pushdma->target) { 231 case NV_MEM_TARGET_VRAM: 232 dmac->push = 0x00000000 | dmac->pushdma->start >> 8; 233 break; 234 case NV_MEM_TARGET_PCI_NOSNOOP: 235 dmac->push = 0x00000003 | dmac->pushdma->start >> 8; 236 break; 237 default: 238 return -EINVAL; 239 } 240 break; 241 default: 242 return -EINVAL; 243 } 244 245 return 0; 246 } 247 248 void 249 nv50_disp_dmac_dtor(struct nvkm_object *object) 250 { 251 struct nv50_disp_dmac *dmac = (void *)object; 252 nvkm_object_ref(NULL, (struct nvkm_object **)&dmac->pushdma); 253 nv50_disp_chan_destroy(&dmac->base); 254 } 255 256 static int 257 nv50_disp_dmac_init(struct nvkm_object *object) 258 { 259 struct nv50_disp_priv *priv = (void *)object->engine; 260 struct nv50_disp_dmac *dmac = (void *)object; 261 int chid = dmac->base.chid; 262 int ret; 263 264 ret = nv50_disp_chan_init(&dmac->base); 265 if (ret) 266 return ret; 267 268 /* enable error reporting */ 269 nv_mask(priv, 0x610028, 0x00010000 << chid, 0x00010000 << chid); 270 271 /* initialise channel for dma command submission */ 272 nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); 273 nv_wr32(priv, 0x610208 + (chid * 0x0010), 0x00010000); 274 nv_wr32(priv, 0x61020c + (chid * 0x0010), chid); 275 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010); 276 nv_wr32(priv, 0x640000 + (chid * 0x1000), 0x00000000); 277 nv_wr32(priv, 0x610200 + (chid * 0x0010), 0x00000013); 278 279 /* wait for it to go inactive */ 280 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x80000000, 0x00000000)) { 281 nv_error(dmac, "init timeout, 0x%08x\n", 282 nv_rd32(priv, 0x610200 + (chid * 0x10))); 283 return -EBUSY; 284 } 285 286 return 0; 287 } 288 289 static int 290 nv50_disp_dmac_fini(struct nvkm_object *object, bool suspend) 291 { 292 struct nv50_disp_priv *priv = (void *)object->engine; 293 struct nv50_disp_dmac *dmac = (void *)object; 294 int chid = dmac->base.chid; 295 296 /* deactivate channel */ 297 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000); 298 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000); 299 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x001e0000, 0x00000000)) { 300 nv_error(dmac, "fini timeout, 0x%08x\n", 301 nv_rd32(priv, 0x610200 + (chid * 0x10))); 302 if (suspend) 303 return -EBUSY; 304 } 305 306 /* disable error reporting and completion notifications */ 307 nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid); 308 309 return nv50_disp_chan_fini(&dmac->base, suspend); 310 } 311 312 /******************************************************************************* 313 * EVO master channel object 314 ******************************************************************************/ 315 316 static void 317 nv50_disp_mthd_list(struct nv50_disp_priv *priv, int debug, u32 base, int c, 318 const struct nv50_disp_mthd_list *list, int inst) 319 { 320 struct nvkm_object *disp = nv_object(priv); 321 int i; 322 323 for (i = 0; list->data[i].mthd; i++) { 324 if (list->data[i].addr) { 325 u32 next = nv_rd32(priv, list->data[i].addr + base + 0); 326 u32 prev = nv_rd32(priv, list->data[i].addr + base + c); 327 u32 mthd = list->data[i].mthd + (list->mthd * inst); 328 const char *name = list->data[i].name; 329 char mods[16]; 330 331 if (prev != next) 332 snprintf(mods, sizeof(mods), "-> 0x%08x", next); 333 else 334 snprintf(mods, sizeof(mods), "%13c", ' '); 335 336 nv_printk_(disp, debug, "\t0x%04x: 0x%08x %s%s%s\n", 337 mthd, prev, mods, name ? " // " : "", 338 name ? name : ""); 339 } 340 } 341 } 342 343 void 344 nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head, 345 const struct nv50_disp_mthd_chan *chan) 346 { 347 struct nvkm_object *disp = nv_object(priv); 348 const struct nv50_disp_impl *impl = (void *)disp->oclass; 349 const struct nv50_disp_mthd_list *list; 350 int i, j; 351 352 if (debug > nv_subdev(priv)->debug) 353 return; 354 355 for (i = 0; (list = chan->data[i].mthd) != NULL; i++) { 356 u32 base = head * chan->addr; 357 for (j = 0; j < chan->data[i].nr; j++, base += list->addr) { 358 const char *cname = chan->name; 359 const char *sname = ""; 360 char cname_[16], sname_[16]; 361 362 if (chan->addr) { 363 snprintf(cname_, sizeof(cname_), "%s %d", 364 chan->name, head); 365 cname = cname_; 366 } 367 368 if (chan->data[i].nr > 1) { 369 snprintf(sname_, sizeof(sname_), " - %s %d", 370 chan->data[i].name, j); 371 sname = sname_; 372 } 373 374 nv_printk_(disp, debug, "%s%s:\n", cname, sname); 375 nv50_disp_mthd_list(priv, debug, base, impl->mthd.prev, 376 list, j); 377 } 378 } 379 } 380 381 const struct nv50_disp_mthd_list 382 nv50_disp_core_mthd_base = { 383 .mthd = 0x0000, 384 .addr = 0x000000, 385 .data = { 386 { 0x0080, 0x000000 }, 387 { 0x0084, 0x610bb8 }, 388 { 0x0088, 0x610b9c }, 389 { 0x008c, 0x000000 }, 390 {} 391 } 392 }; 393 394 static const struct nv50_disp_mthd_list 395 nv50_disp_core_mthd_dac = { 396 .mthd = 0x0080, 397 .addr = 0x000008, 398 .data = { 399 { 0x0400, 0x610b58 }, 400 { 0x0404, 0x610bdc }, 401 { 0x0420, 0x610828 }, 402 {} 403 } 404 }; 405 406 const struct nv50_disp_mthd_list 407 nv50_disp_core_mthd_sor = { 408 .mthd = 0x0040, 409 .addr = 0x000008, 410 .data = { 411 { 0x0600, 0x610b70 }, 412 {} 413 } 414 }; 415 416 const struct nv50_disp_mthd_list 417 nv50_disp_core_mthd_pior = { 418 .mthd = 0x0040, 419 .addr = 0x000008, 420 .data = { 421 { 0x0700, 0x610b80 }, 422 {} 423 } 424 }; 425 426 static const struct nv50_disp_mthd_list 427 nv50_disp_core_mthd_head = { 428 .mthd = 0x0400, 429 .addr = 0x000540, 430 .data = { 431 { 0x0800, 0x610ad8 }, 432 { 0x0804, 0x610ad0 }, 433 { 0x0808, 0x610a48 }, 434 { 0x080c, 0x610a78 }, 435 { 0x0810, 0x610ac0 }, 436 { 0x0814, 0x610af8 }, 437 { 0x0818, 0x610b00 }, 438 { 0x081c, 0x610ae8 }, 439 { 0x0820, 0x610af0 }, 440 { 0x0824, 0x610b08 }, 441 { 0x0828, 0x610b10 }, 442 { 0x082c, 0x610a68 }, 443 { 0x0830, 0x610a60 }, 444 { 0x0834, 0x000000 }, 445 { 0x0838, 0x610a40 }, 446 { 0x0840, 0x610a24 }, 447 { 0x0844, 0x610a2c }, 448 { 0x0848, 0x610aa8 }, 449 { 0x084c, 0x610ab0 }, 450 { 0x0860, 0x610a84 }, 451 { 0x0864, 0x610a90 }, 452 { 0x0868, 0x610b18 }, 453 { 0x086c, 0x610b20 }, 454 { 0x0870, 0x610ac8 }, 455 { 0x0874, 0x610a38 }, 456 { 0x0880, 0x610a58 }, 457 { 0x0884, 0x610a9c }, 458 { 0x08a0, 0x610a70 }, 459 { 0x08a4, 0x610a50 }, 460 { 0x08a8, 0x610ae0 }, 461 { 0x08c0, 0x610b28 }, 462 { 0x08c4, 0x610b30 }, 463 { 0x08c8, 0x610b40 }, 464 { 0x08d4, 0x610b38 }, 465 { 0x08d8, 0x610b48 }, 466 { 0x08dc, 0x610b50 }, 467 { 0x0900, 0x610a18 }, 468 { 0x0904, 0x610ab8 }, 469 {} 470 } 471 }; 472 473 static const struct nv50_disp_mthd_chan 474 nv50_disp_core_mthd_chan = { 475 .name = "Core", 476 .addr = 0x000000, 477 .data = { 478 { "Global", 1, &nv50_disp_core_mthd_base }, 479 { "DAC", 3, &nv50_disp_core_mthd_dac }, 480 { "SOR", 2, &nv50_disp_core_mthd_sor }, 481 { "PIOR", 3, &nv50_disp_core_mthd_pior }, 482 { "HEAD", 2, &nv50_disp_core_mthd_head }, 483 {} 484 } 485 }; 486 487 int 488 nv50_disp_core_ctor(struct nvkm_object *parent, 489 struct nvkm_object *engine, 490 struct nvkm_oclass *oclass, void *data, u32 size, 491 struct nvkm_object **pobject) 492 { 493 union { 494 struct nv50_disp_core_channel_dma_v0 v0; 495 } *args = data; 496 struct nv50_disp_dmac *mast; 497 int ret; 498 499 nv_ioctl(parent, "create disp core channel dma size %d\n", size); 500 if (nvif_unpack(args->v0, 0, 0, false)) { 501 nv_ioctl(parent, "create disp core channel dma vers %d " 502 "pushbuf %08x\n", 503 args->v0.version, args->v0.pushbuf); 504 } else 505 return ret; 506 507 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, 508 0, sizeof(*mast), (void **)&mast); 509 *pobject = nv_object(mast); 510 if (ret) 511 return ret; 512 513 return 0; 514 } 515 516 static int 517 nv50_disp_core_init(struct nvkm_object *object) 518 { 519 struct nv50_disp_priv *priv = (void *)object->engine; 520 struct nv50_disp_dmac *mast = (void *)object; 521 int ret; 522 523 ret = nv50_disp_chan_init(&mast->base); 524 if (ret) 525 return ret; 526 527 /* enable error reporting */ 528 nv_mask(priv, 0x610028, 0x00010000, 0x00010000); 529 530 /* attempt to unstick channel from some unknown state */ 531 if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000) 532 nv_mask(priv, 0x610200, 0x00800000, 0x00800000); 533 if ((nv_rd32(priv, 0x610200) & 0x003f0000) == 0x00030000) 534 nv_mask(priv, 0x610200, 0x00600000, 0x00600000); 535 536 /* initialise channel for dma command submission */ 537 nv_wr32(priv, 0x610204, mast->push); 538 nv_wr32(priv, 0x610208, 0x00010000); 539 nv_wr32(priv, 0x61020c, 0x00000000); 540 nv_mask(priv, 0x610200, 0x00000010, 0x00000010); 541 nv_wr32(priv, 0x640000, 0x00000000); 542 nv_wr32(priv, 0x610200, 0x01000013); 543 544 /* wait for it to go inactive */ 545 if (!nv_wait(priv, 0x610200, 0x80000000, 0x00000000)) { 546 nv_error(mast, "init: 0x%08x\n", nv_rd32(priv, 0x610200)); 547 return -EBUSY; 548 } 549 550 return 0; 551 } 552 553 static int 554 nv50_disp_core_fini(struct nvkm_object *object, bool suspend) 555 { 556 struct nv50_disp_priv *priv = (void *)object->engine; 557 struct nv50_disp_dmac *mast = (void *)object; 558 559 /* deactivate channel */ 560 nv_mask(priv, 0x610200, 0x00000010, 0x00000000); 561 nv_mask(priv, 0x610200, 0x00000003, 0x00000000); 562 if (!nv_wait(priv, 0x610200, 0x001e0000, 0x00000000)) { 563 nv_error(mast, "fini: 0x%08x\n", nv_rd32(priv, 0x610200)); 564 if (suspend) 565 return -EBUSY; 566 } 567 568 /* disable error reporting and completion notifications */ 569 nv_mask(priv, 0x610028, 0x00010001, 0x00000000); 570 571 return nv50_disp_chan_fini(&mast->base, suspend); 572 } 573 574 struct nv50_disp_chan_impl 575 nv50_disp_core_ofuncs = { 576 .base.ctor = nv50_disp_core_ctor, 577 .base.dtor = nv50_disp_dmac_dtor, 578 .base.init = nv50_disp_core_init, 579 .base.fini = nv50_disp_core_fini, 580 .base.map = nv50_disp_chan_map, 581 .base.ntfy = nv50_disp_chan_ntfy, 582 .base.rd32 = nv50_disp_chan_rd32, 583 .base.wr32 = nv50_disp_chan_wr32, 584 .chid = 0, 585 .attach = nv50_disp_dmac_object_attach, 586 .detach = nv50_disp_dmac_object_detach, 587 }; 588 589 /******************************************************************************* 590 * EVO sync channel objects 591 ******************************************************************************/ 592 593 static const struct nv50_disp_mthd_list 594 nv50_disp_base_mthd_base = { 595 .mthd = 0x0000, 596 .addr = 0x000000, 597 .data = { 598 { 0x0080, 0x000000 }, 599 { 0x0084, 0x0008c4 }, 600 { 0x0088, 0x0008d0 }, 601 { 0x008c, 0x0008dc }, 602 { 0x0090, 0x0008e4 }, 603 { 0x0094, 0x610884 }, 604 { 0x00a0, 0x6108a0 }, 605 { 0x00a4, 0x610878 }, 606 { 0x00c0, 0x61086c }, 607 { 0x00e0, 0x610858 }, 608 { 0x00e4, 0x610860 }, 609 { 0x00e8, 0x6108ac }, 610 { 0x00ec, 0x6108b4 }, 611 { 0x0100, 0x610894 }, 612 { 0x0110, 0x6108bc }, 613 { 0x0114, 0x61088c }, 614 {} 615 } 616 }; 617 618 const struct nv50_disp_mthd_list 619 nv50_disp_base_mthd_image = { 620 .mthd = 0x0400, 621 .addr = 0x000000, 622 .data = { 623 { 0x0800, 0x6108f0 }, 624 { 0x0804, 0x6108fc }, 625 { 0x0808, 0x61090c }, 626 { 0x080c, 0x610914 }, 627 { 0x0810, 0x610904 }, 628 {} 629 } 630 }; 631 632 static const struct nv50_disp_mthd_chan 633 nv50_disp_base_mthd_chan = { 634 .name = "Base", 635 .addr = 0x000540, 636 .data = { 637 { "Global", 1, &nv50_disp_base_mthd_base }, 638 { "Image", 2, &nv50_disp_base_mthd_image }, 639 {} 640 } 641 }; 642 643 int 644 nv50_disp_base_ctor(struct nvkm_object *parent, 645 struct nvkm_object *engine, 646 struct nvkm_oclass *oclass, void *data, u32 size, 647 struct nvkm_object **pobject) 648 { 649 union { 650 struct nv50_disp_base_channel_dma_v0 v0; 651 } *args = data; 652 struct nv50_disp_priv *priv = (void *)engine; 653 struct nv50_disp_dmac *dmac; 654 int ret; 655 656 nv_ioctl(parent, "create disp base channel dma size %d\n", size); 657 if (nvif_unpack(args->v0, 0, 0, false)) { 658 nv_ioctl(parent, "create disp base channel dma vers %d " 659 "pushbuf %08x head %d\n", 660 args->v0.version, args->v0.pushbuf, args->v0.head); 661 if (args->v0.head > priv->head.nr) 662 return -EINVAL; 663 } else 664 return ret; 665 666 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, 667 args->v0.head, sizeof(*dmac), 668 (void **)&dmac); 669 *pobject = nv_object(dmac); 670 if (ret) 671 return ret; 672 673 return 0; 674 } 675 676 struct nv50_disp_chan_impl 677 nv50_disp_base_ofuncs = { 678 .base.ctor = nv50_disp_base_ctor, 679 .base.dtor = nv50_disp_dmac_dtor, 680 .base.init = nv50_disp_dmac_init, 681 .base.fini = nv50_disp_dmac_fini, 682 .base.ntfy = nv50_disp_chan_ntfy, 683 .base.map = nv50_disp_chan_map, 684 .base.rd32 = nv50_disp_chan_rd32, 685 .base.wr32 = nv50_disp_chan_wr32, 686 .chid = 1, 687 .attach = nv50_disp_dmac_object_attach, 688 .detach = nv50_disp_dmac_object_detach, 689 }; 690 691 /******************************************************************************* 692 * EVO overlay channel objects 693 ******************************************************************************/ 694 695 const struct nv50_disp_mthd_list 696 nv50_disp_ovly_mthd_base = { 697 .mthd = 0x0000, 698 .addr = 0x000000, 699 .data = { 700 { 0x0080, 0x000000 }, 701 { 0x0084, 0x0009a0 }, 702 { 0x0088, 0x0009c0 }, 703 { 0x008c, 0x0009c8 }, 704 { 0x0090, 0x6109b4 }, 705 { 0x0094, 0x610970 }, 706 { 0x00a0, 0x610998 }, 707 { 0x00a4, 0x610964 }, 708 { 0x00c0, 0x610958 }, 709 { 0x00e0, 0x6109a8 }, 710 { 0x00e4, 0x6109d0 }, 711 { 0x00e8, 0x6109d8 }, 712 { 0x0100, 0x61094c }, 713 { 0x0104, 0x610984 }, 714 { 0x0108, 0x61098c }, 715 { 0x0800, 0x6109f8 }, 716 { 0x0808, 0x610a08 }, 717 { 0x080c, 0x610a10 }, 718 { 0x0810, 0x610a00 }, 719 {} 720 } 721 }; 722 723 static const struct nv50_disp_mthd_chan 724 nv50_disp_ovly_mthd_chan = { 725 .name = "Overlay", 726 .addr = 0x000540, 727 .data = { 728 { "Global", 1, &nv50_disp_ovly_mthd_base }, 729 {} 730 } 731 }; 732 733 int 734 nv50_disp_ovly_ctor(struct nvkm_object *parent, 735 struct nvkm_object *engine, 736 struct nvkm_oclass *oclass, void *data, u32 size, 737 struct nvkm_object **pobject) 738 { 739 union { 740 struct nv50_disp_overlay_channel_dma_v0 v0; 741 } *args = data; 742 struct nv50_disp_priv *priv = (void *)engine; 743 struct nv50_disp_dmac *dmac; 744 int ret; 745 746 nv_ioctl(parent, "create disp overlay channel dma size %d\n", size); 747 if (nvif_unpack(args->v0, 0, 0, false)) { 748 nv_ioctl(parent, "create disp overlay channel dma vers %d " 749 "pushbuf %08x head %d\n", 750 args->v0.version, args->v0.pushbuf, args->v0.head); 751 if (args->v0.head > priv->head.nr) 752 return -EINVAL; 753 } else 754 return ret; 755 756 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, 757 args->v0.head, sizeof(*dmac), 758 (void **)&dmac); 759 *pobject = nv_object(dmac); 760 if (ret) 761 return ret; 762 763 return 0; 764 } 765 766 struct nv50_disp_chan_impl 767 nv50_disp_ovly_ofuncs = { 768 .base.ctor = nv50_disp_ovly_ctor, 769 .base.dtor = nv50_disp_dmac_dtor, 770 .base.init = nv50_disp_dmac_init, 771 .base.fini = nv50_disp_dmac_fini, 772 .base.ntfy = nv50_disp_chan_ntfy, 773 .base.map = nv50_disp_chan_map, 774 .base.rd32 = nv50_disp_chan_rd32, 775 .base.wr32 = nv50_disp_chan_wr32, 776 .chid = 3, 777 .attach = nv50_disp_dmac_object_attach, 778 .detach = nv50_disp_dmac_object_detach, 779 }; 780 781 /******************************************************************************* 782 * EVO PIO channel base class 783 ******************************************************************************/ 784 785 static int 786 nv50_disp_pioc_create_(struct nvkm_object *parent, 787 struct nvkm_object *engine, 788 struct nvkm_oclass *oclass, int head, 789 int length, void **pobject) 790 { 791 return nv50_disp_chan_create_(parent, engine, oclass, head, 792 length, pobject); 793 } 794 795 void 796 nv50_disp_pioc_dtor(struct nvkm_object *object) 797 { 798 struct nv50_disp_pioc *pioc = (void *)object; 799 nv50_disp_chan_destroy(&pioc->base); 800 } 801 802 static int 803 nv50_disp_pioc_init(struct nvkm_object *object) 804 { 805 struct nv50_disp_priv *priv = (void *)object->engine; 806 struct nv50_disp_pioc *pioc = (void *)object; 807 int chid = pioc->base.chid; 808 int ret; 809 810 ret = nv50_disp_chan_init(&pioc->base); 811 if (ret) 812 return ret; 813 814 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00002000); 815 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00000000, 0x00000000)) { 816 nv_error(pioc, "timeout0: 0x%08x\n", 817 nv_rd32(priv, 0x610200 + (chid * 0x10))); 818 return -EBUSY; 819 } 820 821 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00000001); 822 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00010000)) { 823 nv_error(pioc, "timeout1: 0x%08x\n", 824 nv_rd32(priv, 0x610200 + (chid * 0x10))); 825 return -EBUSY; 826 } 827 828 return 0; 829 } 830 831 static int 832 nv50_disp_pioc_fini(struct nvkm_object *object, bool suspend) 833 { 834 struct nv50_disp_priv *priv = (void *)object->engine; 835 struct nv50_disp_pioc *pioc = (void *)object; 836 int chid = pioc->base.chid; 837 838 nv_mask(priv, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000); 839 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00000000)) { 840 nv_error(pioc, "timeout: 0x%08x\n", 841 nv_rd32(priv, 0x610200 + (chid * 0x10))); 842 if (suspend) 843 return -EBUSY; 844 } 845 846 return nv50_disp_chan_fini(&pioc->base, suspend); 847 } 848 849 /******************************************************************************* 850 * EVO immediate overlay channel objects 851 ******************************************************************************/ 852 853 int 854 nv50_disp_oimm_ctor(struct nvkm_object *parent, 855 struct nvkm_object *engine, 856 struct nvkm_oclass *oclass, void *data, u32 size, 857 struct nvkm_object **pobject) 858 { 859 union { 860 struct nv50_disp_overlay_v0 v0; 861 } *args = data; 862 struct nv50_disp_priv *priv = (void *)engine; 863 struct nv50_disp_pioc *pioc; 864 int ret; 865 866 nv_ioctl(parent, "create disp overlay size %d\n", size); 867 if (nvif_unpack(args->v0, 0, 0, false)) { 868 nv_ioctl(parent, "create disp overlay vers %d head %d\n", 869 args->v0.version, args->v0.head); 870 if (args->v0.head > priv->head.nr) 871 return -EINVAL; 872 } else 873 return ret; 874 875 ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head, 876 sizeof(*pioc), (void **)&pioc); 877 *pobject = nv_object(pioc); 878 if (ret) 879 return ret; 880 881 return 0; 882 } 883 884 struct nv50_disp_chan_impl 885 nv50_disp_oimm_ofuncs = { 886 .base.ctor = nv50_disp_oimm_ctor, 887 .base.dtor = nv50_disp_pioc_dtor, 888 .base.init = nv50_disp_pioc_init, 889 .base.fini = nv50_disp_pioc_fini, 890 .base.ntfy = nv50_disp_chan_ntfy, 891 .base.map = nv50_disp_chan_map, 892 .base.rd32 = nv50_disp_chan_rd32, 893 .base.wr32 = nv50_disp_chan_wr32, 894 .chid = 5, 895 }; 896 897 /******************************************************************************* 898 * EVO cursor channel objects 899 ******************************************************************************/ 900 901 int 902 nv50_disp_curs_ctor(struct nvkm_object *parent, 903 struct nvkm_object *engine, 904 struct nvkm_oclass *oclass, void *data, u32 size, 905 struct nvkm_object **pobject) 906 { 907 union { 908 struct nv50_disp_cursor_v0 v0; 909 } *args = data; 910 struct nv50_disp_priv *priv = (void *)engine; 911 struct nv50_disp_pioc *pioc; 912 int ret; 913 914 nv_ioctl(parent, "create disp cursor size %d\n", size); 915 if (nvif_unpack(args->v0, 0, 0, false)) { 916 nv_ioctl(parent, "create disp cursor vers %d head %d\n", 917 args->v0.version, args->v0.head); 918 if (args->v0.head > priv->head.nr) 919 return -EINVAL; 920 } else 921 return ret; 922 923 ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head, 924 sizeof(*pioc), (void **)&pioc); 925 *pobject = nv_object(pioc); 926 if (ret) 927 return ret; 928 929 return 0; 930 } 931 932 struct nv50_disp_chan_impl 933 nv50_disp_curs_ofuncs = { 934 .base.ctor = nv50_disp_curs_ctor, 935 .base.dtor = nv50_disp_pioc_dtor, 936 .base.init = nv50_disp_pioc_init, 937 .base.fini = nv50_disp_pioc_fini, 938 .base.ntfy = nv50_disp_chan_ntfy, 939 .base.map = nv50_disp_chan_map, 940 .base.rd32 = nv50_disp_chan_rd32, 941 .base.wr32 = nv50_disp_chan_wr32, 942 .chid = 7, 943 }; 944 945 /******************************************************************************* 946 * Base display object 947 ******************************************************************************/ 948 949 int 950 nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0) 951 { 952 const u32 blanke = nv_rd32(priv, 0x610aec + (head * 0x540)); 953 const u32 blanks = nv_rd32(priv, 0x610af4 + (head * 0x540)); 954 const u32 total = nv_rd32(priv, 0x610afc + (head * 0x540)); 955 union { 956 struct nv04_disp_scanoutpos_v0 v0; 957 } *args = data; 958 int ret; 959 960 nv_ioctl(object, "disp scanoutpos size %d\n", size); 961 if (nvif_unpack(args->v0, 0, 0, false)) { 962 nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version); 963 args->v0.vblanke = (blanke & 0xffff0000) >> 16; 964 args->v0.hblanke = (blanke & 0x0000ffff); 965 args->v0.vblanks = (blanks & 0xffff0000) >> 16; 966 args->v0.hblanks = (blanks & 0x0000ffff); 967 args->v0.vtotal = ( total & 0xffff0000) >> 16; 968 args->v0.htotal = ( total & 0x0000ffff); 969 args->v0.time[0] = ktime_to_ns(ktime_get()); 970 args->v0.vline = /* vline read locks hline */ 971 nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff; 972 args->v0.time[1] = ktime_to_ns(ktime_get()); 973 args->v0.hline = 974 nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff; 975 } else 976 return ret; 977 978 return 0; 979 } 980 981 int 982 nv50_disp_main_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) 983 { 984 const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine); 985 union { 986 struct nv50_disp_mthd_v0 v0; 987 struct nv50_disp_mthd_v1 v1; 988 } *args = data; 989 struct nv50_disp_priv *priv = (void *)object->engine; 990 struct nvkm_output *outp = NULL; 991 struct nvkm_output *temp; 992 u16 type, mask = 0; 993 int head, ret; 994 995 if (mthd != NV50_DISP_MTHD) 996 return -EINVAL; 997 998 nv_ioctl(object, "disp mthd size %d\n", size); 999 if (nvif_unpack(args->v0, 0, 0, true)) { 1000 nv_ioctl(object, "disp mthd vers %d mthd %02x head %d\n", 1001 args->v0.version, args->v0.method, args->v0.head); 1002 mthd = args->v0.method; 1003 head = args->v0.head; 1004 } else 1005 if (nvif_unpack(args->v1, 1, 1, true)) { 1006 nv_ioctl(object, "disp mthd vers %d mthd %02x " 1007 "type %04x mask %04x\n", 1008 args->v1.version, args->v1.method, 1009 args->v1.hasht, args->v1.hashm); 1010 mthd = args->v1.method; 1011 type = args->v1.hasht; 1012 mask = args->v1.hashm; 1013 head = ffs((mask >> 8) & 0x0f) - 1; 1014 } else 1015 return ret; 1016 1017 if (head < 0 || head >= priv->head.nr) 1018 return -ENXIO; 1019 1020 if (mask) { 1021 list_for_each_entry(temp, &priv->base.outp, head) { 1022 if ((temp->info.hasht == type) && 1023 (temp->info.hashm & mask) == mask) { 1024 outp = temp; 1025 break; 1026 } 1027 } 1028 if (outp == NULL) 1029 return -ENXIO; 1030 } 1031 1032 switch (mthd) { 1033 case NV50_DISP_SCANOUTPOS: 1034 return impl->head.scanoutpos(object, priv, data, size, head); 1035 default: 1036 break; 1037 } 1038 1039 switch (mthd * !!outp) { 1040 case NV50_DISP_MTHD_V1_DAC_PWR: 1041 return priv->dac.power(object, priv, data, size, head, outp); 1042 case NV50_DISP_MTHD_V1_DAC_LOAD: 1043 return priv->dac.sense(object, priv, data, size, head, outp); 1044 case NV50_DISP_MTHD_V1_SOR_PWR: 1045 return priv->sor.power(object, priv, data, size, head, outp); 1046 case NV50_DISP_MTHD_V1_SOR_HDA_ELD: 1047 if (!priv->sor.hda_eld) 1048 return -ENODEV; 1049 return priv->sor.hda_eld(object, priv, data, size, head, outp); 1050 case NV50_DISP_MTHD_V1_SOR_HDMI_PWR: 1051 if (!priv->sor.hdmi) 1052 return -ENODEV; 1053 return priv->sor.hdmi(object, priv, data, size, head, outp); 1054 case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: { 1055 union { 1056 struct nv50_disp_sor_lvds_script_v0 v0; 1057 } *args = data; 1058 nv_ioctl(object, "disp sor lvds script size %d\n", size); 1059 if (nvif_unpack(args->v0, 0, 0, false)) { 1060 nv_ioctl(object, "disp sor lvds script " 1061 "vers %d name %04x\n", 1062 args->v0.version, args->v0.script); 1063 priv->sor.lvdsconf = args->v0.script; 1064 return 0; 1065 } else 1066 return ret; 1067 } 1068 break; 1069 case NV50_DISP_MTHD_V1_SOR_DP_PWR: { 1070 struct nvkm_output_dp *outpdp = (void *)outp; 1071 union { 1072 struct nv50_disp_sor_dp_pwr_v0 v0; 1073 } *args = data; 1074 nv_ioctl(object, "disp sor dp pwr size %d\n", size); 1075 if (nvif_unpack(args->v0, 0, 0, false)) { 1076 nv_ioctl(object, "disp sor dp pwr vers %d state %d\n", 1077 args->v0.version, args->v0.state); 1078 if (args->v0.state == 0) { 1079 nvkm_notify_put(&outpdp->irq); 1080 ((struct nvkm_output_dp_impl *)nv_oclass(outp)) 1081 ->lnk_pwr(outpdp, 0); 1082 atomic_set(&outpdp->lt.done, 0); 1083 return 0; 1084 } else 1085 if (args->v0.state != 0) { 1086 nvkm_output_dp_train(&outpdp->base, 0, true); 1087 return 0; 1088 } 1089 } else 1090 return ret; 1091 } 1092 break; 1093 case NV50_DISP_MTHD_V1_PIOR_PWR: 1094 if (!priv->pior.power) 1095 return -ENODEV; 1096 return priv->pior.power(object, priv, data, size, head, outp); 1097 default: 1098 break; 1099 } 1100 1101 return -EINVAL; 1102 } 1103 1104 int 1105 nv50_disp_main_ctor(struct nvkm_object *parent, 1106 struct nvkm_object *engine, 1107 struct nvkm_oclass *oclass, void *data, u32 size, 1108 struct nvkm_object **pobject) 1109 { 1110 struct nv50_disp_priv *priv = (void *)engine; 1111 struct nv50_disp_base *base; 1112 int ret; 1113 1114 ret = nvkm_parent_create(parent, engine, oclass, 0, 1115 priv->sclass, 0, &base); 1116 *pobject = nv_object(base); 1117 if (ret) 1118 return ret; 1119 1120 return nvkm_ramht_new(nv_object(base), nv_object(base), 0x1000, 0, 1121 &base->ramht); 1122 } 1123 1124 void 1125 nv50_disp_main_dtor(struct nvkm_object *object) 1126 { 1127 struct nv50_disp_base *base = (void *)object; 1128 nvkm_ramht_ref(NULL, &base->ramht); 1129 nvkm_parent_destroy(&base->base); 1130 } 1131 1132 static int 1133 nv50_disp_main_init(struct nvkm_object *object) 1134 { 1135 struct nv50_disp_priv *priv = (void *)object->engine; 1136 struct nv50_disp_base *base = (void *)object; 1137 int ret, i; 1138 u32 tmp; 1139 1140 ret = nvkm_parent_init(&base->base); 1141 if (ret) 1142 return ret; 1143 1144 /* The below segments of code copying values from one register to 1145 * another appear to inform EVO of the display capabilities or 1146 * something similar. NFI what the 0x614004 caps are for.. 1147 */ 1148 tmp = nv_rd32(priv, 0x614004); 1149 nv_wr32(priv, 0x610184, tmp); 1150 1151 /* ... CRTC caps */ 1152 for (i = 0; i < priv->head.nr; i++) { 1153 tmp = nv_rd32(priv, 0x616100 + (i * 0x800)); 1154 nv_wr32(priv, 0x610190 + (i * 0x10), tmp); 1155 tmp = nv_rd32(priv, 0x616104 + (i * 0x800)); 1156 nv_wr32(priv, 0x610194 + (i * 0x10), tmp); 1157 tmp = nv_rd32(priv, 0x616108 + (i * 0x800)); 1158 nv_wr32(priv, 0x610198 + (i * 0x10), tmp); 1159 tmp = nv_rd32(priv, 0x61610c + (i * 0x800)); 1160 nv_wr32(priv, 0x61019c + (i * 0x10), tmp); 1161 } 1162 1163 /* ... DAC caps */ 1164 for (i = 0; i < priv->dac.nr; i++) { 1165 tmp = nv_rd32(priv, 0x61a000 + (i * 0x800)); 1166 nv_wr32(priv, 0x6101d0 + (i * 0x04), tmp); 1167 } 1168 1169 /* ... SOR caps */ 1170 for (i = 0; i < priv->sor.nr; i++) { 1171 tmp = nv_rd32(priv, 0x61c000 + (i * 0x800)); 1172 nv_wr32(priv, 0x6101e0 + (i * 0x04), tmp); 1173 } 1174 1175 /* ... PIOR caps */ 1176 for (i = 0; i < priv->pior.nr; i++) { 1177 tmp = nv_rd32(priv, 0x61e000 + (i * 0x800)); 1178 nv_wr32(priv, 0x6101f0 + (i * 0x04), tmp); 1179 } 1180 1181 /* steal display away from vbios, or something like that */ 1182 if (nv_rd32(priv, 0x610024) & 0x00000100) { 1183 nv_wr32(priv, 0x610024, 0x00000100); 1184 nv_mask(priv, 0x6194e8, 0x00000001, 0x00000000); 1185 if (!nv_wait(priv, 0x6194e8, 0x00000002, 0x00000000)) { 1186 nv_error(priv, "timeout acquiring display\n"); 1187 return -EBUSY; 1188 } 1189 } 1190 1191 /* point at display engine memory area (hash table, objects) */ 1192 nv_wr32(priv, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9); 1193 1194 /* enable supervisor interrupts, disable everything else */ 1195 nv_wr32(priv, 0x61002c, 0x00000370); 1196 nv_wr32(priv, 0x610028, 0x00000000); 1197 return 0; 1198 } 1199 1200 static int 1201 nv50_disp_main_fini(struct nvkm_object *object, bool suspend) 1202 { 1203 struct nv50_disp_priv *priv = (void *)object->engine; 1204 struct nv50_disp_base *base = (void *)object; 1205 1206 /* disable all interrupts */ 1207 nv_wr32(priv, 0x610024, 0x00000000); 1208 nv_wr32(priv, 0x610020, 0x00000000); 1209 1210 return nvkm_parent_fini(&base->base, suspend); 1211 } 1212 1213 struct nvkm_ofuncs 1214 nv50_disp_main_ofuncs = { 1215 .ctor = nv50_disp_main_ctor, 1216 .dtor = nv50_disp_main_dtor, 1217 .init = nv50_disp_main_init, 1218 .fini = nv50_disp_main_fini, 1219 .mthd = nv50_disp_main_mthd, 1220 .ntfy = nvkm_disp_ntfy, 1221 }; 1222 1223 static struct nvkm_oclass 1224 nv50_disp_main_oclass[] = { 1225 { NV50_DISP, &nv50_disp_main_ofuncs }, 1226 {} 1227 }; 1228 1229 static struct nvkm_oclass 1230 nv50_disp_sclass[] = { 1231 { NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base }, 1232 { NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base }, 1233 { NV50_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 1234 { NV50_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 1235 { NV50_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 1236 {} 1237 }; 1238 1239 /******************************************************************************* 1240 * Display context, tracks instmem allocation and prevents more than one 1241 * client using the display hardware at any time. 1242 ******************************************************************************/ 1243 1244 static int 1245 nv50_disp_data_ctor(struct nvkm_object *parent, 1246 struct nvkm_object *engine, 1247 struct nvkm_oclass *oclass, void *data, u32 size, 1248 struct nvkm_object **pobject) 1249 { 1250 struct nv50_disp_priv *priv = (void *)engine; 1251 struct nvkm_engctx *ectx; 1252 int ret = -EBUSY; 1253 1254 /* no context needed for channel objects... */ 1255 if (nv_mclass(parent) != NV_DEVICE) { 1256 atomic_inc(&parent->refcount); 1257 *pobject = parent; 1258 return 1; 1259 } 1260 1261 /* allocate display hardware to client */ 1262 mutex_lock(&nv_subdev(priv)->mutex); 1263 if (list_empty(&nv_engine(priv)->contexts)) { 1264 ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0x10000, 1265 0x10000, NVOBJ_FLAG_HEAP, &ectx); 1266 *pobject = nv_object(ectx); 1267 } 1268 mutex_unlock(&nv_subdev(priv)->mutex); 1269 return ret; 1270 } 1271 1272 struct nvkm_oclass 1273 nv50_disp_cclass = { 1274 .handle = NV_ENGCTX(DISP, 0x50), 1275 .ofuncs = &(struct nvkm_ofuncs) { 1276 .ctor = nv50_disp_data_ctor, 1277 .dtor = _nvkm_engctx_dtor, 1278 .init = _nvkm_engctx_init, 1279 .fini = _nvkm_engctx_fini, 1280 .rd32 = _nvkm_engctx_rd32, 1281 .wr32 = _nvkm_engctx_wr32, 1282 }, 1283 }; 1284 1285 /******************************************************************************* 1286 * Display engine implementation 1287 ******************************************************************************/ 1288 1289 static void 1290 nv50_disp_vblank_fini(struct nvkm_event *event, int type, int head) 1291 { 1292 struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank); 1293 nv_mask(disp, 0x61002c, (4 << head), 0); 1294 } 1295 1296 static void 1297 nv50_disp_vblank_init(struct nvkm_event *event, int type, int head) 1298 { 1299 struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank); 1300 nv_mask(disp, 0x61002c, (4 << head), (4 << head)); 1301 } 1302 1303 const struct nvkm_event_func 1304 nv50_disp_vblank_func = { 1305 .ctor = nvkm_disp_vblank_ctor, 1306 .init = nv50_disp_vblank_init, 1307 .fini = nv50_disp_vblank_fini, 1308 }; 1309 1310 static const struct nvkm_enum 1311 nv50_disp_intr_error_type[] = { 1312 { 3, "ILLEGAL_MTHD" }, 1313 { 4, "INVALID_VALUE" }, 1314 { 5, "INVALID_STATE" }, 1315 { 7, "INVALID_HANDLE" }, 1316 {} 1317 }; 1318 1319 static const struct nvkm_enum 1320 nv50_disp_intr_error_code[] = { 1321 { 0x00, "" }, 1322 {} 1323 }; 1324 1325 static void 1326 nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid) 1327 { 1328 struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; 1329 u32 data = nv_rd32(priv, 0x610084 + (chid * 0x08)); 1330 u32 addr = nv_rd32(priv, 0x610080 + (chid * 0x08)); 1331 u32 code = (addr & 0x00ff0000) >> 16; 1332 u32 type = (addr & 0x00007000) >> 12; 1333 u32 mthd = (addr & 0x00000ffc); 1334 const struct nvkm_enum *ec, *et; 1335 char ecunk[6], etunk[6]; 1336 1337 et = nvkm_enum_find(nv50_disp_intr_error_type, type); 1338 if (!et) 1339 snprintf(etunk, sizeof(etunk), "UNK%02X", type); 1340 1341 ec = nvkm_enum_find(nv50_disp_intr_error_code, code); 1342 if (!ec) 1343 snprintf(ecunk, sizeof(ecunk), "UNK%02X", code); 1344 1345 nv_error(priv, "%s [%s] chid %d mthd 0x%04x data 0x%08x\n", 1346 et ? et->name : etunk, ec ? ec->name : ecunk, 1347 chid, mthd, data); 1348 1349 if (chid == 0) { 1350 switch (mthd) { 1351 case 0x0080: 1352 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0, 1353 impl->mthd.core); 1354 break; 1355 default: 1356 break; 1357 } 1358 } else 1359 if (chid <= 2) { 1360 switch (mthd) { 1361 case 0x0080: 1362 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1, 1363 impl->mthd.base); 1364 break; 1365 default: 1366 break; 1367 } 1368 } else 1369 if (chid <= 4) { 1370 switch (mthd) { 1371 case 0x0080: 1372 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 3, 1373 impl->mthd.ovly); 1374 break; 1375 default: 1376 break; 1377 } 1378 } 1379 1380 nv_wr32(priv, 0x610020, 0x00010000 << chid); 1381 nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000); 1382 } 1383 1384 static struct nvkm_output * 1385 exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl, 1386 u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, 1387 struct nvbios_outp *info) 1388 { 1389 struct nvkm_bios *bios = nvkm_bios(priv); 1390 struct nvkm_output *outp; 1391 u16 mask, type; 1392 1393 if (or < 4) { 1394 type = DCB_OUTPUT_ANALOG; 1395 mask = 0; 1396 } else 1397 if (or < 8) { 1398 switch (ctrl & 0x00000f00) { 1399 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; 1400 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; 1401 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break; 1402 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break; 1403 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break; 1404 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; 1405 default: 1406 nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); 1407 return NULL; 1408 } 1409 or -= 4; 1410 } else { 1411 or = or - 8; 1412 type = 0x0010; 1413 mask = 0; 1414 switch (ctrl & 0x00000f00) { 1415 case 0x00000000: type |= priv->pior.type[or]; break; 1416 default: 1417 nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl); 1418 return NULL; 1419 } 1420 } 1421 1422 mask = 0x00c0 & (mask << 6); 1423 mask |= 0x0001 << or; 1424 mask |= 0x0100 << head; 1425 1426 list_for_each_entry(outp, &priv->base.outp, head) { 1427 if ((outp->info.hasht & 0xff) == type && 1428 (outp->info.hashm & mask) == mask) { 1429 *data = nvbios_outp_match(bios, outp->info.hasht, 1430 outp->info.hashm, 1431 ver, hdr, cnt, len, info); 1432 if (!*data) 1433 return NULL; 1434 return outp; 1435 } 1436 } 1437 1438 return NULL; 1439 } 1440 1441 static struct nvkm_output * 1442 exec_script(struct nv50_disp_priv *priv, int head, int id) 1443 { 1444 struct nvkm_bios *bios = nvkm_bios(priv); 1445 struct nvkm_output *outp; 1446 struct nvbios_outp info; 1447 u8 ver, hdr, cnt, len; 1448 u32 data, ctrl = 0; 1449 u32 reg; 1450 int i; 1451 1452 /* DAC */ 1453 for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++) 1454 ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); 1455 1456 /* SOR */ 1457 if (!(ctrl & (1 << head))) { 1458 if (nv_device(priv)->chipset < 0x90 || 1459 nv_device(priv)->chipset == 0x92 || 1460 nv_device(priv)->chipset == 0xa0) { 1461 reg = 0x610b74; 1462 } else { 1463 reg = 0x610798; 1464 } 1465 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++) 1466 ctrl = nv_rd32(priv, reg + (i * 8)); 1467 i += 4; 1468 } 1469 1470 /* PIOR */ 1471 if (!(ctrl & (1 << head))) { 1472 for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++) 1473 ctrl = nv_rd32(priv, 0x610b84 + (i * 8)); 1474 i += 8; 1475 } 1476 1477 if (!(ctrl & (1 << head))) 1478 return NULL; 1479 i--; 1480 1481 outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info); 1482 if (outp) { 1483 struct nvbios_init init = { 1484 .subdev = nv_subdev(priv), 1485 .bios = bios, 1486 .offset = info.script[id], 1487 .outp = &outp->info, 1488 .crtc = head, 1489 .execute = 1, 1490 }; 1491 1492 nvbios_exec(&init); 1493 } 1494 1495 return outp; 1496 } 1497 1498 static struct nvkm_output * 1499 exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf) 1500 { 1501 struct nvkm_bios *bios = nvkm_bios(priv); 1502 struct nvkm_output *outp; 1503 struct nvbios_outp info1; 1504 struct nvbios_ocfg info2; 1505 u8 ver, hdr, cnt, len; 1506 u32 data, ctrl = 0; 1507 u32 reg; 1508 int i; 1509 1510 /* DAC */ 1511 for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++) 1512 ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); 1513 1514 /* SOR */ 1515 if (!(ctrl & (1 << head))) { 1516 if (nv_device(priv)->chipset < 0x90 || 1517 nv_device(priv)->chipset == 0x92 || 1518 nv_device(priv)->chipset == 0xa0) { 1519 reg = 0x610b70; 1520 } else { 1521 reg = 0x610794; 1522 } 1523 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++) 1524 ctrl = nv_rd32(priv, reg + (i * 8)); 1525 i += 4; 1526 } 1527 1528 /* PIOR */ 1529 if (!(ctrl & (1 << head))) { 1530 for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++) 1531 ctrl = nv_rd32(priv, 0x610b80 + (i * 8)); 1532 i += 8; 1533 } 1534 1535 if (!(ctrl & (1 << head))) 1536 return NULL; 1537 i--; 1538 1539 outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1); 1540 if (!outp) 1541 return NULL; 1542 1543 if (outp->info.location == 0) { 1544 switch (outp->info.type) { 1545 case DCB_OUTPUT_TMDS: 1546 *conf = (ctrl & 0x00000f00) >> 8; 1547 if (pclk >= 165000) 1548 *conf |= 0x0100; 1549 break; 1550 case DCB_OUTPUT_LVDS: 1551 *conf = priv->sor.lvdsconf; 1552 break; 1553 case DCB_OUTPUT_DP: 1554 *conf = (ctrl & 0x00000f00) >> 8; 1555 break; 1556 case DCB_OUTPUT_ANALOG: 1557 default: 1558 *conf = 0x00ff; 1559 break; 1560 } 1561 } else { 1562 *conf = (ctrl & 0x00000f00) >> 8; 1563 pclk = pclk / 2; 1564 } 1565 1566 data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); 1567 if (data && id < 0xff) { 1568 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); 1569 if (data) { 1570 struct nvbios_init init = { 1571 .subdev = nv_subdev(priv), 1572 .bios = bios, 1573 .offset = data, 1574 .outp = &outp->info, 1575 .crtc = head, 1576 .execute = 1, 1577 }; 1578 1579 nvbios_exec(&init); 1580 } 1581 } 1582 1583 return outp; 1584 } 1585 1586 static void 1587 nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head) 1588 { 1589 exec_script(priv, head, 1); 1590 } 1591 1592 static void 1593 nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head) 1594 { 1595 struct nvkm_output *outp = exec_script(priv, head, 2); 1596 1597 /* the binary driver does this outside of the supervisor handling 1598 * (after the third supervisor from a detach). we (currently?) 1599 * allow both detach/attach to happen in the same set of 1600 * supervisor interrupts, so it would make sense to execute this 1601 * (full power down?) script after all the detach phases of the 1602 * supervisor handling. like with training if needed from the 1603 * second supervisor, nvidia doesn't do this, so who knows if it's 1604 * entirely safe, but it does appear to work.. 1605 * 1606 * without this script being run, on some configurations i've 1607 * seen, switching from DP to TMDS on a DP connector may result 1608 * in a blank screen (SOR_PWR off/on can restore it) 1609 */ 1610 if (outp && outp->info.type == DCB_OUTPUT_DP) { 1611 struct nvkm_output_dp *outpdp = (void *)outp; 1612 struct nvbios_init init = { 1613 .subdev = nv_subdev(priv), 1614 .bios = nvkm_bios(priv), 1615 .outp = &outp->info, 1616 .crtc = head, 1617 .offset = outpdp->info.script[4], 1618 .execute = 1, 1619 }; 1620 1621 nvbios_exec(&init); 1622 atomic_set(&outpdp->lt.done, 0); 1623 } 1624 } 1625 1626 static void 1627 nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head) 1628 { 1629 struct nvkm_devinit *devinit = nvkm_devinit(priv); 1630 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1631 if (pclk) 1632 devinit->pll_set(devinit, PLL_VPLL0 + head, pclk); 1633 } 1634 1635 static void 1636 nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, int head, 1637 struct dcb_output *outp, u32 pclk) 1638 { 1639 const int link = !(outp->sorconf.link & 1); 1640 const int or = ffs(outp->or) - 1; 1641 const u32 soff = ( or * 0x800); 1642 const u32 loff = (link * 0x080) + soff; 1643 const u32 ctrl = nv_rd32(priv, 0x610794 + (or * 8)); 1644 const u32 symbol = 100000; 1645 const s32 vactive = nv_rd32(priv, 0x610af8 + (head * 0x540)) & 0xffff; 1646 const s32 vblanke = nv_rd32(priv, 0x610ae8 + (head * 0x540)) & 0xffff; 1647 const s32 vblanks = nv_rd32(priv, 0x610af0 + (head * 0x540)) & 0xffff; 1648 u32 dpctrl = nv_rd32(priv, 0x61c10c + loff); 1649 u32 clksor = nv_rd32(priv, 0x614300 + soff); 1650 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0; 1651 int TU, VTUi, VTUf, VTUa; 1652 u64 link_data_rate, link_ratio, unk; 1653 u32 best_diff = 64 * symbol; 1654 u32 link_nr, link_bw, bits; 1655 u64 value; 1656 1657 link_bw = (clksor & 0x000c0000) ? 270000 : 162000; 1658 link_nr = hweight32(dpctrl & 0x000f0000); 1659 1660 /* symbols/hblank - algorithm taken from comments in tegra driver */ 1661 value = vblanke + vactive - vblanks - 7; 1662 value = value * link_bw; 1663 do_div(value, pclk); 1664 value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr); 1665 nv_mask(priv, 0x61c1e8 + soff, 0x0000ffff, value); 1666 1667 /* symbols/vblank - algorithm taken from comments in tegra driver */ 1668 value = vblanks - vblanke - 25; 1669 value = value * link_bw; 1670 do_div(value, pclk); 1671 value = value - ((36 / link_nr) + 3) - 1; 1672 nv_mask(priv, 0x61c1ec + soff, 0x00ffffff, value); 1673 1674 /* watermark / activesym */ 1675 if ((ctrl & 0xf0000) == 0x60000) bits = 30; 1676 else if ((ctrl & 0xf0000) == 0x50000) bits = 24; 1677 else bits = 18; 1678 1679 link_data_rate = (pclk * bits / 8) / link_nr; 1680 1681 /* calculate ratio of packed data rate to link symbol rate */ 1682 link_ratio = link_data_rate * symbol; 1683 do_div(link_ratio, link_bw); 1684 1685 for (TU = 64; TU >= 32; TU--) { 1686 /* calculate average number of valid symbols in each TU */ 1687 u32 tu_valid = link_ratio * TU; 1688 u32 calc, diff; 1689 1690 /* find a hw representation for the fraction.. */ 1691 VTUi = tu_valid / symbol; 1692 calc = VTUi * symbol; 1693 diff = tu_valid - calc; 1694 if (diff) { 1695 if (diff >= (symbol / 2)) { 1696 VTUf = symbol / (symbol - diff); 1697 if (symbol - (VTUf * diff)) 1698 VTUf++; 1699 1700 if (VTUf <= 15) { 1701 VTUa = 1; 1702 calc += symbol - (symbol / VTUf); 1703 } else { 1704 VTUa = 0; 1705 VTUf = 1; 1706 calc += symbol; 1707 } 1708 } else { 1709 VTUa = 0; 1710 VTUf = min((int)(symbol / diff), 15); 1711 calc += symbol / VTUf; 1712 } 1713 1714 diff = calc - tu_valid; 1715 } else { 1716 /* no remainder, but the hw doesn't like the fractional 1717 * part to be zero. decrement the integer part and 1718 * have the fraction add a whole symbol back 1719 */ 1720 VTUa = 0; 1721 VTUf = 1; 1722 VTUi--; 1723 } 1724 1725 if (diff < best_diff) { 1726 best_diff = diff; 1727 bestTU = TU; 1728 bestVTUa = VTUa; 1729 bestVTUf = VTUf; 1730 bestVTUi = VTUi; 1731 if (diff == 0) 1732 break; 1733 } 1734 } 1735 1736 if (!bestTU) { 1737 nv_error(priv, "unable to find suitable dp config\n"); 1738 return; 1739 } 1740 1741 /* XXX close to vbios numbers, but not right */ 1742 unk = (symbol - link_ratio) * bestTU; 1743 unk *= link_ratio; 1744 do_div(unk, symbol); 1745 do_div(unk, symbol); 1746 unk += 6; 1747 1748 nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2); 1749 nv_mask(priv, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 | 1750 bestVTUf << 16 | 1751 bestVTUi << 8 | unk); 1752 } 1753 1754 static void 1755 nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) 1756 { 1757 struct nvkm_output *outp; 1758 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1759 u32 hval, hreg = 0x614200 + (head * 0x800); 1760 u32 oval, oreg; 1761 u32 mask, conf; 1762 1763 outp = exec_clkcmp(priv, head, 0xff, pclk, &conf); 1764 if (!outp) 1765 return; 1766 1767 /* we allow both encoder attach and detach operations to occur 1768 * within a single supervisor (ie. modeset) sequence. the 1769 * encoder detach scripts quite often switch off power to the 1770 * lanes, which requires the link to be re-trained. 1771 * 1772 * this is not generally an issue as the sink "must" (heh) 1773 * signal an irq when it's lost sync so the driver can 1774 * re-train. 1775 * 1776 * however, on some boards, if one does not configure at least 1777 * the gpu side of the link *before* attaching, then various 1778 * things can go horribly wrong (PDISP disappearing from mmio, 1779 * third supervisor never happens, etc). 1780 * 1781 * the solution is simply to retrain here, if necessary. last 1782 * i checked, the binary driver userspace does not appear to 1783 * trigger this situation (it forces an UPDATE between steps). 1784 */ 1785 if (outp->info.type == DCB_OUTPUT_DP) { 1786 u32 soff = (ffs(outp->info.or) - 1) * 0x08; 1787 u32 ctrl, datarate; 1788 1789 if (outp->info.location == 0) { 1790 ctrl = nv_rd32(priv, 0x610794 + soff); 1791 soff = 1; 1792 } else { 1793 ctrl = nv_rd32(priv, 0x610b80 + soff); 1794 soff = 2; 1795 } 1796 1797 switch ((ctrl & 0x000f0000) >> 16) { 1798 case 6: datarate = pclk * 30; break; 1799 case 5: datarate = pclk * 24; break; 1800 case 2: 1801 default: 1802 datarate = pclk * 18; 1803 break; 1804 } 1805 1806 if (nvkm_output_dp_train(outp, datarate / soff, true)) 1807 ERR("link not trained before attach\n"); 1808 } 1809 1810 exec_clkcmp(priv, head, 0, pclk, &conf); 1811 1812 if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) { 1813 oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800; 1814 oval = 0x00000000; 1815 hval = 0x00000000; 1816 mask = 0xffffffff; 1817 } else 1818 if (!outp->info.location) { 1819 if (outp->info.type == DCB_OUTPUT_DP) 1820 nv50_disp_intr_unk20_2_dp(priv, head, &outp->info, pclk); 1821 oreg = 0x614300 + (ffs(outp->info.or) - 1) * 0x800; 1822 oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; 1823 hval = 0x00000000; 1824 mask = 0x00000707; 1825 } else { 1826 oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800; 1827 oval = 0x00000001; 1828 hval = 0x00000001; 1829 mask = 0x00000707; 1830 } 1831 1832 nv_mask(priv, hreg, 0x0000000f, hval); 1833 nv_mask(priv, oreg, mask, oval); 1834 } 1835 1836 /* If programming a TMDS output on a SOR that can also be configured for 1837 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. 1838 * 1839 * It looks like the VBIOS TMDS scripts make an attempt at this, however, 1840 * the VBIOS scripts on at least one board I have only switch it off on 1841 * link 0, causing a blank display if the output has previously been 1842 * programmed for DisplayPort. 1843 */ 1844 static void 1845 nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, 1846 struct dcb_output *outp) 1847 { 1848 struct nvkm_bios *bios = nvkm_bios(priv); 1849 const int link = !(outp->sorconf.link & 1); 1850 const int or = ffs(outp->or) - 1; 1851 const u32 loff = (or * 0x800) + (link * 0x80); 1852 const u16 mask = (outp->sorconf.link << 6) | outp->or; 1853 struct dcb_output match; 1854 u8 ver, hdr; 1855 1856 if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, &match)) 1857 nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000); 1858 } 1859 1860 static void 1861 nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head) 1862 { 1863 struct nvkm_output *outp; 1864 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1865 u32 conf; 1866 1867 outp = exec_clkcmp(priv, head, 1, pclk, &conf); 1868 if (!outp) 1869 return; 1870 1871 if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS) 1872 nv50_disp_intr_unk40_0_tmds(priv, &outp->info); 1873 } 1874 1875 void 1876 nv50_disp_intr_supervisor(struct work_struct *work) 1877 { 1878 struct nv50_disp_priv *priv = 1879 container_of(work, struct nv50_disp_priv, supervisor); 1880 struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; 1881 u32 super = nv_rd32(priv, 0x610030); 1882 int head; 1883 1884 nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super); 1885 1886 if (priv->super & 0x00000010) { 1887 nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core); 1888 for (head = 0; head < priv->head.nr; head++) { 1889 if (!(super & (0x00000020 << head))) 1890 continue; 1891 if (!(super & (0x00000080 << head))) 1892 continue; 1893 nv50_disp_intr_unk10_0(priv, head); 1894 } 1895 } else 1896 if (priv->super & 0x00000020) { 1897 for (head = 0; head < priv->head.nr; head++) { 1898 if (!(super & (0x00000080 << head))) 1899 continue; 1900 nv50_disp_intr_unk20_0(priv, head); 1901 } 1902 for (head = 0; head < priv->head.nr; head++) { 1903 if (!(super & (0x00000200 << head))) 1904 continue; 1905 nv50_disp_intr_unk20_1(priv, head); 1906 } 1907 for (head = 0; head < priv->head.nr; head++) { 1908 if (!(super & (0x00000080 << head))) 1909 continue; 1910 nv50_disp_intr_unk20_2(priv, head); 1911 } 1912 } else 1913 if (priv->super & 0x00000040) { 1914 for (head = 0; head < priv->head.nr; head++) { 1915 if (!(super & (0x00000080 << head))) 1916 continue; 1917 nv50_disp_intr_unk40_0(priv, head); 1918 } 1919 } 1920 1921 nv_wr32(priv, 0x610030, 0x80000000); 1922 } 1923 1924 void 1925 nv50_disp_intr(struct nvkm_subdev *subdev) 1926 { 1927 struct nv50_disp_priv *priv = (void *)subdev; 1928 u32 intr0 = nv_rd32(priv, 0x610020); 1929 u32 intr1 = nv_rd32(priv, 0x610024); 1930 1931 while (intr0 & 0x001f0000) { 1932 u32 chid = __ffs(intr0 & 0x001f0000) - 16; 1933 nv50_disp_intr_error(priv, chid); 1934 intr0 &= ~(0x00010000 << chid); 1935 } 1936 1937 while (intr0 & 0x0000001f) { 1938 u32 chid = __ffs(intr0 & 0x0000001f); 1939 nv50_disp_chan_uevent_send(priv, chid); 1940 intr0 &= ~(0x00000001 << chid); 1941 } 1942 1943 if (intr1 & 0x00000004) { 1944 nvkm_disp_vblank(&priv->base, 0); 1945 nv_wr32(priv, 0x610024, 0x00000004); 1946 intr1 &= ~0x00000004; 1947 } 1948 1949 if (intr1 & 0x00000008) { 1950 nvkm_disp_vblank(&priv->base, 1); 1951 nv_wr32(priv, 0x610024, 0x00000008); 1952 intr1 &= ~0x00000008; 1953 } 1954 1955 if (intr1 & 0x00000070) { 1956 priv->super = (intr1 & 0x00000070); 1957 schedule_work(&priv->supervisor); 1958 nv_wr32(priv, 0x610024, priv->super); 1959 intr1 &= ~0x00000070; 1960 } 1961 } 1962 1963 static int 1964 nv50_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 1965 struct nvkm_oclass *oclass, void *data, u32 size, 1966 struct nvkm_object **pobject) 1967 { 1968 struct nv50_disp_priv *priv; 1969 int ret; 1970 1971 ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP", 1972 "display", &priv); 1973 *pobject = nv_object(priv); 1974 if (ret) 1975 return ret; 1976 1977 ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent); 1978 if (ret) 1979 return ret; 1980 1981 nv_engine(priv)->sclass = nv50_disp_main_oclass; 1982 nv_engine(priv)->cclass = &nv50_disp_cclass; 1983 nv_subdev(priv)->intr = nv50_disp_intr; 1984 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 1985 priv->sclass = nv50_disp_sclass; 1986 priv->head.nr = 2; 1987 priv->dac.nr = 3; 1988 priv->sor.nr = 2; 1989 priv->pior.nr = 3; 1990 priv->dac.power = nv50_dac_power; 1991 priv->dac.sense = nv50_dac_sense; 1992 priv->sor.power = nv50_sor_power; 1993 priv->pior.power = nv50_pior_power; 1994 return 0; 1995 } 1996 1997 struct nvkm_oclass * 1998 nv50_disp_outp_sclass[] = { 1999 &nv50_pior_dp_impl.base.base, 2000 NULL 2001 }; 2002 2003 struct nvkm_oclass * 2004 nv50_disp_oclass = &(struct nv50_disp_impl) { 2005 .base.base.handle = NV_ENGINE(DISP, 0x50), 2006 .base.base.ofuncs = &(struct nvkm_ofuncs) { 2007 .ctor = nv50_disp_ctor, 2008 .dtor = _nvkm_disp_dtor, 2009 .init = _nvkm_disp_init, 2010 .fini = _nvkm_disp_fini, 2011 }, 2012 .base.vblank = &nv50_disp_vblank_func, 2013 .base.outp = nv50_disp_outp_sclass, 2014 .mthd.core = &nv50_disp_core_mthd_chan, 2015 .mthd.base = &nv50_disp_base_mthd_chan, 2016 .mthd.ovly = &nv50_disp_ovly_mthd_chan, 2017 .mthd.prev = 0x000004, 2018 .head.scanoutpos = nv50_disp_main_scanoutpos, 2019 }.base.base; 2020