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 52static int 53nv50_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 81static void 82nv50_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 89static void 90nv50_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 97static void 98nv50_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 105void 106nv50_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 114int 115nv50_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 134const struct nvkm_event_func 135nv50_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 141int 142nv50_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 156int 157nv50_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 166u32 167nv50_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 174void 175nv50_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 186static int 187nv50_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 198static void 199nv50_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 205static int 206nv50_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 = 0x00000001 | 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 248void 249nv50_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 256static int 257nv50_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 289static int 290nv50_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 316static void 317nv50_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 343void 344nv50_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 381const struct nv50_disp_mthd_list 382nv50_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 394static const struct nv50_disp_mthd_list 395nv50_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 406const struct nv50_disp_mthd_list 407nv50_disp_core_mthd_sor = { 408 .mthd = 0x0040, 409 .addr = 0x000008, 410 .data = { 411 { 0x0600, 0x610b70 }, 412 {} 413 } 414}; 415 416const struct nv50_disp_mthd_list 417nv50_disp_core_mthd_pior = { 418 .mthd = 0x0040, 419 .addr = 0x000008, 420 .data = { 421 { 0x0700, 0x610b80 }, 422 {} 423 } 424}; 425 426static const struct nv50_disp_mthd_list 427nv50_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 473static const struct nv50_disp_mthd_chan 474nv50_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 487int 488nv50_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 516static int 517nv50_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 553static int 554nv50_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 574struct nv50_disp_chan_impl 575nv50_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 593static const struct nv50_disp_mthd_list 594nv50_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 618const struct nv50_disp_mthd_list 619nv50_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 632static const struct nv50_disp_mthd_chan 633nv50_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 643int 644nv50_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 676struct nv50_disp_chan_impl 677nv50_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 695const struct nv50_disp_mthd_list 696nv50_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 723static const struct nv50_disp_mthd_chan 724nv50_disp_ovly_mthd_chan = { 725 .name = "Overlay", 726 .addr = 0x000540, 727 .data = { 728 { "Global", 1, &nv50_disp_ovly_mthd_base }, 729 {} 730 } 731}; 732 733int 734nv50_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 766struct nv50_disp_chan_impl 767nv50_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 785static int 786nv50_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 795void 796nv50_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 802static int 803nv50_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 831static int 832nv50_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 853int 854nv50_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 884struct nv50_disp_chan_impl 885nv50_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 901int 902nv50_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 932struct nv50_disp_chan_impl 933nv50_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 949int 950nv50_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 981int 982nv50_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 1104int 1105nv50_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 1124void 1125nv50_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 1132static int 1133nv50_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 1200static int 1201nv50_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 1213struct nvkm_ofuncs 1214nv50_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 1223static struct nvkm_oclass 1224nv50_disp_main_oclass[] = { 1225 { NV50_DISP, &nv50_disp_main_ofuncs }, 1226 {} 1227}; 1228 1229static struct nvkm_oclass 1230nv50_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 1244static int 1245nv50_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 1272struct nvkm_oclass 1273nv50_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 1289static void 1290nv50_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 1296static void 1297nv50_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 1303const struct nvkm_event_func 1304nv50_disp_vblank_func = { 1305 .ctor = nvkm_disp_vblank_ctor, 1306 .init = nv50_disp_vblank_init, 1307 .fini = nv50_disp_vblank_fini, 1308}; 1309 1310static const struct nvkm_enum 1311nv50_disp_intr_error_type[] = { 1312 { 3, "ILLEGAL_MTHD" }, 1313 { 4, "INVALID_VALUE" }, 1314 { 5, "INVALID_STATE" }, 1315 { 7, "INVALID_HANDLE" }, 1316 {} 1317}; 1318 1319static const struct nvkm_enum 1320nv50_disp_intr_error_code[] = { 1321 { 0x00, "" }, 1322 {} 1323}; 1324 1325static void 1326nv50_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 1384static struct nvkm_output * 1385exec_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 1441static struct nvkm_output * 1442exec_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 1498static struct nvkm_output * 1499exec_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 1586static void 1587nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head) 1588{ 1589 exec_script(priv, head, 1); 1590} 1591 1592static void 1593nv50_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 1626static void 1627nv50_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 1635static void 1636nv50_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 1754static void 1755nv50_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 */ 1844static void 1845nv50_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 1860static void 1861nv50_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 1875void 1876nv50_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 1924void 1925nv50_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 1963static int 1964nv50_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 1997struct nvkm_oclass * 1998nv50_disp_outp_sclass[] = { 1999 &nv50_pior_dp_impl.base.base, 2000 NULL 2001}; 2002 2003struct nvkm_oclass * 2004nv50_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