2 * Copyright (c) 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.
23 #include <subdev/clk.h>
24 #include <subdev/volt.h>
25 #include <subdev/timer.h>
26 #include <core/device.h>
27 #include <core/tegra.h>
32 #define GPCPLL_CFG_SYNC_MODE BIT(2)
34 #define BYPASSCTRL_SYS (SYS_GPCPLL_CFG_BASE + 0x340)
35 #define BYPASSCTRL_SYS_GPCPLL_SHIFT 0
36 #define BYPASSCTRL_SYS_GPCPLL_WIDTH 1
38 #define GPCPLL_CFG2_SDM_DIN_SHIFT 0
39 #define GPCPLL_CFG2_SDM_DIN_WIDTH 8
40 #define GPCPLL_CFG2_SDM_DIN_MASK \
41 (MASK(GPCPLL_CFG2_SDM_DIN_WIDTH) << GPCPLL_CFG2_SDM_DIN_SHIFT)
42 #define GPCPLL_CFG2_SDM_DIN_NEW_SHIFT 8
43 #define GPCPLL_CFG2_SDM_DIN_NEW_WIDTH 15
44 #define GPCPLL_CFG2_SDM_DIN_NEW_MASK \
45 (MASK(GPCPLL_CFG2_SDM_DIN_NEW_WIDTH) << GPCPLL_CFG2_SDM_DIN_NEW_SHIFT)
46 #define GPCPLL_CFG2_SETUP2_SHIFT 16
47 #define GPCPLL_CFG2_PLL_STEPA_SHIFT 24
49 #define GPCPLL_DVFS0 (SYS_GPCPLL_CFG_BASE + 0x10)
50 #define GPCPLL_DVFS0_DFS_COEFF_SHIFT 0
51 #define GPCPLL_DVFS0_DFS_COEFF_WIDTH 7
52 #define GPCPLL_DVFS0_DFS_COEFF_MASK \
53 (MASK(GPCPLL_DVFS0_DFS_COEFF_WIDTH) << GPCPLL_DVFS0_DFS_COEFF_SHIFT)
54 #define GPCPLL_DVFS0_DFS_DET_MAX_SHIFT 8
55 #define GPCPLL_DVFS0_DFS_DET_MAX_WIDTH 7
56 #define GPCPLL_DVFS0_DFS_DET_MAX_MASK \
57 (MASK(GPCPLL_DVFS0_DFS_DET_MAX_WIDTH) << GPCPLL_DVFS0_DFS_DET_MAX_SHIFT)
59 #define GPCPLL_DVFS1 (SYS_GPCPLL_CFG_BASE + 0x14)
60 #define GPCPLL_DVFS1_DFS_EXT_DET_SHIFT 0
61 #define GPCPLL_DVFS1_DFS_EXT_DET_WIDTH 7
62 #define GPCPLL_DVFS1_DFS_EXT_STRB_SHIFT 7
63 #define GPCPLL_DVFS1_DFS_EXT_STRB_WIDTH 1
64 #define GPCPLL_DVFS1_DFS_EXT_CAL_SHIFT 8
65 #define GPCPLL_DVFS1_DFS_EXT_CAL_WIDTH 7
66 #define GPCPLL_DVFS1_DFS_EXT_SEL_SHIFT 15
67 #define GPCPLL_DVFS1_DFS_EXT_SEL_WIDTH 1
68 #define GPCPLL_DVFS1_DFS_CTRL_SHIFT 16
69 #define GPCPLL_DVFS1_DFS_CTRL_WIDTH 12
70 #define GPCPLL_DVFS1_EN_SDM_SHIFT 28
71 #define GPCPLL_DVFS1_EN_SDM_WIDTH 1
72 #define GPCPLL_DVFS1_EN_SDM_BIT BIT(28)
73 #define GPCPLL_DVFS1_EN_DFS_SHIFT 29
74 #define GPCPLL_DVFS1_EN_DFS_WIDTH 1
75 #define GPCPLL_DVFS1_EN_DFS_BIT BIT(29)
76 #define GPCPLL_DVFS1_EN_DFS_CAL_SHIFT 30
77 #define GPCPLL_DVFS1_EN_DFS_CAL_WIDTH 1
78 #define GPCPLL_DVFS1_EN_DFS_CAL_BIT BIT(30)
79 #define GPCPLL_DVFS1_DFS_CAL_DONE_SHIFT 31
80 #define GPCPLL_DVFS1_DFS_CAL_DONE_WIDTH 1
81 #define GPCPLL_DVFS1_DFS_CAL_DONE_BIT BIT(31)
83 #define GPC_BCAST_GPCPLL_DVFS2 (GPC_BCAST_GPCPLL_CFG_BASE + 0x20)
84 #define GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT BIT(16)
86 #define GPCPLL_CFG3_PLL_DFS_TESTOUT_SHIFT 24
87 #define GPCPLL_CFG3_PLL_DFS_TESTOUT_WIDTH 7
89 #define DFS_DET_RANGE 6 /* -2^6 ... 2^6-1 */
90 #define SDM_DIN_RANGE 12 /* -2^12 ... 2^12-1 */
92 struct gm20b_clk_dvfs_params
{
98 static const struct gm20b_clk_dvfs_params gm20b_dvfs_params
= {
99 .coeff_slope
= -165230,
100 .coeff_offs
= 214007,
101 .vco_ctrl
= 0x7 << 3,
105 * base.n is now the *integer* part of the N factor.
106 * sdm_din contains n's decimal part.
109 struct gk20a_pll base
;
113 struct gm20b_clk_dvfs
{
120 /* currently applied parameters */
121 struct gk20a_clk base
;
122 struct gm20b_clk_dvfs dvfs
;
125 /* new parameters to apply */
126 struct gk20a_pll new_pll
;
127 struct gm20b_clk_dvfs new_dvfs
;
130 const struct gm20b_clk_dvfs_params
*dvfs_params
;
132 /* fused parameters */
136 /* safe frequency we can use at minimum voltage */
139 #define gm20b_clk(p) container_of((gk20a_clk(p)), struct gm20b_clk, base)
141 static u32
pl_to_div(u32 pl
)
146 static u32
div_to_pl(u32 div
)
151 static const struct gk20a_clk_pllg_params gm20b_pllg_params
= {
152 .min_vco
= 1300000, .max_vco
= 2600000,
153 .min_u
= 12000, .max_u
= 38400,
154 .min_m
= 1, .max_m
= 255,
155 .min_n
= 8, .max_n
= 255,
156 .min_pl
= 1, .max_pl
= 31,
160 gm20b_pllg_read_mnp(struct gm20b_clk
*clk
, struct gm20b_pll
*pll
)
162 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
163 struct nvkm_device
*device
= subdev
->device
;
166 gk20a_pllg_read_mnp(&clk
->base
, &pll
->base
);
167 val
= nvkm_rd32(device
, GPCPLL_CFG2
);
168 pll
->sdm_din
= (val
>> GPCPLL_CFG2_SDM_DIN_SHIFT
) &
169 MASK(GPCPLL_CFG2_SDM_DIN_WIDTH
);
173 gm20b_pllg_write_mnp(struct gm20b_clk
*clk
, const struct gm20b_pll
*pll
)
175 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
177 nvkm_mask(device
, GPCPLL_CFG2
, GPCPLL_CFG2_SDM_DIN_MASK
,
178 pll
->sdm_din
<< GPCPLL_CFG2_SDM_DIN_SHIFT
);
179 gk20a_pllg_write_mnp(&clk
->base
, &pll
->base
);
183 * Determine DFS_COEFF for the requested voltage. Always select external
184 * calibration override equal to the voltage, and set maximum detection
185 * limit "0" (to make sure that PLL output remains under F/V curve when
186 * voltage increases).
189 gm20b_dvfs_calc_det_coeff(struct gm20b_clk
*clk
, s32 uv
,
190 struct gm20b_clk_dvfs
*dvfs
)
192 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
193 const struct gm20b_clk_dvfs_params
*p
= clk
->dvfs_params
;
195 /* Work with mv as uv would likely trigger an overflow */
196 s32 mv
= DIV_ROUND_CLOSEST(uv
, 1000);
198 /* coeff = slope * voltage + offset */
199 coeff
= DIV_ROUND_CLOSEST(mv
* p
->coeff_slope
, 1000) + p
->coeff_offs
;
200 coeff
= DIV_ROUND_CLOSEST(coeff
, 1000);
201 dvfs
->dfs_coeff
= min_t(u32
, coeff
, MASK(GPCPLL_DVFS0_DFS_COEFF_WIDTH
));
203 dvfs
->dfs_ext_cal
= DIV_ROUND_CLOSEST(uv
- clk
->uvdet_offs
,
205 /* should never happen */
206 if (abs(dvfs
->dfs_ext_cal
) >= BIT(DFS_DET_RANGE
))
207 nvkm_error(subdev
, "dfs_ext_cal overflow!\n");
209 dvfs
->dfs_det_max
= 0;
211 nvkm_debug(subdev
, "%s uv: %d coeff: %x, ext_cal: %d, det_max: %d\n",
212 __func__
, uv
, dvfs
->dfs_coeff
, dvfs
->dfs_ext_cal
,
217 * Solve equation for integer and fractional part of the effective NDIV:
219 * n_eff = n_int + 1/2 + (SDM_DIN / 2^(SDM_DIN_RANGE + 1)) +
220 * (DVFS_COEFF * DVFS_DET_DELTA) / 2^DFS_DET_RANGE
222 * The SDM_DIN LSB is finally shifted out, since it is not accessible by sw.
225 gm20b_dvfs_calc_ndiv(struct gm20b_clk
*clk
, u32 n_eff
, u32
*n_int
, u32
*sdm_din
)
227 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
228 const struct gk20a_clk_pllg_params
*p
= clk
->base
.params
;
233 /* calculate current ext_cal and subtract previous one */
234 det_delta
= DIV_ROUND_CLOSEST(((s32
)clk
->uv
) - clk
->uvdet_offs
,
236 det_delta
-= clk
->dvfs
.dfs_ext_cal
;
237 det_delta
= min(det_delta
, clk
->dvfs
.dfs_det_max
);
238 det_delta
*= clk
->dvfs
.dfs_coeff
;
240 /* integer part of n */
241 n
= (n_eff
<< DFS_DET_RANGE
) - det_delta
;
242 /* should never happen! */
244 nvkm_error(subdev
, "ndiv <= 0 - setting to 1...\n");
245 n
= 1 << DFS_DET_RANGE
;
247 if (n
>> DFS_DET_RANGE
> p
->max_n
) {
248 nvkm_error(subdev
, "ndiv > max_n - setting to max_n...\n");
249 n
= p
->max_n
<< DFS_DET_RANGE
;
251 *n_int
= n
>> DFS_DET_RANGE
;
253 /* fractional part of n */
254 rem
= ((u32
)n
) & MASK(DFS_DET_RANGE
);
255 rem_range
= SDM_DIN_RANGE
+ 1 - DFS_DET_RANGE
;
256 /* subtract 2^SDM_DIN_RANGE to account for the 1/2 of the equation */
257 rem
= (rem
<< rem_range
) - BIT(SDM_DIN_RANGE
);
258 /* lose 8 LSB and clip - sdm_din only keeps the most significant byte */
259 *sdm_din
= (rem
>> BITS_PER_BYTE
) & MASK(GPCPLL_CFG2_SDM_DIN_WIDTH
);
261 nvkm_debug(subdev
, "%s n_eff: %d, n_int: %d, sdm_din: %d\n", __func__
,
262 n_eff
, *n_int
, *sdm_din
);
266 gm20b_pllg_slide(struct gm20b_clk
*clk
, u32 n
)
268 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
269 struct nvkm_device
*device
= subdev
->device
;
270 struct gm20b_pll pll
;
274 /* calculate the new n_int/sdm_din for this n/uv */
275 gm20b_dvfs_calc_ndiv(clk
, n
, &n_int
, &sdm_din
);
277 /* get old coefficients */
278 gm20b_pllg_read_mnp(clk
, &pll
);
279 /* do nothing if NDIV is the same */
280 if (n_int
== pll
.base
.n
&& sdm_din
== pll
.sdm_din
)
283 /* pll slowdown mode */
284 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
285 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
),
286 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
));
288 /* new ndiv ready for ramp */
289 /* in DVFS mode SDM is updated via "new" field */
290 nvkm_mask(device
, GPCPLL_CFG2
, GPCPLL_CFG2_SDM_DIN_NEW_MASK
,
291 sdm_din
<< GPCPLL_CFG2_SDM_DIN_NEW_SHIFT
);
294 gk20a_pllg_write_mnp(&clk
->base
, &pll
.base
);
296 /* dynamic ramp to new ndiv */
298 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
299 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
),
300 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
));
302 /* wait for ramping to complete */
303 if (nvkm_wait_usec(device
, 500, GPC_BCAST_NDIV_SLOWDOWN_DEBUG
,
304 GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK
,
305 GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK
) < 0)
308 /* in DVFS mode complete SDM update */
309 nvkm_mask(device
, GPCPLL_CFG2
, GPCPLL_CFG2_SDM_DIN_MASK
,
310 sdm_din
<< GPCPLL_CFG2_SDM_DIN_SHIFT
);
312 /* exit slowdown mode */
313 nvkm_mask(device
, GPCPLL_NDIV_SLOWDOWN
,
314 BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT
) |
315 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT
), 0);
316 nvkm_rd32(device
, GPCPLL_NDIV_SLOWDOWN
);
322 gm20b_pllg_enable(struct gm20b_clk
*clk
)
324 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
326 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_ENABLE
, GPCPLL_CFG_ENABLE
);
327 nvkm_rd32(device
, GPCPLL_CFG
);
329 /* In DVFS mode lock cannot be used - so just delay */
332 /* set SYNC_MODE for glitchless switch out of bypass */
333 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_SYNC_MODE
,
334 GPCPLL_CFG_SYNC_MODE
);
335 nvkm_rd32(device
, GPCPLL_CFG
);
337 /* switch to VCO mode */
338 nvkm_mask(device
, SEL_VCO
, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
),
339 BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
));
345 gm20b_pllg_disable(struct gm20b_clk
*clk
)
347 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
349 /* put PLL in bypass before disabling it */
350 nvkm_mask(device
, SEL_VCO
, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT
), 0);
352 /* clear SYNC_MODE before disabling PLL */
353 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_SYNC_MODE
, 0);
355 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_ENABLE
, 0);
356 nvkm_rd32(device
, GPCPLL_CFG
);
360 gm20b_pllg_program_mnp(struct gm20b_clk
*clk
, const struct gk20a_pll
*pll
)
362 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
363 struct nvkm_device
*device
= subdev
->device
;
364 struct gm20b_pll cur_pll
;
366 /* if we only change pdiv, we can do a glitchless transition */
370 gm20b_dvfs_calc_ndiv(clk
, pll
->n
, &n_int
, &sdm_din
);
371 gm20b_pllg_read_mnp(clk
, &cur_pll
);
372 pdiv_only
= cur_pll
.base
.n
== n_int
&& cur_pll
.sdm_din
== sdm_din
&&
373 cur_pll
.base
.m
== pll
->m
;
375 /* need full sequence if clock not enabled yet */
376 if (!gk20a_pllg_is_enabled(&clk
->base
))
379 /* split VCO-to-bypass jump in half by setting out divider 1:2 */
380 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
381 GPC2CLK_OUT_VCODIV2
<< GPC2CLK_OUT_VCODIV_SHIFT
);
382 /* Intentional 2nd write to assure linear divider operation */
383 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
384 GPC2CLK_OUT_VCODIV2
<< GPC2CLK_OUT_VCODIV_SHIFT
);
385 nvkm_rd32(device
, GPC2CLK_OUT
);
389 u32 old
= cur_pll
.base
.pl
;
393 * we can do a glitchless transition only if the old and new PL
394 * parameters share at least one bit set to 1. If this is not
395 * the case, calculate and program an interim PL that will allow
396 * us to respect that rule.
398 if ((old
& new) == 0) {
399 cur_pll
.base
.pl
= min(old
| BIT(ffs(new) - 1),
400 new | BIT(ffs(old
) - 1));
401 gk20a_pllg_write_mnp(&clk
->base
, &cur_pll
.base
);
404 cur_pll
.base
.pl
= new;
405 gk20a_pllg_write_mnp(&clk
->base
, &cur_pll
.base
);
407 /* disable before programming if more than pdiv changes */
408 gm20b_pllg_disable(clk
);
411 cur_pll
.base
.n
= n_int
;
412 cur_pll
.sdm_din
= sdm_din
;
413 gm20b_pllg_write_mnp(clk
, &cur_pll
);
415 ret
= gm20b_pllg_enable(clk
);
420 /* restore out divider 1:1 */
422 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
423 GPC2CLK_OUT_VCODIV1
<< GPC2CLK_OUT_VCODIV_SHIFT
);
424 /* Intentional 2nd write to assure linear divider operation */
425 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_VCODIV_MASK
,
426 GPC2CLK_OUT_VCODIV1
<< GPC2CLK_OUT_VCODIV_SHIFT
);
427 nvkm_rd32(device
, GPC2CLK_OUT
);
433 gm20b_pllg_program_mnp_slide(struct gm20b_clk
*clk
, const struct gk20a_pll
*pll
)
435 struct gk20a_pll cur_pll
;
438 if (gk20a_pllg_is_enabled(&clk
->base
)) {
439 gk20a_pllg_read_mnp(&clk
->base
, &cur_pll
);
441 /* just do NDIV slide if there is no change to M and PL */
442 if (pll
->m
== cur_pll
.m
&& pll
->pl
== cur_pll
.pl
)
443 return gm20b_pllg_slide(clk
, pll
->n
);
445 /* slide down to current NDIV_LO */
446 cur_pll
.n
= gk20a_pllg_n_lo(&clk
->base
, &cur_pll
);
447 ret
= gm20b_pllg_slide(clk
, cur_pll
.n
);
452 /* program MNP with the new clock parameters and new NDIV_LO */
454 cur_pll
.n
= gk20a_pllg_n_lo(&clk
->base
, &cur_pll
);
455 ret
= gm20b_pllg_program_mnp(clk
, &cur_pll
);
459 /* slide up to new NDIV */
460 return gm20b_pllg_slide(clk
, pll
->n
);
464 gm20b_clk_calc(struct nvkm_clk
*base
, struct nvkm_cstate
*cstate
)
466 struct gm20b_clk
*clk
= gm20b_clk(base
);
467 struct nvkm_subdev
*subdev
= &base
->subdev
;
468 struct nvkm_volt
*volt
= base
->subdev
.device
->volt
;
471 ret
= gk20a_pllg_calc_mnp(&clk
->base
, cstate
->domain
[nv_clk_src_gpc
] *
472 GK20A_CLK_GPC_MDIV
, &clk
->new_pll
);
476 clk
->new_uv
= volt
->vid
[cstate
->voltage
].uv
;
477 gm20b_dvfs_calc_det_coeff(clk
, clk
->new_uv
, &clk
->new_dvfs
);
479 nvkm_debug(subdev
, "%s uv: %d uv\n", __func__
, clk
->new_uv
);
485 * Compute PLL parameters that are always safe for the current voltage
488 gm20b_dvfs_calc_safe_pll(struct gm20b_clk
*clk
, struct gk20a_pll
*pll
)
490 u32 rate
= gk20a_pllg_calc_rate(&clk
->base
, pll
) / KHZ
;
491 u32 parent_rate
= clk
->base
.parent_rate
/ KHZ
;
494 /* remove a safe margin of 10% */
495 if (rate
> clk
->safe_fmax_vmin
)
496 rate
= rate
* (100 - 10) / 100;
501 nmin
= DIV_ROUND_UP(pll
->m
* clk
->base
.params
->min_vco
, parent_rate
);
502 nsafe
= pll
->m
* rate
/ (clk
->base
.parent_rate
);
505 pll
->pl
= DIV_ROUND_UP(nmin
* parent_rate
, pll
->m
* rate
);
513 gm20b_dvfs_program_coeff(struct gm20b_clk
*clk
, u32 coeff
)
515 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
517 /* strobe to read external DFS coefficient */
518 nvkm_mask(device
, GPC_BCAST_GPCPLL_DVFS2
,
519 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
,
520 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
);
522 nvkm_mask(device
, GPCPLL_DVFS0
, GPCPLL_DVFS0_DFS_COEFF_MASK
,
523 coeff
<< GPCPLL_DVFS0_DFS_COEFF_SHIFT
);
526 nvkm_mask(device
, GPC_BCAST_GPCPLL_DVFS2
,
527 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
, 0);
531 gm20b_dvfs_program_ext_cal(struct gm20b_clk
*clk
, u32 dfs_det_cal
)
533 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
536 nvkm_mask(device
, GPC_BCAST_GPCPLL_DVFS2
, MASK(DFS_DET_RANGE
+ 1),
540 val
= nvkm_rd32(device
, GPCPLL_DVFS1
);
541 if (!(val
& BIT(25))) {
542 /* Use external value to overwrite calibration value */
543 val
|= BIT(25) | BIT(16);
544 nvkm_wr32(device
, GPCPLL_DVFS1
, val
);
549 gm20b_dvfs_program_dfs_detection(struct gm20b_clk
*clk
,
550 struct gm20b_clk_dvfs
*dvfs
)
552 struct nvkm_device
*device
= clk
->base
.base
.subdev
.device
;
554 /* strobe to read external DFS coefficient */
555 nvkm_mask(device
, GPC_BCAST_GPCPLL_DVFS2
,
556 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
,
557 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
);
559 nvkm_mask(device
, GPCPLL_DVFS0
,
560 GPCPLL_DVFS0_DFS_COEFF_MASK
| GPCPLL_DVFS0_DFS_DET_MAX_MASK
,
561 dvfs
->dfs_coeff
<< GPCPLL_DVFS0_DFS_COEFF_SHIFT
|
562 dvfs
->dfs_det_max
<< GPCPLL_DVFS0_DFS_DET_MAX_SHIFT
);
565 nvkm_mask(device
, GPC_BCAST_GPCPLL_DVFS2
,
566 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT
, 0);
568 gm20b_dvfs_program_ext_cal(clk
, dvfs
->dfs_ext_cal
);
572 gm20b_clk_prog(struct nvkm_clk
*base
)
574 struct gm20b_clk
*clk
= gm20b_clk(base
);
578 /* No change in DVFS settings? */
579 if (clk
->uv
== clk
->new_uv
)
583 * Interim step for changing DVFS detection settings: low enough
584 * frequency to be safe at at DVFS coeff = 0.
586 * 1. If voltage is increasing:
587 * - safe frequency target matches the lowest - old - frequency
588 * - DVFS settings are still old
589 * - Voltage already increased to new level by volt, but maximum
590 * detection limit assures PLL output remains under F/V curve
592 * 2. If voltage is decreasing:
593 * - safe frequency target matches the lowest - new - frequency
594 * - DVFS settings are still old
595 * - Voltage is also old, it will be lowered by volt afterwards
597 * Interim step can be skipped if old frequency is below safe minimum,
598 * i.e., it is low enough to be safe at any voltage in operating range
599 * with zero DVFS coefficient.
601 cur_freq
= nvkm_clk_read(&clk
->base
.base
, nv_clk_src_gpc
);
602 if (cur_freq
> clk
->safe_fmax_vmin
) {
603 struct gk20a_pll pll_safe
;
605 if (clk
->uv
< clk
->new_uv
)
606 /* voltage will raise: safe frequency is current one */
607 pll_safe
= clk
->base
.pll
;
609 /* voltage will drop: safe frequency is new one */
610 pll_safe
= clk
->new_pll
;
612 gm20b_dvfs_calc_safe_pll(clk
, &pll_safe
);
613 ret
= gm20b_pllg_program_mnp_slide(clk
, &pll_safe
);
619 * DVFS detection settings transition:
620 * - Set DVFS coefficient zero
621 * - Set calibration level to new voltage
622 * - Set DVFS coefficient to match new voltage
624 gm20b_dvfs_program_coeff(clk
, 0);
625 gm20b_dvfs_program_ext_cal(clk
, clk
->new_dvfs
.dfs_ext_cal
);
626 gm20b_dvfs_program_coeff(clk
, clk
->new_dvfs
.dfs_coeff
);
627 gm20b_dvfs_program_dfs_detection(clk
, &clk
->new_dvfs
);
630 clk
->uv
= clk
->new_uv
;
631 clk
->dvfs
= clk
->new_dvfs
;
632 clk
->base
.pll
= clk
->new_pll
;
634 return gm20b_pllg_program_mnp_slide(clk
, &clk
->base
.pll
);
637 static struct nvkm_pstate
641 .domain
[nv_clk_src_gpc
] = 76800,
647 .domain
[nv_clk_src_gpc
] = 153600,
653 .domain
[nv_clk_src_gpc
] = 230400,
659 .domain
[nv_clk_src_gpc
] = 307200,
665 .domain
[nv_clk_src_gpc
] = 384000,
671 .domain
[nv_clk_src_gpc
] = 460800,
677 .domain
[nv_clk_src_gpc
] = 537600,
683 .domain
[nv_clk_src_gpc
] = 614400,
689 .domain
[nv_clk_src_gpc
] = 691200,
695 .domain
[nv_clk_src_gpc
] = 768000,
701 .domain
[nv_clk_src_gpc
] = 844800,
707 .domain
[nv_clk_src_gpc
] = 921600,
713 .domain
[nv_clk_src_gpc
] = 998400,
720 gm20b_clk_fini(struct nvkm_clk
*base
)
722 struct nvkm_device
*device
= base
->subdev
.device
;
723 struct gm20b_clk
*clk
= gm20b_clk(base
);
725 /* slide to VCO min */
726 if (gk20a_pllg_is_enabled(&clk
->base
)) {
727 struct gk20a_pll pll
;
730 gk20a_pllg_read_mnp(&clk
->base
, &pll
);
731 n_lo
= gk20a_pllg_n_lo(&clk
->base
, &pll
);
732 gm20b_pllg_slide(clk
, n_lo
);
735 gm20b_pllg_disable(clk
);
738 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_IDDQ
, 1);
742 gm20b_clk_init_dvfs(struct gm20b_clk
*clk
)
744 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
745 struct nvkm_device
*device
= subdev
->device
;
746 bool fused
= clk
->uvdet_offs
&& clk
->uvdet_slope
;
747 static const s32 ADC_SLOPE_UV
= 10000; /* default ADC detection slope */
752 nvkm_mask(device
, GPCPLL_DVFS1
, GPCPLL_DVFS1_EN_DFS_BIT
,
753 GPCPLL_DVFS1_EN_DFS_BIT
);
756 if (clk
->dvfs_params
->vco_ctrl
)
757 nvkm_mask(device
, GPCPLL_CFG3
, GPCPLL_CFG3_VCO_CTRL_MASK
,
758 clk
->dvfs_params
->vco_ctrl
<< GPCPLL_CFG3_VCO_CTRL_SHIFT
);
761 /* Start internal calibration, but ignore results */
762 nvkm_mask(device
, GPCPLL_DVFS1
, GPCPLL_DVFS1_EN_DFS_CAL_BIT
,
763 GPCPLL_DVFS1_EN_DFS_CAL_BIT
);
765 /* got uvdev parameters from fuse, skip calibration */
770 * If calibration parameters are not fused, start internal calibration,
771 * wait for completion, and use results along with default slope to
772 * calculate ADC offset during boot.
774 nvkm_mask(device
, GPCPLL_DVFS1
, GPCPLL_DVFS1_EN_DFS_CAL_BIT
,
775 GPCPLL_DVFS1_EN_DFS_CAL_BIT
);
777 /* Wait for internal calibration done (spec < 2us). */
778 ret
= nvkm_wait_usec(device
, 10, GPCPLL_DVFS1
,
779 GPCPLL_DVFS1_DFS_CAL_DONE_BIT
,
780 GPCPLL_DVFS1_DFS_CAL_DONE_BIT
);
782 nvkm_error(subdev
, "GPCPLL calibration timeout\n");
786 data
= nvkm_rd32(device
, GPCPLL_CFG3
) >>
787 GPCPLL_CFG3_PLL_DFS_TESTOUT_SHIFT
;
788 data
&= MASK(GPCPLL_CFG3_PLL_DFS_TESTOUT_WIDTH
);
790 clk
->uvdet_slope
= ADC_SLOPE_UV
;
791 clk
->uvdet_offs
= ((s32
)clk
->uv
) - data
* ADC_SLOPE_UV
;
793 nvkm_debug(subdev
, "calibrated DVFS parameters: offs %d, slope %d\n",
794 clk
->uvdet_offs
, clk
->uvdet_slope
);
797 /* Compute and apply initial DVFS parameters */
798 gm20b_dvfs_calc_det_coeff(clk
, clk
->uv
, &clk
->dvfs
);
799 gm20b_dvfs_program_coeff(clk
, 0);
800 gm20b_dvfs_program_ext_cal(clk
, clk
->dvfs
.dfs_ext_cal
);
801 gm20b_dvfs_program_coeff(clk
, clk
->dvfs
.dfs_coeff
);
802 gm20b_dvfs_program_dfs_detection(clk
, &clk
->new_dvfs
);
807 /* Forward declaration to detect speedo >=1 in gm20b_clk_init() */
808 static const struct nvkm_clk_func gm20b_clk
;
811 gm20b_clk_init(struct nvkm_clk
*base
)
813 struct gk20a_clk
*clk
= gk20a_clk(base
);
814 struct nvkm_subdev
*subdev
= &clk
->base
.subdev
;
815 struct nvkm_device
*device
= subdev
->device
;
819 /* get out from IDDQ */
820 nvkm_mask(device
, GPCPLL_CFG
, GPCPLL_CFG_IDDQ
, 0);
821 nvkm_rd32(device
, GPCPLL_CFG
);
824 nvkm_mask(device
, GPC2CLK_OUT
, GPC2CLK_OUT_INIT_MASK
,
825 GPC2CLK_OUT_INIT_VAL
);
827 /* Set the global bypass control to VCO */
828 nvkm_mask(device
, BYPASSCTRL_SYS
,
829 MASK(BYPASSCTRL_SYS_GPCPLL_WIDTH
) << BYPASSCTRL_SYS_GPCPLL_SHIFT
,
832 ret
= gk20a_clk_setup_slide(clk
);
836 /* If not fused, set RAM SVOP PDP data 0x2, and enable fuse override */
837 data
= nvkm_rd32(device
, 0x021944);
840 nvkm_wr32(device
, 0x021944, data
);
842 data
= nvkm_rd32(device
, 0x021948);
844 nvkm_wr32(device
, 0x021948, data
);
847 /* Disable idle slow down */
848 nvkm_mask(device
, 0x20160, 0x003f0000, 0x0);
851 if (clk
->base
.func
== &gm20b_clk
) {
852 struct gm20b_clk
*_clk
= gm20b_clk(base
);
853 struct nvkm_volt
*volt
= device
->volt
;
855 /* Get current voltage */
856 _clk
->uv
= nvkm_volt_get(volt
);
858 /* Initialize DVFS */
859 ret
= gm20b_clk_init_dvfs(_clk
);
864 /* Start with lowest frequency */
865 base
->func
->calc(base
, &base
->func
->pstates
[0].base
);
866 ret
= base
->func
->prog(base
);
868 nvkm_error(subdev
, "cannot initialize clock\n");
875 static const struct nvkm_clk_func
876 gm20b_clk_speedo0
= {
877 .init
= gm20b_clk_init
,
878 .fini
= gk20a_clk_fini
,
879 .read
= gk20a_clk_read
,
880 .calc
= gk20a_clk_calc
,
881 .prog
= gk20a_clk_prog
,
882 .tidy
= gk20a_clk_tidy
,
883 .pstates
= gm20b_pstates
,
884 /* Speedo 0 only supports 12 voltages */
885 .nr_pstates
= ARRAY_SIZE(gm20b_pstates
) - 1,
887 { nv_clk_src_crystal
, 0xff },
888 { nv_clk_src_gpc
, 0xff, 0, "core", GK20A_CLK_GPC_MDIV
},
893 static const struct nvkm_clk_func
895 .init
= gm20b_clk_init
,
896 .fini
= gm20b_clk_fini
,
897 .read
= gk20a_clk_read
,
898 .calc
= gm20b_clk_calc
,
899 .prog
= gm20b_clk_prog
,
900 .tidy
= gk20a_clk_tidy
,
901 .pstates
= gm20b_pstates
,
902 .nr_pstates
= ARRAY_SIZE(gm20b_pstates
),
904 { nv_clk_src_crystal
, 0xff },
905 { nv_clk_src_gpc
, 0xff, 0, "core", GK20A_CLK_GPC_MDIV
},
911 gm20b_clk_new_speedo0(struct nvkm_device
*device
, int index
,
912 struct nvkm_clk
**pclk
)
914 struct gk20a_clk
*clk
;
917 clk
= kzalloc(sizeof(*clk
), GFP_KERNEL
);
922 ret
= gk20a_clk_ctor(device
, index
, &gm20b_clk_speedo0
,
923 &gm20b_pllg_params
, clk
);
925 clk
->pl_to_div
= pl_to_div
;
926 clk
->div_to_pl
= div_to_pl
;
932 #define FUSE_RESERVED_CALIB0 0x204
933 #define FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_SHIFT 0
934 #define FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_WIDTH 4
935 #define FUSE_RESERVED_CALIB0_INTERCEPT_INT_SHIFT 4
936 #define FUSE_RESERVED_CALIB0_INTERCEPT_INT_WIDTH 10
937 #define FUSE_RESERVED_CALIB0_SLOPE_FRAC_SHIFT 14
938 #define FUSE_RESERVED_CALIB0_SLOPE_FRAC_WIDTH 10
939 #define FUSE_RESERVED_CALIB0_SLOPE_INT_SHIFT 24
940 #define FUSE_RESERVED_CALIB0_SLOPE_INT_WIDTH 6
941 #define FUSE_RESERVED_CALIB0_FUSE_REV_SHIFT 30
942 #define FUSE_RESERVED_CALIB0_FUSE_REV_WIDTH 2
945 gm20b_clk_init_fused_params(struct gm20b_clk
*clk
)
947 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
951 #if IS_ENABLED(CONFIG_ARCH_TEGRA)
952 tegra_fuse_readl(FUSE_RESERVED_CALIB0
, &val
);
953 rev
= (val
>> FUSE_RESERVED_CALIB0_FUSE_REV_SHIFT
) &
954 MASK(FUSE_RESERVED_CALIB0_FUSE_REV_WIDTH
);
957 /* No fused parameters, we will calibrate later */
961 /* Integer part in mV + fractional part in uV */
962 clk
->uvdet_slope
= ((val
>> FUSE_RESERVED_CALIB0_SLOPE_INT_SHIFT
) &
963 MASK(FUSE_RESERVED_CALIB0_SLOPE_INT_WIDTH
)) * 1000 +
964 ((val
>> FUSE_RESERVED_CALIB0_SLOPE_FRAC_SHIFT
) &
965 MASK(FUSE_RESERVED_CALIB0_SLOPE_FRAC_WIDTH
));
967 /* Integer part in mV + fractional part in 100uV */
968 clk
->uvdet_offs
= ((val
>> FUSE_RESERVED_CALIB0_INTERCEPT_INT_SHIFT
) &
969 MASK(FUSE_RESERVED_CALIB0_INTERCEPT_INT_WIDTH
)) * 1000 +
970 ((val
>> FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_SHIFT
) &
971 MASK(FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_WIDTH
)) * 100;
973 nvkm_debug(subdev
, "fused calibration data: slope %d, offs %d\n",
974 clk
->uvdet_slope
, clk
->uvdet_offs
);
979 gm20b_clk_init_safe_fmax(struct gm20b_clk
*clk
)
981 struct nvkm_subdev
*subdev
= &clk
->base
.base
.subdev
;
982 struct nvkm_volt
*volt
= subdev
->device
->volt
;
983 struct nvkm_pstate
*pstates
= clk
->base
.base
.func
->pstates
;
984 int nr_pstates
= clk
->base
.base
.func
->nr_pstates
;
989 /* find lowest voltage we can use */
990 vmin
= volt
->vid
[0].uv
;
991 for (i
= 1; i
< volt
->vid_nr
; i
++) {
992 if (volt
->vid
[i
].uv
<= vmin
) {
993 vmin
= volt
->vid
[i
].uv
;
994 id
= volt
->vid
[i
].vid
;
998 /* find max frequency at this voltage */
999 for (i
= 0; i
< nr_pstates
; i
++)
1000 if (pstates
[i
].base
.voltage
== id
)
1002 pstates
[i
].base
.domain
[nv_clk_src_gpc
]);
1005 nvkm_error(subdev
, "failed to evaluate safe fmax\n");
1009 /* we are safe at 90% of the max frequency */
1010 clk
->safe_fmax_vmin
= fmax
* (100 - 10) / 100;
1011 nvkm_debug(subdev
, "safe fmax @ vmin = %u Khz\n", clk
->safe_fmax_vmin
);
1017 gm20b_clk_new(struct nvkm_device
*device
, int index
, struct nvkm_clk
**pclk
)
1019 struct nvkm_device_tegra
*tdev
= device
->func
->tegra(device
);
1020 struct gm20b_clk
*clk
;
1021 struct nvkm_subdev
*subdev
;
1022 struct gk20a_clk_pllg_params
*clk_params
;
1025 /* Speedo 0 GPUs cannot use noise-aware PLL */
1026 if (tdev
->gpu_speedo_id
== 0)
1027 return gm20b_clk_new_speedo0(device
, index
, pclk
);
1029 /* Speedo >= 1, use NAPLL */
1030 clk
= kzalloc(sizeof(*clk
) + sizeof(*clk_params
), GFP_KERNEL
);
1033 *pclk
= &clk
->base
.base
;
1034 subdev
= &clk
->base
.base
.subdev
;
1036 /* duplicate the clock parameters since we will patch them below */
1037 clk_params
= (void *) (clk
+ 1);
1038 *clk_params
= gm20b_pllg_params
;
1039 ret
= gk20a_clk_ctor(device
, index
, &gm20b_clk
, clk_params
,
1045 * NAPLL can only work with max_u, clamp the m range so
1046 * gk20a_pllg_calc_mnp always uses it
1048 clk_params
->max_m
= clk_params
->min_m
= DIV_ROUND_UP(clk_params
->max_u
,
1049 (clk
->base
.parent_rate
/ KHZ
));
1050 if (clk_params
->max_m
== 0) {
1051 nvkm_warn(subdev
, "cannot use NAPLL, using legacy clock...\n");
1053 return gm20b_clk_new_speedo0(device
, index
, pclk
);
1056 clk
->base
.pl_to_div
= pl_to_div
;
1057 clk
->base
.div_to_pl
= div_to_pl
;
1059 clk
->dvfs_params
= &gm20b_dvfs_params
;
1061 ret
= gm20b_clk_init_fused_params(clk
);
1063 * we will calibrate during init - should never happen on
1067 nvkm_warn(subdev
, "no fused calibration parameters\n");
1069 ret
= gm20b_clk_init_safe_fmax(clk
);