]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
8c132772ba9ea526a5cd2f9339ace5e6a22fd299
[karo-tx-linux.git] / drivers / gpu / drm / nouveau / core / subdev / clock / 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
25 #include <subdev/bios.h>
26 #include <subdev/bios/pll.h>
27
28 #include "nv50.h"
29 #include "pll.h"
30 #include "seq.h"
31
32 static u32
33 read_div(struct nv50_clock_priv *priv)
34 {
35         switch (nv_device(priv)->chipset) {
36         case 0x50: /* it exists, but only has bit 31, not the dividers.. */
37         case 0x84:
38         case 0x86:
39         case 0x98:
40         case 0xa0:
41                 return nv_rd32(priv, 0x004700);
42         case 0x92:
43         case 0x94:
44         case 0x96:
45                 return nv_rd32(priv, 0x004800);
46         default:
47                 return 0x00000000;
48         }
49 }
50
51 static u32
52 read_pll_src(struct nv50_clock_priv *priv, u32 base)
53 {
54         struct nouveau_clock *clk = &priv->base;
55         u32 coef, ref = clk->read(clk, nv_clk_src_crystal);
56         u32 rsel = nv_rd32(priv, 0x00e18c);
57         int P, N, M, id;
58
59         switch (nv_device(priv)->chipset) {
60         case 0x50:
61         case 0xa0:
62                 switch (base) {
63                 case 0x4020:
64                 case 0x4028: id = !!(rsel & 0x00000004); break;
65                 case 0x4008: id = !!(rsel & 0x00000008); break;
66                 case 0x4030: id = 0; break;
67                 default:
68                         nv_error(priv, "ref: bad pll 0x%06x\n", base);
69                         return 0;
70                 }
71
72                 coef = nv_rd32(priv, 0x00e81c + (id * 0x0c));
73                 ref *=  (coef & 0x01000000) ? 2 : 4;
74                 P    =  (coef & 0x00070000) >> 16;
75                 N    = ((coef & 0x0000ff00) >> 8) + 1;
76                 M    = ((coef & 0x000000ff) >> 0) + 1;
77                 break;
78         case 0x84:
79         case 0x86:
80         case 0x92:
81                 coef = nv_rd32(priv, 0x00e81c);
82                 P    = (coef & 0x00070000) >> 16;
83                 N    = (coef & 0x0000ff00) >> 8;
84                 M    = (coef & 0x000000ff) >> 0;
85                 break;
86         case 0x94:
87         case 0x96:
88         case 0x98:
89                 rsel = nv_rd32(priv, 0x00c050);
90                 switch (base) {
91                 case 0x4020: rsel = (rsel & 0x00000003) >> 0; break;
92                 case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break;
93                 case 0x4028: rsel = (rsel & 0x00001800) >> 11; break;
94                 case 0x4030: rsel = 3; break;
95                 default:
96                         nv_error(priv, "ref: bad pll 0x%06x\n", base);
97                         return 0;
98                 }
99
100                 switch (rsel) {
101                 case 0: id = 1; break;
102                 case 1: return clk->read(clk, nv_clk_src_crystal);
103                 case 2: return clk->read(clk, nv_clk_src_href);
104                 case 3: id = 0; break;
105                 }
106
107                 coef =  nv_rd32(priv, 0x00e81c + (id * 0x28));
108                 P    = (nv_rd32(priv, 0x00e824 + (id * 0x28)) >> 16) & 7;
109                 P   += (coef & 0x00070000) >> 16;
110                 N    = (coef & 0x0000ff00) >> 8;
111                 M    = (coef & 0x000000ff) >> 0;
112                 break;
113         default:
114                 BUG_ON(1);
115         }
116
117         if (M)
118                 return (ref * N / M) >> P;
119         return 0;
120 }
121
122 static u32
123 read_pll_ref(struct nv50_clock_priv *priv, u32 base)
124 {
125         struct nouveau_clock *clk = &priv->base;
126         u32 src, mast = nv_rd32(priv, 0x00c040);
127
128         switch (base) {
129         case 0x004028:
130                 src = !!(mast & 0x00200000);
131                 break;
132         case 0x004020:
133                 src = !!(mast & 0x00400000);
134                 break;
135         case 0x004008:
136                 src = !!(mast & 0x00010000);
137                 break;
138         case 0x004030:
139                 src = !!(mast & 0x02000000);
140                 break;
141         case 0x00e810:
142                 return clk->read(clk, nv_clk_src_crystal);
143         default:
144                 nv_error(priv, "bad pll 0x%06x\n", base);
145                 return 0;
146         }
147
148         if (src)
149                 return clk->read(clk, nv_clk_src_href);
150         return read_pll_src(priv, base);
151 }
152
153 static u32
154 read_pll(struct nv50_clock_priv *priv, u32 base)
155 {
156         struct nouveau_clock *clk = &priv->base;
157         u32 mast = nv_rd32(priv, 0x00c040);
158         u32 ctrl = nv_rd32(priv, base + 0);
159         u32 coef = nv_rd32(priv, base + 4);
160         u32 ref = read_pll_ref(priv, base);
161         u32 freq = 0;
162         int N1, N2, M1, M2;
163
164         if (base == 0x004028 && (mast & 0x00100000)) {
165                 /* wtf, appears to only disable post-divider on nva0 */
166                 if (nv_device(priv)->chipset != 0xa0)
167                         return clk->read(clk, nv_clk_src_dom6);
168         }
169
170         N2 = (coef & 0xff000000) >> 24;
171         M2 = (coef & 0x00ff0000) >> 16;
172         N1 = (coef & 0x0000ff00) >> 8;
173         M1 = (coef & 0x000000ff);
174         if ((ctrl & 0x80000000) && M1) {
175                 freq = ref * N1 / M1;
176                 if ((ctrl & 0x40000100) == 0x40000000) {
177                         if (M2)
178                                 freq = freq * N2 / M2;
179                         else
180                                 freq = 0;
181                 }
182         }
183
184         return freq;
185 }
186
187 static int
188 nv50_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
189 {
190         struct nv50_clock_priv *priv = (void *)clk;
191         u32 mast = nv_rd32(priv, 0x00c040);
192         u32 P = 0;
193
194         switch (src) {
195         case nv_clk_src_crystal:
196                 return nv_device(priv)->crystal;
197         case nv_clk_src_href:
198                 return 100000; /* PCIE reference clock */
199         case nv_clk_src_hclk:
200                 return div_u64((u64)clk->read(clk, nv_clk_src_href) * 27778, 10000);
201         case nv_clk_src_hclkm3:
202                 return clk->read(clk, nv_clk_src_hclk) * 3;
203         case nv_clk_src_hclkm3d2:
204                 return clk->read(clk, nv_clk_src_hclk) * 3 / 2;
205         case nv_clk_src_host:
206                 switch (mast & 0x30000000) {
207                 case 0x00000000: return clk->read(clk, nv_clk_src_href);
208                 case 0x10000000: break;
209                 case 0x20000000: /* !0x50 */
210                 case 0x30000000: return clk->read(clk, nv_clk_src_hclk);
211                 }
212                 break;
213         case nv_clk_src_core:
214                 if (!(mast & 0x00100000))
215                         P = (nv_rd32(priv, 0x004028) & 0x00070000) >> 16;
216                 switch (mast & 0x00000003) {
217                 case 0x00000000: return clk->read(clk, nv_clk_src_crystal) >> P;
218                 case 0x00000001: return clk->read(clk, nv_clk_src_dom6);
219                 case 0x00000002: return read_pll(priv, 0x004020) >> P;
220                 case 0x00000003: return read_pll(priv, 0x004028) >> P;
221                 }
222                 break;
223         case nv_clk_src_shader:
224                 P = (nv_rd32(priv, 0x004020) & 0x00070000) >> 16;
225                 switch (mast & 0x00000030) {
226                 case 0x00000000:
227                         if (mast & 0x00000080)
228                                 return clk->read(clk, nv_clk_src_host) >> P;
229                         return clk->read(clk, nv_clk_src_crystal) >> P;
230                 case 0x00000010: break;
231                 case 0x00000020: return read_pll(priv, 0x004028) >> P;
232                 case 0x00000030: return read_pll(priv, 0x004020) >> P;
233                 }
234                 break;
235         case nv_clk_src_mem:
236                 P = (nv_rd32(priv, 0x004008) & 0x00070000) >> 16;
237                 if (nv_rd32(priv, 0x004008) & 0x00000200) {
238                         switch (mast & 0x0000c000) {
239                         case 0x00000000:
240                                 return clk->read(clk, nv_clk_src_crystal) >> P;
241                         case 0x00008000:
242                         case 0x0000c000:
243                                 return clk->read(clk, nv_clk_src_href) >> P;
244                         }
245                 } else {
246                         return read_pll(priv, 0x004008) >> P;
247                 }
248                 break;
249         case nv_clk_src_vdec:
250                 P = (read_div(priv) & 0x00000700) >> 8;
251                 switch (nv_device(priv)->chipset) {
252                 case 0x84:
253                 case 0x86:
254                 case 0x92:
255                 case 0x94:
256                 case 0x96:
257                 case 0xa0:
258                         switch (mast & 0x00000c00) {
259                         case 0x00000000:
260                                 if (nv_device(priv)->chipset == 0xa0) /* wtf?? */
261                                         return clk->read(clk, nv_clk_src_core) >> P;
262                                 return clk->read(clk, nv_clk_src_crystal) >> P;
263                         case 0x00000400:
264                                 return 0;
265                         case 0x00000800:
266                                 if (mast & 0x01000000)
267                                         return read_pll(priv, 0x004028) >> P;
268                                 return read_pll(priv, 0x004030) >> P;
269                         case 0x00000c00:
270                                 return clk->read(clk, nv_clk_src_core) >> P;
271                         }
272                         break;
273                 case 0x98:
274                         switch (mast & 0x00000c00) {
275                         case 0x00000000:
276                                 return clk->read(clk, nv_clk_src_core) >> P;
277                         case 0x00000400:
278                                 return 0;
279                         case 0x00000800:
280                                 return clk->read(clk, nv_clk_src_hclkm3d2) >> P;
281                         case 0x00000c00:
282                                 return clk->read(clk, nv_clk_src_mem) >> P;
283                         }
284                         break;
285                 }
286                 break;
287         case nv_clk_src_dom6:
288                 switch (nv_device(priv)->chipset) {
289                 case 0x50:
290                 case 0xa0:
291                         return read_pll(priv, 0x00e810) >> 2;
292                 case 0x84:
293                 case 0x86:
294                 case 0x92:
295                 case 0x94:
296                 case 0x96:
297                 case 0x98:
298                         P = (read_div(priv) & 0x00000007) >> 0;
299                         switch (mast & 0x0c000000) {
300                         case 0x00000000: return clk->read(clk, nv_clk_src_href);
301                         case 0x04000000: break;
302                         case 0x08000000: return clk->read(clk, nv_clk_src_hclk);
303                         case 0x0c000000:
304                                 return clk->read(clk, nv_clk_src_hclkm3) >> P;
305                         }
306                         break;
307                 default:
308                         break;
309                 }
310         default:
311                 break;
312         }
313
314         nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast);
315         return -EINVAL;
316 }
317
318 static u32
319 calc_pll(struct nv50_clock_priv *priv, u32 reg, u32 clk, int *N, int *M, int *P)
320 {
321         struct nouveau_bios *bios = nouveau_bios(priv);
322         struct nvbios_pll pll;
323         int ret;
324
325         ret = nvbios_pll_parse(bios, reg, &pll);
326         if (ret)
327                 return 0;
328
329         pll.vco2.max_freq = 0;
330         pll.refclk = read_pll_ref(priv, reg);
331         if (!pll.refclk)
332                 return 0;
333
334         return nv04_pll_calc(nv_subdev(priv), &pll, clk, N, M, NULL, NULL, P);
335 }
336
337 static inline u32
338 calc_div(u32 src, u32 target, int *div)
339 {
340         u32 clk0 = src, clk1 = src;
341         for (*div = 0; *div <= 7; (*div)++) {
342                 if (clk0 <= target) {
343                         clk1 = clk0 << (*div ? 1 : 0);
344                         break;
345                 }
346                 clk0 >>= 1;
347         }
348
349         if (target - clk0 <= clk1 - target)
350                 return clk0;
351         (*div)--;
352         return clk1;
353 }
354
355 static inline u32
356 clk_same(u32 a, u32 b)
357 {
358         return ((a / 1000) == (b / 1000));
359 }
360
361 static int
362 nv50_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
363 {
364         struct nv50_clock_priv *priv = (void *)clk;
365         struct nv50_clock_hwsq *hwsq = &priv->hwsq;
366         const int shader = cstate->domain[nv_clk_src_shader];
367         const int core = cstate->domain[nv_clk_src_core];
368         const int vdec = cstate->domain[nv_clk_src_vdec];
369         const int dom6 = cstate->domain[nv_clk_src_dom6];
370         u32 mastm = 0, mastv = 0;
371         u32 divsm = 0, divsv = 0;
372         int N, M, P1, P2;
373         int freq, out;
374
375         /* prepare a hwsq script from which we'll perform the reclock */
376         out = clk_init(hwsq, nv_subdev(clk));
377         if (out)
378                 return out;
379
380         clk_wr32(hwsq, fifo, 0x00000001); /* block fifo */
381         clk_nsec(hwsq, 8000);
382         clk_setf(hwsq, 0x10, 0x00); /* disable fb */
383         clk_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
384
385         /* vdec: avoid modifying xpll until we know exactly how the other
386          * clock domains work, i suspect at least some of them can also be
387          * tied to xpll...
388          */
389         if (vdec) {
390                 /* see how close we can get using nvclk as a source */
391                 freq = calc_div(core, vdec, &P1);
392
393                 /* see how close we can get using xpll/hclk as a source */
394                 if (nv_device(priv)->chipset != 0x98)
395                         out = read_pll(priv, 0x004030);
396                 else
397                         out = clk->read(clk, nv_clk_src_hclkm3d2);
398                 out = calc_div(out, vdec, &P2);
399
400                 /* select whichever gets us closest */
401                 if (abs(vdec - freq) <= abs(vdec - out)) {
402                         if (nv_device(priv)->chipset != 0x98)
403                                 mastv |= 0x00000c00;
404                         divsv |= P1 << 8;
405                 } else {
406                         mastv |= 0x00000800;
407                         divsv |= P2 << 8;
408                 }
409
410                 mastm |= 0x00000c00;
411                 divsm |= 0x00000700;
412         }
413
414         /* dom6: nfi what this is, but we're limited to various combinations
415          * of the host clock frequency
416          */
417         if (dom6) {
418                 if (clk_same(dom6, clk->read(clk, nv_clk_src_href))) {
419                         mastv |= 0x00000000;
420                 } else
421                 if (clk_same(dom6, clk->read(clk, nv_clk_src_hclk))) {
422                         mastv |= 0x08000000;
423                 } else {
424                         freq = clk->read(clk, nv_clk_src_hclk) * 3;
425                         freq = calc_div(freq, dom6, &P1);
426
427                         mastv |= 0x0c000000;
428                         divsv |= P1;
429                 }
430
431                 mastm |= 0x0c000000;
432                 divsm |= 0x00000007;
433         }
434
435         /* vdec/dom6: switch to "safe" clocks temporarily, update dividers
436          * and then switch to target clocks
437          */
438         clk_mask(hwsq, mast, mastm, 0x00000000);
439         clk_mask(hwsq, divs, divsm, divsv);
440         clk_mask(hwsq, mast, mastm, mastv);
441
442         /* core/shader: disconnect nvclk/sclk from their PLLs (nvclk to dom6,
443          * sclk to hclk) before reprogramming
444          */
445         if (nv_device(priv)->chipset < 0x92)
446                 clk_mask(hwsq, mast, 0x001000b0, 0x00100080);
447         else
448                 clk_mask(hwsq, mast, 0x000000b3, 0x00000081);
449
450         /* core: for the moment at least, always use nvpll */
451         freq = calc_pll(priv, 0x4028, core, &N, &M, &P1);
452         if (freq == 0)
453                 return -ERANGE;
454
455         clk_mask(hwsq, nvpll[0], 0xc03f0100,
456                                  0x80000000 | (P1 << 19) | (P1 << 16));
457         clk_mask(hwsq, nvpll[1], 0x0000ffff, (N << 8) | M);
458
459         /* shader: tie to nvclk if possible, otherwise use spll.  have to be
460          * very careful that the shader clock is at least twice the core, or
461          * some chipsets will be very unhappy.  i expect most or all of these
462          * cases will be handled by tying to nvclk, but it's possible there's
463          * corners
464          */
465         if (P1-- && shader == (core << 1)) {
466                 clk_mask(hwsq, spll[0], 0xc03f0100, (P1 << 19) | (P1 << 16));
467                 clk_mask(hwsq, mast, 0x00100033, 0x00000023);
468         } else {
469                 freq = calc_pll(priv, 0x4020, shader, &N, &M, &P1);
470                 if (freq == 0)
471                         return -ERANGE;
472
473                 clk_mask(hwsq, spll[0], 0xc03f0100,
474                                         0x80000000 | (P1 << 19) | (P1 << 16));
475                 clk_mask(hwsq, spll[1], 0x0000ffff, (N << 8) | M);
476                 clk_mask(hwsq, mast, 0x00100033, 0x00000033);
477         }
478
479         /* restore normal operation */
480         clk_setf(hwsq, 0x10, 0x01); /* enable fb */
481         clk_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */
482         clk_wr32(hwsq, fifo, 0x00000000); /* un-block fifo */
483         return 0;
484 }
485
486 static int
487 nv50_clock_prog(struct nouveau_clock *clk)
488 {
489         struct nv50_clock_priv *priv = (void *)clk;
490         return clk_exec(&priv->hwsq, true);
491 }
492
493 static void
494 nv50_clock_tidy(struct nouveau_clock *clk)
495 {
496         struct nv50_clock_priv *priv = (void *)clk;
497         clk_exec(&priv->hwsq, false);
498 }
499
500 int
501 nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
502                 struct nouveau_oclass *oclass, void *data, u32 size,
503                 struct nouveau_object **pobject)
504 {
505         struct nv50_clock_oclass *pclass = (void *)oclass;
506         struct nv50_clock_priv *priv;
507         int ret;
508
509         ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
510                                    false, &priv);
511         *pobject = nv_object(priv);
512         if (ret)
513                 return ret;
514
515         priv->hwsq.r_fifo = hwsq_reg(0x002504);
516         priv->hwsq.r_spll[0] = hwsq_reg(0x004020);
517         priv->hwsq.r_spll[1] = hwsq_reg(0x004024);
518         priv->hwsq.r_nvpll[0] = hwsq_reg(0x004028);
519         priv->hwsq.r_nvpll[1] = hwsq_reg(0x00402c);
520         switch (nv_device(priv)->chipset) {
521         case 0x92:
522         case 0x94:
523         case 0x96:
524                 priv->hwsq.r_divs = hwsq_reg(0x004800);
525                 break;
526         default:
527                 priv->hwsq.r_divs = hwsq_reg(0x004700);
528                 break;
529         }
530         priv->hwsq.r_mast = hwsq_reg(0x00c040);
531
532         priv->base.read = nv50_clock_read;
533         priv->base.calc = nv50_clock_calc;
534         priv->base.prog = nv50_clock_prog;
535         priv->base.tidy = nv50_clock_tidy;
536         return 0;
537 }
538
539 static struct nouveau_clocks
540 nv50_domains[] = {
541         { nv_clk_src_crystal, 0xff },
542         { nv_clk_src_href   , 0xff },
543         { nv_clk_src_core   , 0xff, 0, "core", 1000 },
544         { nv_clk_src_shader , 0xff, 0, "shader", 1000 },
545         { nv_clk_src_mem    , 0xff, 0, "memory", 1000 },
546         { nv_clk_src_max }
547 };
548
549 struct nouveau_oclass *
550 nv50_clock_oclass = &(struct nv50_clock_oclass) {
551         .base.handle = NV_SUBDEV(CLOCK, 0x50),
552         .base.ofuncs = &(struct nouveau_ofuncs) {
553                 .ctor = nv50_clock_ctor,
554                 .dtor = _nouveau_clock_dtor,
555                 .init = _nouveau_clock_init,
556                 .fini = _nouveau_clock_fini,
557         },
558         .domains = nv50_domains,
559 }.base;