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.
29 #include <core/client.h>
30 #include <core/enum.h>
31 #include <core/gpuobj.h>
32 #include <subdev/bios.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>
39 static const struct nvkm_disp_oclass
*
40 nv50_disp_root_(struct nvkm_disp
*base
)
42 return nv50_disp(base
)->func
->root
;
46 nv50_disp_intr_(struct nvkm_disp
*base
)
48 struct nv50_disp
*disp
= nv50_disp(base
);
49 disp
->func
->intr(disp
);
53 nv50_disp_dtor_(struct nvkm_disp
*base
)
55 struct nv50_disp
*disp
= nv50_disp(base
);
56 nvkm_event_fini(&disp
->uevent
);
58 destroy_workqueue(disp
->wq
);
62 static const struct nvkm_disp_func
64 .dtor
= nv50_disp_dtor_
,
65 .intr
= nv50_disp_intr_
,
66 .root
= nv50_disp_root_
,
70 nv50_disp_new_(const struct nv50_disp_func
*func
, struct nvkm_device
*device
,
71 int index
, int heads
, struct nvkm_disp
**pdisp
)
73 struct nv50_disp
*disp
;
76 if (!(disp
= kzalloc(sizeof(*disp
), GFP_KERNEL
)))
81 ret
= nvkm_disp_ctor(&nv50_disp_
, device
, index
, &disp
->base
);
85 disp
->wq
= create_singlethread_workqueue("nvkm-disp");
88 INIT_WORK(&disp
->supervisor
, func
->super
);
90 for (i
= 0; func
->head
.new && i
< heads
; i
++) {
91 ret
= func
->head
.new(&disp
->base
, i
);
96 for (i
= 0; func
->dac
.new && i
< func
->dac
.nr
; i
++) {
97 ret
= func
->dac
.new(&disp
->base
, i
);
102 for (i
= 0; func
->pior
.new && i
< func
->pior
.nr
; i
++) {
103 ret
= func
->pior
.new(&disp
->base
, i
);
108 for (i
= 0; func
->sor
.new && i
< func
->sor
.nr
; i
++) {
109 ret
= func
->sor
.new(&disp
->base
, i
);
114 return nvkm_event_init(func
->uevent
, 1, 1 + (heads
* 4), &disp
->uevent
);
118 nv50_disp_super_iedt(struct nvkm_head
*head
, struct nvkm_outp
*outp
,
119 u8
*ver
, u8
*hdr
, u8
*cnt
, u8
*len
,
120 struct nvbios_outp
*iedt
)
122 struct nvkm_bios
*bios
= head
->disp
->engine
.subdev
.device
->bios
;
123 const u8 l
= ffs(outp
->info
.link
);
124 const u16 t
= outp
->info
.hasht
;
125 const u16 m
= (0x0100 << head
->id
) | (l
<< 6) | outp
->info
.or;
126 u32 data
= nvbios_outp_match(bios
, t
, m
, ver
, hdr
, cnt
, len
, iedt
);
128 OUTP_DBG(outp
, "missing IEDT for %04x:%04x", t
, m
);
133 nv50_disp_super_ied_on(struct nvkm_head
*head
,
134 struct nvkm_ior
*ior
, int id
, u32 khz
)
136 struct nvkm_subdev
*subdev
= &head
->disp
->engine
.subdev
;
137 struct nvkm_bios
*bios
= subdev
->device
->bios
;
138 struct nvkm_outp
*outp
= ior
->asy
.outp
;
139 struct nvbios_ocfg iedtrs
;
140 struct nvbios_outp iedt
;
141 u8 ver
, hdr
, cnt
, len
, flags
= 0x00;
145 IOR_DBG(ior
, "nothing to attach");
149 /* Lookup IED table for the device. */
150 data
= nv50_disp_super_iedt(head
, outp
, &ver
, &hdr
, &cnt
, &len
, &iedt
);
154 /* Lookup IEDT runtime settings for the current configuration. */
155 if (ior
->type
== SOR
) {
156 if (ior
->asy
.proto
== LVDS
) {
157 if (head
->asy
.or.depth
== 24)
160 if (ior
->asy
.link
== 3)
164 data
= nvbios_ocfg_match(bios
, data
, ior
->asy
.proto_evo
, flags
,
165 &ver
, &hdr
, &cnt
, &len
, &iedtrs
);
167 OUTP_DBG(outp
, "missing IEDT RS for %02x:%02x",
168 ior
->asy
.proto_evo
, flags
);
172 /* Execute the OnInt[23] script for the current frequency. */
173 data
= nvbios_oclk_match(bios
, iedtrs
.clkcmp
[id
], khz
);
175 OUTP_DBG(outp
, "missing IEDT RSS %d for %02x:%02x %d khz",
176 id
, ior
->asy
.proto_evo
, flags
, khz
);
180 nvbios_init(subdev
, data
,
181 init
.outp
= &outp
->info
;
183 init
.link
= ior
->asy
.link
;
184 init
.head
= head
->id
;
189 nv50_disp_super_ied_off(struct nvkm_head
*head
, struct nvkm_ior
*ior
, int id
)
191 struct nvkm_outp
*outp
= ior
->arm
.outp
;
192 struct nvbios_outp iedt
;
193 u8 ver
, hdr
, cnt
, len
;
197 IOR_DBG(ior
, "nothing attached");
201 data
= nv50_disp_super_iedt(head
, outp
, &ver
, &hdr
, &cnt
, &len
, &iedt
);
205 nvbios_init(&head
->disp
->engine
.subdev
, iedt
.script
[id
],
206 init
.outp
= &outp
->info
;
208 init
.link
= ior
->arm
.link
;
209 init
.head
= head
->id
;
213 static struct nvkm_ior
*
214 nv50_disp_super_ior_asy(struct nvkm_head
*head
)
216 struct nvkm_ior
*ior
;
217 list_for_each_entry(ior
, &head
->disp
->ior
, head
) {
218 if (ior
->asy
.head
& (1 << head
->id
)) {
219 HEAD_DBG(head
, "to %s", ior
->name
);
223 HEAD_DBG(head
, "nothing to attach");
227 static struct nvkm_ior
*
228 nv50_disp_super_ior_arm(struct nvkm_head
*head
)
230 struct nvkm_ior
*ior
;
231 list_for_each_entry(ior
, &head
->disp
->ior
, head
) {
232 if (ior
->arm
.head
& (1 << head
->id
)) {
233 HEAD_DBG(head
, "on %s", ior
->name
);
237 HEAD_DBG(head
, "nothing attached");
242 nv50_disp_super_3_0(struct nv50_disp
*disp
, struct nvkm_head
*head
)
244 struct nvkm_ior
*ior
;
246 /* Determine which OR, if any, we're attaching to the head. */
247 HEAD_DBG(head
, "supervisor 3.0");
248 ior
= nv50_disp_super_ior_asy(head
);
252 /* Execute OnInt3 IED script. */
253 nv50_disp_super_ied_on(head
, ior
, 1, head
->asy
.hz
/ 1000);
255 /* OR-specific handling. */
256 if (ior
->func
->war_3
)
257 ior
->func
->war_3(ior
);
261 nv50_disp_super_2_2_dp(struct nvkm_head
*head
, struct nvkm_ior
*ior
)
263 struct nvkm_subdev
*subdev
= &head
->disp
->engine
.subdev
;
264 const u32 khz
= head
->asy
.hz
/ 1000;
265 const u32 linkKBps
= ior
->dp
.bw
* 27000;
266 const u32 symbol
= 100000;
267 int bestTU
= 0, bestVTUi
= 0, bestVTUf
= 0, bestVTUa
= 0;
268 int TU
, VTUi
, VTUf
, VTUa
;
269 u64 link_data_rate
, link_ratio
, unk
;
270 u32 best_diff
= 64 * symbol
;
273 /* symbols/hblank - algorithm taken from comments in tegra driver */
274 h
= head
->asy
.hblanke
+ head
->asy
.htotal
- head
->asy
.hblanks
- 7;
277 h
= h
- (3 * ior
->dp
.ef
) - (12 / ior
->dp
.nr
);
279 /* symbols/vblank - algorithm taken from comments in tegra driver */
280 v
= head
->asy
.vblanks
- head
->asy
.vblanke
- 25;
283 v
= v
- ((36 / ior
->dp
.nr
) + 3) - 1;
285 ior
->func
->dp
.audio_sym(ior
, head
->id
, h
, v
);
287 /* watermark / activesym */
288 link_data_rate
= (khz
* head
->asy
.or.depth
/ 8) / ior
->dp
.nr
;
290 /* calculate ratio of packed data rate to link symbol rate */
291 link_ratio
= link_data_rate
* symbol
;
292 do_div(link_ratio
, linkKBps
);
294 for (TU
= 64; ior
->func
->dp
.activesym
&& TU
>= 32; TU
--) {
295 /* calculate average number of valid symbols in each TU */
296 u32 tu_valid
= link_ratio
* TU
;
299 /* find a hw representation for the fraction.. */
300 VTUi
= tu_valid
/ symbol
;
301 calc
= VTUi
* symbol
;
302 diff
= tu_valid
- calc
;
304 if (diff
>= (symbol
/ 2)) {
305 VTUf
= symbol
/ (symbol
- diff
);
306 if (symbol
- (VTUf
* diff
))
311 calc
+= symbol
- (symbol
/ VTUf
);
319 VTUf
= min((int)(symbol
/ diff
), 15);
320 calc
+= symbol
/ VTUf
;
323 diff
= calc
- tu_valid
;
325 /* no remainder, but the hw doesn't like the fractional
326 * part to be zero. decrement the integer part and
327 * have the fraction add a whole symbol back
334 if (diff
< best_diff
) {
345 if (ior
->func
->dp
.activesym
) {
347 nvkm_error(subdev
, "unable to determine dp config\n");
350 ior
->func
->dp
.activesym(ior
, head
->id
, bestTU
,
351 bestVTUa
, bestVTUf
, bestVTUi
);
356 /* XXX close to vbios numbers, but not right */
357 unk
= (symbol
- link_ratio
) * bestTU
;
363 ior
->func
->dp
.watermark(ior
, head
->id
, unk
);
367 nv50_disp_super_2_2(struct nv50_disp
*disp
, struct nvkm_head
*head
)
369 const u32 khz
= head
->asy
.hz
/ 1000;
370 struct nvkm_outp
*outp
;
371 struct nvkm_ior
*ior
;
373 /* Determine which OR, if any, we're attaching from the head. */
374 HEAD_DBG(head
, "supervisor 2.2");
375 ior
= nv50_disp_super_ior_asy(head
);
379 /* For some reason, NVIDIA decided not to:
381 * A) Give dual-link LVDS a separate EVO protocol, like for TMDS.
383 * B) Use SetControlOutputResource.PixelDepth on LVDS.
385 * Override the values we usually read from HW with the same
386 * data we pass though an ioctl instead.
388 if (ior
->type
== SOR
&& ior
->asy
.proto
== LVDS
) {
389 head
->asy
.or.depth
= (disp
->sor
.lvdsconf
& 0x0200) ? 24 : 18;
390 ior
->asy
.link
= (disp
->sor
.lvdsconf
& 0x0100) ? 3 : 1;
393 /* Handle any link training, etc. */
394 if ((outp
= ior
->asy
.outp
) && outp
->func
->acquire
)
395 outp
->func
->acquire(outp
);
397 /* Execute OnInt2 IED script. */
398 nv50_disp_super_ied_on(head
, ior
, 0, khz
);
400 /* Program RG clock divider. */
401 head
->func
->rgclk(head
, ior
->asy
.rgdiv
);
403 /* Mode-specific internal DP configuration. */
404 if (ior
->type
== SOR
&& ior
->asy
.proto
== DP
)
405 nv50_disp_super_2_2_dp(head
, ior
);
407 /* OR-specific handling. */
408 ior
->func
->clock(ior
);
409 if (ior
->func
->war_2
)
410 ior
->func
->war_2(ior
);
414 nv50_disp_super_2_1(struct nv50_disp
*disp
, struct nvkm_head
*head
)
416 struct nvkm_devinit
*devinit
= disp
->base
.engine
.subdev
.device
->devinit
;
417 const u32 khz
= head
->asy
.hz
/ 1000;
418 HEAD_DBG(head
, "supervisor 2.1 - %d khz", khz
);
420 nvkm_devinit_pll_set(devinit
, PLL_VPLL0
+ head
->id
, khz
);
424 nv50_disp_super_2_0(struct nv50_disp
*disp
, struct nvkm_head
*head
)
426 struct nvkm_outp
*outp
;
427 struct nvkm_ior
*ior
;
429 /* Determine which OR, if any, we're detaching from the head. */
430 HEAD_DBG(head
, "supervisor 2.0");
431 ior
= nv50_disp_super_ior_arm(head
);
435 /* Execute OffInt2 IED script. */
436 nv50_disp_super_ied_off(head
, ior
, 2);
438 /* If we're shutting down the OR's only active head, execute
439 * the output path's release function.
441 if (ior
->arm
.head
== (1 << head
->id
)) {
442 if ((outp
= ior
->arm
.outp
) && outp
->func
->release
)
443 outp
->func
->release(outp
, ior
);
448 nv50_disp_super_1_0(struct nv50_disp
*disp
, struct nvkm_head
*head
)
450 struct nvkm_ior
*ior
;
452 /* Determine which OR, if any, we're detaching from the head. */
453 HEAD_DBG(head
, "supervisor 1.0");
454 ior
= nv50_disp_super_ior_arm(head
);
458 /* Execute OffInt1 IED script. */
459 nv50_disp_super_ied_off(head
, ior
, 1);
463 nv50_disp_super_1(struct nv50_disp
*disp
)
465 struct nvkm_head
*head
;
466 struct nvkm_ior
*ior
;
468 list_for_each_entry(head
, &disp
->base
.head
, head
) {
469 head
->func
->state(head
, &head
->arm
);
470 head
->func
->state(head
, &head
->asy
);
473 list_for_each_entry(ior
, &disp
->base
.ior
, head
) {
474 ior
->func
->state(ior
, &ior
->arm
);
475 ior
->func
->state(ior
, &ior
->asy
);
480 nv50_disp_super(struct work_struct
*work
)
482 struct nv50_disp
*disp
=
483 container_of(work
, struct nv50_disp
, supervisor
);
484 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
485 struct nvkm_device
*device
= subdev
->device
;
486 struct nvkm_head
*head
;
487 u32 super
= nvkm_rd32(device
, 0x610030);
489 nvkm_debug(subdev
, "supervisor %08x %08x\n", disp
->super
, super
);
491 if (disp
->super
& 0x00000010) {
492 nv50_disp_chan_mthd(disp
->chan
[0], NV_DBG_DEBUG
);
493 nv50_disp_super_1(disp
);
494 list_for_each_entry(head
, &disp
->base
.head
, head
) {
495 if (!(super
& (0x00000020 << head
->id
)))
497 if (!(super
& (0x00000080 << head
->id
)))
499 nv50_disp_super_1_0(disp
, head
);
502 if (disp
->super
& 0x00000020) {
503 list_for_each_entry(head
, &disp
->base
.head
, head
) {
504 if (!(super
& (0x00000080 << head
->id
)))
506 nv50_disp_super_2_0(disp
, head
);
508 nvkm_outp_route(&disp
->base
);
509 list_for_each_entry(head
, &disp
->base
.head
, head
) {
510 if (!(super
& (0x00000200 << head
->id
)))
512 nv50_disp_super_2_1(disp
, head
);
514 list_for_each_entry(head
, &disp
->base
.head
, head
) {
515 if (!(super
& (0x00000080 << head
->id
)))
517 nv50_disp_super_2_2(disp
, head
);
520 if (disp
->super
& 0x00000040) {
521 list_for_each_entry(head
, &disp
->base
.head
, head
) {
522 if (!(super
& (0x00000080 << head
->id
)))
524 nv50_disp_super_3_0(disp
, head
);
528 nvkm_wr32(device
, 0x610030, 0x80000000);
531 static const struct nvkm_enum
532 nv50_disp_intr_error_type
[] = {
533 { 3, "ILLEGAL_MTHD" },
534 { 4, "INVALID_VALUE" },
535 { 5, "INVALID_STATE" },
536 { 7, "INVALID_HANDLE" },
540 static const struct nvkm_enum
541 nv50_disp_intr_error_code
[] = {
547 nv50_disp_intr_error(struct nv50_disp
*disp
, int chid
)
549 struct nvkm_subdev
*subdev
= &disp
->base
.engine
.subdev
;
550 struct nvkm_device
*device
= subdev
->device
;
551 u32 data
= nvkm_rd32(device
, 0x610084 + (chid
* 0x08));
552 u32 addr
= nvkm_rd32(device
, 0x610080 + (chid
* 0x08));
553 u32 code
= (addr
& 0x00ff0000) >> 16;
554 u32 type
= (addr
& 0x00007000) >> 12;
555 u32 mthd
= (addr
& 0x00000ffc);
556 const struct nvkm_enum
*ec
, *et
;
558 et
= nvkm_enum_find(nv50_disp_intr_error_type
, type
);
559 ec
= nvkm_enum_find(nv50_disp_intr_error_code
, code
);
562 "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n",
563 type
, et
? et
->name
: "", code
, ec
? ec
->name
: "",
566 if (chid
< ARRAY_SIZE(disp
->chan
)) {
569 nv50_disp_chan_mthd(disp
->chan
[chid
], NV_DBG_ERROR
);
576 nvkm_wr32(device
, 0x610020, 0x00010000 << chid
);
577 nvkm_wr32(device
, 0x610080 + (chid
* 0x08), 0x90000000);
581 nv50_disp_intr(struct nv50_disp
*disp
)
583 struct nvkm_device
*device
= disp
->base
.engine
.subdev
.device
;
584 u32 intr0
= nvkm_rd32(device
, 0x610020);
585 u32 intr1
= nvkm_rd32(device
, 0x610024);
587 while (intr0
& 0x001f0000) {
588 u32 chid
= __ffs(intr0
& 0x001f0000) - 16;
589 nv50_disp_intr_error(disp
, chid
);
590 intr0
&= ~(0x00010000 << chid
);
593 while (intr0
& 0x0000001f) {
594 u32 chid
= __ffs(intr0
& 0x0000001f);
595 nv50_disp_chan_uevent_send(disp
, chid
);
596 intr0
&= ~(0x00000001 << chid
);
599 if (intr1
& 0x00000004) {
600 nvkm_disp_vblank(&disp
->base
, 0);
601 nvkm_wr32(device
, 0x610024, 0x00000004);
604 if (intr1
& 0x00000008) {
605 nvkm_disp_vblank(&disp
->base
, 1);
606 nvkm_wr32(device
, 0x610024, 0x00000008);
609 if (intr1
& 0x00000070) {
610 disp
->super
= (intr1
& 0x00000070);
611 queue_work(disp
->wq
, &disp
->supervisor
);
612 nvkm_wr32(device
, 0x610024, disp
->super
);
616 static const struct nv50_disp_func
618 .intr
= nv50_disp_intr
,
619 .uevent
= &nv50_disp_chan_uevent
,
620 .super
= nv50_disp_super
,
621 .root
= &nv50_disp_root_oclass
,
622 .head
.new = nv50_head_new
,
623 .dac
= { .nr
= 3, .new = nv50_dac_new
},
624 .sor
= { .nr
= 2, .new = nv50_sor_new
},
625 .pior
= { .nr
= 3, .new = nv50_pior_new
},
629 nv50_disp_new(struct nvkm_device
*device
, int index
, struct nvkm_disp
**pdisp
)
631 return nv50_disp_new_(&nv50_disp
, device
, index
, 2, pdisp
);