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