2 * Copyright 2012 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <core/object.h>
26 #include <core/client.h>
27 #include <core/parent.h>
28 #include <core/handle.h>
29 #include <core/enum.h>
30 #include <nvif/unpack.h>
31 #include <nvif/class.h>
32 #include <nvif/event.h>
34 #include <subdev/bios.h>
35 #include <subdev/bios/dcb.h>
36 #include <subdev/bios/disp.h>
37 #include <subdev/bios/init.h>
38 #include <subdev/bios/pll.h>
39 #include <subdev/devinit.h>
40 #include <subdev/timer.h>
41 #include <subdev/fb.h>
45 /*******************************************************************************
46 * EVO channel base class
47 ******************************************************************************/
50 nv50_disp_chan_create_(struct nouveau_object *parent,
51 struct nouveau_object *engine,
52 struct nouveau_oclass *oclass, int head,
53 int length, void **pobject)
55 const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs;
56 struct nv50_disp_base *base = (void *)parent;
57 struct nv50_disp_chan *chan;
58 int chid = impl->chid + head;
61 if (base->chan & (1 << chid))
63 base->chan |= (1 << chid);
65 ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
66 (1ULL << NVDEV_ENGINE_DMAOBJ),
73 nv_parent(chan)->object_attach = impl->attach;
74 nv_parent(chan)->object_detach = impl->detach;
79 nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
81 struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
82 base->chan &= ~(1 << chan->chid);
83 nouveau_namedb_destroy(&chan->base);
87 nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
89 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
90 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index);
94 nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
96 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
97 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index);
101 nv50_disp_chan_uevent_send(struct nv50_disp_priv *priv, int chid)
103 struct nvif_notify_uevent_rep {
106 nvkm_event_send(&priv->uevent, 1, chid, &rep, sizeof(rep));
110 nv50_disp_chan_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
111 struct nvkm_notify *notify)
113 struct nv50_disp_dmac *dmac = (void *)object;
115 struct nvif_notify_uevent_req none;
119 if (nvif_unvers(args->none)) {
120 notify->size = sizeof(struct nvif_notify_uevent_rep);
122 notify->index = dmac->base.chid;
129 const struct nvkm_event_func
130 nv50_disp_chan_uevent = {
131 .ctor = nv50_disp_chan_uevent_ctor,
132 .init = nv50_disp_chan_uevent_init,
133 .fini = nv50_disp_chan_uevent_fini,
137 nv50_disp_chan_ntfy(struct nouveau_object *object, u32 type,
138 struct nvkm_event **pevent)
140 struct nv50_disp_priv *priv = (void *)object->engine;
142 case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT:
143 *pevent = &priv->uevent;
152 nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
154 struct nv50_disp_chan *chan = (void *)object;
155 *addr = nv_device_resource_start(nv_device(object), 0) +
156 0x640000 + (chan->chid * 0x1000);
162 nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
164 struct nv50_disp_priv *priv = (void *)object->engine;
165 struct nv50_disp_chan *chan = (void *)object;
166 return nv_rd32(priv, 0x640000 + (chan->chid * 0x1000) + addr);
170 nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data)
172 struct nv50_disp_priv *priv = (void *)object->engine;
173 struct nv50_disp_chan *chan = (void *)object;
174 nv_wr32(priv, 0x640000 + (chan->chid * 0x1000) + addr, data);
177 /*******************************************************************************
178 * EVO DMA channel base class
179 ******************************************************************************/
182 nv50_disp_dmac_object_attach(struct nouveau_object *parent,
183 struct nouveau_object *object, u32 name)
185 struct nv50_disp_base *base = (void *)parent->parent;
186 struct nv50_disp_chan *chan = (void *)parent;
187 u32 addr = nv_gpuobj(object)->node->offset;
188 u32 chid = chan->chid;
189 u32 data = (chid << 28) | (addr << 10) | chid;
190 return nouveau_ramht_insert(base->ramht, chid, name, data);
194 nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
196 struct nv50_disp_base *base = (void *)parent->parent;
197 nouveau_ramht_remove(base->ramht, cookie);
201 nv50_disp_dmac_create_(struct nouveau_object *parent,
202 struct nouveau_object *engine,
203 struct nouveau_oclass *oclass, u32 pushbuf, int head,
204 int length, void **pobject)
206 struct nv50_disp_dmac *dmac;
209 ret = nv50_disp_chan_create_(parent, engine, oclass, head,
215 dmac->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
219 switch (nv_mclass(dmac->pushdma)) {
222 if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff)
225 switch (dmac->pushdma->target) {
226 case NV_MEM_TARGET_VRAM:
227 dmac->push = 0x00000000 | dmac->pushdma->start >> 8;
229 case NV_MEM_TARGET_PCI_NOSNOOP:
230 dmac->push = 0x00000003 | dmac->pushdma->start >> 8;
244 nv50_disp_dmac_dtor(struct nouveau_object *object)
246 struct nv50_disp_dmac *dmac = (void *)object;
247 nouveau_object_ref(NULL, (struct nouveau_object **)&dmac->pushdma);
248 nv50_disp_chan_destroy(&dmac->base);
252 nv50_disp_dmac_init(struct nouveau_object *object)
254 struct nv50_disp_priv *priv = (void *)object->engine;
255 struct nv50_disp_dmac *dmac = (void *)object;
256 int chid = dmac->base.chid;
259 ret = nv50_disp_chan_init(&dmac->base);
263 /* enable error reporting */
264 nv_mask(priv, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
266 /* initialise channel for dma command submission */
267 nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push);
268 nv_wr32(priv, 0x610208 + (chid * 0x0010), 0x00010000);
269 nv_wr32(priv, 0x61020c + (chid * 0x0010), chid);
270 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010);
271 nv_wr32(priv, 0x640000 + (chid * 0x1000), 0x00000000);
272 nv_wr32(priv, 0x610200 + (chid * 0x0010), 0x00000013);
274 /* wait for it to go inactive */
275 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x80000000, 0x00000000)) {
276 nv_error(dmac, "init timeout, 0x%08x\n",
277 nv_rd32(priv, 0x610200 + (chid * 0x10)));
285 nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
287 struct nv50_disp_priv *priv = (void *)object->engine;
288 struct nv50_disp_dmac *dmac = (void *)object;
289 int chid = dmac->base.chid;
291 /* deactivate channel */
292 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000);
293 nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000);
294 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x001e0000, 0x00000000)) {
295 nv_error(dmac, "fini timeout, 0x%08x\n",
296 nv_rd32(priv, 0x610200 + (chid * 0x10)));
301 /* disable error reporting and completion notifications */
302 nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
304 return nv50_disp_chan_fini(&dmac->base, suspend);
307 /*******************************************************************************
308 * EVO master channel object
309 ******************************************************************************/
312 nv50_disp_mthd_list(struct nv50_disp_priv *priv, int debug, u32 base, int c,
313 const struct nv50_disp_mthd_list *list, int inst)
315 struct nouveau_object *disp = nv_object(priv);
318 for (i = 0; list->data[i].mthd; i++) {
319 if (list->data[i].addr) {
320 u32 next = nv_rd32(priv, list->data[i].addr + base + 0);
321 u32 prev = nv_rd32(priv, list->data[i].addr + base + c);
322 u32 mthd = list->data[i].mthd + (list->mthd * inst);
323 const char *name = list->data[i].name;
327 snprintf(mods, sizeof(mods), "-> 0x%08x", next);
329 snprintf(mods, sizeof(mods), "%13c", ' ');
331 nv_printk_(disp, debug, "\t0x%04x: 0x%08x %s%s%s\n",
332 mthd, prev, mods, name ? " // " : "",
339 nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head,
340 const struct nv50_disp_mthd_chan *chan)
342 struct nouveau_object *disp = nv_object(priv);
343 const struct nv50_disp_impl *impl = (void *)disp->oclass;
344 const struct nv50_disp_mthd_list *list;
347 if (debug > nv_subdev(priv)->debug)
350 for (i = 0; (list = chan->data[i].mthd) != NULL; i++) {
351 u32 base = head * chan->addr;
352 for (j = 0; j < chan->data[i].nr; j++, base += list->addr) {
353 const char *cname = chan->name;
354 const char *sname = "";
355 char cname_[16], sname_[16];
358 snprintf(cname_, sizeof(cname_), "%s %d",
363 if (chan->data[i].nr > 1) {
364 snprintf(sname_, sizeof(sname_), " - %s %d",
365 chan->data[i].name, j);
369 nv_printk_(disp, debug, "%s%s:\n", cname, sname);
370 nv50_disp_mthd_list(priv, debug, base, impl->mthd.prev,
376 const struct nv50_disp_mthd_list
377 nv50_disp_mast_mthd_base = {
381 { 0x0080, 0x000000 },
382 { 0x0084, 0x610bb8 },
383 { 0x0088, 0x610b9c },
384 { 0x008c, 0x000000 },
389 static const struct nv50_disp_mthd_list
390 nv50_disp_mast_mthd_dac = {
394 { 0x0400, 0x610b58 },
395 { 0x0404, 0x610bdc },
396 { 0x0420, 0x610828 },
401 const struct nv50_disp_mthd_list
402 nv50_disp_mast_mthd_sor = {
406 { 0x0600, 0x610b70 },
411 const struct nv50_disp_mthd_list
412 nv50_disp_mast_mthd_pior = {
416 { 0x0700, 0x610b80 },
421 static const struct nv50_disp_mthd_list
422 nv50_disp_mast_mthd_head = {
426 { 0x0800, 0x610ad8 },
427 { 0x0804, 0x610ad0 },
428 { 0x0808, 0x610a48 },
429 { 0x080c, 0x610a78 },
430 { 0x0810, 0x610ac0 },
431 { 0x0814, 0x610af8 },
432 { 0x0818, 0x610b00 },
433 { 0x081c, 0x610ae8 },
434 { 0x0820, 0x610af0 },
435 { 0x0824, 0x610b08 },
436 { 0x0828, 0x610b10 },
437 { 0x082c, 0x610a68 },
438 { 0x0830, 0x610a60 },
439 { 0x0834, 0x000000 },
440 { 0x0838, 0x610a40 },
441 { 0x0840, 0x610a24 },
442 { 0x0844, 0x610a2c },
443 { 0x0848, 0x610aa8 },
444 { 0x084c, 0x610ab0 },
445 { 0x0860, 0x610a84 },
446 { 0x0864, 0x610a90 },
447 { 0x0868, 0x610b18 },
448 { 0x086c, 0x610b20 },
449 { 0x0870, 0x610ac8 },
450 { 0x0874, 0x610a38 },
451 { 0x0880, 0x610a58 },
452 { 0x0884, 0x610a9c },
453 { 0x08a0, 0x610a70 },
454 { 0x08a4, 0x610a50 },
455 { 0x08a8, 0x610ae0 },
456 { 0x08c0, 0x610b28 },
457 { 0x08c4, 0x610b30 },
458 { 0x08c8, 0x610b40 },
459 { 0x08d4, 0x610b38 },
460 { 0x08d8, 0x610b48 },
461 { 0x08dc, 0x610b50 },
462 { 0x0900, 0x610a18 },
463 { 0x0904, 0x610ab8 },
468 static const struct nv50_disp_mthd_chan
469 nv50_disp_mast_mthd_chan = {
473 { "Global", 1, &nv50_disp_mast_mthd_base },
474 { "DAC", 3, &nv50_disp_mast_mthd_dac },
475 { "SOR", 2, &nv50_disp_mast_mthd_sor },
476 { "PIOR", 3, &nv50_disp_mast_mthd_pior },
477 { "HEAD", 2, &nv50_disp_mast_mthd_head },
483 nv50_disp_mast_ctor(struct nouveau_object *parent,
484 struct nouveau_object *engine,
485 struct nouveau_oclass *oclass, void *data, u32 size,
486 struct nouveau_object **pobject)
489 struct nv50_disp_core_channel_dma_v0 v0;
491 struct nv50_disp_dmac *mast;
494 nv_ioctl(parent, "create disp core channel dma size %d\n", size);
495 if (nvif_unpack(args->v0, 0, 0, false)) {
496 nv_ioctl(parent, "create disp core channel dma vers %d "
498 args->v0.version, args->v0.pushbuf);
502 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
503 0, sizeof(*mast), (void **)&mast);
504 *pobject = nv_object(mast);
512 nv50_disp_mast_init(struct nouveau_object *object)
514 struct nv50_disp_priv *priv = (void *)object->engine;
515 struct nv50_disp_dmac *mast = (void *)object;
518 ret = nv50_disp_chan_init(&mast->base);
522 /* enable error reporting */
523 nv_mask(priv, 0x610028, 0x00010000, 0x00010000);
525 /* attempt to unstick channel from some unknown state */
526 if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000)
527 nv_mask(priv, 0x610200, 0x00800000, 0x00800000);
528 if ((nv_rd32(priv, 0x610200) & 0x003f0000) == 0x00030000)
529 nv_mask(priv, 0x610200, 0x00600000, 0x00600000);
531 /* initialise channel for dma command submission */
532 nv_wr32(priv, 0x610204, mast->push);
533 nv_wr32(priv, 0x610208, 0x00010000);
534 nv_wr32(priv, 0x61020c, 0x00000000);
535 nv_mask(priv, 0x610200, 0x00000010, 0x00000010);
536 nv_wr32(priv, 0x640000, 0x00000000);
537 nv_wr32(priv, 0x610200, 0x01000013);
539 /* wait for it to go inactive */
540 if (!nv_wait(priv, 0x610200, 0x80000000, 0x00000000)) {
541 nv_error(mast, "init: 0x%08x\n", nv_rd32(priv, 0x610200));
549 nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
551 struct nv50_disp_priv *priv = (void *)object->engine;
552 struct nv50_disp_dmac *mast = (void *)object;
554 /* deactivate channel */
555 nv_mask(priv, 0x610200, 0x00000010, 0x00000000);
556 nv_mask(priv, 0x610200, 0x00000003, 0x00000000);
557 if (!nv_wait(priv, 0x610200, 0x001e0000, 0x00000000)) {
558 nv_error(mast, "fini: 0x%08x\n", nv_rd32(priv, 0x610200));
563 /* disable error reporting and completion notifications */
564 nv_mask(priv, 0x610028, 0x00010001, 0x00000000);
566 return nv50_disp_chan_fini(&mast->base, suspend);
569 struct nv50_disp_chan_impl
570 nv50_disp_mast_ofuncs = {
571 .base.ctor = nv50_disp_mast_ctor,
572 .base.dtor = nv50_disp_dmac_dtor,
573 .base.init = nv50_disp_mast_init,
574 .base.fini = nv50_disp_mast_fini,
575 .base.map = nv50_disp_chan_map,
576 .base.ntfy = nv50_disp_chan_ntfy,
577 .base.rd32 = nv50_disp_chan_rd32,
578 .base.wr32 = nv50_disp_chan_wr32,
580 .attach = nv50_disp_dmac_object_attach,
581 .detach = nv50_disp_dmac_object_detach,
584 /*******************************************************************************
585 * EVO sync channel objects
586 ******************************************************************************/
588 static const struct nv50_disp_mthd_list
589 nv50_disp_sync_mthd_base = {
593 { 0x0080, 0x000000 },
594 { 0x0084, 0x0008c4 },
595 { 0x0088, 0x0008d0 },
596 { 0x008c, 0x0008dc },
597 { 0x0090, 0x0008e4 },
598 { 0x0094, 0x610884 },
599 { 0x00a0, 0x6108a0 },
600 { 0x00a4, 0x610878 },
601 { 0x00c0, 0x61086c },
602 { 0x00e0, 0x610858 },
603 { 0x00e4, 0x610860 },
604 { 0x00e8, 0x6108ac },
605 { 0x00ec, 0x6108b4 },
606 { 0x0100, 0x610894 },
607 { 0x0110, 0x6108bc },
608 { 0x0114, 0x61088c },
613 const struct nv50_disp_mthd_list
614 nv50_disp_sync_mthd_image = {
618 { 0x0800, 0x6108f0 },
619 { 0x0804, 0x6108fc },
620 { 0x0808, 0x61090c },
621 { 0x080c, 0x610914 },
622 { 0x0810, 0x610904 },
627 static const struct nv50_disp_mthd_chan
628 nv50_disp_sync_mthd_chan = {
632 { "Global", 1, &nv50_disp_sync_mthd_base },
633 { "Image", 2, &nv50_disp_sync_mthd_image },
639 nv50_disp_sync_ctor(struct nouveau_object *parent,
640 struct nouveau_object *engine,
641 struct nouveau_oclass *oclass, void *data, u32 size,
642 struct nouveau_object **pobject)
645 struct nv50_disp_base_channel_dma_v0 v0;
647 struct nv50_disp_priv *priv = (void *)engine;
648 struct nv50_disp_dmac *dmac;
651 nv_ioctl(parent, "create disp base channel dma size %d\n", size);
652 if (nvif_unpack(args->v0, 0, 0, false)) {
653 nv_ioctl(parent, "create disp base channel dma vers %d "
654 "pushbuf %08x head %d\n",
655 args->v0.version, args->v0.pushbuf, args->v0.head);
656 if (args->v0.head > priv->head.nr)
661 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
662 args->v0.head, sizeof(*dmac),
664 *pobject = nv_object(dmac);
671 struct nv50_disp_chan_impl
672 nv50_disp_sync_ofuncs = {
673 .base.ctor = nv50_disp_sync_ctor,
674 .base.dtor = nv50_disp_dmac_dtor,
675 .base.init = nv50_disp_dmac_init,
676 .base.fini = nv50_disp_dmac_fini,
677 .base.ntfy = nv50_disp_chan_ntfy,
678 .base.map = nv50_disp_chan_map,
679 .base.rd32 = nv50_disp_chan_rd32,
680 .base.wr32 = nv50_disp_chan_wr32,
682 .attach = nv50_disp_dmac_object_attach,
683 .detach = nv50_disp_dmac_object_detach,
686 /*******************************************************************************
687 * EVO overlay channel objects
688 ******************************************************************************/
690 const struct nv50_disp_mthd_list
691 nv50_disp_ovly_mthd_base = {
695 { 0x0080, 0x000000 },
696 { 0x0084, 0x0009a0 },
697 { 0x0088, 0x0009c0 },
698 { 0x008c, 0x0009c8 },
699 { 0x0090, 0x6109b4 },
700 { 0x0094, 0x610970 },
701 { 0x00a0, 0x610998 },
702 { 0x00a4, 0x610964 },
703 { 0x00c0, 0x610958 },
704 { 0x00e0, 0x6109a8 },
705 { 0x00e4, 0x6109d0 },
706 { 0x00e8, 0x6109d8 },
707 { 0x0100, 0x61094c },
708 { 0x0104, 0x610984 },
709 { 0x0108, 0x61098c },
710 { 0x0800, 0x6109f8 },
711 { 0x0808, 0x610a08 },
712 { 0x080c, 0x610a10 },
713 { 0x0810, 0x610a00 },
718 static const struct nv50_disp_mthd_chan
719 nv50_disp_ovly_mthd_chan = {
723 { "Global", 1, &nv50_disp_ovly_mthd_base },
729 nv50_disp_ovly_ctor(struct nouveau_object *parent,
730 struct nouveau_object *engine,
731 struct nouveau_oclass *oclass, void *data, u32 size,
732 struct nouveau_object **pobject)
735 struct nv50_disp_overlay_channel_dma_v0 v0;
737 struct nv50_disp_priv *priv = (void *)engine;
738 struct nv50_disp_dmac *dmac;
741 nv_ioctl(parent, "create disp overlay channel dma size %d\n", size);
742 if (nvif_unpack(args->v0, 0, 0, false)) {
743 nv_ioctl(parent, "create disp overlay channel dma vers %d "
744 "pushbuf %08x head %d\n",
745 args->v0.version, args->v0.pushbuf, args->v0.head);
746 if (args->v0.head > priv->head.nr)
751 ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
752 args->v0.head, sizeof(*dmac),
754 *pobject = nv_object(dmac);
761 struct nv50_disp_chan_impl
762 nv50_disp_ovly_ofuncs = {
763 .base.ctor = nv50_disp_ovly_ctor,
764 .base.dtor = nv50_disp_dmac_dtor,
765 .base.init = nv50_disp_dmac_init,
766 .base.fini = nv50_disp_dmac_fini,
767 .base.ntfy = nv50_disp_chan_ntfy,
768 .base.map = nv50_disp_chan_map,
769 .base.rd32 = nv50_disp_chan_rd32,
770 .base.wr32 = nv50_disp_chan_wr32,
772 .attach = nv50_disp_dmac_object_attach,
773 .detach = nv50_disp_dmac_object_detach,
776 /*******************************************************************************
777 * EVO PIO channel base class
778 ******************************************************************************/
781 nv50_disp_pioc_create_(struct nouveau_object *parent,
782 struct nouveau_object *engine,
783 struct nouveau_oclass *oclass, int head,
784 int length, void **pobject)
786 return nv50_disp_chan_create_(parent, engine, oclass, head,
791 nv50_disp_pioc_dtor(struct nouveau_object *object)
793 struct nv50_disp_pioc *pioc = (void *)object;
794 nv50_disp_chan_destroy(&pioc->base);
798 nv50_disp_pioc_init(struct nouveau_object *object)
800 struct nv50_disp_priv *priv = (void *)object->engine;
801 struct nv50_disp_pioc *pioc = (void *)object;
802 int chid = pioc->base.chid;
805 ret = nv50_disp_chan_init(&pioc->base);
809 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00002000);
810 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00000000, 0x00000000)) {
811 nv_error(pioc, "timeout0: 0x%08x\n",
812 nv_rd32(priv, 0x610200 + (chid * 0x10)));
816 nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00000001);
817 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00010000)) {
818 nv_error(pioc, "timeout1: 0x%08x\n",
819 nv_rd32(priv, 0x610200 + (chid * 0x10)));
827 nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
829 struct nv50_disp_priv *priv = (void *)object->engine;
830 struct nv50_disp_pioc *pioc = (void *)object;
831 int chid = pioc->base.chid;
833 nv_mask(priv, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000);
834 if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00000000)) {
835 nv_error(pioc, "timeout: 0x%08x\n",
836 nv_rd32(priv, 0x610200 + (chid * 0x10)));
841 return nv50_disp_chan_fini(&pioc->base, suspend);
844 /*******************************************************************************
845 * EVO immediate overlay channel objects
846 ******************************************************************************/
849 nv50_disp_oimm_ctor(struct nouveau_object *parent,
850 struct nouveau_object *engine,
851 struct nouveau_oclass *oclass, void *data, u32 size,
852 struct nouveau_object **pobject)
855 struct nv50_disp_overlay_v0 v0;
857 struct nv50_disp_priv *priv = (void *)engine;
858 struct nv50_disp_pioc *pioc;
861 nv_ioctl(parent, "create disp overlay size %d\n", size);
862 if (nvif_unpack(args->v0, 0, 0, false)) {
863 nv_ioctl(parent, "create disp overlay vers %d head %d\n",
864 args->v0.version, args->v0.head);
865 if (args->v0.head > priv->head.nr)
870 ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head,
871 sizeof(*pioc), (void **)&pioc);
872 *pobject = nv_object(pioc);
879 struct nv50_disp_chan_impl
880 nv50_disp_oimm_ofuncs = {
881 .base.ctor = nv50_disp_oimm_ctor,
882 .base.dtor = nv50_disp_pioc_dtor,
883 .base.init = nv50_disp_pioc_init,
884 .base.fini = nv50_disp_pioc_fini,
885 .base.ntfy = nv50_disp_chan_ntfy,
886 .base.map = nv50_disp_chan_map,
887 .base.rd32 = nv50_disp_chan_rd32,
888 .base.wr32 = nv50_disp_chan_wr32,
892 /*******************************************************************************
893 * EVO cursor channel objects
894 ******************************************************************************/
897 nv50_disp_curs_ctor(struct nouveau_object *parent,
898 struct nouveau_object *engine,
899 struct nouveau_oclass *oclass, void *data, u32 size,
900 struct nouveau_object **pobject)
903 struct nv50_disp_cursor_v0 v0;
905 struct nv50_disp_priv *priv = (void *)engine;
906 struct nv50_disp_pioc *pioc;
909 nv_ioctl(parent, "create disp cursor size %d\n", size);
910 if (nvif_unpack(args->v0, 0, 0, false)) {
911 nv_ioctl(parent, "create disp cursor vers %d head %d\n",
912 args->v0.version, args->v0.head);
913 if (args->v0.head > priv->head.nr)
918 ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head,
919 sizeof(*pioc), (void **)&pioc);
920 *pobject = nv_object(pioc);
927 struct nv50_disp_chan_impl
928 nv50_disp_curs_ofuncs = {
929 .base.ctor = nv50_disp_curs_ctor,
930 .base.dtor = nv50_disp_pioc_dtor,
931 .base.init = nv50_disp_pioc_init,
932 .base.fini = nv50_disp_pioc_fini,
933 .base.ntfy = nv50_disp_chan_ntfy,
934 .base.map = nv50_disp_chan_map,
935 .base.rd32 = nv50_disp_chan_rd32,
936 .base.wr32 = nv50_disp_chan_wr32,
940 /*******************************************************************************
941 * Base display object
942 ******************************************************************************/
945 nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0)
947 const u32 blanke = nv_rd32(priv, 0x610aec + (head * 0x540));
948 const u32 blanks = nv_rd32(priv, 0x610af4 + (head * 0x540));
949 const u32 total = nv_rd32(priv, 0x610afc + (head * 0x540));
951 struct nv04_disp_scanoutpos_v0 v0;
955 nv_ioctl(object, "disp scanoutpos size %d\n", size);
956 if (nvif_unpack(args->v0, 0, 0, false)) {
957 nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version);
958 args->v0.vblanke = (blanke & 0xffff0000) >> 16;
959 args->v0.hblanke = (blanke & 0x0000ffff);
960 args->v0.vblanks = (blanks & 0xffff0000) >> 16;
961 args->v0.hblanks = (blanks & 0x0000ffff);
962 args->v0.vtotal = ( total & 0xffff0000) >> 16;
963 args->v0.htotal = ( total & 0x0000ffff);
964 args->v0.time[0] = ktime_to_ns(ktime_get());
965 args->v0.vline = /* vline read locks hline */
966 nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff;
967 args->v0.time[1] = ktime_to_ns(ktime_get());
969 nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff;
977 nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd,
978 void *data, u32 size)
980 const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine);
982 struct nv50_disp_mthd_v0 v0;
983 struct nv50_disp_mthd_v1 v1;
985 struct nv50_disp_priv *priv = (void *)object->engine;
986 struct nvkm_output *outp = NULL;
987 struct nvkm_output *temp;
991 if (mthd != NV50_DISP_MTHD)
994 nv_ioctl(object, "disp mthd size %d\n", size);
995 if (nvif_unpack(args->v0, 0, 0, true)) {
996 nv_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
997 args->v0.version, args->v0.method, args->v0.head);
998 mthd = args->v0.method;
999 head = args->v0.head;
1001 if (nvif_unpack(args->v1, 1, 1, true)) {
1002 nv_ioctl(object, "disp mthd vers %d mthd %02x "
1003 "type %04x mask %04x\n",
1004 args->v1.version, args->v1.method,
1005 args->v1.hasht, args->v1.hashm);
1006 mthd = args->v1.method;
1007 type = args->v1.hasht;
1008 mask = args->v1.hashm;
1009 head = ffs((mask >> 8) & 0x0f) - 1;
1013 if (head < 0 || head >= priv->head.nr)
1017 list_for_each_entry(temp, &priv->base.outp, head) {
1018 if ((temp->info.hasht == type) &&
1019 (temp->info.hashm & mask) == mask) {
1029 case NV50_DISP_SCANOUTPOS:
1030 return impl->head.scanoutpos(object, priv, data, size, head);
1035 switch (mthd * !!outp) {
1036 case NV50_DISP_MTHD_V1_DAC_PWR:
1037 return priv->dac.power(object, priv, data, size, head, outp);
1038 case NV50_DISP_MTHD_V1_DAC_LOAD:
1039 return priv->dac.sense(object, priv, data, size, head, outp);
1040 case NV50_DISP_MTHD_V1_SOR_PWR:
1041 return priv->sor.power(object, priv, data, size, head, outp);
1042 case NV50_DISP_MTHD_V1_SOR_HDA_ELD:
1043 if (!priv->sor.hda_eld)
1045 return priv->sor.hda_eld(object, priv, data, size, head, outp);
1046 case NV50_DISP_MTHD_V1_SOR_HDMI_PWR:
1047 if (!priv->sor.hdmi)
1049 return priv->sor.hdmi(object, priv, data, size, head, outp);
1050 case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: {
1052 struct nv50_disp_sor_lvds_script_v0 v0;
1054 nv_ioctl(object, "disp sor lvds script size %d\n", size);
1055 if (nvif_unpack(args->v0, 0, 0, false)) {
1056 nv_ioctl(object, "disp sor lvds script "
1057 "vers %d name %04x\n",
1058 args->v0.version, args->v0.script);
1059 priv->sor.lvdsconf = args->v0.script;
1065 case NV50_DISP_MTHD_V1_SOR_DP_PWR: {
1066 struct nvkm_output_dp *outpdp = (void *)outp;
1068 struct nv50_disp_sor_dp_pwr_v0 v0;
1070 nv_ioctl(object, "disp sor dp pwr size %d\n", size);
1071 if (nvif_unpack(args->v0, 0, 0, false)) {
1072 nv_ioctl(object, "disp sor dp pwr vers %d state %d\n",
1073 args->v0.version, args->v0.state);
1074 if (args->v0.state == 0) {
1075 nvkm_notify_put(&outpdp->irq);
1076 ((struct nvkm_output_dp_impl *)nv_oclass(outp))
1077 ->lnk_pwr(outpdp, 0);
1078 atomic_set(&outpdp->lt.done, 0);
1081 if (args->v0.state != 0) {
1082 nvkm_output_dp_train(&outpdp->base, 0, true);
1089 case NV50_DISP_MTHD_V1_PIOR_PWR:
1090 if (!priv->pior.power)
1092 return priv->pior.power(object, priv, data, size, head, outp);
1101 nv50_disp_base_ctor(struct nouveau_object *parent,
1102 struct nouveau_object *engine,
1103 struct nouveau_oclass *oclass, void *data, u32 size,
1104 struct nouveau_object **pobject)
1106 struct nv50_disp_priv *priv = (void *)engine;
1107 struct nv50_disp_base *base;
1110 ret = nouveau_parent_create(parent, engine, oclass, 0,
1111 priv->sclass, 0, &base);
1112 *pobject = nv_object(base);
1116 return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
1121 nv50_disp_base_dtor(struct nouveau_object *object)
1123 struct nv50_disp_base *base = (void *)object;
1124 nouveau_ramht_ref(NULL, &base->ramht);
1125 nouveau_parent_destroy(&base->base);
1129 nv50_disp_base_init(struct nouveau_object *object)
1131 struct nv50_disp_priv *priv = (void *)object->engine;
1132 struct nv50_disp_base *base = (void *)object;
1136 ret = nouveau_parent_init(&base->base);
1140 /* The below segments of code copying values from one register to
1141 * another appear to inform EVO of the display capabilities or
1142 * something similar. NFI what the 0x614004 caps are for..
1144 tmp = nv_rd32(priv, 0x614004);
1145 nv_wr32(priv, 0x610184, tmp);
1148 for (i = 0; i < priv->head.nr; i++) {
1149 tmp = nv_rd32(priv, 0x616100 + (i * 0x800));
1150 nv_wr32(priv, 0x610190 + (i * 0x10), tmp);
1151 tmp = nv_rd32(priv, 0x616104 + (i * 0x800));
1152 nv_wr32(priv, 0x610194 + (i * 0x10), tmp);
1153 tmp = nv_rd32(priv, 0x616108 + (i * 0x800));
1154 nv_wr32(priv, 0x610198 + (i * 0x10), tmp);
1155 tmp = nv_rd32(priv, 0x61610c + (i * 0x800));
1156 nv_wr32(priv, 0x61019c + (i * 0x10), tmp);
1160 for (i = 0; i < priv->dac.nr; i++) {
1161 tmp = nv_rd32(priv, 0x61a000 + (i * 0x800));
1162 nv_wr32(priv, 0x6101d0 + (i * 0x04), tmp);
1166 for (i = 0; i < priv->sor.nr; i++) {
1167 tmp = nv_rd32(priv, 0x61c000 + (i * 0x800));
1168 nv_wr32(priv, 0x6101e0 + (i * 0x04), tmp);
1172 for (i = 0; i < priv->pior.nr; i++) {
1173 tmp = nv_rd32(priv, 0x61e000 + (i * 0x800));
1174 nv_wr32(priv, 0x6101f0 + (i * 0x04), tmp);
1177 /* steal display away from vbios, or something like that */
1178 if (nv_rd32(priv, 0x610024) & 0x00000100) {
1179 nv_wr32(priv, 0x610024, 0x00000100);
1180 nv_mask(priv, 0x6194e8, 0x00000001, 0x00000000);
1181 if (!nv_wait(priv, 0x6194e8, 0x00000002, 0x00000000)) {
1182 nv_error(priv, "timeout acquiring display\n");
1187 /* point at display engine memory area (hash table, objects) */
1188 nv_wr32(priv, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9);
1190 /* enable supervisor interrupts, disable everything else */
1191 nv_wr32(priv, 0x61002c, 0x00000370);
1192 nv_wr32(priv, 0x610028, 0x00000000);
1197 nv50_disp_base_fini(struct nouveau_object *object, bool suspend)
1199 struct nv50_disp_priv *priv = (void *)object->engine;
1200 struct nv50_disp_base *base = (void *)object;
1202 /* disable all interrupts */
1203 nv_wr32(priv, 0x610024, 0x00000000);
1204 nv_wr32(priv, 0x610020, 0x00000000);
1206 return nouveau_parent_fini(&base->base, suspend);
1209 struct nouveau_ofuncs
1210 nv50_disp_base_ofuncs = {
1211 .ctor = nv50_disp_base_ctor,
1212 .dtor = nv50_disp_base_dtor,
1213 .init = nv50_disp_base_init,
1214 .fini = nv50_disp_base_fini,
1215 .mthd = nv50_disp_base_mthd,
1216 .ntfy = nouveau_disp_ntfy,
1219 static struct nouveau_oclass
1220 nv50_disp_base_oclass[] = {
1221 { NV50_DISP, &nv50_disp_base_ofuncs },
1225 static struct nouveau_oclass
1226 nv50_disp_sclass[] = {
1227 { NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base },
1228 { NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base },
1229 { NV50_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
1230 { NV50_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
1231 { NV50_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
1235 /*******************************************************************************
1236 * Display context, tracks instmem allocation and prevents more than one
1237 * client using the display hardware at any time.
1238 ******************************************************************************/
1241 nv50_disp_data_ctor(struct nouveau_object *parent,
1242 struct nouveau_object *engine,
1243 struct nouveau_oclass *oclass, void *data, u32 size,
1244 struct nouveau_object **pobject)
1246 struct nv50_disp_priv *priv = (void *)engine;
1247 struct nouveau_engctx *ectx;
1250 /* no context needed for channel objects... */
1251 if (nv_mclass(parent) != NV_DEVICE) {
1252 atomic_inc(&parent->refcount);
1257 /* allocate display hardware to client */
1258 mutex_lock(&nv_subdev(priv)->mutex);
1259 if (list_empty(&nv_engine(priv)->contexts)) {
1260 ret = nouveau_engctx_create(parent, engine, oclass, NULL,
1262 NVOBJ_FLAG_HEAP, &ectx);
1263 *pobject = nv_object(ectx);
1265 mutex_unlock(&nv_subdev(priv)->mutex);
1269 struct nouveau_oclass
1270 nv50_disp_cclass = {
1271 .handle = NV_ENGCTX(DISP, 0x50),
1272 .ofuncs = &(struct nouveau_ofuncs) {
1273 .ctor = nv50_disp_data_ctor,
1274 .dtor = _nouveau_engctx_dtor,
1275 .init = _nouveau_engctx_init,
1276 .fini = _nouveau_engctx_fini,
1277 .rd32 = _nouveau_engctx_rd32,
1278 .wr32 = _nouveau_engctx_wr32,
1282 /*******************************************************************************
1283 * Display engine implementation
1284 ******************************************************************************/
1287 nv50_disp_vblank_fini(struct nvkm_event *event, int type, int head)
1289 struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
1290 nv_mask(disp, 0x61002c, (4 << head), 0);
1294 nv50_disp_vblank_init(struct nvkm_event *event, int type, int head)
1296 struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
1297 nv_mask(disp, 0x61002c, (4 << head), (4 << head));
1300 const struct nvkm_event_func
1301 nv50_disp_vblank_func = {
1302 .ctor = nouveau_disp_vblank_ctor,
1303 .init = nv50_disp_vblank_init,
1304 .fini = nv50_disp_vblank_fini,
1307 static const struct nouveau_enum
1308 nv50_disp_intr_error_type[] = {
1309 { 3, "ILLEGAL_MTHD" },
1310 { 4, "INVALID_VALUE" },
1311 { 5, "INVALID_STATE" },
1312 { 7, "INVALID_HANDLE" },
1316 static const struct nouveau_enum
1317 nv50_disp_intr_error_code[] = {
1323 nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid)
1325 struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
1326 u32 data = nv_rd32(priv, 0x610084 + (chid * 0x08));
1327 u32 addr = nv_rd32(priv, 0x610080 + (chid * 0x08));
1328 u32 code = (addr & 0x00ff0000) >> 16;
1329 u32 type = (addr & 0x00007000) >> 12;
1330 u32 mthd = (addr & 0x00000ffc);
1331 const struct nouveau_enum *ec, *et;
1332 char ecunk[6], etunk[6];
1334 et = nouveau_enum_find(nv50_disp_intr_error_type, type);
1336 snprintf(etunk, sizeof(etunk), "UNK%02X", type);
1338 ec = nouveau_enum_find(nv50_disp_intr_error_code, code);
1340 snprintf(ecunk, sizeof(ecunk), "UNK%02X", code);
1342 nv_error(priv, "%s [%s] chid %d mthd 0x%04x data 0x%08x\n",
1343 et ? et->name : etunk, ec ? ec->name : ecunk,
1349 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0,
1359 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1,
1369 nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 3,
1377 nv_wr32(priv, 0x610020, 0x00010000 << chid);
1378 nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000);
1381 static struct nvkm_output *
1382 exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
1383 u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
1384 struct nvbios_outp *info)
1386 struct nouveau_bios *bios = nouveau_bios(priv);
1387 struct nvkm_output *outp;
1391 type = DCB_OUTPUT_ANALOG;
1395 switch (ctrl & 0x00000f00) {
1396 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
1397 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
1398 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
1399 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
1400 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
1401 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
1403 nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
1411 switch (ctrl & 0x00000f00) {
1412 case 0x00000000: type |= priv->pior.type[or]; break;
1414 nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl);
1419 mask = 0x00c0 & (mask << 6);
1420 mask |= 0x0001 << or;
1421 mask |= 0x0100 << head;
1423 list_for_each_entry(outp, &priv->base.outp, head) {
1424 if ((outp->info.hasht & 0xff) == type &&
1425 (outp->info.hashm & mask) == mask) {
1426 *data = nvbios_outp_match(bios, outp->info.hasht,
1428 ver, hdr, cnt, len, info);
1438 static struct nvkm_output *
1439 exec_script(struct nv50_disp_priv *priv, int head, int id)
1441 struct nouveau_bios *bios = nouveau_bios(priv);
1442 struct nvkm_output *outp;
1443 struct nvbios_outp info;
1444 u8 ver, hdr, cnt, len;
1450 for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++)
1451 ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
1454 if (!(ctrl & (1 << head))) {
1455 if (nv_device(priv)->chipset < 0x90 ||
1456 nv_device(priv)->chipset == 0x92 ||
1457 nv_device(priv)->chipset == 0xa0) {
1462 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++)
1463 ctrl = nv_rd32(priv, reg + (i * 8));
1468 if (!(ctrl & (1 << head))) {
1469 for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++)
1470 ctrl = nv_rd32(priv, 0x610b84 + (i * 8));
1474 if (!(ctrl & (1 << head)))
1478 outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
1480 struct nvbios_init init = {
1481 .subdev = nv_subdev(priv),
1483 .offset = info.script[id],
1484 .outp = &outp->info,
1495 static struct nvkm_output *
1496 exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
1498 struct nouveau_bios *bios = nouveau_bios(priv);
1499 struct nvkm_output *outp;
1500 struct nvbios_outp info1;
1501 struct nvbios_ocfg info2;
1502 u8 ver, hdr, cnt, len;
1508 for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++)
1509 ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
1512 if (!(ctrl & (1 << head))) {
1513 if (nv_device(priv)->chipset < 0x90 ||
1514 nv_device(priv)->chipset == 0x92 ||
1515 nv_device(priv)->chipset == 0xa0) {
1520 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++)
1521 ctrl = nv_rd32(priv, reg + (i * 8));
1526 if (!(ctrl & (1 << head))) {
1527 for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++)
1528 ctrl = nv_rd32(priv, 0x610b80 + (i * 8));
1532 if (!(ctrl & (1 << head)))
1536 outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
1540 if (outp->info.location == 0) {
1541 switch (outp->info.type) {
1542 case DCB_OUTPUT_TMDS:
1543 *conf = (ctrl & 0x00000f00) >> 8;
1547 case DCB_OUTPUT_LVDS:
1548 *conf = priv->sor.lvdsconf;
1551 *conf = (ctrl & 0x00000f00) >> 8;
1553 case DCB_OUTPUT_ANALOG:
1559 *conf = (ctrl & 0x00000f00) >> 8;
1563 data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
1564 if (data && id < 0xff) {
1565 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
1567 struct nvbios_init init = {
1568 .subdev = nv_subdev(priv),
1571 .outp = &outp->info,
1584 nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head)
1586 exec_script(priv, head, 1);
1590 nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
1592 struct nvkm_output *outp = exec_script(priv, head, 2);
1594 /* the binary driver does this outside of the supervisor handling
1595 * (after the third supervisor from a detach). we (currently?)
1596 * allow both detach/attach to happen in the same set of
1597 * supervisor interrupts, so it would make sense to execute this
1598 * (full power down?) script after all the detach phases of the
1599 * supervisor handling. like with training if needed from the
1600 * second supervisor, nvidia doesn't do this, so who knows if it's
1601 * entirely safe, but it does appear to work..
1603 * without this script being run, on some configurations i've
1604 * seen, switching from DP to TMDS on a DP connector may result
1605 * in a blank screen (SOR_PWR off/on can restore it)
1607 if (outp && outp->info.type == DCB_OUTPUT_DP) {
1608 struct nvkm_output_dp *outpdp = (void *)outp;
1609 struct nvbios_init init = {
1610 .subdev = nv_subdev(priv),
1611 .bios = nouveau_bios(priv),
1612 .outp = &outp->info,
1614 .offset = outpdp->info.script[4],
1619 atomic_set(&outpdp->lt.done, 0);
1624 nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
1626 struct nouveau_devinit *devinit = nouveau_devinit(priv);
1627 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1629 devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
1633 nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, int head,
1634 struct dcb_output *outp, u32 pclk)
1636 const int link = !(outp->sorconf.link & 1);
1637 const int or = ffs(outp->or) - 1;
1638 const u32 soff = ( or * 0x800);
1639 const u32 loff = (link * 0x080) + soff;
1640 const u32 ctrl = nv_rd32(priv, 0x610794 + (or * 8));
1641 const u32 symbol = 100000;
1642 const s32 vactive = nv_rd32(priv, 0x610af8 + (head * 0x540)) & 0xffff;
1643 const s32 vblanke = nv_rd32(priv, 0x610ae8 + (head * 0x540)) & 0xffff;
1644 const s32 vblanks = nv_rd32(priv, 0x610af0 + (head * 0x540)) & 0xffff;
1645 u32 dpctrl = nv_rd32(priv, 0x61c10c + loff);
1646 u32 clksor = nv_rd32(priv, 0x614300 + soff);
1647 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
1648 int TU, VTUi, VTUf, VTUa;
1649 u64 link_data_rate, link_ratio, unk;
1650 u32 best_diff = 64 * symbol;
1651 u32 link_nr, link_bw, bits;
1654 link_bw = (clksor & 0x000c0000) ? 270000 : 162000;
1655 link_nr = hweight32(dpctrl & 0x000f0000);
1657 /* symbols/hblank - algorithm taken from comments in tegra driver */
1658 value = vblanke + vactive - vblanks - 7;
1659 value = value * link_bw;
1660 do_div(value, pclk);
1661 value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr);
1662 nv_mask(priv, 0x61c1e8 + soff, 0x0000ffff, value);
1664 /* symbols/vblank - algorithm taken from comments in tegra driver */
1665 value = vblanks - vblanke - 25;
1666 value = value * link_bw;
1667 do_div(value, pclk);
1668 value = value - ((36 / link_nr) + 3) - 1;
1669 nv_mask(priv, 0x61c1ec + soff, 0x00ffffff, value);
1671 /* watermark / activesym */
1672 if ((ctrl & 0xf0000) == 0x60000) bits = 30;
1673 else if ((ctrl & 0xf0000) == 0x50000) bits = 24;
1676 link_data_rate = (pclk * bits / 8) / link_nr;
1678 /* calculate ratio of packed data rate to link symbol rate */
1679 link_ratio = link_data_rate * symbol;
1680 do_div(link_ratio, link_bw);
1682 for (TU = 64; TU >= 32; TU--) {
1683 /* calculate average number of valid symbols in each TU */
1684 u32 tu_valid = link_ratio * TU;
1687 /* find a hw representation for the fraction.. */
1688 VTUi = tu_valid / symbol;
1689 calc = VTUi * symbol;
1690 diff = tu_valid - calc;
1692 if (diff >= (symbol / 2)) {
1693 VTUf = symbol / (symbol - diff);
1694 if (symbol - (VTUf * diff))
1699 calc += symbol - (symbol / VTUf);
1707 VTUf = min((int)(symbol / diff), 15);
1708 calc += symbol / VTUf;
1711 diff = calc - tu_valid;
1713 /* no remainder, but the hw doesn't like the fractional
1714 * part to be zero. decrement the integer part and
1715 * have the fraction add a whole symbol back
1722 if (diff < best_diff) {
1734 nv_error(priv, "unable to find suitable dp config\n");
1738 /* XXX close to vbios numbers, but not right */
1739 unk = (symbol - link_ratio) * bestTU;
1741 do_div(unk, symbol);
1742 do_div(unk, symbol);
1745 nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2);
1746 nv_mask(priv, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 |
1748 bestVTUi << 8 | unk);
1752 nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
1754 struct nvkm_output *outp;
1755 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1756 u32 hval, hreg = 0x614200 + (head * 0x800);
1760 outp = exec_clkcmp(priv, head, 0xff, pclk, &conf);
1764 /* we allow both encoder attach and detach operations to occur
1765 * within a single supervisor (ie. modeset) sequence. the
1766 * encoder detach scripts quite often switch off power to the
1767 * lanes, which requires the link to be re-trained.
1769 * this is not generally an issue as the sink "must" (heh)
1770 * signal an irq when it's lost sync so the driver can
1773 * however, on some boards, if one does not configure at least
1774 * the gpu side of the link *before* attaching, then various
1775 * things can go horribly wrong (PDISP disappearing from mmio,
1776 * third supervisor never happens, etc).
1778 * the solution is simply to retrain here, if necessary. last
1779 * i checked, the binary driver userspace does not appear to
1780 * trigger this situation (it forces an UPDATE between steps).
1782 if (outp->info.type == DCB_OUTPUT_DP) {
1783 u32 soff = (ffs(outp->info.or) - 1) * 0x08;
1786 if (outp->info.location == 0) {
1787 ctrl = nv_rd32(priv, 0x610794 + soff);
1790 ctrl = nv_rd32(priv, 0x610b80 + soff);
1794 switch ((ctrl & 0x000f0000) >> 16) {
1795 case 6: datarate = pclk * 30; break;
1796 case 5: datarate = pclk * 24; break;
1799 datarate = pclk * 18;
1803 if (nvkm_output_dp_train(outp, datarate / soff, true))
1804 ERR("link not trained before attach\n");
1807 exec_clkcmp(priv, head, 0, pclk, &conf);
1809 if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) {
1810 oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800;
1815 if (!outp->info.location) {
1816 if (outp->info.type == DCB_OUTPUT_DP)
1817 nv50_disp_intr_unk20_2_dp(priv, head, &outp->info, pclk);
1818 oreg = 0x614300 + (ffs(outp->info.or) - 1) * 0x800;
1819 oval = (conf & 0x0100) ? 0x00000101 : 0x00000000;
1823 oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800;
1829 nv_mask(priv, hreg, 0x0000000f, hval);
1830 nv_mask(priv, oreg, mask, oval);
1833 /* If programming a TMDS output on a SOR that can also be configured for
1834 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
1836 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
1837 * the VBIOS scripts on at least one board I have only switch it off on
1838 * link 0, causing a blank display if the output has previously been
1839 * programmed for DisplayPort.
1842 nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp)
1844 struct nouveau_bios *bios = nouveau_bios(priv);
1845 const int link = !(outp->sorconf.link & 1);
1846 const int or = ffs(outp->or) - 1;
1847 const u32 loff = (or * 0x800) + (link * 0x80);
1848 const u16 mask = (outp->sorconf.link << 6) | outp->or;
1851 if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, outp))
1852 nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000);
1856 nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head)
1858 struct nvkm_output *outp;
1859 u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1862 outp = exec_clkcmp(priv, head, 1, pclk, &conf);
1866 if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS)
1867 nv50_disp_intr_unk40_0_tmds(priv, &outp->info);
1871 nv50_disp_intr_supervisor(struct work_struct *work)
1873 struct nv50_disp_priv *priv =
1874 container_of(work, struct nv50_disp_priv, supervisor);
1875 struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
1876 u32 super = nv_rd32(priv, 0x610030);
1879 nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
1881 if (priv->super & 0x00000010) {
1882 nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core);
1883 for (head = 0; head < priv->head.nr; head++) {
1884 if (!(super & (0x00000020 << head)))
1886 if (!(super & (0x00000080 << head)))
1888 nv50_disp_intr_unk10_0(priv, head);
1891 if (priv->super & 0x00000020) {
1892 for (head = 0; head < priv->head.nr; head++) {
1893 if (!(super & (0x00000080 << head)))
1895 nv50_disp_intr_unk20_0(priv, head);
1897 for (head = 0; head < priv->head.nr; head++) {
1898 if (!(super & (0x00000200 << head)))
1900 nv50_disp_intr_unk20_1(priv, head);
1902 for (head = 0; head < priv->head.nr; head++) {
1903 if (!(super & (0x00000080 << head)))
1905 nv50_disp_intr_unk20_2(priv, head);
1908 if (priv->super & 0x00000040) {
1909 for (head = 0; head < priv->head.nr; head++) {
1910 if (!(super & (0x00000080 << head)))
1912 nv50_disp_intr_unk40_0(priv, head);
1916 nv_wr32(priv, 0x610030, 0x80000000);
1920 nv50_disp_intr(struct nouveau_subdev *subdev)
1922 struct nv50_disp_priv *priv = (void *)subdev;
1923 u32 intr0 = nv_rd32(priv, 0x610020);
1924 u32 intr1 = nv_rd32(priv, 0x610024);
1926 while (intr0 & 0x001f0000) {
1927 u32 chid = __ffs(intr0 & 0x001f0000) - 16;
1928 nv50_disp_intr_error(priv, chid);
1929 intr0 &= ~(0x00010000 << chid);
1932 while (intr0 & 0x0000001f) {
1933 u32 chid = __ffs(intr0 & 0x0000001f);
1934 nv50_disp_chan_uevent_send(priv, chid);
1935 intr0 &= ~(0x00000001 << chid);
1938 if (intr1 & 0x00000004) {
1939 nouveau_disp_vblank(&priv->base, 0);
1940 nv_wr32(priv, 0x610024, 0x00000004);
1941 intr1 &= ~0x00000004;
1944 if (intr1 & 0x00000008) {
1945 nouveau_disp_vblank(&priv->base, 1);
1946 nv_wr32(priv, 0x610024, 0x00000008);
1947 intr1 &= ~0x00000008;
1950 if (intr1 & 0x00000070) {
1951 priv->super = (intr1 & 0x00000070);
1952 schedule_work(&priv->supervisor);
1953 nv_wr32(priv, 0x610024, priv->super);
1954 intr1 &= ~0x00000070;
1959 nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1960 struct nouveau_oclass *oclass, void *data, u32 size,
1961 struct nouveau_object **pobject)
1963 struct nv50_disp_priv *priv;
1966 ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
1968 *pobject = nv_object(priv);
1972 ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
1976 nv_engine(priv)->sclass = nv50_disp_base_oclass;
1977 nv_engine(priv)->cclass = &nv50_disp_cclass;
1978 nv_subdev(priv)->intr = nv50_disp_intr;
1979 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
1980 priv->sclass = nv50_disp_sclass;
1985 priv->dac.power = nv50_dac_power;
1986 priv->dac.sense = nv50_dac_sense;
1987 priv->sor.power = nv50_sor_power;
1988 priv->pior.power = nv50_pior_power;
1992 struct nouveau_oclass *
1993 nv50_disp_outp_sclass[] = {
1994 &nv50_pior_dp_impl.base.base,
1998 struct nouveau_oclass *
1999 nv50_disp_oclass = &(struct nv50_disp_impl) {
2000 .base.base.handle = NV_ENGINE(DISP, 0x50),
2001 .base.base.ofuncs = &(struct nouveau_ofuncs) {
2002 .ctor = nv50_disp_ctor,
2003 .dtor = _nouveau_disp_dtor,
2004 .init = _nouveau_disp_init,
2005 .fini = _nouveau_disp_fini,
2007 .base.vblank = &nv50_disp_vblank_func,
2008 .base.outp = nv50_disp_outp_sclass,
2009 .mthd.core = &nv50_disp_mast_mthd_chan,
2010 .mthd.base = &nv50_disp_sync_mthd_chan,
2011 .mthd.ovly = &nv50_disp_ovly_mthd_chan,
2012 .mthd.prev = 0x000004,
2013 .head.scanoutpos = nv50_disp_base_scanoutpos,