]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
Merge branch 'linus' into locking/core, to pick up fixes before merging new changes
[karo-tx-linux.git] / drivers / gpu / drm / nouveau / nvkm / engine / disp / gf119.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 "rootnv50.h"
26
27 #include <subdev/bios.h>
28 #include <subdev/bios/disp.h>
29 #include <subdev/bios/init.h>
30 #include <subdev/bios/pll.h>
31 #include <subdev/devinit.h>
32
33 void
34 gf119_disp_vblank_init(struct nv50_disp *disp, int head)
35 {
36         struct nvkm_device *device = disp->base.engine.subdev.device;
37         nvkm_mask(device, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001);
38 }
39
40 void
41 gf119_disp_vblank_fini(struct nv50_disp *disp, int head)
42 {
43         struct nvkm_device *device = disp->base.engine.subdev.device;
44         nvkm_mask(device, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000);
45 }
46
47 static struct nvkm_output *
48 exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl,
49             u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
50             struct nvbios_outp *info)
51 {
52         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
53         struct nvkm_bios *bios = subdev->device->bios;
54         struct nvkm_output *outp;
55         u16 mask, type;
56
57         if (or < 4) {
58                 type = DCB_OUTPUT_ANALOG;
59                 mask = 0;
60         } else {
61                 or -= 4;
62                 switch (ctrl & 0x00000f00) {
63                 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
64                 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
65                 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
66                 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
67                 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
68                 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
69                 default:
70                         nvkm_error(subdev, "unknown SOR mc %08x\n", ctrl);
71                         return NULL;
72                 }
73         }
74
75         mask  = 0x00c0 & (mask << 6);
76         mask |= 0x0001 << or;
77         mask |= 0x0100 << head;
78
79
80         list_for_each_entry(outp, &disp->base.outp, head) {
81                 if ((outp->info.hasht & 0xff) == type &&
82                     (outp->info.hashm & mask) == mask) {
83                         *data = nvbios_outp_match(bios, outp->info.hasht,
84                                                         outp->info.hashm,
85                                                   ver, hdr, cnt, len, info);
86                         if (!*data)
87                                 return NULL;
88                         return outp;
89                 }
90         }
91
92         return NULL;
93 }
94
95 static struct nvkm_output *
96 exec_script(struct nv50_disp *disp, int head, int id)
97 {
98         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
99         struct nvkm_device *device = subdev->device;
100         struct nvkm_bios *bios = device->bios;
101         struct nvkm_output *outp;
102         struct nvbios_outp info;
103         u8  ver, hdr, cnt, len;
104         u32 data, ctrl = 0;
105         int or;
106
107         for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) {
108                 ctrl = nvkm_rd32(device, 0x640180 + (or * 0x20));
109                 if (ctrl & (1 << head))
110                         break;
111         }
112
113         if (or == 8)
114                 return NULL;
115
116         outp = exec_lookup(disp, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
117         if (outp) {
118                 struct nvbios_init init = {
119                         .subdev = subdev,
120                         .bios = bios,
121                         .offset = info.script[id],
122                         .outp = &outp->info,
123                         .crtc = head,
124                         .execute = 1,
125                 };
126
127                 nvbios_exec(&init);
128         }
129
130         return outp;
131 }
132
133 static struct nvkm_output *
134 exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
135 {
136         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
137         struct nvkm_device *device = subdev->device;
138         struct nvkm_bios *bios = device->bios;
139         struct nvkm_output *outp;
140         struct nvbios_outp info1;
141         struct nvbios_ocfg info2;
142         u8  ver, hdr, cnt, len;
143         u32 data, ctrl = 0;
144         int or;
145
146         for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) {
147                 ctrl = nvkm_rd32(device, 0x660180 + (or * 0x20));
148                 if (ctrl & (1 << head))
149                         break;
150         }
151
152         if (or == 8)
153                 return NULL;
154
155         outp = exec_lookup(disp, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
156         if (!outp)
157                 return NULL;
158
159         *conf = (ctrl & 0x00000f00) >> 8;
160         switch (outp->info.type) {
161         case DCB_OUTPUT_TMDS:
162                 if (*conf == 5)
163                         *conf |= 0x0100;
164                 break;
165         case DCB_OUTPUT_LVDS:
166                 *conf |= disp->sor.lvdsconf;
167                 break;
168         default:
169                 break;
170         }
171
172         data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8,
173                                  &ver, &hdr, &cnt, &len, &info2);
174         if (data && id < 0xff) {
175                 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
176                 if (data) {
177                         struct nvbios_init init = {
178                                 .subdev = subdev,
179                                 .bios = bios,
180                                 .offset = data,
181                                 .outp = &outp->info,
182                                 .crtc = head,
183                                 .execute = 1,
184                         };
185
186                         nvbios_exec(&init);
187                 }
188         }
189
190         return outp;
191 }
192
193 static void
194 gf119_disp_intr_unk1_0(struct nv50_disp *disp, int head)
195 {
196         exec_script(disp, head, 1);
197 }
198
199 static void
200 gf119_disp_intr_unk2_0(struct nv50_disp *disp, int head)
201 {
202         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
203         struct nvkm_output *outp = exec_script(disp, head, 2);
204
205         /* see note in nv50_disp_intr_unk20_0() */
206         if (outp && outp->info.type == DCB_OUTPUT_DP) {
207                 struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
208                 struct nvbios_init init = {
209                         .subdev = subdev,
210                         .bios = subdev->device->bios,
211                         .outp = &outp->info,
212                         .crtc = head,
213                         .offset = outpdp->info.script[4],
214                         .execute = 1,
215                 };
216
217                 nvbios_exec(&init);
218                 atomic_set(&outpdp->lt.done, 0);
219         }
220 }
221
222 static void
223 gf119_disp_intr_unk2_1(struct nv50_disp *disp, int head)
224 {
225         struct nvkm_device *device = disp->base.engine.subdev.device;
226         struct nvkm_devinit *devinit = device->devinit;
227         u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
228         if (pclk)
229                 nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk);
230         nvkm_wr32(device, 0x612200 + (head * 0x800), 0x00000000);
231 }
232
233 static void
234 gf119_disp_intr_unk2_2_tu(struct nv50_disp *disp, int head,
235                           struct dcb_output *outp)
236 {
237         struct nvkm_device *device = disp->base.engine.subdev.device;
238         const int or = ffs(outp->or) - 1;
239         const u32 ctrl = nvkm_rd32(device, 0x660200 + (or   * 0x020));
240         const u32 conf = nvkm_rd32(device, 0x660404 + (head * 0x300));
241         const s32 vactive = nvkm_rd32(device, 0x660414 + (head * 0x300)) & 0xffff;
242         const s32 vblanke = nvkm_rd32(device, 0x66041c + (head * 0x300)) & 0xffff;
243         const s32 vblanks = nvkm_rd32(device, 0x660420 + (head * 0x300)) & 0xffff;
244         const u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
245         const u32 link = ((ctrl & 0xf00) == 0x800) ? 0 : 1;
246         const u32 hoff = (head * 0x800);
247         const u32 soff = (  or * 0x800);
248         const u32 loff = (link * 0x080) + soff;
249         const u32 symbol = 100000;
250         const u32 TU = 64;
251         u32 dpctrl = nvkm_rd32(device, 0x61c10c + loff);
252         u32 clksor = nvkm_rd32(device, 0x612300 + soff);
253         u32 datarate, link_nr, link_bw, bits;
254         u64 ratio, value;
255
256         link_nr  = hweight32(dpctrl & 0x000f0000);
257         link_bw  = (clksor & 0x007c0000) >> 18;
258         link_bw *= 27000;
259
260         /* symbols/hblank - algorithm taken from comments in tegra driver */
261         value = vblanke + vactive - vblanks - 7;
262         value = value * link_bw;
263         do_div(value, pclk);
264         value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr);
265         nvkm_mask(device, 0x616620 + hoff, 0x0000ffff, value);
266
267         /* symbols/vblank - algorithm taken from comments in tegra driver */
268         value = vblanks - vblanke - 25;
269         value = value * link_bw;
270         do_div(value, pclk);
271         value = value - ((36 / link_nr) + 3) - 1;
272         nvkm_mask(device, 0x616624 + hoff, 0x00ffffff, value);
273
274         /* watermark */
275         if      ((conf & 0x3c0) == 0x180) bits = 30;
276         else if ((conf & 0x3c0) == 0x140) bits = 24;
277         else                              bits = 18;
278         datarate = (pclk * bits) / 8;
279
280         ratio  = datarate;
281         ratio *= symbol;
282         do_div(ratio, link_nr * link_bw);
283
284         value  = (symbol - ratio) * TU;
285         value *= ratio;
286         do_div(value, symbol);
287         do_div(value, symbol);
288
289         value += 5;
290         value |= 0x08000000;
291
292         nvkm_wr32(device, 0x616610 + hoff, value);
293 }
294
295 static void
296 gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head)
297 {
298         struct nvkm_device *device = disp->base.engine.subdev.device;
299         struct nvkm_output *outp;
300         u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
301         u32 conf, addr, data;
302
303         outp = exec_clkcmp(disp, head, 0xff, pclk, &conf);
304         if (!outp)
305                 return;
306
307         /* see note in nv50_disp_intr_unk20_2() */
308         if (outp->info.type == DCB_OUTPUT_DP) {
309                 u32 sync = nvkm_rd32(device, 0x660404 + (head * 0x300));
310                 switch ((sync & 0x000003c0) >> 6) {
311                 case 6: pclk = pclk * 30; break;
312                 case 5: pclk = pclk * 24; break;
313                 case 2:
314                 default:
315                         pclk = pclk * 18;
316                         break;
317                 }
318
319                 if (nvkm_output_dp_train(outp, pclk, true))
320                         OUTP_ERR(outp, "link not trained before attach");
321         } else {
322                 if (disp->func->sor.magic)
323                         disp->func->sor.magic(outp);
324         }
325
326         exec_clkcmp(disp, head, 0, pclk, &conf);
327
328         if (outp->info.type == DCB_OUTPUT_ANALOG) {
329                 addr = 0x612280 + (ffs(outp->info.or) - 1) * 0x800;
330                 data = 0x00000000;
331         } else {
332                 addr = 0x612300 + (ffs(outp->info.or) - 1) * 0x800;
333                 data = (conf & 0x0100) ? 0x00000101 : 0x00000000;
334                 switch (outp->info.type) {
335                 case DCB_OUTPUT_TMDS:
336                         nvkm_mask(device, addr, 0x007c0000, 0x00280000);
337                         break;
338                 case DCB_OUTPUT_DP:
339                         gf119_disp_intr_unk2_2_tu(disp, head, &outp->info);
340                         break;
341                 default:
342                         break;
343                 }
344         }
345
346         nvkm_mask(device, addr, 0x00000707, data);
347 }
348
349 static void
350 gf119_disp_intr_unk4_0(struct nv50_disp *disp, int head)
351 {
352         struct nvkm_device *device = disp->base.engine.subdev.device;
353         u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
354         u32 conf;
355
356         exec_clkcmp(disp, head, 1, pclk, &conf);
357 }
358
359 void
360 gf119_disp_intr_supervisor(struct work_struct *work)
361 {
362         struct nv50_disp *disp =
363                 container_of(work, struct nv50_disp, supervisor);
364         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
365         struct nvkm_device *device = subdev->device;
366         u32 mask[4];
367         int head;
368
369         nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super));
370         for (head = 0; head < disp->base.head.nr; head++) {
371                 mask[head] = nvkm_rd32(device, 0x6101d4 + (head * 0x800));
372                 nvkm_debug(subdev, "head %d: %08x\n", head, mask[head]);
373         }
374
375         if (disp->super & 0x00000001) {
376                 nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
377                 for (head = 0; head < disp->base.head.nr; head++) {
378                         if (!(mask[head] & 0x00001000))
379                                 continue;
380                         nvkm_debug(subdev, "supervisor 1.0 - head %d\n", head);
381                         gf119_disp_intr_unk1_0(disp, head);
382                 }
383         } else
384         if (disp->super & 0x00000002) {
385                 for (head = 0; head < disp->base.head.nr; head++) {
386                         if (!(mask[head] & 0x00001000))
387                                 continue;
388                         nvkm_debug(subdev, "supervisor 2.0 - head %d\n", head);
389                         gf119_disp_intr_unk2_0(disp, head);
390                 }
391                 for (head = 0; head < disp->base.head.nr; head++) {
392                         if (!(mask[head] & 0x00010000))
393                                 continue;
394                         nvkm_debug(subdev, "supervisor 2.1 - head %d\n", head);
395                         gf119_disp_intr_unk2_1(disp, head);
396                 }
397                 for (head = 0; head < disp->base.head.nr; head++) {
398                         if (!(mask[head] & 0x00001000))
399                                 continue;
400                         nvkm_debug(subdev, "supervisor 2.2 - head %d\n", head);
401                         gf119_disp_intr_unk2_2(disp, head);
402                 }
403         } else
404         if (disp->super & 0x00000004) {
405                 for (head = 0; head < disp->base.head.nr; head++) {
406                         if (!(mask[head] & 0x00001000))
407                                 continue;
408                         nvkm_debug(subdev, "supervisor 3.0 - head %d\n", head);
409                         gf119_disp_intr_unk4_0(disp, head);
410                 }
411         }
412
413         for (head = 0; head < disp->base.head.nr; head++)
414                 nvkm_wr32(device, 0x6101d4 + (head * 0x800), 0x00000000);
415         nvkm_wr32(device, 0x6101d0, 0x80000000);
416 }
417
418 static void
419 gf119_disp_intr_error(struct nv50_disp *disp, int chid)
420 {
421         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
422         struct nvkm_device *device = subdev->device;
423         u32 mthd = nvkm_rd32(device, 0x6101f0 + (chid * 12));
424         u32 data = nvkm_rd32(device, 0x6101f4 + (chid * 12));
425         u32 unkn = nvkm_rd32(device, 0x6101f8 + (chid * 12));
426
427         nvkm_error(subdev, "chid %d mthd %04x data %08x %08x %08x\n",
428                    chid, (mthd & 0x0000ffc), data, mthd, unkn);
429
430         if (chid < ARRAY_SIZE(disp->chan)) {
431                 switch (mthd & 0xffc) {
432                 case 0x0080:
433                         nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
434                         break;
435                 default:
436                         break;
437                 }
438         }
439
440         nvkm_wr32(device, 0x61009c, (1 << chid));
441         nvkm_wr32(device, 0x6101f0 + (chid * 12), 0x90000000);
442 }
443
444 void
445 gf119_disp_intr(struct nv50_disp *disp)
446 {
447         struct nvkm_subdev *subdev = &disp->base.engine.subdev;
448         struct nvkm_device *device = subdev->device;
449         u32 intr = nvkm_rd32(device, 0x610088);
450         int i;
451
452         if (intr & 0x00000001) {
453                 u32 stat = nvkm_rd32(device, 0x61008c);
454                 while (stat) {
455                         int chid = __ffs(stat); stat &= ~(1 << chid);
456                         nv50_disp_chan_uevent_send(disp, chid);
457                         nvkm_wr32(device, 0x61008c, 1 << chid);
458                 }
459                 intr &= ~0x00000001;
460         }
461
462         if (intr & 0x00000002) {
463                 u32 stat = nvkm_rd32(device, 0x61009c);
464                 int chid = ffs(stat) - 1;
465                 if (chid >= 0)
466                         gf119_disp_intr_error(disp, chid);
467                 intr &= ~0x00000002;
468         }
469
470         if (intr & 0x00100000) {
471                 u32 stat = nvkm_rd32(device, 0x6100ac);
472                 if (stat & 0x00000007) {
473                         disp->super = (stat & 0x00000007);
474                         schedule_work(&disp->supervisor);
475                         nvkm_wr32(device, 0x6100ac, disp->super);
476                         stat &= ~0x00000007;
477                 }
478
479                 if (stat) {
480                         nvkm_warn(subdev, "intr24 %08x\n", stat);
481                         nvkm_wr32(device, 0x6100ac, stat);
482                 }
483
484                 intr &= ~0x00100000;
485         }
486
487         for (i = 0; i < disp->base.head.nr; i++) {
488                 u32 mask = 0x01000000 << i;
489                 if (mask & intr) {
490                         u32 stat = nvkm_rd32(device, 0x6100bc + (i * 0x800));
491                         if (stat & 0x00000001)
492                                 nvkm_disp_vblank(&disp->base, i);
493                         nvkm_mask(device, 0x6100bc + (i * 0x800), 0, 0);
494                         nvkm_rd32(device, 0x6100c0 + (i * 0x800));
495                 }
496         }
497 }
498
499 int
500 gf119_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
501                 int index, struct nvkm_disp **pdisp)
502 {
503         u32 heads = nvkm_rd32(device, 0x022448);
504         return nv50_disp_new_(func, device, index, heads, pdisp);
505 }
506
507 static const struct nv50_disp_func
508 gf119_disp = {
509         .intr = gf119_disp_intr,
510         .uevent = &gf119_disp_chan_uevent,
511         .super = gf119_disp_intr_supervisor,
512         .root = &gf119_disp_root_oclass,
513         .head.vblank_init = gf119_disp_vblank_init,
514         .head.vblank_fini = gf119_disp_vblank_fini,
515         .head.scanoutpos = gf119_disp_root_scanoutpos,
516         .outp.internal.crt = nv50_dac_output_new,
517         .outp.internal.tmds = nv50_sor_output_new,
518         .outp.internal.lvds = nv50_sor_output_new,
519         .outp.internal.dp = gf119_sor_dp_new,
520         .dac.nr = 3,
521         .dac.power = nv50_dac_power,
522         .dac.sense = nv50_dac_sense,
523         .sor.nr = 4,
524         .sor.power = nv50_sor_power,
525         .sor.hda_eld = gf119_hda_eld,
526         .sor.hdmi = gf119_hdmi_ctrl,
527 };
528
529 int
530 gf119_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
531 {
532         return gf119_disp_new_(&gf119_disp, device, index, pdisp);
533 }