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