GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / gpu / drm / nouveau / nvkm / engine / disp / nv50.c
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24 #include "nv50.h"
25 #include "head.h"
26 #include "ior.h"
27 #include "rootnv50.h"
28
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>
38
39 static const struct nvkm_disp_oclass *
40 nv50_disp_root_(struct nvkm_disp *base)
41 {
42         return nv50_disp(base)->func->root;
43 }
44
45 static void
46 nv50_disp_intr_(struct nvkm_disp *base)
47 {
48         struct nv50_disp *disp = nv50_disp(base);
49         disp->func->intr(disp);
50 }
51
52 static void *
53 nv50_disp_dtor_(struct nvkm_disp *base)
54 {
55         struct nv50_disp *disp = nv50_disp(base);
56         nvkm_event_fini(&disp->uevent);
57         if (disp->wq)
58                 destroy_workqueue(disp->wq);
59         return disp;
60 }
61
62 static const struct nvkm_disp_func
63 nv50_disp_ = {
64         .dtor = nv50_disp_dtor_,
65         .intr = nv50_disp_intr_,
66         .root = nv50_disp_root_,
67 };
68
69 int
70 nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
71                int index, int heads, struct nvkm_disp **pdisp)
72 {
73         struct nv50_disp *disp;
74         int ret, i;
75
76         if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL)))
77                 return -ENOMEM;
78         disp->func = func;
79         *pdisp = &disp->base;
80
81         ret = nvkm_disp_ctor(&nv50_disp_, device, index, &disp->base);
82         if (ret)
83                 return ret;
84
85         disp->wq = create_singlethread_workqueue("nvkm-disp");
86         if (!disp->wq)
87                 return -ENOMEM;
88         INIT_WORK(&disp->supervisor, func->super);
89
90         for (i = 0; func->head.new && i < heads; i++) {
91                 ret = func->head.new(&disp->base, i);
92                 if (ret)
93                         return ret;
94         }
95
96         for (i = 0; func->dac.new && i < func->dac.nr; i++) {
97                 ret = func->dac.new(&disp->base, i);
98                 if (ret)
99                         return ret;
100         }
101
102         for (i = 0; func->pior.new && i < func->pior.nr; i++) {
103                 ret = func->pior.new(&disp->base, i);
104                 if (ret)
105                         return ret;
106         }
107
108         for (i = 0; func->sor.new && i < func->sor.nr; i++) {
109                 ret = func->sor.new(&disp->base, i);
110                 if (ret)
111                         return ret;
112         }
113
114         return nvkm_event_init(func->uevent, 1, 1 + (heads * 4), &disp->uevent);
115 }
116
117 static u32
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)
121 {
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);
127         if (!data)
128                 OUTP_DBG(outp, "missing IEDT for %04x:%04x", t, m);
129         return data;
130 }
131
132 static void
133 nv50_disp_super_ied_on(struct nvkm_head *head,
134                        struct nvkm_ior *ior, int id, u32 khz)
135 {
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;
142         u32 data;
143
144         if (!outp) {
145                 IOR_DBG(ior, "nothing to attach");
146                 return;
147         }
148
149         /* Lookup IED table for the device. */
150         data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt);
151         if (!data)
152                 return;
153
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)
158                                 flags |= 0x02;
159                 }
160                 if (ior->asy.link == 3)
161                         flags |= 0x01;
162         }
163
164         data = nvbios_ocfg_match(bios, data, ior->asy.proto_evo, flags,
165                                  &ver, &hdr, &cnt, &len, &iedtrs);
166         if (!data) {
167                 OUTP_DBG(outp, "missing IEDT RS for %02x:%02x",
168                          ior->asy.proto_evo, flags);
169                 return;
170         }
171
172         /* Execute the OnInt[23] script for the current frequency. */
173         data = nvbios_oclk_match(bios, iedtrs.clkcmp[id], khz);
174         if (!data) {
175                 OUTP_DBG(outp, "missing IEDT RSS %d for %02x:%02x %d khz",
176                          id, ior->asy.proto_evo, flags, khz);
177                 return;
178         }
179
180         nvbios_init(subdev, data,
181                 init.outp = &outp->info;
182                 init.or   = ior->id;
183                 init.link = ior->asy.link;
184                 init.head = head->id;
185         );
186 }
187
188 static void
189 nv50_disp_super_ied_off(struct nvkm_head *head, struct nvkm_ior *ior, int id)
190 {
191         struct nvkm_outp *outp = ior->arm.outp;
192         struct nvbios_outp iedt;
193         u8  ver, hdr, cnt, len;
194         u32 data;
195
196         if (!outp) {
197                 IOR_DBG(ior, "nothing attached");
198                 return;
199         }
200
201         data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt);
202         if (!data)
203                 return;
204
205         nvbios_init(&head->disp->engine.subdev, iedt.script[id],
206                 init.outp = &outp->info;
207                 init.or   = ior->id;
208                 init.link = ior->arm.link;
209                 init.head = head->id;
210         );
211 }
212
213 static struct nvkm_ior *
214 nv50_disp_super_ior_asy(struct nvkm_head *head)
215 {
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);
220                         return ior;
221                 }
222         }
223         HEAD_DBG(head, "nothing to attach");
224         return NULL;
225 }
226
227 static struct nvkm_ior *
228 nv50_disp_super_ior_arm(struct nvkm_head *head)
229 {
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);
234                         return ior;
235                 }
236         }
237         HEAD_DBG(head, "nothing attached");
238         return NULL;
239 }
240
241 void
242 nv50_disp_super_3_0(struct nv50_disp *disp, struct nvkm_head *head)
243 {
244         struct nvkm_ior *ior;
245
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);
249         if (!ior)
250                 return;
251
252         /* Execute OnInt3 IED script. */
253         nv50_disp_super_ied_on(head, ior, 1, head->asy.hz / 1000);
254
255         /* OR-specific handling. */
256         if (ior->func->war_3)
257                 ior->func->war_3(ior);
258 }
259
260 static void
261 nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
262 {
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;
271         u64 h, v;
272
273         /* symbols/hblank - algorithm taken from comments in tegra driver */
274         h = head->asy.hblanke + head->asy.htotal - head->asy.hblanks - 7;
275         h = h * linkKBps;
276         do_div(h, khz);
277         h = h - (3 * ior->dp.ef) - (12 / ior->dp.nr);
278
279         /* symbols/vblank - algorithm taken from comments in tegra driver */
280         v = head->asy.vblanks - head->asy.vblanke - 25;
281         v = v * linkKBps;
282         do_div(v, khz);
283         v = v - ((36 / ior->dp.nr) + 3) - 1;
284
285         ior->func->dp.audio_sym(ior, head->id, h, v);
286
287         /* watermark / activesym */
288         link_data_rate = (khz * head->asy.or.depth / 8) / ior->dp.nr;
289
290         /* calculate ratio of packed data rate to link symbol rate */
291         link_ratio = link_data_rate * symbol;
292         do_div(link_ratio, linkKBps);
293
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;
297                 u32 calc, diff;
298
299                 /* find a hw representation for the fraction.. */
300                 VTUi = tu_valid / symbol;
301                 calc = VTUi * symbol;
302                 diff = tu_valid - calc;
303                 if (diff) {
304                         if (diff >= (symbol / 2)) {
305                                 VTUf = symbol / (symbol - diff);
306                                 if (symbol - (VTUf * diff))
307                                         VTUf++;
308
309                                 if (VTUf <= 15) {
310                                         VTUa  = 1;
311                                         calc += symbol - (symbol / VTUf);
312                                 } else {
313                                         VTUa  = 0;
314                                         VTUf  = 1;
315                                         calc += symbol;
316                                 }
317                         } else {
318                                 VTUa  = 0;
319                                 VTUf  = min((int)(symbol / diff), 15);
320                                 calc += symbol / VTUf;
321                         }
322
323                         diff = calc - tu_valid;
324                 } else {
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
328                          */
329                         VTUa = 0;
330                         VTUf = 1;
331                         VTUi--;
332                 }
333
334                 if (diff < best_diff) {
335                         best_diff = diff;
336                         bestTU = TU;
337                         bestVTUa = VTUa;
338                         bestVTUf = VTUf;
339                         bestVTUi = VTUi;
340                         if (diff == 0)
341                                 break;
342                 }
343         }
344
345         if (ior->func->dp.activesym) {
346                 if (!bestTU) {
347                         nvkm_error(subdev, "unable to determine dp config\n");
348                         return;
349                 }
350                 ior->func->dp.activesym(ior, head->id, bestTU,
351                                         bestVTUa, bestVTUf, bestVTUi);
352         } else {
353                 bestTU = 64;
354         }
355
356         /* XXX close to vbios numbers, but not right */
357         unk  = (symbol - link_ratio) * bestTU;
358         unk *= link_ratio;
359         do_div(unk, symbol);
360         do_div(unk, symbol);
361         unk += 6;
362
363         ior->func->dp.watermark(ior, head->id, unk);
364 }
365
366 void
367 nv50_disp_super_2_2(struct nv50_disp *disp, struct nvkm_head *head)
368 {
369         const u32 khz = head->asy.hz / 1000;
370         struct nvkm_outp *outp;
371         struct nvkm_ior *ior;
372
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);
376         if (!ior)
377                 return;
378
379         /* For some reason, NVIDIA decided not to:
380          *
381          * A) Give dual-link LVDS a separate EVO protocol, like for TMDS.
382          *  and
383          * B) Use SetControlOutputResource.PixelDepth on LVDS.
384          *
385          * Override the values we usually read from HW with the same
386          * data we pass though an ioctl instead.
387          */
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;
391         }
392
393         /* Handle any link training, etc. */
394         if ((outp = ior->asy.outp) && outp->func->acquire)
395                 outp->func->acquire(outp);
396
397         /* Execute OnInt2 IED script. */
398         nv50_disp_super_ied_on(head, ior, 0, khz);
399
400         /* Program RG clock divider. */
401         head->func->rgclk(head, ior->asy.rgdiv);
402
403         /* Mode-specific internal DP configuration. */
404         if (ior->type == SOR && ior->asy.proto == DP)
405                 nv50_disp_super_2_2_dp(head, ior);
406
407         /* OR-specific handling. */
408         ior->func->clock(ior);
409         if (ior->func->war_2)
410                 ior->func->war_2(ior);
411 }
412
413 void
414 nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head)
415 {
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);
419         if (khz)
420                 nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head->id, khz);
421 }
422
423 void
424 nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head)
425 {
426         struct nvkm_outp *outp;
427         struct nvkm_ior *ior;
428
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);
432         if (!ior)
433                 return;
434
435         /* Execute OffInt2 IED script. */
436         nv50_disp_super_ied_off(head, ior, 2);
437
438         /* If we're shutting down the OR's only active head, execute
439          * the output path's disable function.
440          */
441         if (ior->arm.head == (1 << head->id)) {
442                 if ((outp = ior->arm.outp) && outp->func->disable)
443                         outp->func->disable(outp, ior);
444         }
445 }
446
447 void
448 nv50_disp_super_1_0(struct nv50_disp *disp, struct nvkm_head *head)
449 {
450         struct nvkm_ior *ior;
451
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);
455         if (!ior)
456                 return;
457
458         /* Execute OffInt1 IED script. */
459         nv50_disp_super_ied_off(head, ior, 1);
460 }
461
462 void
463 nv50_disp_super_1(struct nv50_disp *disp)
464 {
465         struct nvkm_head *head;
466         struct nvkm_ior *ior;
467
468         list_for_each_entry(head, &disp->base.head, head) {
469                 head->func->state(head, &head->arm);
470                 head->func->state(head, &head->asy);
471         }
472
473         list_for_each_entry(ior, &disp->base.ior, head) {
474                 ior->func->state(ior, &ior->arm);
475                 ior->func->state(ior, &ior->asy);
476         }
477 }
478
479 void
480 nv50_disp_super(struct work_struct *work)
481 {
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);
488
489         nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super);
490
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)))
496                                 continue;
497                         if (!(super & (0x00000080 << head->id)))
498                                 continue;
499                         nv50_disp_super_1_0(disp, head);
500                 }
501         } else
502         if (disp->super & 0x00000020) {
503                 list_for_each_entry(head, &disp->base.head, head) {
504                         if (!(super & (0x00000080 << head->id)))
505                                 continue;
506                         nv50_disp_super_2_0(disp, head);
507                 }
508                 nvkm_outp_route(&disp->base);
509                 list_for_each_entry(head, &disp->base.head, head) {
510                         if (!(super & (0x00000200 << head->id)))
511                                 continue;
512                         nv50_disp_super_2_1(disp, head);
513                 }
514                 list_for_each_entry(head, &disp->base.head, head) {
515                         if (!(super & (0x00000080 << head->id)))
516                                 continue;
517                         nv50_disp_super_2_2(disp, head);
518                 }
519         } else
520         if (disp->super & 0x00000040) {
521                 list_for_each_entry(head, &disp->base.head, head) {
522                         if (!(super & (0x00000080 << head->id)))
523                                 continue;
524                         nv50_disp_super_3_0(disp, head);
525                 }
526         }
527
528         nvkm_wr32(device, 0x610030, 0x80000000);
529 }
530
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" },
537         {}
538 };
539
540 static const struct nvkm_enum
541 nv50_disp_intr_error_code[] = {
542         { 0x00, "" },
543         {}
544 };
545
546 static void
547 nv50_disp_intr_error(struct nv50_disp *disp, int chid)
548 {
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;
557
558         et = nvkm_enum_find(nv50_disp_intr_error_type, type);
559         ec = nvkm_enum_find(nv50_disp_intr_error_code, code);
560
561         nvkm_error(subdev,
562                    "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n",
563                    type, et ? et->name : "", code, ec ? ec->name : "",
564                    chid, mthd, data);
565
566         if (chid < ARRAY_SIZE(disp->chan)) {
567                 switch (mthd) {
568                 case 0x0080:
569                         nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
570                         break;
571                 default:
572                         break;
573                 }
574         }
575
576         nvkm_wr32(device, 0x610020, 0x00010000 << chid);
577         nvkm_wr32(device, 0x610080 + (chid * 0x08), 0x90000000);
578 }
579
580 void
581 nv50_disp_intr(struct nv50_disp *disp)
582 {
583         struct nvkm_device *device = disp->base.engine.subdev.device;
584         u32 intr0 = nvkm_rd32(device, 0x610020);
585         u32 intr1 = nvkm_rd32(device, 0x610024);
586
587         while (intr0 & 0x001f0000) {
588                 u32 chid = __ffs(intr0 & 0x001f0000) - 16;
589                 nv50_disp_intr_error(disp, chid);
590                 intr0 &= ~(0x00010000 << chid);
591         }
592
593         while (intr0 & 0x0000001f) {
594                 u32 chid = __ffs(intr0 & 0x0000001f);
595                 nv50_disp_chan_uevent_send(disp, chid);
596                 intr0 &= ~(0x00000001 << chid);
597         }
598
599         if (intr1 & 0x00000004) {
600                 nvkm_disp_vblank(&disp->base, 0);
601                 nvkm_wr32(device, 0x610024, 0x00000004);
602         }
603
604         if (intr1 & 0x00000008) {
605                 nvkm_disp_vblank(&disp->base, 1);
606                 nvkm_wr32(device, 0x610024, 0x00000008);
607         }
608
609         if (intr1 & 0x00000070) {
610                 disp->super = (intr1 & 0x00000070);
611                 queue_work(disp->wq, &disp->supervisor);
612                 nvkm_wr32(device, 0x610024, disp->super);
613         }
614 }
615
616 static const struct nv50_disp_func
617 nv50_disp = {
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 },
626 };
627
628 int
629 nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
630 {
631         return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp);
632 }