nv50.c revision 5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96
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 30#include <engine/disp.h> 31 32#include <subdev/bios.h> 33#include <subdev/bios/dcb.h> 34#include <subdev/bios/disp.h> 35#include <subdev/bios/init.h> 36#include <subdev/bios/pll.h> 37#include <subdev/timer.h> 38#include <subdev/fb.h> 39#include <subdev/clock.h> 40 41#include "nv50.h" 42 43/******************************************************************************* 44 * EVO channel base class 45 ******************************************************************************/ 46 47int 48nv50_disp_chan_create_(struct nouveau_object *parent, 49 struct nouveau_object *engine, 50 struct nouveau_oclass *oclass, int chid, 51 int length, void **pobject) 52{ 53 struct nv50_disp_base *base = (void *)parent; 54 struct nv50_disp_chan *chan; 55 int ret; 56 57 if (base->chan & (1 << chid)) 58 return -EBUSY; 59 base->chan |= (1 << chid); 60 61 ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL, 62 (1ULL << NVDEV_ENGINE_DMAOBJ), 63 length, pobject); 64 chan = *pobject; 65 if (ret) 66 return ret; 67 68 chan->chid = chid; 69 return 0; 70} 71 72void 73nv50_disp_chan_destroy(struct nv50_disp_chan *chan) 74{ 75 struct nv50_disp_base *base = (void *)nv_object(chan)->parent; 76 base->chan &= ~(1 << chan->chid); 77 nouveau_namedb_destroy(&chan->base); 78} 79 80u32 81nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr) 82{ 83 struct nv50_disp_priv *priv = (void *)object->engine; 84 struct nv50_disp_chan *chan = (void *)object; 85 return nv_rd32(priv, 0x640000 + (chan->chid * 0x1000) + addr); 86} 87 88void 89nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data) 90{ 91 struct nv50_disp_priv *priv = (void *)object->engine; 92 struct nv50_disp_chan *chan = (void *)object; 93 nv_wr32(priv, 0x640000 + (chan->chid * 0x1000) + addr, data); 94} 95 96/******************************************************************************* 97 * EVO DMA channel base class 98 ******************************************************************************/ 99 100static int 101nv50_disp_dmac_object_attach(struct nouveau_object *parent, 102 struct nouveau_object *object, u32 name) 103{ 104 struct nv50_disp_base *base = (void *)parent->parent; 105 struct nv50_disp_chan *chan = (void *)parent; 106 u32 addr = nv_gpuobj(object)->node->offset; 107 u32 chid = chan->chid; 108 u32 data = (chid << 28) | (addr << 10) | chid; 109 return nouveau_ramht_insert(base->ramht, chid, name, data); 110} 111 112static void 113nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie) 114{ 115 struct nv50_disp_base *base = (void *)parent->parent; 116 nouveau_ramht_remove(base->ramht, cookie); 117} 118 119int 120nv50_disp_dmac_create_(struct nouveau_object *parent, 121 struct nouveau_object *engine, 122 struct nouveau_oclass *oclass, u32 pushbuf, int chid, 123 int length, void **pobject) 124{ 125 struct nv50_disp_dmac *dmac; 126 int ret; 127 128 ret = nv50_disp_chan_create_(parent, engine, oclass, chid, 129 length, pobject); 130 dmac = *pobject; 131 if (ret) 132 return ret; 133 134 dmac->pushdma = (void *)nouveau_handle_ref(parent, pushbuf); 135 if (!dmac->pushdma) 136 return -ENOENT; 137 138 switch (nv_mclass(dmac->pushdma)) { 139 case 0x0002: 140 case 0x003d: 141 if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff) 142 return -EINVAL; 143 144 switch (dmac->pushdma->target) { 145 case NV_MEM_TARGET_VRAM: 146 dmac->push = 0x00000000 | dmac->pushdma->start >> 8; 147 break; 148 case NV_MEM_TARGET_PCI_NOSNOOP: 149 dmac->push = 0x00000003 | dmac->pushdma->start >> 8; 150 break; 151 default: 152 return -EINVAL; 153 } 154 break; 155 default: 156 return -EINVAL; 157 } 158 159 return 0; 160} 161 162void 163nv50_disp_dmac_dtor(struct nouveau_object *object) 164{ 165 struct nv50_disp_dmac *dmac = (void *)object; 166 nouveau_object_ref(NULL, (struct nouveau_object **)&dmac->pushdma); 167 nv50_disp_chan_destroy(&dmac->base); 168} 169 170static int 171nv50_disp_dmac_init(struct nouveau_object *object) 172{ 173 struct nv50_disp_priv *priv = (void *)object->engine; 174 struct nv50_disp_dmac *dmac = (void *)object; 175 int chid = dmac->base.chid; 176 int ret; 177 178 ret = nv50_disp_chan_init(&dmac->base); 179 if (ret) 180 return ret; 181 182 /* enable error reporting */ 183 nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00010001 << chid); 184 185 /* initialise channel for dma command submission */ 186 nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push); 187 nv_wr32(priv, 0x610208 + (chid * 0x0010), 0x00010000); 188 nv_wr32(priv, 0x61020c + (chid * 0x0010), chid); 189 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010); 190 nv_wr32(priv, 0x640000 + (chid * 0x1000), 0x00000000); 191 nv_wr32(priv, 0x610200 + (chid * 0x0010), 0x00000013); 192 193 /* wait for it to go inactive */ 194 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x80000000, 0x00000000)) { 195 nv_error(dmac, "init timeout, 0x%08x\n", 196 nv_rd32(priv, 0x610200 + (chid * 0x10))); 197 return -EBUSY; 198 } 199 200 return 0; 201} 202 203static int 204nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend) 205{ 206 struct nv50_disp_priv *priv = (void *)object->engine; 207 struct nv50_disp_dmac *dmac = (void *)object; 208 int chid = dmac->base.chid; 209 210 /* deactivate channel */ 211 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000); 212 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000); 213 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x001e0000, 0x00000000)) { 214 nv_error(dmac, "fini timeout, 0x%08x\n", 215 nv_rd32(priv, 0x610200 + (chid * 0x10))); 216 if (suspend) 217 return -EBUSY; 218 } 219 220 /* disable error reporting */ 221 nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid); 222 223 return nv50_disp_chan_fini(&dmac->base, suspend); 224} 225 226/******************************************************************************* 227 * EVO master channel object 228 ******************************************************************************/ 229 230static int 231nv50_disp_mast_ctor(struct nouveau_object *parent, 232 struct nouveau_object *engine, 233 struct nouveau_oclass *oclass, void *data, u32 size, 234 struct nouveau_object **pobject) 235{ 236 struct nv50_display_mast_class *args = data; 237 struct nv50_disp_dmac *mast; 238 int ret; 239 240 if (size < sizeof(*args)) 241 return -EINVAL; 242 243 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, 244 0, sizeof(*mast), (void **)&mast); 245 *pobject = nv_object(mast); 246 if (ret) 247 return ret; 248 249 nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach; 250 nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach; 251 return 0; 252} 253 254static int 255nv50_disp_mast_init(struct nouveau_object *object) 256{ 257 struct nv50_disp_priv *priv = (void *)object->engine; 258 struct nv50_disp_dmac *mast = (void *)object; 259 int ret; 260 261 ret = nv50_disp_chan_init(&mast->base); 262 if (ret) 263 return ret; 264 265 /* enable error reporting */ 266 nv_mask(priv, 0x610028, 0x00010001, 0x00010001); 267 268 /* attempt to unstick channel from some unknown state */ 269 if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000) 270 nv_mask(priv, 0x610200, 0x00800000, 0x00800000); 271 if ((nv_rd32(priv, 0x610200) & 0x003f0000) == 0x00030000) 272 nv_mask(priv, 0x610200, 0x00600000, 0x00600000); 273 274 /* initialise channel for dma command submission */ 275 nv_wr32(priv, 0x610204, mast->push); 276 nv_wr32(priv, 0x610208, 0x00010000); 277 nv_wr32(priv, 0x61020c, 0x00000000); 278 nv_mask(priv, 0x610200, 0x00000010, 0x00000010); 279 nv_wr32(priv, 0x640000, 0x00000000); 280 nv_wr32(priv, 0x610200, 0x01000013); 281 282 /* wait for it to go inactive */ 283 if (!nv_wait(priv, 0x610200, 0x80000000, 0x00000000)) { 284 nv_error(mast, "init: 0x%08x\n", nv_rd32(priv, 0x610200)); 285 return -EBUSY; 286 } 287 288 return 0; 289} 290 291static int 292nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) 293{ 294 struct nv50_disp_priv *priv = (void *)object->engine; 295 struct nv50_disp_dmac *mast = (void *)object; 296 297 /* deactivate channel */ 298 nv_mask(priv, 0x610200, 0x00000010, 0x00000000); 299 nv_mask(priv, 0x610200, 0x00000003, 0x00000000); 300 if (!nv_wait(priv, 0x610200, 0x001e0000, 0x00000000)) { 301 nv_error(mast, "fini: 0x%08x\n", nv_rd32(priv, 0x610200)); 302 if (suspend) 303 return -EBUSY; 304 } 305 306 /* disable error reporting */ 307 nv_mask(priv, 0x610028, 0x00010001, 0x00000000); 308 309 return nv50_disp_chan_fini(&mast->base, suspend); 310} 311 312struct nouveau_ofuncs 313nv50_disp_mast_ofuncs = { 314 .ctor = nv50_disp_mast_ctor, 315 .dtor = nv50_disp_dmac_dtor, 316 .init = nv50_disp_mast_init, 317 .fini = nv50_disp_mast_fini, 318 .rd32 = nv50_disp_chan_rd32, 319 .wr32 = nv50_disp_chan_wr32, 320}; 321 322/******************************************************************************* 323 * EVO sync channel objects 324 ******************************************************************************/ 325 326static int 327nv50_disp_sync_ctor(struct nouveau_object *parent, 328 struct nouveau_object *engine, 329 struct nouveau_oclass *oclass, void *data, u32 size, 330 struct nouveau_object **pobject) 331{ 332 struct nv50_display_sync_class *args = data; 333 struct nv50_disp_dmac *dmac; 334 int ret; 335 336 if (size < sizeof(*args) || args->head > 1) 337 return -EINVAL; 338 339 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, 340 1 + args->head, sizeof(*dmac), 341 (void **)&dmac); 342 *pobject = nv_object(dmac); 343 if (ret) 344 return ret; 345 346 nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach; 347 nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach; 348 return 0; 349} 350 351struct nouveau_ofuncs 352nv50_disp_sync_ofuncs = { 353 .ctor = nv50_disp_sync_ctor, 354 .dtor = nv50_disp_dmac_dtor, 355 .init = nv50_disp_dmac_init, 356 .fini = nv50_disp_dmac_fini, 357 .rd32 = nv50_disp_chan_rd32, 358 .wr32 = nv50_disp_chan_wr32, 359}; 360 361/******************************************************************************* 362 * EVO overlay channel objects 363 ******************************************************************************/ 364 365static int 366nv50_disp_ovly_ctor(struct nouveau_object *parent, 367 struct nouveau_object *engine, 368 struct nouveau_oclass *oclass, void *data, u32 size, 369 struct nouveau_object **pobject) 370{ 371 struct nv50_display_ovly_class *args = data; 372 struct nv50_disp_dmac *dmac; 373 int ret; 374 375 if (size < sizeof(*args) || args->head > 1) 376 return -EINVAL; 377 378 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, 379 3 + args->head, sizeof(*dmac), 380 (void **)&dmac); 381 *pobject = nv_object(dmac); 382 if (ret) 383 return ret; 384 385 nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach; 386 nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach; 387 return 0; 388} 389 390struct nouveau_ofuncs 391nv50_disp_ovly_ofuncs = { 392 .ctor = nv50_disp_ovly_ctor, 393 .dtor = nv50_disp_dmac_dtor, 394 .init = nv50_disp_dmac_init, 395 .fini = nv50_disp_dmac_fini, 396 .rd32 = nv50_disp_chan_rd32, 397 .wr32 = nv50_disp_chan_wr32, 398}; 399 400/******************************************************************************* 401 * EVO PIO channel base class 402 ******************************************************************************/ 403 404static int 405nv50_disp_pioc_create_(struct nouveau_object *parent, 406 struct nouveau_object *engine, 407 struct nouveau_oclass *oclass, int chid, 408 int length, void **pobject) 409{ 410 return nv50_disp_chan_create_(parent, engine, oclass, chid, 411 length, pobject); 412} 413 414static void 415nv50_disp_pioc_dtor(struct nouveau_object *object) 416{ 417 struct nv50_disp_pioc *pioc = (void *)object; 418 nv50_disp_chan_destroy(&pioc->base); 419} 420 421static int 422nv50_disp_pioc_init(struct nouveau_object *object) 423{ 424 struct nv50_disp_priv *priv = (void *)object->engine; 425 struct nv50_disp_pioc *pioc = (void *)object; 426 int chid = pioc->base.chid; 427 int ret; 428 429 ret = nv50_disp_chan_init(&pioc->base); 430 if (ret) 431 return ret; 432 433 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00002000); 434 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00000000, 0x00000000)) { 435 nv_error(pioc, "timeout0: 0x%08x\n", 436 nv_rd32(priv, 0x610200 + (chid * 0x10))); 437 return -EBUSY; 438 } 439 440 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00000001); 441 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00010000)) { 442 nv_error(pioc, "timeout1: 0x%08x\n", 443 nv_rd32(priv, 0x610200 + (chid * 0x10))); 444 return -EBUSY; 445 } 446 447 return 0; 448} 449 450static int 451nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend) 452{ 453 struct nv50_disp_priv *priv = (void *)object->engine; 454 struct nv50_disp_pioc *pioc = (void *)object; 455 int chid = pioc->base.chid; 456 457 nv_mask(priv, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000); 458 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00000000)) { 459 nv_error(pioc, "timeout: 0x%08x\n", 460 nv_rd32(priv, 0x610200 + (chid * 0x10))); 461 if (suspend) 462 return -EBUSY; 463 } 464 465 return nv50_disp_chan_fini(&pioc->base, suspend); 466} 467 468/******************************************************************************* 469 * EVO immediate overlay channel objects 470 ******************************************************************************/ 471 472static int 473nv50_disp_oimm_ctor(struct nouveau_object *parent, 474 struct nouveau_object *engine, 475 struct nouveau_oclass *oclass, void *data, u32 size, 476 struct nouveau_object **pobject) 477{ 478 struct nv50_display_oimm_class *args = data; 479 struct nv50_disp_pioc *pioc; 480 int ret; 481 482 if (size < sizeof(*args) || args->head > 1) 483 return -EINVAL; 484 485 ret = nv50_disp_pioc_create_(parent, engine, oclass, 5 + args->head, 486 sizeof(*pioc), (void **)&pioc); 487 *pobject = nv_object(pioc); 488 if (ret) 489 return ret; 490 491 return 0; 492} 493 494struct nouveau_ofuncs 495nv50_disp_oimm_ofuncs = { 496 .ctor = nv50_disp_oimm_ctor, 497 .dtor = nv50_disp_pioc_dtor, 498 .init = nv50_disp_pioc_init, 499 .fini = nv50_disp_pioc_fini, 500 .rd32 = nv50_disp_chan_rd32, 501 .wr32 = nv50_disp_chan_wr32, 502}; 503 504/******************************************************************************* 505 * EVO cursor channel objects 506 ******************************************************************************/ 507 508static int 509nv50_disp_curs_ctor(struct nouveau_object *parent, 510 struct nouveau_object *engine, 511 struct nouveau_oclass *oclass, void *data, u32 size, 512 struct nouveau_object **pobject) 513{ 514 struct nv50_display_curs_class *args = data; 515 struct nv50_disp_pioc *pioc; 516 int ret; 517 518 if (size < sizeof(*args) || args->head > 1) 519 return -EINVAL; 520 521 ret = nv50_disp_pioc_create_(parent, engine, oclass, 7 + args->head, 522 sizeof(*pioc), (void **)&pioc); 523 *pobject = nv_object(pioc); 524 if (ret) 525 return ret; 526 527 return 0; 528} 529 530struct nouveau_ofuncs 531nv50_disp_curs_ofuncs = { 532 .ctor = nv50_disp_curs_ctor, 533 .dtor = nv50_disp_pioc_dtor, 534 .init = nv50_disp_pioc_init, 535 .fini = nv50_disp_pioc_fini, 536 .rd32 = nv50_disp_chan_rd32, 537 .wr32 = nv50_disp_chan_wr32, 538}; 539 540/******************************************************************************* 541 * Base display object 542 ******************************************************************************/ 543 544static void 545nv50_disp_base_vblank_enable(struct nouveau_event *event, int head) 546{ 547 nv_mask(event->priv, 0x61002c, (1 << head), (1 << head)); 548} 549 550static void 551nv50_disp_base_vblank_disable(struct nouveau_event *event, int head) 552{ 553 nv_mask(event->priv, 0x61002c, (1 << head), (0 << head)); 554} 555 556static int 557nv50_disp_base_ctor(struct nouveau_object *parent, 558 struct nouveau_object *engine, 559 struct nouveau_oclass *oclass, void *data, u32 size, 560 struct nouveau_object **pobject) 561{ 562 struct nv50_disp_priv *priv = (void *)engine; 563 struct nv50_disp_base *base; 564 int ret; 565 566 ret = nouveau_parent_create(parent, engine, oclass, 0, 567 priv->sclass, 0, &base); 568 *pobject = nv_object(base); 569 if (ret) 570 return ret; 571 572 priv->base.vblank->priv = priv; 573 priv->base.vblank->enable = nv50_disp_base_vblank_enable; 574 priv->base.vblank->disable = nv50_disp_base_vblank_disable; 575 return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); 576} 577 578static void 579nv50_disp_base_dtor(struct nouveau_object *object) 580{ 581 struct nv50_disp_base *base = (void *)object; 582 nouveau_ramht_ref(NULL, &base->ramht); 583 nouveau_parent_destroy(&base->base); 584} 585 586static int 587nv50_disp_base_init(struct nouveau_object *object) 588{ 589 struct nv50_disp_priv *priv = (void *)object->engine; 590 struct nv50_disp_base *base = (void *)object; 591 int ret, i; 592 u32 tmp; 593 594 ret = nouveau_parent_init(&base->base); 595 if (ret) 596 return ret; 597 598 /* The below segments of code copying values from one register to 599 * another appear to inform EVO of the display capabilities or 600 * something similar. NFI what the 0x614004 caps are for.. 601 */ 602 tmp = nv_rd32(priv, 0x614004); 603 nv_wr32(priv, 0x610184, tmp); 604 605 /* ... CRTC caps */ 606 for (i = 0; i < priv->head.nr; i++) { 607 tmp = nv_rd32(priv, 0x616100 + (i * 0x800)); 608 nv_wr32(priv, 0x610190 + (i * 0x10), tmp); 609 tmp = nv_rd32(priv, 0x616104 + (i * 0x800)); 610 nv_wr32(priv, 0x610194 + (i * 0x10), tmp); 611 tmp = nv_rd32(priv, 0x616108 + (i * 0x800)); 612 nv_wr32(priv, 0x610198 + (i * 0x10), tmp); 613 tmp = nv_rd32(priv, 0x61610c + (i * 0x800)); 614 nv_wr32(priv, 0x61019c + (i * 0x10), tmp); 615 } 616 617 /* ... DAC caps */ 618 for (i = 0; i < priv->dac.nr; i++) { 619 tmp = nv_rd32(priv, 0x61a000 + (i * 0x800)); 620 nv_wr32(priv, 0x6101d0 + (i * 0x04), tmp); 621 } 622 623 /* ... SOR caps */ 624 for (i = 0; i < priv->sor.nr; i++) { 625 tmp = nv_rd32(priv, 0x61c000 + (i * 0x800)); 626 nv_wr32(priv, 0x6101e0 + (i * 0x04), tmp); 627 } 628 629 /* ... EXT caps */ 630 for (i = 0; i < 3; i++) { 631 tmp = nv_rd32(priv, 0x61e000 + (i * 0x800)); 632 nv_wr32(priv, 0x6101f0 + (i * 0x04), tmp); 633 } 634 635 /* steal display away from vbios, or something like that */ 636 if (nv_rd32(priv, 0x610024) & 0x00000100) { 637 nv_wr32(priv, 0x610024, 0x00000100); 638 nv_mask(priv, 0x6194e8, 0x00000001, 0x00000000); 639 if (!nv_wait(priv, 0x6194e8, 0x00000002, 0x00000000)) { 640 nv_error(priv, "timeout acquiring display\n"); 641 return -EBUSY; 642 } 643 } 644 645 /* point at display engine memory area (hash table, objects) */ 646 nv_wr32(priv, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9); 647 648 /* enable supervisor interrupts, disable everything else */ 649 nv_wr32(priv, 0x61002c, 0x00000370); 650 nv_wr32(priv, 0x610028, 0x00000000); 651 return 0; 652} 653 654static int 655nv50_disp_base_fini(struct nouveau_object *object, bool suspend) 656{ 657 struct nv50_disp_priv *priv = (void *)object->engine; 658 struct nv50_disp_base *base = (void *)object; 659 660 /* disable all interrupts */ 661 nv_wr32(priv, 0x610024, 0x00000000); 662 nv_wr32(priv, 0x610020, 0x00000000); 663 664 return nouveau_parent_fini(&base->base, suspend); 665} 666 667struct nouveau_ofuncs 668nv50_disp_base_ofuncs = { 669 .ctor = nv50_disp_base_ctor, 670 .dtor = nv50_disp_base_dtor, 671 .init = nv50_disp_base_init, 672 .fini = nv50_disp_base_fini, 673}; 674 675static struct nouveau_omthds 676nv50_disp_base_omthds[] = { 677 { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, 678 { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, 679 { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, 680 { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, 681 {}, 682}; 683 684static struct nouveau_oclass 685nv50_disp_base_oclass[] = { 686 { NV50_DISP_CLASS, &nv50_disp_base_ofuncs, nv50_disp_base_omthds }, 687 {} 688}; 689 690static struct nouveau_oclass 691nv50_disp_sclass[] = { 692 { NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, 693 { NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, 694 { NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, 695 { NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, 696 { NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, 697 {} 698}; 699 700/******************************************************************************* 701 * Display context, tracks instmem allocation and prevents more than one 702 * client using the display hardware at any time. 703 ******************************************************************************/ 704 705static int 706nv50_disp_data_ctor(struct nouveau_object *parent, 707 struct nouveau_object *engine, 708 struct nouveau_oclass *oclass, void *data, u32 size, 709 struct nouveau_object **pobject) 710{ 711 struct nv50_disp_priv *priv = (void *)engine; 712 struct nouveau_engctx *ectx; 713 int ret = -EBUSY; 714 715 /* no context needed for channel objects... */ 716 if (nv_mclass(parent) != NV_DEVICE_CLASS) { 717 atomic_inc(&parent->refcount); 718 *pobject = parent; 719 return 0; 720 } 721 722 /* allocate display hardware to client */ 723 mutex_lock(&nv_subdev(priv)->mutex); 724 if (list_empty(&nv_engine(priv)->contexts)) { 725 ret = nouveau_engctx_create(parent, engine, oclass, NULL, 726 0x10000, 0x10000, 727 NVOBJ_FLAG_HEAP, &ectx); 728 *pobject = nv_object(ectx); 729 } 730 mutex_unlock(&nv_subdev(priv)->mutex); 731 return ret; 732} 733 734struct nouveau_oclass 735nv50_disp_cclass = { 736 .handle = NV_ENGCTX(DISP, 0x50), 737 .ofuncs = &(struct nouveau_ofuncs) { 738 .ctor = nv50_disp_data_ctor, 739 .dtor = _nouveau_engctx_dtor, 740 .init = _nouveau_engctx_init, 741 .fini = _nouveau_engctx_fini, 742 .rd32 = _nouveau_engctx_rd32, 743 .wr32 = _nouveau_engctx_wr32, 744 }, 745}; 746 747/******************************************************************************* 748 * Display engine implementation 749 ******************************************************************************/ 750 751static void 752nv50_disp_intr_error(struct nv50_disp_priv *priv) 753{ 754 u32 channels = (nv_rd32(priv, 0x610020) & 0x001f0000) >> 16; 755 u32 addr, data; 756 int chid; 757 758 for (chid = 0; chid < 5; chid++) { 759 if (!(channels & (1 << chid))) 760 continue; 761 762 nv_wr32(priv, 0x610020, 0x00010000 << chid); 763 addr = nv_rd32(priv, 0x610080 + (chid * 0x08)); 764 data = nv_rd32(priv, 0x610084 + (chid * 0x08)); 765 nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000); 766 767 nv_error(priv, "chid %d mthd 0x%04x data 0x%08x 0x%08x\n", 768 chid, addr & 0xffc, data, addr); 769 } 770} 771 772static u16 773exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, 774 struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, 775 struct nvbios_outp *info) 776{ 777 struct nouveau_bios *bios = nouveau_bios(priv); 778 u16 mask, type, data; 779 780 if (outp < 4) { 781 type = DCB_OUTPUT_ANALOG; 782 mask = 0; 783 } else { 784 outp -= 4; 785 switch (ctrl & 0x00000f00) { 786 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; 787 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; 788 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break; 789 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break; 790 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break; 791 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; 792 default: 793 nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); 794 return 0x0000; 795 } 796 } 797 798 mask = 0x00c0 & (mask << 6); 799 mask |= 0x0001 << outp; 800 mask |= 0x0100 << head; 801 802 data = dcb_outp_match(bios, type, mask, ver, hdr, dcb); 803 if (!data) 804 return 0x0000; 805 806 return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info); 807} 808 809static bool 810exec_script(struct nv50_disp_priv *priv, int head, int id) 811{ 812 struct nouveau_bios *bios = nouveau_bios(priv); 813 struct nvbios_outp info; 814 struct dcb_output dcb; 815 u8 ver, hdr, cnt, len; 816 u16 data; 817 u32 ctrl = 0x00000000; 818 int i; 819 820 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) 821 ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); 822 823 if (!(ctrl & (1 << head))) { 824 if (nv_device(priv)->chipset < 0x90 || 825 nv_device(priv)->chipset == 0x92 || 826 nv_device(priv)->chipset == 0xa0) { 827 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) 828 ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); 829 i += 4; 830 } else { 831 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) 832 ctrl = nv_rd32(priv, 0x610798 + (i * 8)); 833 i += 4; 834 } 835 } 836 837 if (!(ctrl & (1 << head))) 838 return false; 839 i--; 840 841 data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); 842 if (data) { 843 struct nvbios_init init = { 844 .subdev = nv_subdev(priv), 845 .bios = bios, 846 .offset = info.script[id], 847 .outp = &dcb, 848 .crtc = head, 849 .execute = 1, 850 }; 851 852 return nvbios_exec(&init) == 0; 853 } 854 855 return false; 856} 857 858static u32 859exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, 860 struct dcb_output *outp) 861{ 862 struct nouveau_bios *bios = nouveau_bios(priv); 863 struct nvbios_outp info1; 864 struct nvbios_ocfg info2; 865 u8 ver, hdr, cnt, len; 866 u32 ctrl = 0x00000000; 867 u32 data, conf = ~0; 868 int i; 869 870 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) 871 ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); 872 873 if (!(ctrl & (1 << head))) { 874 if (nv_device(priv)->chipset < 0x90 || 875 nv_device(priv)->chipset == 0x92 || 876 nv_device(priv)->chipset == 0xa0) { 877 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) 878 ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); 879 i += 4; 880 } else { 881 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) 882 ctrl = nv_rd32(priv, 0x610794 + (i * 8)); 883 i += 4; 884 } 885 } 886 887 if (!(ctrl & (1 << head))) 888 return conf; 889 i--; 890 891 data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); 892 if (!data) 893 return conf; 894 895 switch (outp->type) { 896 case DCB_OUTPUT_TMDS: 897 conf = (ctrl & 0x00000f00) >> 8; 898 if (pclk >= 165000) 899 conf |= 0x0100; 900 break; 901 case DCB_OUTPUT_LVDS: 902 conf = priv->sor.lvdsconf; 903 break; 904 case DCB_OUTPUT_DP: 905 conf = (ctrl & 0x00000f00) >> 8; 906 break; 907 case DCB_OUTPUT_ANALOG: 908 default: 909 conf = 0x00ff; 910 break; 911 } 912 913 data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); 914 if (data) { 915 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); 916 if (data) { 917 struct nvbios_init init = { 918 .subdev = nv_subdev(priv), 919 .bios = bios, 920 .offset = data, 921 .outp = outp, 922 .crtc = head, 923 .execute = 1, 924 }; 925 926 nvbios_exec(&init); 927 } 928 } 929 930 return conf; 931} 932 933static void 934nv50_disp_intr_unk10(struct nv50_disp_priv *priv, u32 super) 935{ 936 int head = ffs((super & 0x00000060) >> 5) - 1; 937 if (head >= 0) { 938 head = ffs((super & 0x00000180) >> 7) - 1; 939 if (head >= 0) 940 exec_script(priv, head, 1); 941 } 942 943 nv_wr32(priv, 0x610030, 0x80000000); 944} 945 946static void 947nv50_disp_intr_unk20_dp(struct nv50_disp_priv *priv, 948 struct dcb_output *outp, u32 pclk) 949{ 950 const int link = !(outp->sorconf.link & 1); 951 const int or = ffs(outp->or) - 1; 952 const u32 soff = ( or * 0x800); 953 const u32 loff = (link * 0x080) + soff; 954 const u32 ctrl = nv_rd32(priv, 0x610794 + (or * 8)); 955 const u32 symbol = 100000; 956 u32 dpctrl = nv_rd32(priv, 0x61c10c + loff) & 0x0000f0000; 957 u32 clksor = nv_rd32(priv, 0x614300 + soff); 958 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0; 959 int TU, VTUi, VTUf, VTUa; 960 u64 link_data_rate, link_ratio, unk; 961 u32 best_diff = 64 * symbol; 962 u32 link_nr, link_bw, bits, r; 963 964 /* calculate packed data rate for each lane */ 965 if (dpctrl > 0x00030000) link_nr = 4; 966 else if (dpctrl > 0x00010000) link_nr = 2; 967 else link_nr = 1; 968 969 if (clksor & 0x000c0000) 970 link_bw = 270000; 971 else 972 link_bw = 162000; 973 974 if ((ctrl & 0xf0000) == 0x60000) bits = 30; 975 else if ((ctrl & 0xf0000) == 0x50000) bits = 24; 976 else bits = 18; 977 978 link_data_rate = (pclk * bits / 8) / link_nr; 979 980 /* calculate ratio of packed data rate to link symbol rate */ 981 link_ratio = link_data_rate * symbol; 982 r = do_div(link_ratio, link_bw); 983 984 for (TU = 64; TU >= 32; TU--) { 985 /* calculate average number of valid symbols in each TU */ 986 u32 tu_valid = link_ratio * TU; 987 u32 calc, diff; 988 989 /* find a hw representation for the fraction.. */ 990 VTUi = tu_valid / symbol; 991 calc = VTUi * symbol; 992 diff = tu_valid - calc; 993 if (diff) { 994 if (diff >= (symbol / 2)) { 995 VTUf = symbol / (symbol - diff); 996 if (symbol - (VTUf * diff)) 997 VTUf++; 998 999 if (VTUf <= 15) { 1000 VTUa = 1; 1001 calc += symbol - (symbol / VTUf); 1002 } else { 1003 VTUa = 0; 1004 VTUf = 1; 1005 calc += symbol; 1006 } 1007 } else { 1008 VTUa = 0; 1009 VTUf = min((int)(symbol / diff), 15); 1010 calc += symbol / VTUf; 1011 } 1012 1013 diff = calc - tu_valid; 1014 } else { 1015 /* no remainder, but the hw doesn't like the fractional 1016 * part to be zero. decrement the integer part and 1017 * have the fraction add a whole symbol back 1018 */ 1019 VTUa = 0; 1020 VTUf = 1; 1021 VTUi--; 1022 } 1023 1024 if (diff < best_diff) { 1025 best_diff = diff; 1026 bestTU = TU; 1027 bestVTUa = VTUa; 1028 bestVTUf = VTUf; 1029 bestVTUi = VTUi; 1030 if (diff == 0) 1031 break; 1032 } 1033 } 1034 1035 if (!bestTU) { 1036 nv_error(priv, "unable to find suitable dp config\n"); 1037 return; 1038 } 1039 1040 /* XXX close to vbios numbers, but not right */ 1041 unk = (symbol - link_ratio) * bestTU; 1042 unk *= link_ratio; 1043 r = do_div(unk, symbol); 1044 r = do_div(unk, symbol); 1045 unk += 6; 1046 1047 nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2); 1048 nv_mask(priv, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 | 1049 bestVTUf << 16 | 1050 bestVTUi << 8 | unk); 1051} 1052 1053static void 1054nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super) 1055{ 1056 struct dcb_output outp; 1057 u32 addr, mask, data; 1058 int head; 1059 1060 /* finish detaching encoder? */ 1061 head = ffs((super & 0x00000180) >> 7) - 1; 1062 if (head >= 0) 1063 exec_script(priv, head, 2); 1064 1065 /* check whether a vpll change is required */ 1066 head = ffs((super & 0x00000600) >> 9) - 1; 1067 if (head >= 0) { 1068 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1069 if (pclk) { 1070 struct nouveau_clock *clk = nouveau_clock(priv); 1071 clk->pll_set(clk, PLL_VPLL0 + head, pclk); 1072 } 1073 1074 nv_mask(priv, 0x614200 + head * 0x800, 0x0000000f, 0x00000000); 1075 } 1076 1077 /* (re)attach the relevant OR to the head */ 1078 head = ffs((super & 0x00000180) >> 7) - 1; 1079 if (head >= 0) { 1080 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1081 u32 conf = exec_clkcmp(priv, head, 0, pclk, &outp); 1082 if (conf != ~0) { 1083 if (outp.type == DCB_OUTPUT_ANALOG) { 1084 addr = 0x614280 + (ffs(outp.or) - 1) * 0x800; 1085 mask = 0xffffffff; 1086 data = 0x00000000; 1087 } else { 1088 if (outp.type == DCB_OUTPUT_DP) 1089 nv50_disp_intr_unk20_dp(priv, &outp, pclk); 1090 addr = 0x614300 + (ffs(outp.or) - 1) * 0x800; 1091 mask = 0x00000707; 1092 data = (conf & 0x0100) ? 0x0101 : 0x0000; 1093 } 1094 1095 nv_mask(priv, addr, mask, data); 1096 } 1097 } 1098 1099 nv_wr32(priv, 0x610030, 0x80000000); 1100} 1101 1102/* If programming a TMDS output on a SOR that can also be configured for 1103 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. 1104 * 1105 * It looks like the VBIOS TMDS scripts make an attempt at this, however, 1106 * the VBIOS scripts on at least one board I have only switch it off on 1107 * link 0, causing a blank display if the output has previously been 1108 * programmed for DisplayPort. 1109 */ 1110static void 1111nv50_disp_intr_unk40_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp) 1112{ 1113 struct nouveau_bios *bios = nouveau_bios(priv); 1114 const int link = !(outp->sorconf.link & 1); 1115 const int or = ffs(outp->or) - 1; 1116 const u32 loff = (or * 0x800) + (link * 0x80); 1117 const u16 mask = (outp->sorconf.link << 6) | outp->or; 1118 u8 ver, hdr; 1119 1120 if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, outp)) 1121 nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000); 1122} 1123 1124static void 1125nv50_disp_intr_unk40(struct nv50_disp_priv *priv, u32 super) 1126{ 1127 int head = ffs((super & 0x00000180) >> 7) - 1; 1128 if (head >= 0) { 1129 struct dcb_output outp; 1130 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; 1131 if (exec_clkcmp(priv, head, 1, pclk, &outp) != ~0) { 1132 if (outp.type == DCB_OUTPUT_TMDS) 1133 nv50_disp_intr_unk40_tmds(priv, &outp); 1134 } 1135 } 1136 1137 nv_wr32(priv, 0x610030, 0x80000000); 1138} 1139 1140void 1141nv50_disp_intr_supervisor(struct work_struct *work) 1142{ 1143 struct nv50_disp_priv *priv = 1144 container_of(work, struct nv50_disp_priv, supervisor); 1145 u32 super = nv_rd32(priv, 0x610030); 1146 1147 nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super); 1148 1149 if (priv->super & 0x00000010) 1150 nv50_disp_intr_unk10(priv, super); 1151 if (priv->super & 0x00000020) 1152 nv50_disp_intr_unk20(priv, super); 1153 if (priv->super & 0x00000040) 1154 nv50_disp_intr_unk40(priv, super); 1155} 1156 1157void 1158nv50_disp_intr(struct nouveau_subdev *subdev) 1159{ 1160 struct nv50_disp_priv *priv = (void *)subdev; 1161 u32 intr0 = nv_rd32(priv, 0x610020); 1162 u32 intr1 = nv_rd32(priv, 0x610024); 1163 1164 if (intr0 & 0x001f0000) { 1165 nv50_disp_intr_error(priv); 1166 intr0 &= ~0x001f0000; 1167 } 1168 1169 if (intr1 & 0x00000004) { 1170 nouveau_event_trigger(priv->base.vblank, 0); 1171 nv_wr32(priv, 0x610024, 0x00000004); 1172 intr1 &= ~0x00000004; 1173 } 1174 1175 if (intr1 & 0x00000008) { 1176 nouveau_event_trigger(priv->base.vblank, 1); 1177 nv_wr32(priv, 0x610024, 0x00000008); 1178 intr1 &= ~0x00000008; 1179 } 1180 1181 if (intr1 & 0x00000070) { 1182 priv->super = (intr1 & 0x00000070); 1183 schedule_work(&priv->supervisor); 1184 nv_wr32(priv, 0x610024, priv->super); 1185 intr1 &= ~0x00000070; 1186 } 1187} 1188 1189static int 1190nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 1191 struct nouveau_oclass *oclass, void *data, u32 size, 1192 struct nouveau_object **pobject) 1193{ 1194 struct nv50_disp_priv *priv; 1195 int ret; 1196 1197 ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP", 1198 "display", &priv); 1199 *pobject = nv_object(priv); 1200 if (ret) 1201 return ret; 1202 1203 nv_engine(priv)->sclass = nv50_disp_base_oclass; 1204 nv_engine(priv)->cclass = &nv50_disp_cclass; 1205 nv_subdev(priv)->intr = nv50_disp_intr; 1206 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 1207 priv->sclass = nv50_disp_sclass; 1208 priv->head.nr = 2; 1209 priv->dac.nr = 3; 1210 priv->sor.nr = 2; 1211 priv->dac.power = nv50_dac_power; 1212 priv->dac.sense = nv50_dac_sense; 1213 priv->sor.power = nv50_sor_power; 1214 return 0; 1215} 1216 1217struct nouveau_oclass 1218nv50_disp_oclass = { 1219 .handle = NV_ENGINE(DISP, 0x50), 1220 .ofuncs = &(struct nouveau_ofuncs) { 1221 .ctor = nv50_disp_ctor, 1222 .dtor = _nouveau_disp_dtor, 1223 .init = _nouveau_disp_init, 1224 .fini = _nouveau_disp_fini, 1225 }, 1226}; 1227