nv50.c revision 5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96
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
30#include <engine/disp.h>
31
32#include <subdev/bios.h>
33#include <subdev/bios/dcb.h>
34#include <subdev/bios/disp.h>
35#include <subdev/bios/init.h>
36#include <subdev/bios/pll.h>
37#include <subdev/timer.h>
38#include <subdev/fb.h>
39#include <subdev/clock.h>
40
41#include "nv50.h"
42
43/*******************************************************************************
44 * EVO channel base class
45 ******************************************************************************/
46
47int
48nv50_disp_chan_create_(struct nouveau_object *parent,
49		       struct nouveau_object *engine,
50		       struct nouveau_oclass *oclass, int chid,
51		       int length, void **pobject)
52{
53	struct nv50_disp_base *base = (void *)parent;
54	struct nv50_disp_chan *chan;
55	int ret;
56
57	if (base->chan & (1 << chid))
58		return -EBUSY;
59	base->chan |= (1 << chid);
60
61	ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
62				     (1ULL << NVDEV_ENGINE_DMAOBJ),
63				     length, pobject);
64	chan = *pobject;
65	if (ret)
66		return ret;
67
68	chan->chid = chid;
69	return 0;
70}
71
72void
73nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
74{
75	struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
76	base->chan &= ~(1 << chan->chid);
77	nouveau_namedb_destroy(&chan->base);
78}
79
80u32
81nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
82{
83	struct nv50_disp_priv *priv = (void *)object->engine;
84	struct nv50_disp_chan *chan = (void *)object;
85	return nv_rd32(priv, 0x640000 + (chan->chid * 0x1000) + addr);
86}
87
88void
89nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data)
90{
91	struct nv50_disp_priv *priv = (void *)object->engine;
92	struct nv50_disp_chan *chan = (void *)object;
93	nv_wr32(priv, 0x640000 + (chan->chid * 0x1000) + addr, data);
94}
95
96/*******************************************************************************
97 * EVO DMA channel base class
98 ******************************************************************************/
99
100static int
101nv50_disp_dmac_object_attach(struct nouveau_object *parent,
102			     struct nouveau_object *object, u32 name)
103{
104	struct nv50_disp_base *base = (void *)parent->parent;
105	struct nv50_disp_chan *chan = (void *)parent;
106	u32 addr = nv_gpuobj(object)->node->offset;
107	u32 chid = chan->chid;
108	u32 data = (chid << 28) | (addr << 10) | chid;
109	return nouveau_ramht_insert(base->ramht, chid, name, data);
110}
111
112static void
113nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
114{
115	struct nv50_disp_base *base = (void *)parent->parent;
116	nouveau_ramht_remove(base->ramht, cookie);
117}
118
119int
120nv50_disp_dmac_create_(struct nouveau_object *parent,
121		       struct nouveau_object *engine,
122		       struct nouveau_oclass *oclass, u32 pushbuf, int chid,
123		       int length, void **pobject)
124{
125	struct nv50_disp_dmac *dmac;
126	int ret;
127
128	ret = nv50_disp_chan_create_(parent, engine, oclass, chid,
129				     length, pobject);
130	dmac = *pobject;
131	if (ret)
132		return ret;
133
134	dmac->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
135	if (!dmac->pushdma)
136		return -ENOENT;
137
138	switch (nv_mclass(dmac->pushdma)) {
139	case 0x0002:
140	case 0x003d:
141		if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff)
142			return -EINVAL;
143
144		switch (dmac->pushdma->target) {
145		case NV_MEM_TARGET_VRAM:
146			dmac->push = 0x00000000 | dmac->pushdma->start >> 8;
147			break;
148		case NV_MEM_TARGET_PCI_NOSNOOP:
149			dmac->push = 0x00000003 | dmac->pushdma->start >> 8;
150			break;
151		default:
152			return -EINVAL;
153		}
154		break;
155	default:
156		return -EINVAL;
157	}
158
159	return 0;
160}
161
162void
163nv50_disp_dmac_dtor(struct nouveau_object *object)
164{
165	struct nv50_disp_dmac *dmac = (void *)object;
166	nouveau_object_ref(NULL, (struct nouveau_object **)&dmac->pushdma);
167	nv50_disp_chan_destroy(&dmac->base);
168}
169
170static int
171nv50_disp_dmac_init(struct nouveau_object *object)
172{
173	struct nv50_disp_priv *priv = (void *)object->engine;
174	struct nv50_disp_dmac *dmac = (void *)object;
175	int chid = dmac->base.chid;
176	int ret;
177
178	ret = nv50_disp_chan_init(&dmac->base);
179	if (ret)
180		return ret;
181
182	/* enable error reporting */
183	nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00010001 << chid);
184
185	/* initialise channel for dma command submission */
186	nv_wr32(priv, 0x610204 + (chid * 0x0010), dmac->push);
187	nv_wr32(priv, 0x610208 + (chid * 0x0010), 0x00010000);
188	nv_wr32(priv, 0x61020c + (chid * 0x0010), chid);
189	nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010);
190	nv_wr32(priv, 0x640000 + (chid * 0x1000), 0x00000000);
191	nv_wr32(priv, 0x610200 + (chid * 0x0010), 0x00000013);
192
193	/* wait for it to go inactive */
194	if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x80000000, 0x00000000)) {
195		nv_error(dmac, "init timeout, 0x%08x\n",
196			 nv_rd32(priv, 0x610200 + (chid * 0x10)));
197		return -EBUSY;
198	}
199
200	return 0;
201}
202
203static int
204nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
205{
206	struct nv50_disp_priv *priv = (void *)object->engine;
207	struct nv50_disp_dmac *dmac = (void *)object;
208	int chid = dmac->base.chid;
209
210	/* deactivate channel */
211	nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000);
212	nv_mask(priv, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000);
213	if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x001e0000, 0x00000000)) {
214		nv_error(dmac, "fini timeout, 0x%08x\n",
215			 nv_rd32(priv, 0x610200 + (chid * 0x10)));
216		if (suspend)
217			return -EBUSY;
218	}
219
220	/* disable error reporting */
221	nv_mask(priv, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
222
223	return nv50_disp_chan_fini(&dmac->base, suspend);
224}
225
226/*******************************************************************************
227 * EVO master channel object
228 ******************************************************************************/
229
230static int
231nv50_disp_mast_ctor(struct nouveau_object *parent,
232		    struct nouveau_object *engine,
233		    struct nouveau_oclass *oclass, void *data, u32 size,
234		    struct nouveau_object **pobject)
235{
236	struct nv50_display_mast_class *args = data;
237	struct nv50_disp_dmac *mast;
238	int ret;
239
240	if (size < sizeof(*args))
241		return -EINVAL;
242
243	ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
244				     0, sizeof(*mast), (void **)&mast);
245	*pobject = nv_object(mast);
246	if (ret)
247		return ret;
248
249	nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach;
250	nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach;
251	return 0;
252}
253
254static int
255nv50_disp_mast_init(struct nouveau_object *object)
256{
257	struct nv50_disp_priv *priv = (void *)object->engine;
258	struct nv50_disp_dmac *mast = (void *)object;
259	int ret;
260
261	ret = nv50_disp_chan_init(&mast->base);
262	if (ret)
263		return ret;
264
265	/* enable error reporting */
266	nv_mask(priv, 0x610028, 0x00010001, 0x00010001);
267
268	/* attempt to unstick channel from some unknown state */
269	if ((nv_rd32(priv, 0x610200) & 0x009f0000) == 0x00020000)
270		nv_mask(priv, 0x610200, 0x00800000, 0x00800000);
271	if ((nv_rd32(priv, 0x610200) & 0x003f0000) == 0x00030000)
272		nv_mask(priv, 0x610200, 0x00600000, 0x00600000);
273
274	/* initialise channel for dma command submission */
275	nv_wr32(priv, 0x610204, mast->push);
276	nv_wr32(priv, 0x610208, 0x00010000);
277	nv_wr32(priv, 0x61020c, 0x00000000);
278	nv_mask(priv, 0x610200, 0x00000010, 0x00000010);
279	nv_wr32(priv, 0x640000, 0x00000000);
280	nv_wr32(priv, 0x610200, 0x01000013);
281
282	/* wait for it to go inactive */
283	if (!nv_wait(priv, 0x610200, 0x80000000, 0x00000000)) {
284		nv_error(mast, "init: 0x%08x\n", nv_rd32(priv, 0x610200));
285		return -EBUSY;
286	}
287
288	return 0;
289}
290
291static int
292nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
293{
294	struct nv50_disp_priv *priv = (void *)object->engine;
295	struct nv50_disp_dmac *mast = (void *)object;
296
297	/* deactivate channel */
298	nv_mask(priv, 0x610200, 0x00000010, 0x00000000);
299	nv_mask(priv, 0x610200, 0x00000003, 0x00000000);
300	if (!nv_wait(priv, 0x610200, 0x001e0000, 0x00000000)) {
301		nv_error(mast, "fini: 0x%08x\n", nv_rd32(priv, 0x610200));
302		if (suspend)
303			return -EBUSY;
304	}
305
306	/* disable error reporting */
307	nv_mask(priv, 0x610028, 0x00010001, 0x00000000);
308
309	return nv50_disp_chan_fini(&mast->base, suspend);
310}
311
312struct nouveau_ofuncs
313nv50_disp_mast_ofuncs = {
314	.ctor = nv50_disp_mast_ctor,
315	.dtor = nv50_disp_dmac_dtor,
316	.init = nv50_disp_mast_init,
317	.fini = nv50_disp_mast_fini,
318	.rd32 = nv50_disp_chan_rd32,
319	.wr32 = nv50_disp_chan_wr32,
320};
321
322/*******************************************************************************
323 * EVO sync channel objects
324 ******************************************************************************/
325
326static int
327nv50_disp_sync_ctor(struct nouveau_object *parent,
328		    struct nouveau_object *engine,
329		    struct nouveau_oclass *oclass, void *data, u32 size,
330		    struct nouveau_object **pobject)
331{
332	struct nv50_display_sync_class *args = data;
333	struct nv50_disp_dmac *dmac;
334	int ret;
335
336	if (size < sizeof(*args) || args->head > 1)
337		return -EINVAL;
338
339	ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
340				     1 + args->head, sizeof(*dmac),
341				     (void **)&dmac);
342	*pobject = nv_object(dmac);
343	if (ret)
344		return ret;
345
346	nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
347	nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
348	return 0;
349}
350
351struct nouveau_ofuncs
352nv50_disp_sync_ofuncs = {
353	.ctor = nv50_disp_sync_ctor,
354	.dtor = nv50_disp_dmac_dtor,
355	.init = nv50_disp_dmac_init,
356	.fini = nv50_disp_dmac_fini,
357	.rd32 = nv50_disp_chan_rd32,
358	.wr32 = nv50_disp_chan_wr32,
359};
360
361/*******************************************************************************
362 * EVO overlay channel objects
363 ******************************************************************************/
364
365static int
366nv50_disp_ovly_ctor(struct nouveau_object *parent,
367		    struct nouveau_object *engine,
368		    struct nouveau_oclass *oclass, void *data, u32 size,
369		    struct nouveau_object **pobject)
370{
371	struct nv50_display_ovly_class *args = data;
372	struct nv50_disp_dmac *dmac;
373	int ret;
374
375	if (size < sizeof(*args) || args->head > 1)
376		return -EINVAL;
377
378	ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
379				     3 + args->head, sizeof(*dmac),
380				     (void **)&dmac);
381	*pobject = nv_object(dmac);
382	if (ret)
383		return ret;
384
385	nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
386	nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
387	return 0;
388}
389
390struct nouveau_ofuncs
391nv50_disp_ovly_ofuncs = {
392	.ctor = nv50_disp_ovly_ctor,
393	.dtor = nv50_disp_dmac_dtor,
394	.init = nv50_disp_dmac_init,
395	.fini = nv50_disp_dmac_fini,
396	.rd32 = nv50_disp_chan_rd32,
397	.wr32 = nv50_disp_chan_wr32,
398};
399
400/*******************************************************************************
401 * EVO PIO channel base class
402 ******************************************************************************/
403
404static int
405nv50_disp_pioc_create_(struct nouveau_object *parent,
406		       struct nouveau_object *engine,
407		       struct nouveau_oclass *oclass, int chid,
408		       int length, void **pobject)
409{
410	return nv50_disp_chan_create_(parent, engine, oclass, chid,
411				      length, pobject);
412}
413
414static void
415nv50_disp_pioc_dtor(struct nouveau_object *object)
416{
417	struct nv50_disp_pioc *pioc = (void *)object;
418	nv50_disp_chan_destroy(&pioc->base);
419}
420
421static int
422nv50_disp_pioc_init(struct nouveau_object *object)
423{
424	struct nv50_disp_priv *priv = (void *)object->engine;
425	struct nv50_disp_pioc *pioc = (void *)object;
426	int chid = pioc->base.chid;
427	int ret;
428
429	ret = nv50_disp_chan_init(&pioc->base);
430	if (ret)
431		return ret;
432
433	nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00002000);
434	if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00000000, 0x00000000)) {
435		nv_error(pioc, "timeout0: 0x%08x\n",
436			 nv_rd32(priv, 0x610200 + (chid * 0x10)));
437		return -EBUSY;
438	}
439
440	nv_wr32(priv, 0x610200 + (chid * 0x10), 0x00000001);
441	if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00010000)) {
442		nv_error(pioc, "timeout1: 0x%08x\n",
443			 nv_rd32(priv, 0x610200 + (chid * 0x10)));
444		return -EBUSY;
445	}
446
447	return 0;
448}
449
450static int
451nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
452{
453	struct nv50_disp_priv *priv = (void *)object->engine;
454	struct nv50_disp_pioc *pioc = (void *)object;
455	int chid = pioc->base.chid;
456
457	nv_mask(priv, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000);
458	if (!nv_wait(priv, 0x610200 + (chid * 0x10), 0x00030000, 0x00000000)) {
459		nv_error(pioc, "timeout: 0x%08x\n",
460			 nv_rd32(priv, 0x610200 + (chid * 0x10)));
461		if (suspend)
462			return -EBUSY;
463	}
464
465	return nv50_disp_chan_fini(&pioc->base, suspend);
466}
467
468/*******************************************************************************
469 * EVO immediate overlay channel objects
470 ******************************************************************************/
471
472static int
473nv50_disp_oimm_ctor(struct nouveau_object *parent,
474		    struct nouveau_object *engine,
475		    struct nouveau_oclass *oclass, void *data, u32 size,
476		    struct nouveau_object **pobject)
477{
478	struct nv50_display_oimm_class *args = data;
479	struct nv50_disp_pioc *pioc;
480	int ret;
481
482	if (size < sizeof(*args) || args->head > 1)
483		return -EINVAL;
484
485	ret = nv50_disp_pioc_create_(parent, engine, oclass, 5 + args->head,
486				     sizeof(*pioc), (void **)&pioc);
487	*pobject = nv_object(pioc);
488	if (ret)
489		return ret;
490
491	return 0;
492}
493
494struct nouveau_ofuncs
495nv50_disp_oimm_ofuncs = {
496	.ctor = nv50_disp_oimm_ctor,
497	.dtor = nv50_disp_pioc_dtor,
498	.init = nv50_disp_pioc_init,
499	.fini = nv50_disp_pioc_fini,
500	.rd32 = nv50_disp_chan_rd32,
501	.wr32 = nv50_disp_chan_wr32,
502};
503
504/*******************************************************************************
505 * EVO cursor channel objects
506 ******************************************************************************/
507
508static int
509nv50_disp_curs_ctor(struct nouveau_object *parent,
510		    struct nouveau_object *engine,
511		    struct nouveau_oclass *oclass, void *data, u32 size,
512		    struct nouveau_object **pobject)
513{
514	struct nv50_display_curs_class *args = data;
515	struct nv50_disp_pioc *pioc;
516	int ret;
517
518	if (size < sizeof(*args) || args->head > 1)
519		return -EINVAL;
520
521	ret = nv50_disp_pioc_create_(parent, engine, oclass, 7 + args->head,
522				     sizeof(*pioc), (void **)&pioc);
523	*pobject = nv_object(pioc);
524	if (ret)
525		return ret;
526
527	return 0;
528}
529
530struct nouveau_ofuncs
531nv50_disp_curs_ofuncs = {
532	.ctor = nv50_disp_curs_ctor,
533	.dtor = nv50_disp_pioc_dtor,
534	.init = nv50_disp_pioc_init,
535	.fini = nv50_disp_pioc_fini,
536	.rd32 = nv50_disp_chan_rd32,
537	.wr32 = nv50_disp_chan_wr32,
538};
539
540/*******************************************************************************
541 * Base display object
542 ******************************************************************************/
543
544static void
545nv50_disp_base_vblank_enable(struct nouveau_event *event, int head)
546{
547	nv_mask(event->priv, 0x61002c, (1 << head), (1 << head));
548}
549
550static void
551nv50_disp_base_vblank_disable(struct nouveau_event *event, int head)
552{
553	nv_mask(event->priv, 0x61002c, (1 << head), (0 << head));
554}
555
556static int
557nv50_disp_base_ctor(struct nouveau_object *parent,
558		    struct nouveau_object *engine,
559		    struct nouveau_oclass *oclass, void *data, u32 size,
560		    struct nouveau_object **pobject)
561{
562	struct nv50_disp_priv *priv = (void *)engine;
563	struct nv50_disp_base *base;
564	int ret;
565
566	ret = nouveau_parent_create(parent, engine, oclass, 0,
567				    priv->sclass, 0, &base);
568	*pobject = nv_object(base);
569	if (ret)
570		return ret;
571
572	priv->base.vblank->priv = priv;
573	priv->base.vblank->enable = nv50_disp_base_vblank_enable;
574	priv->base.vblank->disable = nv50_disp_base_vblank_disable;
575	return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht);
576}
577
578static void
579nv50_disp_base_dtor(struct nouveau_object *object)
580{
581	struct nv50_disp_base *base = (void *)object;
582	nouveau_ramht_ref(NULL, &base->ramht);
583	nouveau_parent_destroy(&base->base);
584}
585
586static int
587nv50_disp_base_init(struct nouveau_object *object)
588{
589	struct nv50_disp_priv *priv = (void *)object->engine;
590	struct nv50_disp_base *base = (void *)object;
591	int ret, i;
592	u32 tmp;
593
594	ret = nouveau_parent_init(&base->base);
595	if (ret)
596		return ret;
597
598	/* The below segments of code copying values from one register to
599	 * another appear to inform EVO of the display capabilities or
600	 * something similar.  NFI what the 0x614004 caps are for..
601	 */
602	tmp = nv_rd32(priv, 0x614004);
603	nv_wr32(priv, 0x610184, tmp);
604
605	/* ... CRTC caps */
606	for (i = 0; i < priv->head.nr; i++) {
607		tmp = nv_rd32(priv, 0x616100 + (i * 0x800));
608		nv_wr32(priv, 0x610190 + (i * 0x10), tmp);
609		tmp = nv_rd32(priv, 0x616104 + (i * 0x800));
610		nv_wr32(priv, 0x610194 + (i * 0x10), tmp);
611		tmp = nv_rd32(priv, 0x616108 + (i * 0x800));
612		nv_wr32(priv, 0x610198 + (i * 0x10), tmp);
613		tmp = nv_rd32(priv, 0x61610c + (i * 0x800));
614		nv_wr32(priv, 0x61019c + (i * 0x10), tmp);
615	}
616
617	/* ... DAC caps */
618	for (i = 0; i < priv->dac.nr; i++) {
619		tmp = nv_rd32(priv, 0x61a000 + (i * 0x800));
620		nv_wr32(priv, 0x6101d0 + (i * 0x04), tmp);
621	}
622
623	/* ... SOR caps */
624	for (i = 0; i < priv->sor.nr; i++) {
625		tmp = nv_rd32(priv, 0x61c000 + (i * 0x800));
626		nv_wr32(priv, 0x6101e0 + (i * 0x04), tmp);
627	}
628
629	/* ... EXT caps */
630	for (i = 0; i < 3; i++) {
631		tmp = nv_rd32(priv, 0x61e000 + (i * 0x800));
632		nv_wr32(priv, 0x6101f0 + (i * 0x04), tmp);
633	}
634
635	/* steal display away from vbios, or something like that */
636	if (nv_rd32(priv, 0x610024) & 0x00000100) {
637		nv_wr32(priv, 0x610024, 0x00000100);
638		nv_mask(priv, 0x6194e8, 0x00000001, 0x00000000);
639		if (!nv_wait(priv, 0x6194e8, 0x00000002, 0x00000000)) {
640			nv_error(priv, "timeout acquiring display\n");
641			return -EBUSY;
642		}
643	}
644
645	/* point at display engine memory area (hash table, objects) */
646	nv_wr32(priv, 0x610010, (nv_gpuobj(base->ramht)->addr >> 8) | 9);
647
648	/* enable supervisor interrupts, disable everything else */
649	nv_wr32(priv, 0x61002c, 0x00000370);
650	nv_wr32(priv, 0x610028, 0x00000000);
651	return 0;
652}
653
654static int
655nv50_disp_base_fini(struct nouveau_object *object, bool suspend)
656{
657	struct nv50_disp_priv *priv = (void *)object->engine;
658	struct nv50_disp_base *base = (void *)object;
659
660	/* disable all interrupts */
661	nv_wr32(priv, 0x610024, 0x00000000);
662	nv_wr32(priv, 0x610020, 0x00000000);
663
664	return nouveau_parent_fini(&base->base, suspend);
665}
666
667struct nouveau_ofuncs
668nv50_disp_base_ofuncs = {
669	.ctor = nv50_disp_base_ctor,
670	.dtor = nv50_disp_base_dtor,
671	.init = nv50_disp_base_init,
672	.fini = nv50_disp_base_fini,
673};
674
675static struct nouveau_omthds
676nv50_disp_base_omthds[] = {
677	{ SOR_MTHD(NV50_DISP_SOR_PWR)         , nv50_sor_mthd },
678	{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
679	{ DAC_MTHD(NV50_DISP_DAC_PWR)         , nv50_dac_mthd },
680	{ DAC_MTHD(NV50_DISP_DAC_LOAD)        , nv50_dac_mthd },
681	{},
682};
683
684static struct nouveau_oclass
685nv50_disp_base_oclass[] = {
686	{ NV50_DISP_CLASS, &nv50_disp_base_ofuncs, nv50_disp_base_omthds },
687	{}
688};
689
690static struct nouveau_oclass
691nv50_disp_sclass[] = {
692	{ NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
693	{ NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
694	{ NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
695	{ NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
696	{ NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
697	{}
698};
699
700/*******************************************************************************
701 * Display context, tracks instmem allocation and prevents more than one
702 * client using the display hardware at any time.
703 ******************************************************************************/
704
705static int
706nv50_disp_data_ctor(struct nouveau_object *parent,
707		    struct nouveau_object *engine,
708		    struct nouveau_oclass *oclass, void *data, u32 size,
709		    struct nouveau_object **pobject)
710{
711	struct nv50_disp_priv *priv = (void *)engine;
712	struct nouveau_engctx *ectx;
713	int ret = -EBUSY;
714
715	/* no context needed for channel objects... */
716	if (nv_mclass(parent) != NV_DEVICE_CLASS) {
717		atomic_inc(&parent->refcount);
718		*pobject = parent;
719		return 0;
720	}
721
722	/* allocate display hardware to client */
723	mutex_lock(&nv_subdev(priv)->mutex);
724	if (list_empty(&nv_engine(priv)->contexts)) {
725		ret = nouveau_engctx_create(parent, engine, oclass, NULL,
726					    0x10000, 0x10000,
727					    NVOBJ_FLAG_HEAP, &ectx);
728		*pobject = nv_object(ectx);
729	}
730	mutex_unlock(&nv_subdev(priv)->mutex);
731	return ret;
732}
733
734struct nouveau_oclass
735nv50_disp_cclass = {
736	.handle = NV_ENGCTX(DISP, 0x50),
737	.ofuncs = &(struct nouveau_ofuncs) {
738		.ctor = nv50_disp_data_ctor,
739		.dtor = _nouveau_engctx_dtor,
740		.init = _nouveau_engctx_init,
741		.fini = _nouveau_engctx_fini,
742		.rd32 = _nouveau_engctx_rd32,
743		.wr32 = _nouveau_engctx_wr32,
744	},
745};
746
747/*******************************************************************************
748 * Display engine implementation
749 ******************************************************************************/
750
751static void
752nv50_disp_intr_error(struct nv50_disp_priv *priv)
753{
754	u32 channels = (nv_rd32(priv, 0x610020) & 0x001f0000) >> 16;
755	u32 addr, data;
756	int chid;
757
758	for (chid = 0; chid < 5; chid++) {
759		if (!(channels & (1 << chid)))
760			continue;
761
762		nv_wr32(priv, 0x610020, 0x00010000 << chid);
763		addr = nv_rd32(priv, 0x610080 + (chid * 0x08));
764		data = nv_rd32(priv, 0x610084 + (chid * 0x08));
765		nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000);
766
767		nv_error(priv, "chid %d mthd 0x%04x data 0x%08x 0x%08x\n",
768			 chid, addr & 0xffc, data, addr);
769	}
770}
771
772static u16
773exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
774	    struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
775	    struct nvbios_outp *info)
776{
777	struct nouveau_bios *bios = nouveau_bios(priv);
778	u16 mask, type, data;
779
780	if (outp < 4) {
781		type = DCB_OUTPUT_ANALOG;
782		mask = 0;
783	} else {
784		outp -= 4;
785		switch (ctrl & 0x00000f00) {
786		case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
787		case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
788		case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
789		case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
790		case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
791		case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
792		default:
793			nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
794			return 0x0000;
795		}
796	}
797
798	mask  = 0x00c0 & (mask << 6);
799	mask |= 0x0001 << outp;
800	mask |= 0x0100 << head;
801
802	data = dcb_outp_match(bios, type, mask, ver, hdr, dcb);
803	if (!data)
804		return 0x0000;
805
806	return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info);
807}
808
809static bool
810exec_script(struct nv50_disp_priv *priv, int head, int id)
811{
812	struct nouveau_bios *bios = nouveau_bios(priv);
813	struct nvbios_outp info;
814	struct dcb_output dcb;
815	u8  ver, hdr, cnt, len;
816	u16 data;
817	u32 ctrl = 0x00000000;
818	int i;
819
820	for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
821		ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
822
823	if (!(ctrl & (1 << head))) {
824		if (nv_device(priv)->chipset  < 0x90 ||
825		    nv_device(priv)->chipset == 0x92 ||
826		    nv_device(priv)->chipset == 0xa0) {
827			for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
828				ctrl = nv_rd32(priv, 0x610b74 + (i * 8));
829			i += 4;
830		} else {
831			for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
832				ctrl = nv_rd32(priv, 0x610798 + (i * 8));
833			i += 4;
834		}
835	}
836
837	if (!(ctrl & (1 << head)))
838		return false;
839	i--;
840
841	data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info);
842	if (data) {
843		struct nvbios_init init = {
844			.subdev = nv_subdev(priv),
845			.bios = bios,
846			.offset = info.script[id],
847			.outp = &dcb,
848			.crtc = head,
849			.execute = 1,
850		};
851
852		return nvbios_exec(&init) == 0;
853	}
854
855	return false;
856}
857
858static u32
859exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk,
860	    struct dcb_output *outp)
861{
862	struct nouveau_bios *bios = nouveau_bios(priv);
863	struct nvbios_outp info1;
864	struct nvbios_ocfg info2;
865	u8  ver, hdr, cnt, len;
866	u32 ctrl = 0x00000000;
867	u32 data, conf = ~0;
868	int i;
869
870	for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
871		ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
872
873	if (!(ctrl & (1 << head))) {
874		if (nv_device(priv)->chipset  < 0x90 ||
875		    nv_device(priv)->chipset == 0x92 ||
876		    nv_device(priv)->chipset == 0xa0) {
877			for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
878				ctrl = nv_rd32(priv, 0x610b70 + (i * 8));
879			i += 4;
880		} else {
881			for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
882				ctrl = nv_rd32(priv, 0x610794 + (i * 8));
883			i += 4;
884		}
885	}
886
887	if (!(ctrl & (1 << head)))
888		return conf;
889	i--;
890
891	data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1);
892	if (!data)
893		return conf;
894
895	switch (outp->type) {
896	case DCB_OUTPUT_TMDS:
897		conf = (ctrl & 0x00000f00) >> 8;
898		if (pclk >= 165000)
899			conf |= 0x0100;
900		break;
901	case DCB_OUTPUT_LVDS:
902		conf = priv->sor.lvdsconf;
903		break;
904	case DCB_OUTPUT_DP:
905		conf = (ctrl & 0x00000f00) >> 8;
906		break;
907	case DCB_OUTPUT_ANALOG:
908	default:
909		conf = 0x00ff;
910		break;
911	}
912
913	data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
914	if (data) {
915		data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
916		if (data) {
917			struct nvbios_init init = {
918				.subdev = nv_subdev(priv),
919				.bios = bios,
920				.offset = data,
921				.outp = outp,
922				.crtc = head,
923				.execute = 1,
924			};
925
926			nvbios_exec(&init);
927		}
928	}
929
930	return conf;
931}
932
933static void
934nv50_disp_intr_unk10(struct nv50_disp_priv *priv, u32 super)
935{
936	int head = ffs((super & 0x00000060) >> 5) - 1;
937	if (head >= 0) {
938		head = ffs((super & 0x00000180) >> 7) - 1;
939		if (head >= 0)
940			exec_script(priv, head, 1);
941	}
942
943	nv_wr32(priv, 0x610030, 0x80000000);
944}
945
946static void
947nv50_disp_intr_unk20_dp(struct nv50_disp_priv *priv,
948		        struct dcb_output *outp, u32 pclk)
949{
950	const int link = !(outp->sorconf.link & 1);
951	const int   or = ffs(outp->or) - 1;
952	const u32 soff = (  or * 0x800);
953	const u32 loff = (link * 0x080) + soff;
954	const u32 ctrl = nv_rd32(priv, 0x610794 + (or * 8));
955	const u32 symbol = 100000;
956	u32 dpctrl = nv_rd32(priv, 0x61c10c + loff) & 0x0000f0000;
957	u32 clksor = nv_rd32(priv, 0x614300 + soff);
958	int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
959	int TU, VTUi, VTUf, VTUa;
960	u64 link_data_rate, link_ratio, unk;
961	u32 best_diff = 64 * symbol;
962	u32 link_nr, link_bw, bits, r;
963
964	/* calculate packed data rate for each lane */
965	if      (dpctrl > 0x00030000) link_nr = 4;
966	else if (dpctrl > 0x00010000) link_nr = 2;
967	else			      link_nr = 1;
968
969	if (clksor & 0x000c0000)
970		link_bw = 270000;
971	else
972		link_bw = 162000;
973
974	if      ((ctrl & 0xf0000) == 0x60000) bits = 30;
975	else if ((ctrl & 0xf0000) == 0x50000) bits = 24;
976	else                                  bits = 18;
977
978	link_data_rate = (pclk * bits / 8) / link_nr;
979
980	/* calculate ratio of packed data rate to link symbol rate */
981	link_ratio = link_data_rate * symbol;
982	r = do_div(link_ratio, link_bw);
983
984	for (TU = 64; TU >= 32; TU--) {
985		/* calculate average number of valid symbols in each TU */
986		u32 tu_valid = link_ratio * TU;
987		u32 calc, diff;
988
989		/* find a hw representation for the fraction.. */
990		VTUi = tu_valid / symbol;
991		calc = VTUi * symbol;
992		diff = tu_valid - calc;
993		if (diff) {
994			if (diff >= (symbol / 2)) {
995				VTUf = symbol / (symbol - diff);
996				if (symbol - (VTUf * diff))
997					VTUf++;
998
999				if (VTUf <= 15) {
1000					VTUa  = 1;
1001					calc += symbol - (symbol / VTUf);
1002				} else {
1003					VTUa  = 0;
1004					VTUf  = 1;
1005					calc += symbol;
1006				}
1007			} else {
1008				VTUa  = 0;
1009				VTUf  = min((int)(symbol / diff), 15);
1010				calc += symbol / VTUf;
1011			}
1012
1013			diff = calc - tu_valid;
1014		} else {
1015			/* no remainder, but the hw doesn't like the fractional
1016			 * part to be zero.  decrement the integer part and
1017			 * have the fraction add a whole symbol back
1018			 */
1019			VTUa = 0;
1020			VTUf = 1;
1021			VTUi--;
1022		}
1023
1024		if (diff < best_diff) {
1025			best_diff = diff;
1026			bestTU = TU;
1027			bestVTUa = VTUa;
1028			bestVTUf = VTUf;
1029			bestVTUi = VTUi;
1030			if (diff == 0)
1031				break;
1032		}
1033	}
1034
1035	if (!bestTU) {
1036		nv_error(priv, "unable to find suitable dp config\n");
1037		return;
1038	}
1039
1040	/* XXX close to vbios numbers, but not right */
1041	unk  = (symbol - link_ratio) * bestTU;
1042	unk *= link_ratio;
1043	r = do_div(unk, symbol);
1044	r = do_div(unk, symbol);
1045	unk += 6;
1046
1047	nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2);
1048	nv_mask(priv, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 |
1049						   bestVTUf << 16 |
1050						   bestVTUi << 8 | unk);
1051}
1052
1053static void
1054nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super)
1055{
1056	struct dcb_output outp;
1057	u32 addr, mask, data;
1058	int head;
1059
1060	/* finish detaching encoder? */
1061	head = ffs((super & 0x00000180) >> 7) - 1;
1062	if (head >= 0)
1063		exec_script(priv, head, 2);
1064
1065	/* check whether a vpll change is required */
1066	head = ffs((super & 0x00000600) >> 9) - 1;
1067	if (head >= 0) {
1068		u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1069		if (pclk) {
1070			struct nouveau_clock *clk = nouveau_clock(priv);
1071			clk->pll_set(clk, PLL_VPLL0 + head, pclk);
1072		}
1073
1074		nv_mask(priv, 0x614200 + head * 0x800, 0x0000000f, 0x00000000);
1075	}
1076
1077	/* (re)attach the relevant OR to the head */
1078	head = ffs((super & 0x00000180) >> 7) - 1;
1079	if (head >= 0) {
1080		u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1081		u32 conf = exec_clkcmp(priv, head, 0, pclk, &outp);
1082		if (conf != ~0) {
1083			if (outp.type == DCB_OUTPUT_ANALOG) {
1084				addr = 0x614280 + (ffs(outp.or) - 1) * 0x800;
1085				mask = 0xffffffff;
1086				data = 0x00000000;
1087			} else {
1088				if (outp.type == DCB_OUTPUT_DP)
1089					nv50_disp_intr_unk20_dp(priv, &outp, pclk);
1090				addr = 0x614300 + (ffs(outp.or) - 1) * 0x800;
1091				mask = 0x00000707;
1092				data = (conf & 0x0100) ? 0x0101 : 0x0000;
1093			}
1094
1095			nv_mask(priv, addr, mask, data);
1096		}
1097	}
1098
1099	nv_wr32(priv, 0x610030, 0x80000000);
1100}
1101
1102/* If programming a TMDS output on a SOR that can also be configured for
1103 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
1104 *
1105 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
1106 * the VBIOS scripts on at least one board I have only switch it off on
1107 * link 0, causing a blank display if the output has previously been
1108 * programmed for DisplayPort.
1109 */
1110static void
1111nv50_disp_intr_unk40_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp)
1112{
1113	struct nouveau_bios *bios = nouveau_bios(priv);
1114	const int link = !(outp->sorconf.link & 1);
1115	const int   or = ffs(outp->or) - 1;
1116	const u32 loff = (or * 0x800) + (link * 0x80);
1117	const u16 mask = (outp->sorconf.link << 6) | outp->or;
1118	u8  ver, hdr;
1119
1120	if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, outp))
1121		nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000);
1122}
1123
1124static void
1125nv50_disp_intr_unk40(struct nv50_disp_priv *priv, u32 super)
1126{
1127	int head = ffs((super & 0x00000180) >> 7) - 1;
1128	if (head >= 0) {
1129		struct dcb_output outp;
1130		u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
1131		if (exec_clkcmp(priv, head, 1, pclk, &outp) != ~0) {
1132			if (outp.type == DCB_OUTPUT_TMDS)
1133				nv50_disp_intr_unk40_tmds(priv, &outp);
1134		}
1135	}
1136
1137	nv_wr32(priv, 0x610030, 0x80000000);
1138}
1139
1140void
1141nv50_disp_intr_supervisor(struct work_struct *work)
1142{
1143	struct nv50_disp_priv *priv =
1144		container_of(work, struct nv50_disp_priv, supervisor);
1145	u32 super = nv_rd32(priv, 0x610030);
1146
1147	nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
1148
1149	if (priv->super & 0x00000010)
1150		nv50_disp_intr_unk10(priv, super);
1151	if (priv->super & 0x00000020)
1152		nv50_disp_intr_unk20(priv, super);
1153	if (priv->super & 0x00000040)
1154		nv50_disp_intr_unk40(priv, super);
1155}
1156
1157void
1158nv50_disp_intr(struct nouveau_subdev *subdev)
1159{
1160	struct nv50_disp_priv *priv = (void *)subdev;
1161	u32 intr0 = nv_rd32(priv, 0x610020);
1162	u32 intr1 = nv_rd32(priv, 0x610024);
1163
1164	if (intr0 & 0x001f0000) {
1165		nv50_disp_intr_error(priv);
1166		intr0 &= ~0x001f0000;
1167	}
1168
1169	if (intr1 & 0x00000004) {
1170		nouveau_event_trigger(priv->base.vblank, 0);
1171		nv_wr32(priv, 0x610024, 0x00000004);
1172		intr1 &= ~0x00000004;
1173	}
1174
1175	if (intr1 & 0x00000008) {
1176		nouveau_event_trigger(priv->base.vblank, 1);
1177		nv_wr32(priv, 0x610024, 0x00000008);
1178		intr1 &= ~0x00000008;
1179	}
1180
1181	if (intr1 & 0x00000070) {
1182		priv->super = (intr1 & 0x00000070);
1183		schedule_work(&priv->supervisor);
1184		nv_wr32(priv, 0x610024, priv->super);
1185		intr1 &= ~0x00000070;
1186	}
1187}
1188
1189static int
1190nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1191	       struct nouveau_oclass *oclass, void *data, u32 size,
1192	       struct nouveau_object **pobject)
1193{
1194	struct nv50_disp_priv *priv;
1195	int ret;
1196
1197	ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
1198				  "display", &priv);
1199	*pobject = nv_object(priv);
1200	if (ret)
1201		return ret;
1202
1203	nv_engine(priv)->sclass = nv50_disp_base_oclass;
1204	nv_engine(priv)->cclass = &nv50_disp_cclass;
1205	nv_subdev(priv)->intr = nv50_disp_intr;
1206	INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
1207	priv->sclass = nv50_disp_sclass;
1208	priv->head.nr = 2;
1209	priv->dac.nr = 3;
1210	priv->sor.nr = 2;
1211	priv->dac.power = nv50_dac_power;
1212	priv->dac.sense = nv50_dac_sense;
1213	priv->sor.power = nv50_sor_power;
1214	return 0;
1215}
1216
1217struct nouveau_oclass
1218nv50_disp_oclass = {
1219	.handle = NV_ENGINE(DISP, 0x50),
1220	.ofuncs = &(struct nouveau_ofuncs) {
1221		.ctor = nv50_disp_ctor,
1222		.dtor = _nouveau_disp_dtor,
1223		.init = _nouveau_disp_init,
1224		.fini = _nouveau_disp_fini,
1225	},
1226};
1227