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