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
49static int
50nv50_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
78static void
79nv50_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
86static void
87nv50_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
93static void
94nv50_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
100void
101nv50_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
109int
110nv50_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
129const struct nvkm_event_func
130nv50_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
136int
137nv50_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
151int
152nv50_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
161u32
162nv50_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
169void
170nv50_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
181static int
182nv50_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
193static void
194nv50_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
200static int
201nv50_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
243void
244nv50_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
251static int
252nv50_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
284static int
285nv50_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
311static void
312nv50_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
338void
339nv50_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
376const struct nv50_disp_mthd_list
377nv50_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
389static const struct nv50_disp_mthd_list
390nv50_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
401const struct nv50_disp_mthd_list
402nv50_disp_mast_mthd_sor = {
403	.mthd = 0x0040,
404	.addr = 0x000008,
405	.data = {
406		{ 0x0600, 0x610b70 },
407		{}
408	}
409};
410
411const struct nv50_disp_mthd_list
412nv50_disp_mast_mthd_pior = {
413	.mthd = 0x0040,
414	.addr = 0x000008,
415	.data = {
416		{ 0x0700, 0x610b80 },
417		{}
418	}
419};
420
421static const struct nv50_disp_mthd_list
422nv50_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
468static const struct nv50_disp_mthd_chan
469nv50_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
482int
483nv50_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
511static int
512nv50_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
548static int
549nv50_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
569struct nv50_disp_chan_impl
570nv50_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
588static const struct nv50_disp_mthd_list
589nv50_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
613const struct nv50_disp_mthd_list
614nv50_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
627static const struct nv50_disp_mthd_chan
628nv50_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
638int
639nv50_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
671struct nv50_disp_chan_impl
672nv50_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
690const struct nv50_disp_mthd_list
691nv50_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
718static const struct nv50_disp_mthd_chan
719nv50_disp_ovly_mthd_chan = {
720	.name = "Overlay",
721	.addr = 0x000540,
722	.data = {
723		{ "Global", 1, &nv50_disp_ovly_mthd_base },
724		{}
725	}
726};
727
728int
729nv50_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
761struct nv50_disp_chan_impl
762nv50_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
780static int
781nv50_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
790void
791nv50_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
797static int
798nv50_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
826static int
827nv50_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
848int
849nv50_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
879struct nv50_disp_chan_impl
880nv50_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
896int
897nv50_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
927struct nv50_disp_chan_impl
928nv50_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
944int
945nv50_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
976int
977nv50_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
1100int
1101nv50_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
1120void
1121nv50_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
1128static int
1129nv50_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
1196static int
1197nv50_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
1209struct nouveau_ofuncs
1210nv50_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
1219static struct nouveau_oclass
1220nv50_disp_base_oclass[] = {
1221	{ NV50_DISP, &nv50_disp_base_ofuncs },
1222	{}
1223};
1224
1225static struct nouveau_oclass
1226nv50_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
1240static int
1241nv50_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
1269struct nouveau_oclass
1270nv50_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
1286static void
1287nv50_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
1293static void
1294nv50_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
1300const struct nvkm_event_func
1301nv50_disp_vblank_func = {
1302	.ctor = nouveau_disp_vblank_ctor,
1303	.init = nv50_disp_vblank_init,
1304	.fini = nv50_disp_vblank_fini,
1305};
1306
1307static const struct nouveau_enum
1308nv50_disp_intr_error_type[] = {
1309	{ 3, "ILLEGAL_MTHD" },
1310	{ 4, "INVALID_VALUE" },
1311	{ 5, "INVALID_STATE" },
1312	{ 7, "INVALID_HANDLE" },
1313	{}
1314};
1315
1316static const struct nouveau_enum
1317nv50_disp_intr_error_code[] = {
1318	{ 0x00, "" },
1319	{}
1320};
1321
1322static void
1323nv50_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
1381static struct nvkm_output *
1382exec_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
1438static struct nvkm_output *
1439exec_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
1495static struct nvkm_output *
1496exec_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
1583static void
1584nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head)
1585{
1586	exec_script(priv, head, 1);
1587}
1588
1589static void
1590nv50_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
1623static void
1624nv50_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
1632static void
1633nv50_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
1751static void
1752nv50_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 */
1841static void
1842nv50_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	struct dcb_output match;
1850	u8  ver, hdr;
1851
1852	if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, &match))
1853		nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000);
1854}
1855
1856static void
1857nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head)
1858{
1859	struct nvkm_output *outp;
1860	u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1861	u32 conf;
1862
1863	outp = exec_clkcmp(priv, head, 1, pclk, &conf);
1864	if (!outp)
1865		return;
1866
1867	if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS)
1868		nv50_disp_intr_unk40_0_tmds(priv, &outp->info);
1869}
1870
1871void
1872nv50_disp_intr_supervisor(struct work_struct *work)
1873{
1874	struct nv50_disp_priv *priv =
1875		container_of(work, struct nv50_disp_priv, supervisor);
1876	struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
1877	u32 super = nv_rd32(priv, 0x610030);
1878	int head;
1879
1880	nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
1881
1882	if (priv->super & 0x00000010) {
1883		nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core);
1884		for (head = 0; head < priv->head.nr; head++) {
1885			if (!(super & (0x00000020 << head)))
1886				continue;
1887			if (!(super & (0x00000080 << head)))
1888				continue;
1889			nv50_disp_intr_unk10_0(priv, head);
1890		}
1891	} else
1892	if (priv->super & 0x00000020) {
1893		for (head = 0; head < priv->head.nr; head++) {
1894			if (!(super & (0x00000080 << head)))
1895				continue;
1896			nv50_disp_intr_unk20_0(priv, head);
1897		}
1898		for (head = 0; head < priv->head.nr; head++) {
1899			if (!(super & (0x00000200 << head)))
1900				continue;
1901			nv50_disp_intr_unk20_1(priv, head);
1902		}
1903		for (head = 0; head < priv->head.nr; head++) {
1904			if (!(super & (0x00000080 << head)))
1905				continue;
1906			nv50_disp_intr_unk20_2(priv, head);
1907		}
1908	} else
1909	if (priv->super & 0x00000040) {
1910		for (head = 0; head < priv->head.nr; head++) {
1911			if (!(super & (0x00000080 << head)))
1912				continue;
1913			nv50_disp_intr_unk40_0(priv, head);
1914		}
1915	}
1916
1917	nv_wr32(priv, 0x610030, 0x80000000);
1918}
1919
1920void
1921nv50_disp_intr(struct nouveau_subdev *subdev)
1922{
1923	struct nv50_disp_priv *priv = (void *)subdev;
1924	u32 intr0 = nv_rd32(priv, 0x610020);
1925	u32 intr1 = nv_rd32(priv, 0x610024);
1926
1927	while (intr0 & 0x001f0000) {
1928		u32 chid = __ffs(intr0 & 0x001f0000) - 16;
1929		nv50_disp_intr_error(priv, chid);
1930		intr0 &= ~(0x00010000 << chid);
1931	}
1932
1933	while (intr0 & 0x0000001f) {
1934		u32 chid = __ffs(intr0 & 0x0000001f);
1935		nv50_disp_chan_uevent_send(priv, chid);
1936		intr0 &= ~(0x00000001 << chid);
1937	}
1938
1939	if (intr1 & 0x00000004) {
1940		nouveau_disp_vblank(&priv->base, 0);
1941		nv_wr32(priv, 0x610024, 0x00000004);
1942		intr1 &= ~0x00000004;
1943	}
1944
1945	if (intr1 & 0x00000008) {
1946		nouveau_disp_vblank(&priv->base, 1);
1947		nv_wr32(priv, 0x610024, 0x00000008);
1948		intr1 &= ~0x00000008;
1949	}
1950
1951	if (intr1 & 0x00000070) {
1952		priv->super = (intr1 & 0x00000070);
1953		schedule_work(&priv->supervisor);
1954		nv_wr32(priv, 0x610024, priv->super);
1955		intr1 &= ~0x00000070;
1956	}
1957}
1958
1959static int
1960nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1961	       struct nouveau_oclass *oclass, void *data, u32 size,
1962	       struct nouveau_object **pobject)
1963{
1964	struct nv50_disp_priv *priv;
1965	int ret;
1966
1967	ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
1968				  "display", &priv);
1969	*pobject = nv_object(priv);
1970	if (ret)
1971		return ret;
1972
1973	ret = nvkm_event_init(&nv50_disp_chan_uevent, 1, 9, &priv->uevent);
1974	if (ret)
1975		return ret;
1976
1977	nv_engine(priv)->sclass = nv50_disp_base_oclass;
1978	nv_engine(priv)->cclass = &nv50_disp_cclass;
1979	nv_subdev(priv)->intr = nv50_disp_intr;
1980	INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
1981	priv->sclass = nv50_disp_sclass;
1982	priv->head.nr = 2;
1983	priv->dac.nr = 3;
1984	priv->sor.nr = 2;
1985	priv->pior.nr = 3;
1986	priv->dac.power = nv50_dac_power;
1987	priv->dac.sense = nv50_dac_sense;
1988	priv->sor.power = nv50_sor_power;
1989	priv->pior.power = nv50_pior_power;
1990	return 0;
1991}
1992
1993struct nouveau_oclass *
1994nv50_disp_outp_sclass[] = {
1995	&nv50_pior_dp_impl.base.base,
1996	NULL
1997};
1998
1999struct nouveau_oclass *
2000nv50_disp_oclass = &(struct nv50_disp_impl) {
2001	.base.base.handle = NV_ENGINE(DISP, 0x50),
2002	.base.base.ofuncs = &(struct nouveau_ofuncs) {
2003		.ctor = nv50_disp_ctor,
2004		.dtor = _nouveau_disp_dtor,
2005		.init = _nouveau_disp_init,
2006		.fini = _nouveau_disp_fini,
2007	},
2008	.base.vblank = &nv50_disp_vblank_func,
2009	.base.outp =  nv50_disp_outp_sclass,
2010	.mthd.core = &nv50_disp_mast_mthd_chan,
2011	.mthd.base = &nv50_disp_sync_mthd_chan,
2012	.mthd.ovly = &nv50_disp_ovly_mthd_chan,
2013	.mthd.prev = 0x000004,
2014	.head.scanoutpos = nv50_disp_base_scanoutpos,
2015}.base.base;
2016