2 * Copyright 2012 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
27 #include <core/client.h>
28 #include <core/enum.h>
29 #include <core/gpuobj.h>
30 #include <subdev/bios.h>
31 #include <subdev/bios/disp.h>
32 #include <subdev/bios/init.h>
33 #include <subdev/bios/pll.h>
34 #include <subdev/devinit.h>
36 static const struct nvkm_disp_oclass
*
37 nv50_disp_root_(struct nvkm_disp
*base
)
39 return nv50_disp(base
)->func
->root
;
43 nv50_disp_outp_internal_crt_(struct nvkm_disp
*base
, int index
,
44 struct dcb_output
*dcb
, struct nvkm_output
**poutp
)
46 struct nv50_disp
*disp
= nv50_disp(base
);
47 return disp
->func
->outp
.internal
.crt(base
, index
, dcb
, poutp
);
51 nv50_disp_outp_internal_tmds_(struct nvkm_disp
*base
, int index
,
52 struct dcb_output
*dcb
,
53 struct nvkm_output
**poutp
)
55 struct nv50_disp
*disp
= nv50_disp(base
);
56 return disp
->func
->outp
.internal
.tmds(base
, index
, dcb
, poutp
);
60 nv50_disp_outp_internal_lvds_(struct nvkm_disp
*base
, int index
,
61 struct dcb_output
*dcb
,
62 struct nvkm_output
**poutp
)
64 struct nv50_disp
*disp
= nv50_disp(base
);
65 return disp
->func
->outp
.internal
.lvds(base
, index
, dcb
, poutp
);
69 nv50_disp_outp_internal_dp_(struct nvkm_disp
*base
, int index
,
70 struct dcb_output
*dcb
, struct nvkm_output
**poutp
)
72 struct nv50_disp
*disp
= nv50_disp(base
);
73 if (disp
->func
->outp
.internal
.dp
)
74 return disp
->func
->outp
.internal
.dp(base
, index
, dcb
, poutp
);
79 nv50_disp_outp_external_tmds_(struct nvkm_disp
*base
, int index
,
80 struct dcb_output
*dcb
,
81 struct nvkm_output
**poutp
)
83 struct nv50_disp
*disp
= nv50_disp(base
);
84 if (disp
->func
->outp
.external
.tmds
)
85 return disp
->func
->outp
.external
.tmds(base
, index
, dcb
, poutp
);
90 nv50_disp_outp_external_dp_(struct nvkm_disp
*base
, int index
,
91 struct dcb_output
*dcb
, struct nvkm_output
**poutp
)
93 struct nv50_disp
*disp
= nv50_disp(base
);
94 if (disp
->func
->outp
.external
.dp
)
95 return disp
->func
->outp
.external
.dp(base
, index
, dcb
, poutp
);
100 nv50_disp_vblank_fini_(struct nvkm_disp
*base
, int head
)
102 struct nv50_disp
*disp
= nv50_disp(base
);
103 disp
->func
->head
.vblank_fini(disp
, head
);
107 nv50_disp_vblank_init_(struct nvkm_disp
*base
, int head
)
109 struct nv50_disp
*disp
= nv50_disp(base
);
110 disp
->func
->head
.vblank_init(disp
, head
);
114 nv50_disp_intr_(struct nvkm_disp
*base
)
116 struct nv50_disp
*disp
= nv50_disp(base
);
117 disp
->func
->intr(disp
);
121 nv50_disp_dtor_(struct nvkm_disp
*base
)
123 struct nv50_disp
*disp
= nv50_disp(base
);
124 nvkm_event_fini(&disp
->uevent
);
128 static const struct nvkm_disp_func
130 .dtor
= nv50_disp_dtor_
,
131 .intr
= nv50_disp_intr_
,
132 .root
= nv50_disp_root_
,
133 .outp
.internal
.crt
= nv50_disp_outp_internal_crt_
,
134 .outp
.internal
.tmds
= nv50_disp_outp_internal_tmds_
,
135 .outp
.internal
.lvds
= nv50_disp_outp_internal_lvds_
,
136 .outp
.internal
.dp
= nv50_disp_outp_internal_dp_
,
137 .outp
.external
.tmds
= nv50_disp_outp_external_tmds_
,
138 .outp
.external
.dp
= nv50_disp_outp_external_dp_
,
139 .head
.vblank_init
= nv50_disp_vblank_init_
,
140 .head
.vblank_fini
= nv50_disp_vblank_fini_
,
144 nv50_disp_new_(const struct nv50_disp_func
*func
, struct nvkm_device
*device
,
145 int index
, int heads
, struct nvkm_disp
**pdisp
)
147 struct nv50_disp
*disp
;
150 if (!(disp
= kzalloc(sizeof(*disp
), GFP_KERNEL
)))
152 INIT_WORK(&disp
->supervisor
, func
->super
);
154 *pdisp
= &disp
->base
;
156 ret
= nvkm_disp_ctor(&nv50_disp_
, device
, index
, heads
, &disp
->base
);
160 return nvkm_event_init(func
->uevent
, 1, 1 + (heads
* 4), &disp
->uevent
);
164 nv50_disp_vblank_fini(struct nv50_disp
*disp
, int head
)
166 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
167 nvkm_mask(device
, 0x61002c, (4 << head
), 0);
171 nv50_disp_vblank_init(struct nv50_disp
*disp
, int head
)
173 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
174 nvkm_mask(device
, 0x61002c, (4 << head
), (4 << head
));
177 static const struct nvkm_enum
178 nv50_disp_intr_error_type
[] = {
179 { 3, "ILLEGAL_MTHD" },
180 { 4, "INVALID_VALUE" },
181 { 5, "INVALID_STATE" },
182 { 7, "INVALID_HANDLE" },
186 static const struct nvkm_enum
187 nv50_disp_intr_error_code
[] = {
193 nv50_disp_intr_error(struct nv50_disp
*disp
, int chid
)
195 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
196 struct nvkm_device
*device
= subdev
->device
;
197 u32 data
= nvkm_rd32(device
, 0x610084 + (chid
* 0x08));
198 u32 addr
= nvkm_rd32(device
, 0x610080 + (chid
* 0x08));
199 u32 code
= (addr
& 0x00ff0000) >> 16;
200 u32 type
= (addr
& 0x00007000) >> 12;
201 u32 mthd
= (addr
& 0x00000ffc);
202 const struct nvkm_enum
*ec
, *et
;
204 et
= nvkm_enum_find(nv50_disp_intr_error_type
, type
);
205 ec
= nvkm_enum_find(nv50_disp_intr_error_code
, code
);
208 "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n",
209 type
, et
? et
->name
: "", code
, ec
? ec
->name
: "",
212 if (chid
< ARRAY_SIZE(disp
->chan
)) {
215 nv50_disp_chan_mthd(disp
->chan
[chid
], NV_DBG_ERROR
);
222 nvkm_wr32(device
, 0x610020, 0x00010000 << chid
);
223 nvkm_wr32(device
, 0x610080 + (chid
* 0x08), 0x90000000);
226 static struct nvkm_output
*
227 exec_lookup(struct nv50_disp
*disp
, int head
, int or, u32 ctrl
,
228 u32
*data
, u8
*ver
, u8
*hdr
, u8
*cnt
, u8
*len
,
229 struct nvbios_outp
*info
)
231 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
232 struct nvkm_bios
*bios
= subdev
->device
->bios
;
233 struct nvkm_output
*outp
;
237 type
= DCB_OUTPUT_ANALOG
;
241 switch (ctrl
& 0x00000f00) {
242 case 0x00000000: type
= DCB_OUTPUT_LVDS
; mask
= 1; break;
243 case 0x00000100: type
= DCB_OUTPUT_TMDS
; mask
= 1; break;
244 case 0x00000200: type
= DCB_OUTPUT_TMDS
; mask
= 2; break;
245 case 0x00000500: type
= DCB_OUTPUT_TMDS
; mask
= 3; break;
246 case 0x00000800: type
= DCB_OUTPUT_DP
; mask
= 1; break;
247 case 0x00000900: type
= DCB_OUTPUT_DP
; mask
= 2; break;
249 nvkm_error(subdev
, "unknown SOR mc %08x\n", ctrl
);
257 switch (ctrl
& 0x00000f00) {
258 case 0x00000000: type
|= disp
->pior
.type
[or]; break;
260 nvkm_error(subdev
, "unknown PIOR mc %08x\n", ctrl
);
265 mask
= 0x00c0 & (mask
<< 6);
266 mask
|= 0x0001 << or;
267 mask
|= 0x0100 << head
;
269 list_for_each_entry(outp
, &disp
->base
.outp
, head
) {
270 if ((outp
->info
.hasht
& 0xff) == type
&&
271 (outp
->info
.hashm
& mask
) == mask
) {
272 *data
= nvbios_outp_match(bios
, outp
->info
.hasht
,
274 ver
, hdr
, cnt
, len
, info
);
284 static struct nvkm_output
*
285 exec_script(struct nv50_disp
*disp
, int head
, int id
)
287 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
288 struct nvkm_device
*device
= subdev
->device
;
289 struct nvkm_bios
*bios
= device
->bios
;
290 struct nvkm_output
*outp
;
291 struct nvbios_outp info
;
292 u8 ver
, hdr
, cnt
, len
;
298 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->dac
.nr
; i
++)
299 ctrl
= nvkm_rd32(device
, 0x610b5c + (i
* 8));
302 if (!(ctrl
& (1 << head
))) {
303 if (device
->chipset
< 0x90 ||
304 device
->chipset
== 0x92 ||
305 device
->chipset
== 0xa0) {
310 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->sor
.nr
; i
++)
311 ctrl
= nvkm_rd32(device
, reg
+ (i
* 8));
316 if (!(ctrl
& (1 << head
))) {
317 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->pior
.nr
; i
++)
318 ctrl
= nvkm_rd32(device
, 0x610b84 + (i
* 8));
322 if (!(ctrl
& (1 << head
)))
326 outp
= exec_lookup(disp
, head
, i
, ctrl
, &data
, &ver
, &hdr
, &cnt
, &len
, &info
);
328 struct nvbios_init init
= {
331 .offset
= info
.script
[id
],
343 static struct nvkm_output
*
344 exec_clkcmp(struct nv50_disp
*disp
, int head
, int id
, u32 pclk
, u32
*conf
)
346 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
347 struct nvkm_device
*device
= subdev
->device
;
348 struct nvkm_bios
*bios
= device
->bios
;
349 struct nvkm_output
*outp
;
350 struct nvbios_outp info1
;
351 struct nvbios_ocfg info2
;
352 u8 ver
, hdr
, cnt
, len
;
358 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->dac
.nr
; i
++)
359 ctrl
= nvkm_rd32(device
, 0x610b58 + (i
* 8));
362 if (!(ctrl
& (1 << head
))) {
363 if (device
->chipset
< 0x90 ||
364 device
->chipset
== 0x92 ||
365 device
->chipset
== 0xa0) {
370 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->sor
.nr
; i
++)
371 ctrl
= nvkm_rd32(device
, reg
+ (i
* 8));
376 if (!(ctrl
& (1 << head
))) {
377 for (i
= 0; !(ctrl
& (1 << head
)) && i
< disp
->func
->pior
.nr
; i
++)
378 ctrl
= nvkm_rd32(device
, 0x610b80 + (i
* 8));
382 if (!(ctrl
& (1 << head
)))
386 outp
= exec_lookup(disp
, head
, i
, ctrl
, &data
, &ver
, &hdr
, &cnt
, &len
, &info1
);
390 if (outp
->info
.location
== 0) {
391 switch (outp
->info
.type
) {
392 case DCB_OUTPUT_TMDS
:
393 *conf
= (ctrl
& 0x00000f00) >> 8;
397 case DCB_OUTPUT_LVDS
:
398 *conf
= disp
->sor
.lvdsconf
;
401 *conf
= (ctrl
& 0x00000f00) >> 8;
403 case DCB_OUTPUT_ANALOG
:
409 *conf
= (ctrl
& 0x00000f00) >> 8;
413 data
= nvbios_ocfg_match(bios
, data
, *conf
, &ver
, &hdr
, &cnt
, &len
, &info2
);
414 if (data
&& id
< 0xff) {
415 data
= nvbios_oclk_match(bios
, info2
.clkcmp
[id
], pclk
);
417 struct nvbios_init init
= {
434 nv50_disp_intr_unk10_0(struct nv50_disp
*disp
, int head
)
436 exec_script(disp
, head
, 1);
440 nv50_disp_intr_unk20_0(struct nv50_disp
*disp
, int head
)
442 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
443 struct nvkm_output
*outp
= exec_script(disp
, head
, 2);
445 /* the binary driver does this outside of the supervisor handling
446 * (after the third supervisor from a detach). we (currently?)
447 * allow both detach/attach to happen in the same set of
448 * supervisor interrupts, so it would make sense to execute this
449 * (full power down?) script after all the detach phases of the
450 * supervisor handling. like with training if needed from the
451 * second supervisor, nvidia doesn't do this, so who knows if it's
452 * entirely safe, but it does appear to work..
454 * without this script being run, on some configurations i've
455 * seen, switching from DP to TMDS on a DP connector may result
456 * in a blank screen (SOR_PWR off/on can restore it)
458 if (outp
&& outp
->info
.type
== DCB_OUTPUT_DP
) {
459 struct nvkm_output_dp
*outpdp
= nvkm_output_dp(outp
);
460 struct nvbios_init init
= {
462 .bios
= subdev
->device
->bios
,
465 .offset
= outpdp
->info
.script
[4],
470 atomic_set(&outpdp
->lt
.done
, 0);
475 nv50_disp_intr_unk20_1(struct nv50_disp
*disp
, int head
)
477 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
478 struct nvkm_devinit
*devinit
= device
->devinit
;
479 u32 pclk
= nvkm_rd32(device
, 0x610ad0 + (head
* 0x540)) & 0x3fffff;
481 nvkm_devinit_pll_set(devinit
, PLL_VPLL0
+ head
, pclk
);
485 nv50_disp_intr_unk20_2_dp(struct nv50_disp
*disp
, int head
,
486 struct dcb_output
*outp
, u32 pclk
)
488 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
489 struct nvkm_device
*device
= subdev
->device
;
490 const int link
= !(outp
->sorconf
.link
& 1);
491 const int or = ffs(outp
->or) - 1;
492 const u32 soff
= ( or * 0x800);
493 const u32 loff
= (link
* 0x080) + soff
;
494 const u32 ctrl
= nvkm_rd32(device
, 0x610794 + (or * 8));
495 const u32 symbol
= 100000;
496 const s32 vactive
= nvkm_rd32(device
, 0x610af8 + (head
* 0x540)) & 0xffff;
497 const s32 vblanke
= nvkm_rd32(device
, 0x610ae8 + (head
* 0x540)) & 0xffff;
498 const s32 vblanks
= nvkm_rd32(device
, 0x610af0 + (head
* 0x540)) & 0xffff;
499 u32 dpctrl
= nvkm_rd32(device
, 0x61c10c + loff
);
500 u32 clksor
= nvkm_rd32(device
, 0x614300 + soff
);
501 int bestTU
= 0, bestVTUi
= 0, bestVTUf
= 0, bestVTUa
= 0;
502 int TU
, VTUi
, VTUf
, VTUa
;
503 u64 link_data_rate
, link_ratio
, unk
;
504 u32 best_diff
= 64 * symbol
;
505 u32 link_nr
, link_bw
, bits
;
508 link_bw
= (clksor
& 0x000c0000) ? 270000 : 162000;
509 link_nr
= hweight32(dpctrl
& 0x000f0000);
511 /* symbols/hblank - algorithm taken from comments in tegra driver */
512 value
= vblanke
+ vactive
- vblanks
- 7;
513 value
= value
* link_bw
;
515 value
= value
- (3 * !!(dpctrl
& 0x00004000)) - (12 / link_nr
);
516 nvkm_mask(device
, 0x61c1e8 + soff
, 0x0000ffff, value
);
518 /* symbols/vblank - algorithm taken from comments in tegra driver */
519 value
= vblanks
- vblanke
- 25;
520 value
= value
* link_bw
;
522 value
= value
- ((36 / link_nr
) + 3) - 1;
523 nvkm_mask(device
, 0x61c1ec + soff
, 0x00ffffff, value
);
525 /* watermark / activesym */
526 if ((ctrl
& 0xf0000) == 0x60000) bits
= 30;
527 else if ((ctrl
& 0xf0000) == 0x50000) bits
= 24;
530 link_data_rate
= (pclk
* bits
/ 8) / link_nr
;
532 /* calculate ratio of packed data rate to link symbol rate */
533 link_ratio
= link_data_rate
* symbol
;
534 do_div(link_ratio
, link_bw
);
536 for (TU
= 64; TU
>= 32; TU
--) {
537 /* calculate average number of valid symbols in each TU */
538 u32 tu_valid
= link_ratio
* TU
;
541 /* find a hw representation for the fraction.. */
542 VTUi
= tu_valid
/ symbol
;
543 calc
= VTUi
* symbol
;
544 diff
= tu_valid
- calc
;
546 if (diff
>= (symbol
/ 2)) {
547 VTUf
= symbol
/ (symbol
- diff
);
548 if (symbol
- (VTUf
* diff
))
553 calc
+= symbol
- (symbol
/ VTUf
);
561 VTUf
= min((int)(symbol
/ diff
), 15);
562 calc
+= symbol
/ VTUf
;
565 diff
= calc
- tu_valid
;
567 /* no remainder, but the hw doesn't like the fractional
568 * part to be zero. decrement the integer part and
569 * have the fraction add a whole symbol back
576 if (diff
< best_diff
) {
588 nvkm_error(subdev
, "unable to find suitable dp config\n");
592 /* XXX close to vbios numbers, but not right */
593 unk
= (symbol
- link_ratio
) * bestTU
;
599 nvkm_mask(device
, 0x61c10c + loff
, 0x000001fc, bestTU
<< 2);
600 nvkm_mask(device
, 0x61c128 + loff
, 0x010f7f3f, bestVTUa
<< 24 |
602 bestVTUi
<< 8 | unk
);
606 nv50_disp_intr_unk20_2(struct nv50_disp
*disp
, int head
)
608 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
609 struct nvkm_output
*outp
;
610 u32 pclk
= nvkm_rd32(device
, 0x610ad0 + (head
* 0x540)) & 0x3fffff;
611 u32 hval
, hreg
= 0x614200 + (head
* 0x800);
615 outp
= exec_clkcmp(disp
, head
, 0xff, pclk
, &conf
);
619 /* we allow both encoder attach and detach operations to occur
620 * within a single supervisor (ie. modeset) sequence. the
621 * encoder detach scripts quite often switch off power to the
622 * lanes, which requires the link to be re-trained.
624 * this is not generally an issue as the sink "must" (heh)
625 * signal an irq when it's lost sync so the driver can
628 * however, on some boards, if one does not configure at least
629 * the gpu side of the link *before* attaching, then various
630 * things can go horribly wrong (PDISP disappearing from mmio,
631 * third supervisor never happens, etc).
633 * the solution is simply to retrain here, if necessary. last
634 * i checked, the binary driver userspace does not appear to
635 * trigger this situation (it forces an UPDATE between steps).
637 if (outp
->info
.type
== DCB_OUTPUT_DP
) {
638 u32 soff
= (ffs(outp
->info
.or) - 1) * 0x08;
641 if (outp
->info
.location
== 0) {
642 ctrl
= nvkm_rd32(device
, 0x610794 + soff
);
645 ctrl
= nvkm_rd32(device
, 0x610b80 + soff
);
649 switch ((ctrl
& 0x000f0000) >> 16) {
650 case 6: datarate
= pclk
* 30; break;
651 case 5: datarate
= pclk
* 24; break;
654 datarate
= pclk
* 18;
658 if (nvkm_output_dp_train(outp
, datarate
/ soff
, true))
659 OUTP_ERR(outp
, "link not trained before attach");
662 exec_clkcmp(disp
, head
, 0, pclk
, &conf
);
664 if (!outp
->info
.location
&& outp
->info
.type
== DCB_OUTPUT_ANALOG
) {
665 oreg
= 0x614280 + (ffs(outp
->info
.or) - 1) * 0x800;
670 if (!outp
->info
.location
) {
671 if (outp
->info
.type
== DCB_OUTPUT_DP
)
672 nv50_disp_intr_unk20_2_dp(disp
, head
, &outp
->info
, pclk
);
673 oreg
= 0x614300 + (ffs(outp
->info
.or) - 1) * 0x800;
674 oval
= (conf
& 0x0100) ? 0x00000101 : 0x00000000;
678 oreg
= 0x614380 + (ffs(outp
->info
.or) - 1) * 0x800;
684 nvkm_mask(device
, hreg
, 0x0000000f, hval
);
685 nvkm_mask(device
, oreg
, mask
, oval
);
688 /* If programming a TMDS output on a SOR that can also be configured for
689 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
691 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
692 * the VBIOS scripts on at least one board I have only switch it off on
693 * link 0, causing a blank display if the output has previously been
694 * programmed for DisplayPort.
697 nv50_disp_intr_unk40_0_tmds(struct nv50_disp
*disp
,
698 struct dcb_output
*outp
)
700 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
701 struct nvkm_bios
*bios
= device
->bios
;
702 const int link
= !(outp
->sorconf
.link
& 1);
703 const int or = ffs(outp
->or) - 1;
704 const u32 loff
= (or * 0x800) + (link
* 0x80);
705 const u16 mask
= (outp
->sorconf
.link
<< 6) | outp
->or;
706 struct dcb_output match
;
709 if (dcb_outp_match(bios
, DCB_OUTPUT_DP
, mask
, &ver
, &hdr
, &match
))
710 nvkm_mask(device
, 0x61c10c + loff
, 0x00000001, 0x00000000);
714 nv50_disp_intr_unk40_0(struct nv50_disp
*disp
, int head
)
716 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
717 struct nvkm_output
*outp
;
718 u32 pclk
= nvkm_rd32(device
, 0x610ad0 + (head
* 0x540)) & 0x3fffff;
721 outp
= exec_clkcmp(disp
, head
, 1, pclk
, &conf
);
725 if (outp
->info
.location
== 0 && outp
->info
.type
== DCB_OUTPUT_TMDS
)
726 nv50_disp_intr_unk40_0_tmds(disp
, &outp
->info
);
730 nv50_disp_intr_supervisor(struct work_struct
*work
)
732 struct nv50_disp
*disp
=
733 container_of(work
, struct nv50_disp
, supervisor
);
734 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
735 struct nvkm_device
*device
= subdev
->device
;
736 u32 super
= nvkm_rd32(device
, 0x610030);
739 nvkm_debug(subdev
, "supervisor %08x %08x\n", disp
->super
, super
);
741 if (disp
->super
& 0x00000010) {
742 nv50_disp_chan_mthd(disp
->chan
[0], NV_DBG_DEBUG
);
743 for (head
= 0; head
< disp
->base
.head
.nr
; head
++) {
744 if (!(super
& (0x00000020 << head
)))
746 if (!(super
& (0x00000080 << head
)))
748 nv50_disp_intr_unk10_0(disp
, head
);
751 if (disp
->super
& 0x00000020) {
752 for (head
= 0; head
< disp
->base
.head
.nr
; head
++) {
753 if (!(super
& (0x00000080 << head
)))
755 nv50_disp_intr_unk20_0(disp
, head
);
757 for (head
= 0; head
< disp
->base
.head
.nr
; head
++) {
758 if (!(super
& (0x00000200 << head
)))
760 nv50_disp_intr_unk20_1(disp
, head
);
762 for (head
= 0; head
< disp
->base
.head
.nr
; head
++) {
763 if (!(super
& (0x00000080 << head
)))
765 nv50_disp_intr_unk20_2(disp
, head
);
768 if (disp
->super
& 0x00000040) {
769 for (head
= 0; head
< disp
->base
.head
.nr
; head
++) {
770 if (!(super
& (0x00000080 << head
)))
772 nv50_disp_intr_unk40_0(disp
, head
);
776 nvkm_wr32(device
, 0x610030, 0x80000000);
780 nv50_disp_intr(struct nv50_disp
*disp
)
782 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
783 u32 intr0
= nvkm_rd32(device
, 0x610020);
784 u32 intr1
= nvkm_rd32(device
, 0x610024);
786 while (intr0
& 0x001f0000) {
787 u32 chid
= __ffs(intr0
& 0x001f0000) - 16;
788 nv50_disp_intr_error(disp
, chid
);
789 intr0
&= ~(0x00010000 << chid
);
792 while (intr0
& 0x0000001f) {
793 u32 chid
= __ffs(intr0
& 0x0000001f);
794 nv50_disp_chan_uevent_send(disp
, chid
);
795 intr0
&= ~(0x00000001 << chid
);
798 if (intr1
& 0x00000004) {
799 nvkm_disp_vblank(&disp
->base
, 0);
800 nvkm_wr32(device
, 0x610024, 0x00000004);
803 if (intr1
& 0x00000008) {
804 nvkm_disp_vblank(&disp
->base
, 1);
805 nvkm_wr32(device
, 0x610024, 0x00000008);
808 if (intr1
& 0x00000070) {
809 disp
->super
= (intr1
& 0x00000070);
810 schedule_work(&disp
->supervisor
);
811 nvkm_wr32(device
, 0x610024, disp
->super
);
815 static const struct nv50_disp_func
817 .intr
= nv50_disp_intr
,
818 .uevent
= &nv50_disp_chan_uevent
,
819 .super
= nv50_disp_intr_supervisor
,
820 .root
= &nv50_disp_root_oclass
,
821 .head
.vblank_init
= nv50_disp_vblank_init
,
822 .head
.vblank_fini
= nv50_disp_vblank_fini
,
823 .head
.scanoutpos
= nv50_disp_root_scanoutpos
,
824 .outp
.internal
.crt
= nv50_dac_output_new
,
825 .outp
.internal
.tmds
= nv50_sor_output_new
,
826 .outp
.internal
.lvds
= nv50_sor_output_new
,
827 .outp
.external
.tmds
= nv50_pior_output_new
,
828 .outp
.external
.dp
= nv50_pior_dp_new
,
830 .dac
.power
= nv50_dac_power
,
831 .dac
.sense
= nv50_dac_sense
,
833 .sor
.power
= nv50_sor_power
,
835 .pior
.power
= nv50_pior_power
,
839 nv50_disp_new(struct nvkm_device
*device
, int index
, struct nvkm_disp
**pdisp
)
841 return nv50_disp_new_(&nv50_disp
, device
, index
, 2, pdisp
);