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.
26 #include <engine/fifo.h>
27 #include <subdev/bios.h>
28 #include <subdev/bios/pll.h>
29 #include <subdev/timer.h>
35 struct nva3_clock_priv
{
36 struct nouveau_clock base
;
37 struct nva3_clock_info eng
[nv_clk_src_max
];
40 static u32
read_clk(struct nva3_clock_priv
*, int, bool);
41 static u32
read_pll(struct nva3_clock_priv
*, int, u32
);
44 read_vco(struct nva3_clock_priv
*priv
, int clk
)
46 u32 sctl
= nv_rd32(priv
, 0x4120 + (clk
* 4));
48 switch (sctl
& 0x00000030) {
50 return nv_device(priv
)->crystal
;
52 return read_pll(priv
, 0x41, 0x00e820);
54 return read_pll(priv
, 0x42, 0x00e8a0);
61 read_clk(struct nva3_clock_priv
*priv
, int clk
, bool ignore_en
)
65 /* refclk for the 0xe8xx plls is a fixed frequency */
67 if (nv_device(priv
)->chipset
== 0xaf) {
68 /* no joke.. seriously.. sigh.. */
69 return nv_rd32(priv
, 0x00471c) * 1000;
72 return nv_device(priv
)->crystal
;
75 sctl
= nv_rd32(priv
, 0x4120 + (clk
* 4));
76 if (!ignore_en
&& !(sctl
& 0x00000100))
80 if (sctl
& 0x00000400)
84 switch (sctl
& 0x00003000) {
86 if (!(sctl
& 0x00000200))
87 return nv_device(priv
)->crystal
;
90 if (sctl
& 0x00000040)
95 if (!(sctl
& 0x00000001))
98 sclk
= read_vco(priv
, clk
);
99 sdiv
= ((sctl
& 0x003f0000) >> 16) + 2;
100 return (sclk
* 2) / sdiv
;
107 read_pll(struct nva3_clock_priv
*priv
, int clk
, u32 pll
)
109 u32 ctrl
= nv_rd32(priv
, pll
+ 0);
110 u32 sclk
= 0, P
= 1, N
= 1, M
= 1;
112 if (!(ctrl
& 0x00000008)) {
113 if (ctrl
& 0x00000001) {
114 u32 coef
= nv_rd32(priv
, pll
+ 4);
115 M
= (coef
& 0x000000ff) >> 0;
116 N
= (coef
& 0x0000ff00) >> 8;
117 P
= (coef
& 0x003f0000) >> 16;
119 /* no post-divider on these..
120 * XXX: it looks more like two post-"dividers" that
121 * cross each other out in the default RPLL config */
122 if ((pll
& 0x00ff00) == 0x00e800)
125 sclk
= read_clk(priv
, 0x00 + clk
, false);
128 sclk
= read_clk(priv
, 0x10 + clk
, false);
132 return sclk
* N
/ (M
* P
);
137 nva3_clock_read(struct nouveau_clock
*clk
, enum nv_clk_src src
)
139 struct nva3_clock_priv
*priv
= (void *)clk
;
143 case nv_clk_src_crystal
:
144 return nv_device(priv
)->crystal
;
145 case nv_clk_src_core
:
146 case nv_clk_src_core_intm
:
147 return read_pll(priv
, 0x00, 0x4200);
148 case nv_clk_src_shader
:
149 return read_pll(priv
, 0x01, 0x4220);
151 return read_pll(priv
, 0x02, 0x4000);
152 case nv_clk_src_disp
:
153 return read_clk(priv
, 0x20, false);
154 case nv_clk_src_vdec
:
155 return read_clk(priv
, 0x21, false);
156 case nv_clk_src_daemon
:
157 return read_clk(priv
, 0x25, false);
158 case nv_clk_src_host
:
159 hsrc
= (nv_rd32(priv
, 0xc040) & 0x30000000) >> 28;
162 return read_clk(priv
, 0x1d, false);
167 nv_error(clk
, "unknown HOST clock source %d\n", hsrc
);
171 nv_error(clk
, "invalid clock source %d\n", src
);
179 nva3_clk_info(struct nouveau_clock
*clock
, int clk
, u32 khz
,
180 struct nva3_clock_info
*info
)
182 struct nva3_clock_priv
*priv
= (void *)clock
;
183 u32 oclk
, sclk
, sdiv
, diff
;
189 info
->clk
= 0x00000100;
192 info
->clk
= 0x00002100;
195 info
->clk
= 0x00002140;
198 sclk
= read_vco(priv
, clk
);
199 sdiv
= min((sclk
* 2) / khz
, (u32
)65);
200 oclk
= (sclk
* 2) / sdiv
;
201 diff
= ((khz
+ 3000) - oclk
);
203 /* When imprecise, play it safe and aim for a clock lower than
204 * desired rather than higher */
207 oclk
= (sclk
* 2) / sdiv
;
210 /* divider can go as low as 2, limited here because NVIDIA
211 * and the VBIOS on my NVA8 seem to prefer using the PLL
212 * for 810MHz - is there a good reason?
213 * XXX: PLLs with refclk 810MHz? */
215 info
->clk
= (((sdiv
- 2) << 16) | 0x00003100);
226 nva3_pll_info(struct nouveau_clock
*clock
, int clk
, u32 pll
, u32 khz
,
227 struct nva3_clock_info
*info
)
229 struct nouveau_bios
*bios
= nouveau_bios(clock
);
230 struct nva3_clock_priv
*priv
= (void *)clock
;
231 struct nvbios_pll limits
;
237 /* If we can get a within [-2, 3) MHz of a divider, we'll disable the
238 * PLL and use the divider instead. */
239 ret
= nva3_clk_info(clock
, clk
, khz
, info
);
241 if (!pll
|| (diff
>= -2000 && diff
< 3000)) {
246 ret
= nvbios_pll_parse(bios
, pll
, &limits
);
250 ret
= nva3_clk_info(clock
, clk
- 0x10, limits
.refclk
, info
);
251 if (ret
!= limits
.refclk
)
254 ret
= nva3_pll_calc(nv_subdev(priv
), &limits
, khz
, &N
, NULL
, &M
, &P
);
256 info
->pll
= (P
<< 16) | (N
<< 8) | M
;
260 info
->fb_delay
= max(((khz
+ 7566) / 15133), (u32
) 18);
262 return ret
? ret
: -ERANGE
;
266 calc_clk(struct nva3_clock_priv
*priv
, struct nouveau_cstate
*cstate
,
267 int clk
, u32 pll
, int idx
)
269 int ret
= nva3_pll_info(&priv
->base
, clk
, pll
, cstate
->domain
[idx
],
277 calc_host(struct nva3_clock_priv
*priv
, struct nouveau_cstate
*cstate
)
280 u32 kHz
= cstate
->domain
[nv_clk_src_host
];
281 struct nva3_clock_info
*info
= &priv
->eng
[nv_clk_src_host
];
285 info
->host_out
= NVA3_HOST_277
;
289 info
->host_out
= NVA3_HOST_CLK
;
291 ret
= nva3_clk_info(&priv
->base
, 0x1d, kHz
, info
);
298 nva3_clock_pre(struct nouveau_clock
*clk
, unsigned long *flags
)
300 struct nouveau_fifo
*pfifo
= nouveau_fifo(clk
);
302 /* halt and idle execution engines */
303 nv_mask(clk
, 0x020060, 0x00070000, 0x00000000);
304 nv_mask(clk
, 0x002504, 0x00000001, 0x00000001);
305 /* Wait until the interrupt handler is finished */
306 if (!nv_wait(clk
, 0x000100, 0xffffffff, 0x00000000))
310 pfifo
->pause(pfifo
, flags
);
312 if (!nv_wait(clk
, 0x002504, 0x00000010, 0x00000010))
314 if (!nv_wait(clk
, 0x00251c, 0x0000003f, 0x0000003f))
321 nva3_clock_post(struct nouveau_clock
*clk
, unsigned long *flags
)
323 struct nouveau_fifo
*pfifo
= nouveau_fifo(clk
);
326 pfifo
->start(pfifo
, flags
);
328 nv_mask(clk
, 0x002504, 0x00000001, 0x00000000);
329 nv_mask(clk
, 0x020060, 0x00070000, 0x00040000);
333 disable_clk_src(struct nva3_clock_priv
*priv
, u32 src
)
335 nv_mask(priv
, src
, 0x00000100, 0x00000000);
336 nv_mask(priv
, src
, 0x00000001, 0x00000000);
340 prog_pll(struct nva3_clock_priv
*priv
, int clk
, u32 pll
, int idx
)
342 struct nva3_clock_info
*info
= &priv
->eng
[idx
];
343 const u32 src0
= 0x004120 + (clk
* 4);
344 const u32 src1
= 0x004160 + (clk
* 4);
345 const u32 ctrl
= pll
+ 0;
346 const u32 coef
= pll
+ 4;
350 /* Always start from a non-PLL clock */
351 bypass
= nv_rd32(priv
, ctrl
) & 0x00000008;
353 nv_mask(priv
, src1
, 0x00000101, 0x00000101);
354 nv_mask(priv
, ctrl
, 0x00000008, 0x00000008);
358 nv_mask(priv
, src0
, 0x003f3141, 0x00000101 | info
->clk
);
359 nv_wr32(priv
, coef
, info
->pll
);
360 nv_mask(priv
, ctrl
, 0x00000015, 0x00000015);
361 nv_mask(priv
, ctrl
, 0x00000010, 0x00000000);
362 if (!nv_wait(priv
, ctrl
, 0x00020000, 0x00020000)) {
363 nv_mask(priv
, ctrl
, 0x00000010, 0x00000010);
364 nv_mask(priv
, src0
, 0x00000101, 0x00000000);
367 nv_mask(priv
, ctrl
, 0x00000010, 0x00000010);
368 nv_mask(priv
, ctrl
, 0x00000008, 0x00000000);
369 disable_clk_src(priv
, src1
);
371 nv_mask(priv
, src1
, 0x003f3141, 0x00000101 | info
->clk
);
372 nv_mask(priv
, ctrl
, 0x00000018, 0x00000018);
374 nv_mask(priv
, ctrl
, 0x00000001, 0x00000000);
375 disable_clk_src(priv
, src0
);
380 prog_clk(struct nva3_clock_priv
*priv
, int clk
, int idx
)
382 struct nva3_clock_info
*info
= &priv
->eng
[idx
];
383 nv_mask(priv
, 0x004120 + (clk
* 4), 0x003f3141, 0x00000101 | info
->clk
);
387 prog_host(struct nva3_clock_priv
*priv
)
389 struct nva3_clock_info
*info
= &priv
->eng
[nv_clk_src_host
];
390 u32 hsrc
= (nv_rd32(priv
, 0xc040));
392 switch (info
->host_out
) {
394 if ((hsrc
& 0x30000000) == 0) {
395 nv_wr32(priv
, 0xc040, hsrc
| 0x20000000);
396 disable_clk_src(priv
, 0x4194);
400 prog_clk(priv
, 0x1d, nv_clk_src_host
);
401 if ((hsrc
& 0x30000000) >= 0x20000000) {
402 nv_wr32(priv
, 0xc040, hsrc
& ~0x30000000);
409 /* This seems to be a clock gating factor on idle, always set to 64 */
410 nv_wr32(priv
, 0xc044, 0x3e);
414 prog_core(struct nva3_clock_priv
*priv
, int idx
)
416 struct nva3_clock_info
*info
= &priv
->eng
[idx
];
417 u32 fb_delay
= nv_rd32(priv
, 0x10002c);
419 if (fb_delay
< info
->fb_delay
)
420 nv_wr32(priv
, 0x10002c, info
->fb_delay
);
422 prog_pll(priv
, 0x00, 0x004200, idx
);
424 if (fb_delay
> info
->fb_delay
)
425 nv_wr32(priv
, 0x10002c, info
->fb_delay
);
429 nva3_clock_calc(struct nouveau_clock
*clk
, struct nouveau_cstate
*cstate
)
431 struct nva3_clock_priv
*priv
= (void *)clk
;
432 struct nva3_clock_info
*core
= &priv
->eng
[nv_clk_src_core
];
435 if ((ret
= calc_clk(priv
, cstate
, 0x10, 0x4200, nv_clk_src_core
)) ||
436 (ret
= calc_clk(priv
, cstate
, 0x11, 0x4220, nv_clk_src_shader
)) ||
437 (ret
= calc_clk(priv
, cstate
, 0x20, 0x0000, nv_clk_src_disp
)) ||
438 (ret
= calc_clk(priv
, cstate
, 0x21, 0x0000, nv_clk_src_vdec
)) ||
439 (ret
= calc_host(priv
, cstate
)))
442 /* XXX: Should be reading the highest bit in the VBIOS clock to decide
443 * whether to use a PLL or not... but using a PLL defeats the purpose */
445 ret
= nva3_clk_info(clk
, 0x10,
446 cstate
->domain
[nv_clk_src_core_intm
],
447 &priv
->eng
[nv_clk_src_core_intm
]);
456 nva3_clock_prog(struct nouveau_clock
*clk
)
458 struct nva3_clock_priv
*priv
= (void *)clk
;
459 struct nva3_clock_info
*core
= &priv
->eng
[nv_clk_src_core
];
462 unsigned long *f
= &flags
;
464 ret
= nva3_clock_pre(clk
, f
);
469 prog_core(priv
, nv_clk_src_core_intm
);
471 prog_core(priv
, nv_clk_src_core
);
472 prog_pll(priv
, 0x01, 0x004220, nv_clk_src_shader
);
473 prog_clk(priv
, 0x20, nv_clk_src_disp
);
474 prog_clk(priv
, 0x21, nv_clk_src_vdec
);
481 nva3_clock_post(clk
, f
);
487 nva3_clock_tidy(struct nouveau_clock
*clk
)
491 static struct nouveau_clocks
493 { nv_clk_src_crystal
, 0xff },
494 { nv_clk_src_core
, 0x00, 0, "core", 1000 },
495 { nv_clk_src_shader
, 0x01, 0, "shader", 1000 },
496 { nv_clk_src_mem
, 0x02, 0, "memory", 1000 },
497 { nv_clk_src_vdec
, 0x03 },
498 { nv_clk_src_disp
, 0x04 },
499 { nv_clk_src_host
, 0x05 },
500 { nv_clk_src_core_intm
, 0x06 },
505 nva3_clock_ctor(struct nouveau_object
*parent
, struct nouveau_object
*engine
,
506 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
507 struct nouveau_object
**pobject
)
509 struct nva3_clock_priv
*priv
;
512 ret
= nouveau_clock_create(parent
, engine
, oclass
, nva3_domain
, NULL
, 0,
514 *pobject
= nv_object(priv
);
518 priv
->base
.read
= nva3_clock_read
;
519 priv
->base
.calc
= nva3_clock_calc
;
520 priv
->base
.prog
= nva3_clock_prog
;
521 priv
->base
.tidy
= nva3_clock_tidy
;
525 struct nouveau_oclass
526 nva3_clock_oclass
= {
527 .handle
= NV_SUBDEV(CLOCK
, 0xa3),
528 .ofuncs
= &(struct nouveau_ofuncs
) {
529 .ctor
= nva3_clock_ctor
,
530 .dtor
= _nouveau_clock_dtor
,
531 .init
= _nouveau_clock_init
,
532 .fini
= _nouveau_clock_fini
,
This page took 0.060666 seconds and 5 git commands to generate.