2 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
22 * Shamelessly ripped off from ChromeOS's gk20a/clk_pllg.c
28 #include <core/tegra.h>
29 #include <subdev/timer.h>
31 static const u8 _pl_to_div
[] = {
32 /* PL: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */
33 /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32,
36 static u32
pl_to_div(u32 pl
)
38 if (pl
>= ARRAY_SIZE(_pl_to_div
))
41 return _pl_to_div
[pl
];
44 static u32
div_to_pl(u32 div
)
48 for (pl
= 0; pl
< ARRAY_SIZE(_pl_to_div
) - 1; pl
++) {
49 if (_pl_to_div
[pl
] >= div
)
53 return ARRAY_SIZE(_pl_to_div
) - 1;
56 static const struct gk20a_clk_pllg_params gk20a_pllg_params
= {
57 .min_vco
= 1000000, .max_vco
= 2064000,
58 .min_u
= 12000, .max_u
= 38000,
59 .min_m
= 1, .max_m
= 255,
60 .min_n
= 8, .max_n
= 255,
61 .min_pl
= 1, .max_pl
= 32,
65 gk20a_pllg_read_mnp(struct gk20a_clk
*clk
, struct gk20a_pll
*pll
)
67 struct nvkm_device
*device
= clk
->base
.subdev
.device
;
70 val
= nvkm_rd32(device
, GPCPLL_COEFF
);
71 pll
->m
= (val
>> GPCPLL_COEFF_M_SHIFT
) & MASK(GPCPLL_COEFF_M_WIDTH
);
72 pll
->n
= (val
>> GPCPLL_COEFF_N_SHIFT
) & MASK(GPCPLL_COEFF_N_WIDTH
);
73 pll
->pl
= (val
>> GPCPLL_COEFF_P_SHIFT
) & MASK(GPCPLL_COEFF_P_WIDTH
);
77 gk20a_pllg_write_mnp(struct gk20a_clk
*clk
, const struct gk20a_pll
*pll
)
79 struct nvkm_device
*device
= clk
->base
.subdev
.device
;
82 val
= (pll
->m
& MASK(GPCPLL_COEFF_M_WIDTH
)) << GPCPLL_COEFF_M_SHIFT
;
83 val
|= (pll
->n
& MASK(GPCPLL_COEFF_N_WIDTH
)) << GPCPLL_COEFF_N_SHIFT
;
84 val
|= (pll
->pl
& MASK(GPCPLL_COEFF_P_WIDTH
)) << GPCPLL_COEFF_P_SHIFT
;
85 nvkm_wr32(device
, GPCPLL_COEFF
, val
);
89 gk20a_pllg_calc_rate(struct gk20a_clk
*clk
, struct gk20a_pll
*pll
)
94 rate
= clk
->parent_rate
* pll
->n
;
95 divider
= pll
->m
* clk
->pl_to_div(pll
->pl
);
97 return rate
/ divider
/ 2;
101 gk20a_pllg_calc_mnp(struct gk20a_clk
*clk
, unsigned long rate
,
102 struct gk20a_pll
*pll
)
104 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
105 u32 target_clk_f
, ref_clk_f
, target_freq
;
106 u32 min_vco_f
, max_vco_f
;
107 u32 low_pl
, high_pl
, best_pl
;
113 target_clk_f
= rate
* 2 / KHZ
;
114 ref_clk_f
= clk
->parent_rate
/ KHZ
;
116 target_vco_f
= target_clk_f
+ target_clk_f
/ 50;
117 max_vco_f
= max(clk
->params
->max_vco
, target_vco_f
);
118 min_vco_f
= clk
->params
->min_vco
;
119 best_m
= clk
->params
->max_m
;
120 best_n
= clk
->params
->min_n
;
121 best_pl
= clk
->params
->min_pl
;
123 /* min_pl <= high_pl <= max_pl */
124 high_pl
= (max_vco_f
+ target_vco_f
- 1) / target_vco_f
;
125 high_pl
= min(high_pl
, clk
->params
->max_pl
);
126 high_pl
= max(high_pl
, clk
->params
->min_pl
);
127 high_pl
= clk
->div_to_pl(high_pl
);
129 /* min_pl <= low_pl <= max_pl */
130 low_pl
= min_vco_f
/ target_vco_f
;
131 low_pl
= min(low_pl
, clk
->params
->max_pl
);
132 low_pl
= max(low_pl
, clk
->params
->min_pl
);
133 low_pl
= clk
->div_to_pl(low_pl
);
135 nvkm_debug(subdev
, "low_PL %d(div%d), high_PL %d(div%d)", low_pl
,
136 clk
->pl_to_div(low_pl
), high_pl
, clk
->pl_to_div(high_pl
));
138 /* Select lowest possible VCO */
139 for (pl
= low_pl
; pl
<= high_pl
; pl
++) {
142 target_vco_f
= target_clk_f
* clk
->pl_to_div(pl
);
144 for (m
= clk
->params
->min_m
; m
<= clk
->params
->max_m
; m
++) {
145 u32 u_f
= ref_clk_f
/ m
;
147 if (u_f
< clk
->params
->min_u
)
149 if (u_f
> clk
->params
->max_u
)
152 n
= (target_vco_f
* m
) / ref_clk_f
;
153 n2
= ((target_vco_f
* m
) + (ref_clk_f
- 1)) / ref_clk_f
;
155 if (n
> clk
->params
->max_n
)
158 for (; n
<= n2
; n
++) {
161 if (n
< clk
->params
->min_n
)
163 if (n
> clk
->params
->max_n
)
166 vco_f
= ref_clk_f
* n
/ m
;
168 if (vco_f
>= min_vco_f
&& vco_f
<= max_vco_f
) {
171 lwv
= (vco_f
+ (clk
->pl_to_div(pl
) / 2))
172 / clk
->pl_to_div(pl
);
173 delta
= abs(lwv
- target_clk_f
);
175 if (delta
< best_delta
) {
190 WARN_ON(best_delta
== ~0);
194 "no best match for target @ %dMHz on gpc_pll",
201 target_freq
= gk20a_pllg_calc_rate(clk
, pll
);
204 "actual target freq %d KHz, M %d, N %d, PL %d(div%d)\n",
205 target_freq
/ KHZ
, pll
->m
, pll
->n
, pll
->pl
,
206 clk
->pl_to_div(pll
->pl
));
211 gk20a_pllg_slide(struct gk20a_clk
*clk
, u32 n
)
213 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
214 struct nvkm_device
*device
= subdev
->device
;
215 struct gk20a_pll pll
;
218 /* get old coefficients */
219 gk20a_pllg_read_mnp(clk
, &pll
);
220 /* do nothing if NDIV is the same */
224 /* pll slowdown mode */
225 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
226 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
),
227 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
));
229 /* new ndiv ready for ramp */
232 gk20a_pllg_write_mnp(clk
, &pll
);
234 /* dynamic ramp to new ndiv */
236 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
237 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
),
238 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
));
240 /* wait for ramping to complete */
241 if (nvkm_wait_usec(device
, 500, GPC_BCAST_NDIV_SLOWDOWN_DEBUG
,
242 GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK
,
243 GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK
) < 0)
246 /* exit slowdown mode */
247 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
248 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
) |
249 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
), 0);
250 nvkm_rd32(device
, GPCPLL_NDIV_SLOWDOWN
);
256 gk20a_pllg_enable(struct gk20a_clk
*clk
)
258 struct nvkm_device
*device
= clk
->base
.subdev
.device
;
261 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_ENABLE
, GPCPLL_CFG_ENABLE
);
262 nvkm_rd32(device
, GPCPLL_CFG
);
264 /* enable lock detection */
265 val
= nvkm_rd32(device
, GPCPLL_CFG
);
266 if (val
& GPCPLL_CFG_LOCK_DET_OFF
) {
267 val
&= ~GPCPLL_CFG_LOCK_DET_OFF
;
268 nvkm_wr32(device
, GPCPLL_CFG
, val
);
272 if (nvkm_wait_usec(device
, 300, GPCPLL_CFG
, GPCPLL_CFG_LOCK
,
273 GPCPLL_CFG_LOCK
) < 0)
276 /* switch to VCO mode */
277 nvkm_mask(device
, SEL_VCO
, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
),
278 BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
));
284 gk20a_pllg_disable(struct gk20a_clk
*clk
)
286 struct nvkm_device
*device
= clk
->base
.subdev
.device
;
288 /* put PLL in bypass before disabling it */
289 nvkm_mask(device
, SEL_VCO
, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
), 0);
291 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_ENABLE
, 0);
292 nvkm_rd32(device
, GPCPLL_CFG
);
296 gk20a_pllg_program_mnp(struct gk20a_clk
*clk
, const struct gk20a_pll
*pll
)
298 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
299 struct nvkm_device
*device
= subdev
->device
;
300 struct gk20a_pll cur_pll
;
303 gk20a_pllg_read_mnp(clk
, &cur_pll
);
305 /* split VCO-to-bypass jump in half by setting out divider 1:2 */
306 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
307 GPC2CLK_OUT_VCODIV2
<< GPC2CLK_OUT_VCODIV_SHIFT
);
308 /* Intentional 2nd write to assure linear divider operation */
309 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
310 GPC2CLK_OUT_VCODIV2
<< GPC2CLK_OUT_VCODIV_SHIFT
);
311 nvkm_rd32(device
, GPC2CLK_OUT
);
314 gk20a_pllg_disable(clk
);
316 gk20a_pllg_write_mnp(clk
, pll
);
318 ret
= gk20a_pllg_enable(clk
);
322 /* restore out divider 1:1 */
324 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
325 GPC2CLK_OUT_VCODIV1
<< GPC2CLK_OUT_VCODIV_SHIFT
);
326 /* Intentional 2nd write to assure linear divider operation */
327 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
328 GPC2CLK_OUT_VCODIV1
<< GPC2CLK_OUT_VCODIV_SHIFT
);
329 nvkm_rd32(device
, GPC2CLK_OUT
);
335 gk20a_pllg_program_mnp_slide(struct gk20a_clk
*clk
, const struct gk20a_pll
*pll
)
337 struct gk20a_pll cur_pll
;
340 if (gk20a_pllg_is_enabled(clk
)) {
341 gk20a_pllg_read_mnp(clk
, &cur_pll
);
343 /* just do NDIV slide if there is no change to M and PL */
344 if (pll
->m
== cur_pll
.m
&& pll
->pl
== cur_pll
.pl
)
345 return gk20a_pllg_slide(clk
, pll
->n
);
347 /* slide down to current NDIV_LO */
348 cur_pll
.n
= gk20a_pllg_n_lo(clk
, &cur_pll
);
349 ret
= gk20a_pllg_slide(clk
, cur_pll
.n
);
354 /* program MNP with the new clock parameters and new NDIV_LO */
356 cur_pll
.n
= gk20a_pllg_n_lo(clk
, &cur_pll
);
357 ret
= gk20a_pllg_program_mnp(clk
, &cur_pll
);
361 /* slide up to new NDIV */
362 return gk20a_pllg_slide(clk
, pll
->n
);
365 static struct nvkm_pstate
369 .domain
[nv_clk_src_gpc
] = 72000,
375 .domain
[nv_clk_src_gpc
] = 108000,
381 .domain
[nv_clk_src_gpc
] = 180000,
387 .domain
[nv_clk_src_gpc
] = 252000,
393 .domain
[nv_clk_src_gpc
] = 324000,
399 .domain
[nv_clk_src_gpc
] = 396000,
405 .domain
[nv_clk_src_gpc
] = 468000,
411 .domain
[nv_clk_src_gpc
] = 540000,
417 .domain
[nv_clk_src_gpc
] = 612000,
423 .domain
[nv_clk_src_gpc
] = 648000,
429 .domain
[nv_clk_src_gpc
] = 684000,
435 .domain
[nv_clk_src_gpc
] = 708000,
441 .domain
[nv_clk_src_gpc
] = 756000,
447 .domain
[nv_clk_src_gpc
] = 804000,
453 .domain
[nv_clk_src_gpc
] = 852000,
460 gk20a_clk_read(struct nvkm_clk
*base
, enum nv_clk_src src
)
462 struct gk20a_clk
*clk
= gk20a_clk(base
);
463 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
464 struct nvkm_device
*device
= subdev
->device
;
465 struct gk20a_pll pll
;
468 case nv_clk_src_crystal
:
469 return device
->crystal
;
471 gk20a_pllg_read_mnp(clk
, &pll
);
472 return gk20a_pllg_calc_rate(clk
, &pll
) / GK20A_CLK_GPC_MDIV
;
474 nvkm_error(subdev
, "invalid clock source %d\n", src
);
480 gk20a_clk_calc(struct nvkm_clk
*base
, struct nvkm_cstate
*cstate
)
482 struct gk20a_clk
*clk
= gk20a_clk(base
);
484 return gk20a_pllg_calc_mnp(clk
, cstate
->domain
[nv_clk_src_gpc
] *
485 GK20A_CLK_GPC_MDIV
, &clk
->pll
);
489 gk20a_clk_prog(struct nvkm_clk
*base
)
491 struct gk20a_clk
*clk
= gk20a_clk(base
);
494 ret
= gk20a_pllg_program_mnp_slide(clk
, &clk
->pll
);
496 ret
= gk20a_pllg_program_mnp(clk
, &clk
->pll
);
502 gk20a_clk_tidy(struct nvkm_clk
*base
)
507 gk20a_clk_setup_slide(struct gk20a_clk
*clk
)
509 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
510 struct nvkm_device
*device
= subdev
->device
;
513 switch (clk
->parent_rate
) {
529 nvkm_error(subdev
, "invalid parent clock rate %u KHz",
530 clk
->parent_rate
/ KHZ
);
534 nvkm_mask(device
, GPCPLL_CFG2
, 0xff << GPCPLL_CFG2_PLL_STEPA_SHIFT
,
535 step_a
<< GPCPLL_CFG2_PLL_STEPA_SHIFT
);
536 nvkm_mask(device
, GPCPLL_CFG3
, 0xff << GPCPLL_CFG3_PLL_STEPB_SHIFT
,
537 step_b
<< GPCPLL_CFG3_PLL_STEPB_SHIFT
);
543 gk20a_clk_fini(struct nvkm_clk
*base
)
545 struct nvkm_device
*device
= base
->subdev
.device
;
546 struct gk20a_clk
*clk
= gk20a_clk(base
);
548 /* slide to VCO min */
549 if (gk20a_pllg_is_enabled(clk
)) {
550 struct gk20a_pll pll
;
553 gk20a_pllg_read_mnp(clk
, &pll
);
554 n_lo
= gk20a_pllg_n_lo(clk
, &pll
);
555 gk20a_pllg_slide(clk
, n_lo
);
558 gk20a_pllg_disable(clk
);
561 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_IDDQ
, 1);
565 gk20a_clk_init(struct nvkm_clk
*base
)
567 struct gk20a_clk
*clk
= gk20a_clk(base
);
568 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
569 struct nvkm_device
*device
= subdev
->device
;
572 /* get out from IDDQ */
573 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_IDDQ
, 0);
574 nvkm_rd32(device
, GPCPLL_CFG
);
577 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_INIT_MASK
,
578 GPC2CLK_OUT_INIT_VAL
);
580 ret
= gk20a_clk_setup_slide(clk
);
584 /* Start with lowest frequency */
585 base
->func
->calc(base
, &base
->func
->pstates
[0].base
);
586 ret
= base
->func
->prog(&clk
->base
);
588 nvkm_error(subdev
, "cannot initialize clock\n");
595 static const struct nvkm_clk_func
597 .init
= gk20a_clk_init
,
598 .fini
= gk20a_clk_fini
,
599 .read
= gk20a_clk_read
,
600 .calc
= gk20a_clk_calc
,
601 .prog
= gk20a_clk_prog
,
602 .tidy
= gk20a_clk_tidy
,
603 .pstates
= gk20a_pstates
,
604 .nr_pstates
= ARRAY_SIZE(gk20a_pstates
),
606 { nv_clk_src_crystal
, 0xff },
607 { nv_clk_src_gpc
, 0xff, 0, "core", GK20A_CLK_GPC_MDIV
},
613 gk20a_clk_ctor(struct nvkm_device
*device
, int index
,
614 const struct nvkm_clk_func
*func
,
615 const struct gk20a_clk_pllg_params
*params
,
616 struct gk20a_clk
*clk
)
618 struct nvkm_device_tegra
*tdev
= device
->func
->tegra(device
);
622 /* Finish initializing the pstates */
623 for (i
= 0; i
< func
->nr_pstates
; i
++) {
624 INIT_LIST_HEAD(&func
->pstates
[i
].list
);
625 func
->pstates
[i
].pstate
= i
+ 1;
628 clk
->params
= params
;
629 clk
->parent_rate
= clk_get_rate(tdev
->clk
);
631 ret
= nvkm_clk_ctor(func
, device
, index
, true, &clk
->base
);
635 nvkm_debug(&clk
->base
.subdev
, "parent clock rate: %d Khz\n",
636 clk
->parent_rate
/ KHZ
);
642 gk20a_clk_new(struct nvkm_device
*device
, int index
, struct nvkm_clk
**pclk
)
644 struct gk20a_clk
*clk
;
647 clk
= kzalloc(sizeof(*clk
), GFP_KERNEL
);
652 ret
= gk20a_clk_ctor(device
, index
, &gk20a_clk
, &gk20a_pllg_params
,
655 clk
->pl_to_div
= pl_to_div
;
656 clk
->div_to_pl
= div_to_pl
;