]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
Merge tag 'ipu-fixes-3.18' of git://git.pengutronix.de/git/pza/linux into drm-next
[karo-tx-linux.git] / drivers / gpu / drm / nouveau / core / engine / disp / nv50.c
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/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>
33
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>
42
43 #include "nv50.h"
44
45 /*******************************************************************************
46  * EVO channel base class
47  ******************************************************************************/
48
49 static int
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)
54 {
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;
59         int ret;
60
61         if (base->chan & (1 << chid))
62                 return -EBUSY;
63         base->chan |= (1 << chid);
64
65         ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
66                                      (1ULL << NVDEV_ENGINE_DMAOBJ),
67                                      length, pobject);
68         chan = *pobject;
69         if (ret)
70                 return ret;
71         chan->chid = chid;
72
73         nv_parent(chan)->object_attach = impl->attach;
74         nv_parent(chan)->object_detach = impl->detach;
75         return 0;
76 }
77
78 static void
79 nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
80 {
81         struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
82         base->chan &= ~(1 << chan->chid);
83         nouveau_namedb_destroy(&chan->base);
84 }
85
86 static void
87 nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
88 {
89         struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
90         nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index);
91 }
92
93 static void
94 nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
95 {
96         struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
97         nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index);
98 }
99
100 void
101 nv50_disp_chan_uevent_send(struct nv50_disp_priv *priv, int chid)
102 {
103         struct nvif_notify_uevent_rep {
104         } rep;
105
106         nvkm_event_send(&priv->uevent, 1, chid, &rep, sizeof(rep));
107 }
108
109 int
110 nv50_disp_chan_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
111                            struct nvkm_notify *notify)
112 {
113         struct nv50_disp_dmac *dmac = (void *)object;
114         union {
115                 struct nvif_notify_uevent_req none;
116         } *args = data;
117         int ret;
118
119         if (nvif_unvers(args->none)) {
120                 notify->size  = sizeof(struct nvif_notify_uevent_rep);
121                 notify->types = 1;
122                 notify->index = dmac->base.chid;
123                 return 0;
124         }
125
126         return ret;
127 }
128
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,
134 };
135
136 int
137 nv50_disp_chan_ntfy(struct nouveau_object *object, u32 type,
138                     struct nvkm_event **pevent)
139 {
140         struct nv50_disp_priv *priv = (void *)object->engine;
141         switch (type) {
142         case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT:
143                 *pevent = &priv->uevent;
144                 return 0;
145         default:
146                 break;
147         }
148         return -EINVAL;
149 }
150
151 int
152 nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
153 {
154         struct nv50_disp_chan *chan = (void *)object;
155         *addr = nv_device_resource_start(nv_device(object), 0) +
156                 0x640000 + (chan->chid * 0x1000);
157         *size = 0x001000;
158         return 0;
159 }
160
161 u32
162 nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
163 {
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);
167 }
168
169 void
170 nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data)
171 {
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);
175 }
176
177 /*******************************************************************************
178  * EVO DMA channel base class
179  ******************************************************************************/
180
181 static int
182 nv50_disp_dmac_object_attach(struct nouveau_object *parent,
183                              struct nouveau_object *object, u32 name)
184 {
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);
191 }
192
193 static void
194 nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
195 {
196         struct nv50_disp_base *base = (void *)parent->parent;
197         nouveau_ramht_remove(base->ramht, cookie);
198 }
199
200 static int
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)
205 {
206         struct nv50_disp_dmac *dmac;
207         int ret;
208
209         ret = nv50_disp_chan_create_(parent, engine, oclass, head,
210                                      length, pobject);
211         dmac = *pobject;
212         if (ret)
213                 return ret;
214
215         dmac->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
216         if (!dmac->pushdma)
217                 return -ENOENT;
218
219         switch (nv_mclass(dmac->pushdma)) {
220         case 0x0002:
221         case 0x003d:
222                 if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff)
223                         return -EINVAL;
224
225                 switch (dmac->pushdma->target) {
226                 case NV_MEM_TARGET_VRAM:
227                         dmac->push = 0x00000000 | dmac->pushdma->start >> 8;
228                         break;
229                 case NV_MEM_TARGET_PCI_NOSNOOP:
230                         dmac->push = 0x00000003 | dmac->pushdma->start >> 8;
231                         break;
232                 default:
233                         return -EINVAL;
234                 }
235                 break;
236         default:
237                 return -EINVAL;
238         }
239
240         return 0;
241 }
242
243 void
244 nv50_disp_dmac_dtor(struct nouveau_object *object)
245 {
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);
249 }
250
251 static int
252 nv50_disp_dmac_init(struct nouveau_object *object)
253 {
254         struct nv50_disp_priv *priv = (void *)object->engine;
255         struct nv50_disp_dmac *dmac = (void *)object;
256         int chid = dmac->base.chid;
257         int ret;
258
259         ret = nv50_disp_chan_init(&dmac->base);
260         if (ret)
261                 return ret;
262
263         /* enable error reporting */
264         nv_mask(priv, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
265
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);
273
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)));
278                 return -EBUSY;
279         }
280
281         return 0;
282 }
283
284 static int
285 nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
286 {
287         struct nv50_disp_priv *priv = (void *)object->engine;
288         struct nv50_disp_dmac *dmac = (void *)object;
289         int chid = dmac->base.chid;
290
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)));
297                 if (suspend)
298                         return -EBUSY;
299         }
300
301         /* disable error reporting and completion notifications */
302         nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
303
304         return nv50_disp_chan_fini(&dmac->base, suspend);
305 }
306
307 /*******************************************************************************
308  * EVO master channel object
309  ******************************************************************************/
310
311 static void
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)
314 {
315         struct nouveau_object *disp = nv_object(priv);
316         int i;
317
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;
324                         char mods[16];
325
326                         if (prev != next)
327                                 snprintf(mods, sizeof(mods), "-> 0x%08x", next);
328                         else
329                                 snprintf(mods, sizeof(mods), "%13c", ' ');
330
331                         nv_printk_(disp, debug, "\t0x%04x: 0x%08x %s%s%s\n",
332                                    mthd, prev, mods, name ? " // " : "",
333                                    name ? name : "");
334                 }
335         }
336 }
337
338 void
339 nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head,
340                     const struct nv50_disp_mthd_chan *chan)
341 {
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;
345         int i, j;
346
347         if (debug > nv_subdev(priv)->debug)
348                 return;
349
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];
356
357                         if (chan->addr) {
358                                 snprintf(cname_, sizeof(cname_), "%s %d",
359                                          chan->name, head);
360                                 cname = cname_;
361                         }
362
363                         if (chan->data[i].nr > 1) {
364                                 snprintf(sname_, sizeof(sname_), " - %s %d",
365                                          chan->data[i].name, j);
366                                 sname = sname_;
367                         }
368
369                         nv_printk_(disp, debug, "%s%s:\n", cname, sname);
370                         nv50_disp_mthd_list(priv, debug, base, impl->mthd.prev,
371                                             list, j);
372                 }
373         }
374 }
375
376 const struct nv50_disp_mthd_list
377 nv50_disp_mast_mthd_base = {
378         .mthd = 0x0000,
379         .addr = 0x000000,
380         .data = {
381                 { 0x0080, 0x000000 },
382                 { 0x0084, 0x610bb8 },
383                 { 0x0088, 0x610b9c },
384                 { 0x008c, 0x000000 },
385                 {}
386         }
387 };
388
389 static const struct nv50_disp_mthd_list
390 nv50_disp_mast_mthd_dac = {
391         .mthd = 0x0080,
392         .addr = 0x000008,
393         .data = {
394                 { 0x0400, 0x610b58 },
395                 { 0x0404, 0x610bdc },
396                 { 0x0420, 0x610828 },
397                 {}
398         }
399 };
400
401 const struct nv50_disp_mthd_list
402 nv50_disp_mast_mthd_sor = {
403         .mthd = 0x0040,
404         .addr = 0x000008,
405         .data = {
406                 { 0x0600, 0x610b70 },
407                 {}
408         }
409 };
410
411 const struct nv50_disp_mthd_list
412 nv50_disp_mast_mthd_pior = {
413         .mthd = 0x0040,
414         .addr = 0x000008,
415         .data = {
416                 { 0x0700, 0x610b80 },
417                 {}
418         }
419 };
420
421 static const struct nv50_disp_mthd_list
422 nv50_disp_mast_mthd_head = {
423         .mthd = 0x0400,
424         .addr = 0x000540,
425         .data = {
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 },
464                 {}
465         }
466 };
467
468 static const struct nv50_disp_mthd_chan
469 nv50_disp_mast_mthd_chan = {
470         .name = "Core",
471         .addr = 0x000000,
472         .data = {
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 },
478                 {}
479         }
480 };
481
482 int
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)
487 {
488         union {
489                 struct nv50_disp_core_channel_dma_v0 v0;
490         } *args = data;
491         struct nv50_disp_dmac *mast;
492         int ret;
493
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 "
497                                  "pushbuf %08x\n",
498                          args->v0.version, args->v0.pushbuf);
499         } else
500                 return ret;
501
502         ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
503                                      0, sizeof(*mast), (void **)&mast);
504         *pobject = nv_object(mast);
505         if (ret)
506                 return ret;
507
508         return 0;
509 }
510
511 static int
512 nv50_disp_mast_init(struct nouveau_object *object)
513 {
514         struct nv50_disp_priv *priv = (void *)object->engine;
515         struct nv50_disp_dmac *mast = (void *)object;
516         int ret;
517
518         ret = nv50_disp_chan_init(&mast->base);
519         if (ret)
520                 return ret;
521
522         /* enable error reporting */
523         nv_mask(priv, 0x610028, 0x00010000, 0x00010000);
524
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);
530
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);
538
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));
542                 return -EBUSY;
543         }
544
545         return 0;
546 }
547
548 static int
549 nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
550 {
551         struct nv50_disp_priv *priv = (void *)object->engine;
552         struct nv50_disp_dmac *mast = (void *)object;
553
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));
559                 if (suspend)
560                         return -EBUSY;
561         }
562
563         /* disable error reporting and completion notifications */
564         nv_mask(priv, 0x610028, 0x00010001, 0x00000000);
565
566         return nv50_disp_chan_fini(&mast->base, suspend);
567 }
568
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,
579         .chid = 0,
580         .attach = nv50_disp_dmac_object_attach,
581         .detach = nv50_disp_dmac_object_detach,
582 };
583
584 /*******************************************************************************
585  * EVO sync channel objects
586  ******************************************************************************/
587
588 static const struct nv50_disp_mthd_list
589 nv50_disp_sync_mthd_base = {
590         .mthd = 0x0000,
591         .addr = 0x000000,
592         .data = {
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 },
609                 {}
610         }
611 };
612
613 const struct nv50_disp_mthd_list
614 nv50_disp_sync_mthd_image = {
615         .mthd = 0x0400,
616         .addr = 0x000000,
617         .data = {
618                 { 0x0800, 0x6108f0 },
619                 { 0x0804, 0x6108fc },
620                 { 0x0808, 0x61090c },
621                 { 0x080c, 0x610914 },
622                 { 0x0810, 0x610904 },
623                 {}
624         }
625 };
626
627 static const struct nv50_disp_mthd_chan
628 nv50_disp_sync_mthd_chan = {
629         .name = "Base",
630         .addr = 0x000540,
631         .data = {
632                 { "Global", 1, &nv50_disp_sync_mthd_base },
633                 {  "Image", 2, &nv50_disp_sync_mthd_image },
634                 {}
635         }
636 };
637
638 int
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)
643 {
644         union {
645                 struct nv50_disp_base_channel_dma_v0 v0;
646         } *args = data;
647         struct nv50_disp_priv *priv = (void *)engine;
648         struct nv50_disp_dmac *dmac;
649         int ret;
650
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)
657                         return -EINVAL;
658         } else
659                 return ret;
660
661         ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
662                                      args->v0.head, sizeof(*dmac),
663                                      (void **)&dmac);
664         *pobject = nv_object(dmac);
665         if (ret)
666                 return ret;
667
668         return 0;
669 }
670
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,
681         .chid = 1,
682         .attach = nv50_disp_dmac_object_attach,
683         .detach = nv50_disp_dmac_object_detach,
684 };
685
686 /*******************************************************************************
687  * EVO overlay channel objects
688  ******************************************************************************/
689
690 const struct nv50_disp_mthd_list
691 nv50_disp_ovly_mthd_base = {
692         .mthd = 0x0000,
693         .addr = 0x000000,
694         .data = {
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 },
714                 {}
715         }
716 };
717
718 static const struct nv50_disp_mthd_chan
719 nv50_disp_ovly_mthd_chan = {
720         .name = "Overlay",
721         .addr = 0x000540,
722         .data = {
723                 { "Global", 1, &nv50_disp_ovly_mthd_base },
724                 {}
725         }
726 };
727
728 int
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)
733 {
734         union {
735                 struct nv50_disp_overlay_channel_dma_v0 v0;
736         } *args = data;
737         struct nv50_disp_priv *priv = (void *)engine;
738         struct nv50_disp_dmac *dmac;
739         int ret;
740
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)
747                         return -EINVAL;
748         } else
749                 return ret;
750
751         ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf,
752                                      args->v0.head, sizeof(*dmac),
753                                      (void **)&dmac);
754         *pobject = nv_object(dmac);
755         if (ret)
756                 return ret;
757
758         return 0;
759 }
760
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,
771         .chid = 3,
772         .attach = nv50_disp_dmac_object_attach,
773         .detach = nv50_disp_dmac_object_detach,
774 };
775
776 /*******************************************************************************
777  * EVO PIO channel base class
778  ******************************************************************************/
779
780 static int
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)
785 {
786         return nv50_disp_chan_create_(parent, engine, oclass, head,
787                                       length, pobject);
788 }
789
790 void
791 nv50_disp_pioc_dtor(struct nouveau_object *object)
792 {
793         struct nv50_disp_pioc *pioc = (void *)object;
794         nv50_disp_chan_destroy(&pioc->base);
795 }
796
797 static int
798 nv50_disp_pioc_init(struct nouveau_object *object)
799 {
800         struct nv50_disp_priv *priv = (void *)object->engine;
801         struct nv50_disp_pioc *pioc = (void *)object;
802         int chid = pioc->base.chid;
803         int ret;
804
805         ret = nv50_disp_chan_init(&pioc->base);
806         if (ret)
807                 return ret;
808
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)));
813                 return -EBUSY;
814         }
815
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)));
820                 return -EBUSY;
821         }
822
823         return 0;
824 }
825
826 static int
827 nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
828 {
829         struct nv50_disp_priv *priv = (void *)object->engine;
830         struct nv50_disp_pioc *pioc = (void *)object;
831         int chid = pioc->base.chid;
832
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)));
837                 if (suspend)
838                         return -EBUSY;
839         }
840
841         return nv50_disp_chan_fini(&pioc->base, suspend);
842 }
843
844 /*******************************************************************************
845  * EVO immediate overlay channel objects
846  ******************************************************************************/
847
848 int
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)
853 {
854         union {
855                 struct nv50_disp_overlay_v0 v0;
856         } *args = data;
857         struct nv50_disp_priv *priv = (void *)engine;
858         struct nv50_disp_pioc *pioc;
859         int ret;
860
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)
866                         return -EINVAL;
867         } else
868                 return ret;
869
870         ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head,
871                                      sizeof(*pioc), (void **)&pioc);
872         *pobject = nv_object(pioc);
873         if (ret)
874                 return ret;
875
876         return 0;
877 }
878
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,
889         .chid = 5,
890 };
891
892 /*******************************************************************************
893  * EVO cursor channel objects
894  ******************************************************************************/
895
896 int
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)
901 {
902         union {
903                 struct nv50_disp_cursor_v0 v0;
904         } *args = data;
905         struct nv50_disp_priv *priv = (void *)engine;
906         struct nv50_disp_pioc *pioc;
907         int ret;
908
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)
914                         return -EINVAL;
915         } else
916                 return ret;
917
918         ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head,
919                                      sizeof(*pioc), (void **)&pioc);
920         *pobject = nv_object(pioc);
921         if (ret)
922                 return ret;
923
924         return 0;
925 }
926
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,
937         .chid = 7,
938 };
939
940 /*******************************************************************************
941  * Base display object
942  ******************************************************************************/
943
944 int
945 nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0)
946 {
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));
950         union {
951                 struct nv04_disp_scanoutpos_v0 v0;
952         } *args = data;
953         int ret;
954
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());
968                 args->v0.hline =
969                         nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff;
970         } else
971                 return ret;
972
973         return 0;
974 }
975
976 int
977 nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd,
978                     void *data, u32 size)
979 {
980         const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine);
981         union {
982                 struct nv50_disp_mthd_v0 v0;
983                 struct nv50_disp_mthd_v1 v1;
984         } *args = data;
985         struct nv50_disp_priv *priv = (void *)object->engine;
986         struct nvkm_output *outp = NULL;
987         struct nvkm_output *temp;
988         u16 type, mask = 0;
989         int head, ret;
990
991         if (mthd != NV50_DISP_MTHD)
992                 return -EINVAL;
993
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;
1000         } else
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;
1010         } else
1011                 return ret;
1012
1013         if (head < 0 || head >= priv->head.nr)
1014                 return -ENXIO;
1015
1016         if (mask) {
1017                 list_for_each_entry(temp, &priv->base.outp, head) {
1018                         if ((temp->info.hasht         == type) &&
1019                             (temp->info.hashm & mask) == mask) {
1020                                 outp = temp;
1021                                 break;
1022                         }
1023                 }
1024                 if (outp == NULL)
1025                         return -ENXIO;
1026         }
1027
1028         switch (mthd) {
1029         case NV50_DISP_SCANOUTPOS:
1030                 return impl->head.scanoutpos(object, priv, data, size, head);
1031         default:
1032                 break;
1033         }
1034
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)
1044                         return -ENODEV;
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)
1048                         return -ENODEV;
1049                 return priv->sor.hdmi(object, priv, data, size, head, outp);
1050         case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: {
1051                 union {
1052                         struct nv50_disp_sor_lvds_script_v0 v0;
1053                 } *args = data;
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;
1060                         return 0;
1061                 } else
1062                         return ret;
1063         }
1064                 break;
1065         case NV50_DISP_MTHD_V1_SOR_DP_PWR: {
1066                 struct nvkm_output_dp *outpdp = (void *)outp;
1067                 union {
1068                         struct nv50_disp_sor_dp_pwr_v0 v0;
1069                 } *args = data;
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);
1079                                 return 0;
1080                         } else
1081                         if (args->v0.state != 0) {
1082                                 nvkm_output_dp_train(&outpdp->base, 0, true);
1083                                 return 0;
1084                         }
1085                 } else
1086                         return ret;
1087         }
1088                 break;
1089         case NV50_DISP_MTHD_V1_PIOR_PWR:
1090                 if (!priv->pior.power)
1091                         return -ENODEV;
1092                 return priv->pior.power(object, priv, data, size, head, outp);
1093         default:
1094                 break;
1095         }
1096
1097         return -EINVAL;
1098 }
1099
1100 int
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)
1105 {
1106         struct nv50_disp_priv *priv = (void *)engine;
1107         struct nv50_disp_base *base;
1108         int ret;
1109
1110         ret = nouveau_parent_create(parent, engine, oclass, 0,
1111                                     priv->sclass, 0, &base);
1112         *pobject = nv_object(base);
1113         if (ret)
1114                 return ret;
1115
1116         return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
1117                                 &base->ramht);
1118 }
1119
1120 void
1121 nv50_disp_base_dtor(struct nouveau_object *object)
1122 {
1123         struct nv50_disp_base *base = (void *)object;
1124         nouveau_ramht_ref(NULL, &base->ramht);
1125         nouveau_parent_destroy(&base->base);
1126 }
1127
1128 static int
1129 nv50_disp_base_init(struct nouveau_object *object)
1130 {
1131         struct nv50_disp_priv *priv = (void *)object->engine;
1132         struct nv50_disp_base *base = (void *)object;
1133         int ret, i;
1134         u32 tmp;
1135
1136         ret = nouveau_parent_init(&base->base);
1137         if (ret)
1138                 return ret;
1139
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..
1143          */
1144         tmp = nv_rd32(priv, 0x614004);
1145         nv_wr32(priv, 0x610184, tmp);
1146
1147         /* ... CRTC caps */
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);
1157         }
1158
1159         /* ... DAC caps */
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);
1163         }
1164
1165         /* ... SOR caps */
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);
1169         }
1170
1171         /* ... PIOR caps */
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);
1175         }
1176
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");
1183                         return -EBUSY;
1184                 }
1185         }
1186
1187         /* point at display engine memory area (hash table, objects) */
1188         nv_wr32(priv, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9);
1189
1190         /* enable supervisor interrupts, disable everything else */
1191         nv_wr32(priv, 0x61002c, 0x00000370);
1192         nv_wr32(priv, 0x610028, 0x00000000);
1193         return 0;
1194 }
1195
1196 static int
1197 nv50_disp_base_fini(struct nouveau_object *object, bool suspend)
1198 {
1199         struct nv50_disp_priv *priv = (void *)object->engine;
1200         struct nv50_disp_base *base = (void *)object;
1201
1202         /* disable all interrupts */
1203         nv_wr32(priv, 0x610024, 0x00000000);
1204         nv_wr32(priv, 0x610020, 0x00000000);
1205
1206         return nouveau_parent_fini(&base->base, suspend);
1207 }
1208
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,
1217 };
1218
1219 static struct nouveau_oclass
1220 nv50_disp_base_oclass[] = {
1221         { NV50_DISP, &nv50_disp_base_ofuncs },
1222         {}
1223 };
1224
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 },
1232         {}
1233 };
1234
1235 /*******************************************************************************
1236  * Display context, tracks instmem allocation and prevents more than one
1237  * client using the display hardware at any time.
1238  ******************************************************************************/
1239
1240 static int
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)
1245 {
1246         struct nv50_disp_priv *priv = (void *)engine;
1247         struct nouveau_engctx *ectx;
1248         int ret = -EBUSY;
1249
1250         /* no context needed for channel objects... */
1251         if (nv_mclass(parent) != NV_DEVICE) {
1252                 atomic_inc(&parent->refcount);
1253                 *pobject = parent;
1254                 return 1;
1255         }
1256
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,
1261                                             0x10000, 0x10000,
1262                                             NVOBJ_FLAG_HEAP, &ectx);
1263                 *pobject = nv_object(ectx);
1264         }
1265         mutex_unlock(&nv_subdev(priv)->mutex);
1266         return ret;
1267 }
1268
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,
1279         },
1280 };
1281
1282 /*******************************************************************************
1283  * Display engine implementation
1284  ******************************************************************************/
1285
1286 static void
1287 nv50_disp_vblank_fini(struct nvkm_event *event, int type, int head)
1288 {
1289         struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
1290         nv_mask(disp, 0x61002c, (4 << head), 0);
1291 }
1292
1293 static void
1294 nv50_disp_vblank_init(struct nvkm_event *event, int type, int head)
1295 {
1296         struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
1297         nv_mask(disp, 0x61002c, (4 << head), (4 << head));
1298 }
1299
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,
1305 };
1306
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" },
1313         {}
1314 };
1315
1316 static const struct nouveau_enum
1317 nv50_disp_intr_error_code[] = {
1318         { 0x00, "" },
1319         {}
1320 };
1321
1322 static void
1323 nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid)
1324 {
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];
1333
1334         et = nouveau_enum_find(nv50_disp_intr_error_type, type);
1335         if (!et)
1336                 snprintf(etunk, sizeof(etunk), "UNK%02X", type);
1337
1338         ec = nouveau_enum_find(nv50_disp_intr_error_code, code);
1339         if (!ec)
1340                 snprintf(ecunk, sizeof(ecunk), "UNK%02X", code);
1341
1342         nv_error(priv, "%s [%s] chid %d mthd 0x%04x data 0x%08x\n",
1343                  et ? et->name : etunk, ec ? ec->name : ecunk,
1344                  chid, mthd, data);
1345
1346         if (chid == 0) {
1347                 switch (mthd) {
1348                 case 0x0080:
1349                         nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0,
1350                                             impl->mthd.core);
1351                         break;
1352                 default:
1353                         break;
1354                 }
1355         } else
1356         if (chid <= 2) {
1357                 switch (mthd) {
1358                 case 0x0080:
1359                         nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1,
1360                                             impl->mthd.base);
1361                         break;
1362                 default:
1363                         break;
1364                 }
1365         } else
1366         if (chid <= 4) {
1367                 switch (mthd) {
1368                 case 0x0080:
1369                         nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 3,
1370                                             impl->mthd.ovly);
1371                         break;
1372                 default:
1373                         break;
1374                 }
1375         }
1376
1377         nv_wr32(priv, 0x610020, 0x00010000 << chid);
1378         nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000);
1379 }
1380
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)
1385 {
1386         struct nouveau_bios *bios = nouveau_bios(priv);
1387         struct nvkm_output *outp;
1388         u16 mask, type;
1389
1390         if (or < 4) {
1391                 type = DCB_OUTPUT_ANALOG;
1392                 mask = 0;
1393         } else
1394         if (or < 8) {
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;
1402                 default:
1403                         nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
1404                         return NULL;
1405                 }
1406                 or  -= 4;
1407         } else {
1408                 or   = or - 8;
1409                 type = 0x0010;
1410                 mask = 0;
1411                 switch (ctrl & 0x00000f00) {
1412                 case 0x00000000: type |= priv->pior.type[or]; break;
1413                 default:
1414                         nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl);
1415                         return NULL;
1416                 }
1417         }
1418
1419         mask  = 0x00c0 & (mask << 6);
1420         mask |= 0x0001 << or;
1421         mask |= 0x0100 << head;
1422
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,
1427                                                         outp->info.hashm,
1428                                                   ver, hdr, cnt, len, info);
1429                         if (!*data)
1430                                 return NULL;
1431                         return outp;
1432                 }
1433         }
1434
1435         return NULL;
1436 }
1437
1438 static struct nvkm_output *
1439 exec_script(struct nv50_disp_priv *priv, int head, int id)
1440 {
1441         struct nouveau_bios *bios = nouveau_bios(priv);
1442         struct nvkm_output *outp;
1443         struct nvbios_outp info;
1444         u8  ver, hdr, cnt, len;
1445         u32 data, ctrl = 0;
1446         u32 reg;
1447         int i;
1448
1449         /* DAC */
1450         for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++)
1451                 ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
1452
1453         /* SOR */
1454         if (!(ctrl & (1 << head))) {
1455                 if (nv_device(priv)->chipset  < 0x90 ||
1456                     nv_device(priv)->chipset == 0x92 ||
1457                     nv_device(priv)->chipset == 0xa0) {
1458                         reg = 0x610b74;
1459                 } else {
1460                         reg = 0x610798;
1461                 }
1462                 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++)
1463                         ctrl = nv_rd32(priv, reg + (i * 8));
1464                 i += 4;
1465         }
1466
1467         /* PIOR */
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));
1471                 i += 8;
1472         }
1473
1474         if (!(ctrl & (1 << head)))
1475                 return NULL;
1476         i--;
1477
1478         outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
1479         if (outp) {
1480                 struct nvbios_init init = {
1481                         .subdev = nv_subdev(priv),
1482                         .bios = bios,
1483                         .offset = info.script[id],
1484                         .outp = &outp->info,
1485                         .crtc = head,
1486                         .execute = 1,
1487                 };
1488
1489                 nvbios_exec(&init);
1490         }
1491
1492         return outp;
1493 }
1494
1495 static struct nvkm_output *
1496 exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
1497 {
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;
1503         u32 data, ctrl = 0;
1504         u32 reg;
1505         int i;
1506
1507         /* DAC */
1508         for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++)
1509                 ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
1510
1511         /* SOR */
1512         if (!(ctrl & (1 << head))) {
1513                 if (nv_device(priv)->chipset  < 0x90 ||
1514                     nv_device(priv)->chipset == 0x92 ||
1515                     nv_device(priv)->chipset == 0xa0) {
1516                         reg = 0x610b70;
1517                 } else {
1518                         reg = 0x610794;
1519                 }
1520                 for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++)
1521                         ctrl = nv_rd32(priv, reg + (i * 8));
1522                 i += 4;
1523         }
1524
1525         /* PIOR */
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));
1529                 i += 8;
1530         }
1531
1532         if (!(ctrl & (1 << head)))
1533                 return NULL;
1534         i--;
1535
1536         outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
1537         if (!outp)
1538                 return NULL;
1539
1540         if (outp->info.location == 0) {
1541                 switch (outp->info.type) {
1542                 case DCB_OUTPUT_TMDS:
1543                         *conf = (ctrl & 0x00000f00) >> 8;
1544                         if (pclk >= 165000)
1545                                 *conf |= 0x0100;
1546                         break;
1547                 case DCB_OUTPUT_LVDS:
1548                         *conf = priv->sor.lvdsconf;
1549                         break;
1550                 case DCB_OUTPUT_DP:
1551                         *conf = (ctrl & 0x00000f00) >> 8;
1552                         break;
1553                 case DCB_OUTPUT_ANALOG:
1554                 default:
1555                         *conf = 0x00ff;
1556                         break;
1557                 }
1558         } else {
1559                 *conf = (ctrl & 0x00000f00) >> 8;
1560                 pclk = pclk / 2;
1561         }
1562
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);
1566                 if (data) {
1567                         struct nvbios_init init = {
1568                                 .subdev = nv_subdev(priv),
1569                                 .bios = bios,
1570                                 .offset = data,
1571                                 .outp = &outp->info,
1572                                 .crtc = head,
1573                                 .execute = 1,
1574                         };
1575
1576                         nvbios_exec(&init);
1577                 }
1578         }
1579
1580         return outp;
1581 }
1582
1583 static void
1584 nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head)
1585 {
1586         exec_script(priv, head, 1);
1587 }
1588
1589 static void
1590 nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
1591 {
1592         struct nvkm_output *outp = exec_script(priv, head, 2);
1593
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..
1602          *
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)
1606          */
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,
1613                         .crtc = head,
1614                         .offset = outpdp->info.script[4],
1615                         .execute = 1,
1616                 };
1617
1618                 nvbios_exec(&init);
1619                 atomic_set(&outpdp->lt.done, 0);
1620         }
1621 }
1622
1623 static void
1624 nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
1625 {
1626         struct nouveau_devinit *devinit = nouveau_devinit(priv);
1627         u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1628         if (pclk)
1629                 devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
1630 }
1631
1632 static void
1633 nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, int head,
1634                           struct dcb_output *outp, u32 pclk)
1635 {
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;
1652         u64 value;
1653
1654         link_bw = (clksor & 0x000c0000) ? 270000 : 162000;
1655         link_nr = hweight32(dpctrl & 0x000f0000);
1656
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);
1663
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);
1670
1671         /* watermark / activesym */
1672         if      ((ctrl & 0xf0000) == 0x60000) bits = 30;
1673         else if ((ctrl & 0xf0000) == 0x50000) bits = 24;
1674         else                                  bits = 18;
1675
1676         link_data_rate = (pclk * bits / 8) / link_nr;
1677
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);
1681
1682         for (TU = 64; TU >= 32; TU--) {
1683                 /* calculate average number of valid symbols in each TU */
1684                 u32 tu_valid = link_ratio * TU;
1685                 u32 calc, diff;
1686
1687                 /* find a hw representation for the fraction.. */
1688                 VTUi = tu_valid / symbol;
1689                 calc = VTUi * symbol;
1690                 diff = tu_valid - calc;
1691                 if (diff) {
1692                         if (diff >= (symbol / 2)) {
1693                                 VTUf = symbol / (symbol - diff);
1694                                 if (symbol - (VTUf * diff))
1695                                         VTUf++;
1696
1697                                 if (VTUf <= 15) {
1698                                         VTUa  = 1;
1699                                         calc += symbol - (symbol / VTUf);
1700                                 } else {
1701                                         VTUa  = 0;
1702                                         VTUf  = 1;
1703                                         calc += symbol;
1704                                 }
1705                         } else {
1706                                 VTUa  = 0;
1707                                 VTUf  = min((int)(symbol / diff), 15);
1708                                 calc += symbol / VTUf;
1709                         }
1710
1711                         diff = calc - tu_valid;
1712                 } else {
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
1716                          */
1717                         VTUa = 0;
1718                         VTUf = 1;
1719                         VTUi--;
1720                 }
1721
1722                 if (diff < best_diff) {
1723                         best_diff = diff;
1724                         bestTU = TU;
1725                         bestVTUa = VTUa;
1726                         bestVTUf = VTUf;
1727                         bestVTUi = VTUi;
1728                         if (diff == 0)
1729                                 break;
1730                 }
1731         }
1732
1733         if (!bestTU) {
1734                 nv_error(priv, "unable to find suitable dp config\n");
1735                 return;
1736         }
1737
1738         /* XXX close to vbios numbers, but not right */
1739         unk  = (symbol - link_ratio) * bestTU;
1740         unk *= link_ratio;
1741         do_div(unk, symbol);
1742         do_div(unk, symbol);
1743         unk += 6;
1744
1745         nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2);
1746         nv_mask(priv, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 |
1747                                                    bestVTUf << 16 |
1748                                                    bestVTUi << 8 | unk);
1749 }
1750
1751 static void
1752 nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
1753 {
1754         struct nvkm_output *outp;
1755         u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1756         u32 hval, hreg = 0x614200 + (head * 0x800);
1757         u32 oval, oreg;
1758         u32 mask, conf;
1759
1760         outp = exec_clkcmp(priv, head, 0xff, pclk, &conf);
1761         if (!outp)
1762                 return;
1763
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.
1768          *
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
1771          * re-train.
1772          *
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).
1777          *
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).
1781          */
1782         if (outp->info.type == DCB_OUTPUT_DP) {
1783                 u32 soff = (ffs(outp->info.or) - 1) * 0x08;
1784                 u32 ctrl, datarate;
1785
1786                 if (outp->info.location == 0) {
1787                         ctrl = nv_rd32(priv, 0x610794 + soff);
1788                         soff = 1;
1789                 } else {
1790                         ctrl = nv_rd32(priv, 0x610b80 + soff);
1791                         soff = 2;
1792                 }
1793
1794                 switch ((ctrl & 0x000f0000) >> 16) {
1795                 case 6: datarate = pclk * 30; break;
1796                 case 5: datarate = pclk * 24; break;
1797                 case 2:
1798                 default:
1799                         datarate = pclk * 18;
1800                         break;
1801                 }
1802
1803                 if (nvkm_output_dp_train(outp, datarate / soff, true))
1804                         ERR("link not trained before attach\n");
1805         }
1806
1807         exec_clkcmp(priv, head, 0, pclk, &conf);
1808
1809         if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) {
1810                 oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800;
1811                 oval = 0x00000000;
1812                 hval = 0x00000000;
1813                 mask = 0xffffffff;
1814         } else
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;
1820                 hval = 0x00000000;
1821                 mask = 0x00000707;
1822         } else {
1823                 oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800;
1824                 oval = 0x00000001;
1825                 hval = 0x00000001;
1826                 mask = 0x00000707;
1827         }
1828
1829         nv_mask(priv, hreg, 0x0000000f, hval);
1830         nv_mask(priv, oreg, mask, oval);
1831 }
1832
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.
1835  *
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.
1840  */
1841 static void
1842 nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp)
1843 {
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;
1849         u8  ver, hdr;
1850
1851         if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, outp))
1852                 nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000);
1853 }
1854
1855 static void
1856 nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head)
1857 {
1858         struct nvkm_output *outp;
1859         u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1860         u32 conf;
1861
1862         outp = exec_clkcmp(priv, head, 1, pclk, &conf);
1863         if (!outp)
1864                 return;
1865
1866         if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS)
1867                 nv50_disp_intr_unk40_0_tmds(priv, &outp->info);
1868 }
1869
1870 void
1871 nv50_disp_intr_supervisor(struct work_struct *work)
1872 {
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);
1877         int head;
1878
1879         nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
1880
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)))
1885                                 continue;
1886                         if (!(super & (0x00000080 << head)))
1887                                 continue;
1888                         nv50_disp_intr_unk10_0(priv, head);
1889                 }
1890         } else
1891         if (priv->super & 0x00000020) {
1892                 for (head = 0; head < priv->head.nr; head++) {
1893                         if (!(super & (0x00000080 << head)))
1894                                 continue;
1895                         nv50_disp_intr_unk20_0(priv, head);
1896                 }
1897                 for (head = 0; head < priv->head.nr; head++) {
1898                         if (!(super & (0x00000200 << head)))
1899                                 continue;
1900                         nv50_disp_intr_unk20_1(priv, head);
1901                 }
1902                 for (head = 0; head < priv->head.nr; head++) {
1903                         if (!(super & (0x00000080 << head)))
1904                                 continue;
1905                         nv50_disp_intr_unk20_2(priv, head);
1906                 }
1907         } else
1908         if (priv->super & 0x00000040) {
1909                 for (head = 0; head < priv->head.nr; head++) {
1910                         if (!(super & (0x00000080 << head)))
1911                                 continue;
1912                         nv50_disp_intr_unk40_0(priv, head);
1913                 }
1914         }
1915
1916         nv_wr32(priv, 0x610030, 0x80000000);
1917 }
1918
1919 void
1920 nv50_disp_intr(struct nouveau_subdev *subdev)
1921 {
1922         struct nv50_disp_priv *priv = (void *)subdev;
1923         u32 intr0 = nv_rd32(priv, 0x610020);
1924         u32 intr1 = nv_rd32(priv, 0x610024);
1925
1926         while (intr0 & 0x001f0000) {
1927                 u32 chid = __ffs(intr0 & 0x001f0000) - 16;
1928                 nv50_disp_intr_error(priv, chid);
1929                 intr0 &= ~(0x00010000 << chid);
1930         }
1931
1932         while (intr0 & 0x0000001f) {
1933                 u32 chid = __ffs(intr0 & 0x0000001f);
1934                 nv50_disp_chan_uevent_send(priv, chid);
1935                 intr0 &= ~(0x00000001 << chid);
1936         }
1937
1938         if (intr1 & 0x00000004) {
1939                 nouveau_disp_vblank(&priv->base, 0);
1940                 nv_wr32(priv, 0x610024, 0x00000004);
1941                 intr1 &= ~0x00000004;
1942         }
1943
1944         if (intr1 & 0x00000008) {
1945                 nouveau_disp_vblank(&priv->base, 1);
1946                 nv_wr32(priv, 0x610024, 0x00000008);
1947                 intr1 &= ~0x00000008;
1948         }
1949
1950         if (intr1 & 0x00000070) {
1951                 priv->super = (intr1 & 0x00000070);
1952                 schedule_work(&priv->supervisor);
1953                 nv_wr32(priv, 0x610024, priv->super);
1954                 intr1 &= ~0x00000070;
1955         }
1956 }
1957
1958 static int
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)
1962 {
1963         struct nv50_disp_priv *priv;
1964         int ret;
1965
1966         ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
1967                                   "display", &priv);
1968         *pobject = nv_object(priv);
1969         if (ret)
1970                 return ret;
1971
1972         ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
1973         if (ret)
1974                 return ret;
1975
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;
1981         priv->head.nr = 2;
1982         priv->dac.nr = 3;
1983         priv->sor.nr = 2;
1984         priv->pior.nr = 3;
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;
1989         return 0;
1990 }
1991
1992 struct nouveau_oclass *
1993 nv50_disp_outp_sclass[] = {
1994         &nv50_pior_dp_impl.base.base,
1995         NULL
1996 };
1997
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,
2006         },
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,
2014 }.base.base;