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