Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[deliverable/linux.git] / drivers / gpu / drm / nouveau / nvkm / subdev / clk / gm20b.c
CommitLineData
52829d4f
AC
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
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 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.
21 */
22
23#include <subdev/clk.h>
22b6c9e8
AC
24#include <subdev/volt.h>
25#include <subdev/timer.h>
52829d4f 26#include <core/device.h>
22b6c9e8 27#include <core/tegra.h>
52829d4f
AC
28
29#include "priv.h"
30#include "gk20a.h"
31
22b6c9e8 32#define GPCPLL_CFG_SYNC_MODE BIT(2)
52829d4f
AC
33
34#define BYPASSCTRL_SYS (SYS_GPCPLL_CFG_BASE + 0x340)
35#define BYPASSCTRL_SYS_GPCPLL_SHIFT 0
36#define BYPASSCTRL_SYS_GPCPLL_WIDTH 1
37
22b6c9e8
AC
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
48
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)
58
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)
82
83#define GPC_BCAST_GPCPLL_DVFS2 (GPC_BCAST_GPCPLL_CFG_BASE + 0x20)
84#define GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT BIT(16)
85
86#define GPCPLL_CFG3_PLL_DFS_TESTOUT_SHIFT 24
87#define GPCPLL_CFG3_PLL_DFS_TESTOUT_WIDTH 7
88
89#define DFS_DET_RANGE 6 /* -2^6 ... 2^6-1 */
90#define SDM_DIN_RANGE 12 /* -2^12 ... 2^12-1 */
91
92struct gm20b_clk_dvfs_params {
93 s32 coeff_slope;
94 s32 coeff_offs;
95 u32 vco_ctrl;
96};
97
98static const struct gm20b_clk_dvfs_params gm20b_dvfs_params = {
99 .coeff_slope = -165230,
100 .coeff_offs = 214007,
101 .vco_ctrl = 0x7 << 3,
102};
103
104/*
105 * base.n is now the *integer* part of the N factor.
106 * sdm_din contains n's decimal part.
107 */
108struct gm20b_pll {
109 struct gk20a_pll base;
110 u32 sdm_din;
111};
112
113struct gm20b_clk_dvfs {
114 u32 dfs_coeff;
115 s32 dfs_det_max;
116 s32 dfs_ext_cal;
117};
118
119struct gm20b_clk {
120 /* currently applied parameters */
121 struct gk20a_clk base;
122 struct gm20b_clk_dvfs dvfs;
123 u32 uv;
124
125 /* new parameters to apply */
126 struct gk20a_pll new_pll;
127 struct gm20b_clk_dvfs new_dvfs;
128 u32 new_uv;
129
130 const struct gm20b_clk_dvfs_params *dvfs_params;
131
132 /* fused parameters */
133 s32 uvdet_slope;
134 s32 uvdet_offs;
135
136 /* safe frequency we can use at minimum voltage */
137 u32 safe_fmax_vmin;
138};
139#define gm20b_clk(p) container_of((gk20a_clk(p)), struct gm20b_clk, base)
140
52829d4f
AC
141static u32 pl_to_div(u32 pl)
142{
143 return pl;
144}
145
146static u32 div_to_pl(u32 div)
147{
148 return div;
149}
150
151static 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,
157};
158
22b6c9e8
AC
159static void
160gm20b_pllg_read_mnp(struct gm20b_clk *clk, struct gm20b_pll *pll)
161{
162 struct nvkm_subdev *subdev = &clk->base.base.subdev;
163 struct nvkm_device *device = subdev->device;
164 u32 val;
165
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);
170}
171
172static void
173gm20b_pllg_write_mnp(struct gm20b_clk *clk, const struct gm20b_pll *pll)
174{
175 struct nvkm_device *device = clk->base.base.subdev.device;
176
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);
180}
181
182/*
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).
187 */
188static void
189gm20b_dvfs_calc_det_coeff(struct gm20b_clk *clk, s32 uv,
190 struct gm20b_clk_dvfs *dvfs)
191{
192 struct nvkm_subdev *subdev = &clk->base.base.subdev;
193 const struct gm20b_clk_dvfs_params *p = clk->dvfs_params;
194 u32 coeff;
195 /* Work with mv as uv would likely trigger an overflow */
196 s32 mv = DIV_ROUND_CLOSEST(uv, 1000);
197
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));
202
203 dvfs->dfs_ext_cal = DIV_ROUND_CLOSEST(uv - clk->uvdet_offs,
204 clk->uvdet_slope);
205 /* should never happen */
206 if (abs(dvfs->dfs_ext_cal) >= BIT(DFS_DET_RANGE))
207 nvkm_error(subdev, "dfs_ext_cal overflow!\n");
208
209 dvfs->dfs_det_max = 0;
210
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,
213 dvfs->dfs_det_max);
214}
215
216/*
217 * Solve equation for integer and fractional part of the effective NDIV:
218 *
219 * n_eff = n_int + 1/2 + (SDM_DIN / 2^(SDM_DIN_RANGE + 1)) +
220 * (DVFS_COEFF * DVFS_DET_DELTA) / 2^DFS_DET_RANGE
221 *
222 * The SDM_DIN LSB is finally shifted out, since it is not accessible by sw.
223 */
224static void
225gm20b_dvfs_calc_ndiv(struct gm20b_clk *clk, u32 n_eff, u32 *n_int, u32 *sdm_din)
226{
227 struct nvkm_subdev *subdev = &clk->base.base.subdev;
228 const struct gk20a_clk_pllg_params *p = clk->base.params;
229 u32 n;
230 s32 det_delta;
231 u32 rem, rem_range;
232
233 /* calculate current ext_cal and subtract previous one */
234 det_delta = DIV_ROUND_CLOSEST(((s32)clk->uv) - clk->uvdet_offs,
235 clk->uvdet_slope);
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;
239
240 /* integer part of n */
241 n = (n_eff << DFS_DET_RANGE) - det_delta;
242 /* should never happen! */
243 if (n <= 0) {
244 nvkm_error(subdev, "ndiv <= 0 - setting to 1...\n");
245 n = 1 << DFS_DET_RANGE;
246 }
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;
250 }
251 *n_int = n >> DFS_DET_RANGE;
252
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);
260
261 nvkm_debug(subdev, "%s n_eff: %d, n_int: %d, sdm_din: %d\n", __func__,
262 n_eff, *n_int, *sdm_din);
263}
264
265static int
266gm20b_pllg_slide(struct gm20b_clk *clk, u32 n)
267{
268 struct nvkm_subdev *subdev = &clk->base.base.subdev;
269 struct nvkm_device *device = subdev->device;
270 struct gm20b_pll pll;
271 u32 n_int, sdm_din;
272 int ret = 0;
273
274 /* calculate the new n_int/sdm_din for this n/uv */
275 gm20b_dvfs_calc_ndiv(clk, n, &n_int, &sdm_din);
276
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)
281 return 0;
282
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));
287
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);
292 pll.base.n = n_int;
293 udelay(1);
294 gk20a_pllg_write_mnp(&clk->base, &pll.base);
295
296 /* dynamic ramp to new ndiv */
297 udelay(1);
298 nvkm_mask(device, GPCPLL_NDIV_SLOWDOWN,
299 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT),
300 BIT(GPCPLL_NDIV_SLOWDOWN_EN_DYNRAMP_SHIFT));
301
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)
306 ret = -ETIMEDOUT;
307
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);
311
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);
317
318 return ret;
319}
320
321static int
322gm20b_pllg_enable(struct gm20b_clk *clk)
323{
324 struct nvkm_device *device = clk->base.base.subdev.device;
325
326 nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_ENABLE, GPCPLL_CFG_ENABLE);
327 nvkm_rd32(device, GPCPLL_CFG);
328
329 /* In DVFS mode lock cannot be used - so just delay */
330 udelay(40);
331
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);
336
337 /* switch to VCO mode */
338 nvkm_mask(device, SEL_VCO, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT),
339 BIT(SEL_VCO_GPC2CLK_OUT_SHIFT));
340
341 return 0;
342}
343
344static void
345gm20b_pllg_disable(struct gm20b_clk *clk)
346{
347 struct nvkm_device *device = clk->base.base.subdev.device;
348
349 /* put PLL in bypass before disabling it */
350 nvkm_mask(device, SEL_VCO, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT), 0);
351
352 /* clear SYNC_MODE before disabling PLL */
353 nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_SYNC_MODE, 0);
354
355 nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_ENABLE, 0);
356 nvkm_rd32(device, GPCPLL_CFG);
357}
358
359static int
360gm20b_pllg_program_mnp(struct gm20b_clk *clk, const struct gk20a_pll *pll)
361{
362 struct nvkm_subdev *subdev = &clk->base.base.subdev;
363 struct nvkm_device *device = subdev->device;
364 struct gm20b_pll cur_pll;
365 u32 n_int, sdm_din;
366 /* if we only change pdiv, we can do a glitchless transition */
367 bool pdiv_only;
368 int ret;
369
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;
374
375 /* need full sequence if clock not enabled yet */
376 if (!gk20a_pllg_is_enabled(&clk->base))
377 pdiv_only = false;
378
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);
386 udelay(2);
387
388 if (pdiv_only) {
389 u32 old = cur_pll.base.pl;
390 u32 new = pll->pl;
391
392 /*
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.
397 */
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);
402 }
403
404 cur_pll.base.pl = new;
405 gk20a_pllg_write_mnp(&clk->base, &cur_pll.base);
406 } else {
407 /* disable before programming if more than pdiv changes */
408 gm20b_pllg_disable(clk);
409
410 cur_pll.base = *pll;
411 cur_pll.base.n = n_int;
412 cur_pll.sdm_din = sdm_din;
413 gm20b_pllg_write_mnp(clk, &cur_pll);
414
415 ret = gm20b_pllg_enable(clk);
416 if (ret)
417 return ret;
418 }
419
420 /* restore out divider 1:1 */
421 udelay(2);
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);
428
429 return 0;
430}
431
432static int
433gm20b_pllg_program_mnp_slide(struct gm20b_clk *clk, const struct gk20a_pll *pll)
434{
435 struct gk20a_pll cur_pll;
436 int ret;
437
438 if (gk20a_pllg_is_enabled(&clk->base)) {
439 gk20a_pllg_read_mnp(&clk->base, &cur_pll);
440
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);
444
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);
448 if (ret)
449 return ret;
450 }
451
452 /* program MNP with the new clock parameters and new NDIV_LO */
453 cur_pll = *pll;
454 cur_pll.n = gk20a_pllg_n_lo(&clk->base, &cur_pll);
455 ret = gm20b_pllg_program_mnp(clk, &cur_pll);
456 if (ret)
457 return ret;
458
459 /* slide up to new NDIV */
460 return gm20b_pllg_slide(clk, pll->n);
461}
462
463static int
464gm20b_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate)
465{
466 struct gm20b_clk *clk = gm20b_clk(base);
467 struct nvkm_subdev *subdev = &base->subdev;
468 struct nvkm_volt *volt = base->subdev.device->volt;
469 int ret;
470
471 ret = gk20a_pllg_calc_mnp(&clk->base, cstate->domain[nv_clk_src_gpc] *
472 GK20A_CLK_GPC_MDIV, &clk->new_pll);
473 if (ret)
474 return ret;
475
476 clk->new_uv = volt->vid[cstate->voltage].uv;
477 gm20b_dvfs_calc_det_coeff(clk, clk->new_uv, &clk->new_dvfs);
478
479 nvkm_debug(subdev, "%s uv: %d uv\n", __func__, clk->new_uv);
480
481 return 0;
482}
483
484/*
485 * Compute PLL parameters that are always safe for the current voltage
486 */
487static void
488gm20b_dvfs_calc_safe_pll(struct gm20b_clk *clk, struct gk20a_pll *pll)
489{
490 u32 rate = gk20a_pllg_calc_rate(&clk->base, pll) / KHZ;
491 u32 parent_rate = clk->base.parent_rate / KHZ;
492 u32 nmin, nsafe;
493
494 /* remove a safe margin of 10% */
495 if (rate > clk->safe_fmax_vmin)
496 rate = rate * (100 - 10) / 100;
497
498 /* gpc2clk */
499 rate *= 2;
500
501 nmin = DIV_ROUND_UP(pll->m * clk->base.params->min_vco, parent_rate);
502 nsafe = pll->m * rate / (clk->base.parent_rate);
503
504 if (nsafe < nmin) {
505 pll->pl = DIV_ROUND_UP(nmin * parent_rate, pll->m * rate);
506 nsafe = nmin;
507 }
508
509 pll->n = nsafe;
510}
511
512static void
513gm20b_dvfs_program_coeff(struct gm20b_clk *clk, u32 coeff)
514{
515 struct nvkm_device *device = clk->base.base.subdev.device;
516
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);
521
522 nvkm_mask(device, GPCPLL_DVFS0, GPCPLL_DVFS0_DFS_COEFF_MASK,
523 coeff << GPCPLL_DVFS0_DFS_COEFF_SHIFT);
524
525 udelay(1);
526 nvkm_mask(device, GPC_BCAST_GPCPLL_DVFS2,
527 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT, 0);
528}
529
530static void
531gm20b_dvfs_program_ext_cal(struct gm20b_clk *clk, u32 dfs_det_cal)
532{
533 struct nvkm_device *device = clk->base.base.subdev.device;
534 u32 val;
535
536 nvkm_mask(device, GPC_BCAST_GPCPLL_DVFS2, MASK(DFS_DET_RANGE + 1),
537 dfs_det_cal);
538 udelay(1);
539
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);
545 }
546}
547
548static void
549gm20b_dvfs_program_dfs_detection(struct gm20b_clk *clk,
550 struct gm20b_clk_dvfs *dvfs)
551{
552 struct nvkm_device *device = clk->base.base.subdev.device;
553
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);
558
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);
563
564 udelay(1);
565 nvkm_mask(device, GPC_BCAST_GPCPLL_DVFS2,
566 GPC_BCAST_GPCPLL_DVFS2_DFS_EXT_STROBE_BIT, 0);
567
568 gm20b_dvfs_program_ext_cal(clk, dvfs->dfs_ext_cal);
569}
570
571static int
572gm20b_clk_prog(struct nvkm_clk *base)
573{
574 struct gm20b_clk *clk = gm20b_clk(base);
575 u32 cur_freq;
576 int ret;
577
578 /* No change in DVFS settings? */
579 if (clk->uv == clk->new_uv)
580 goto prog;
581
582 /*
583 * Interim step for changing DVFS detection settings: low enough
584 * frequency to be safe at at DVFS coeff = 0.
585 *
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
591 *
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
596 *
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.
600 */
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;
604
605 if (clk->uv < clk->new_uv)
606 /* voltage will raise: safe frequency is current one */
607 pll_safe = clk->base.pll;
608 else
609 /* voltage will drop: safe frequency is new one */
610 pll_safe = clk->new_pll;
611
612 gm20b_dvfs_calc_safe_pll(clk, &pll_safe);
613 ret = gm20b_pllg_program_mnp_slide(clk, &pll_safe);
614 if (ret)
615 return ret;
616 }
617
618 /*
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
623 */
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);
628
629prog:
630 clk->uv = clk->new_uv;
631 clk->dvfs = clk->new_dvfs;
632 clk->base.pll = clk->new_pll;
633
634 return gm20b_pllg_program_mnp_slide(clk, &clk->base.pll);
635}
636
52829d4f
AC
637static struct nvkm_pstate
638gm20b_pstates[] = {
639 {
640 .base = {
641 .domain[nv_clk_src_gpc] = 76800,
642 .voltage = 0,
643 },
644 },
645 {
646 .base = {
647 .domain[nv_clk_src_gpc] = 153600,
648 .voltage = 1,
649 },
650 },
651 {
652 .base = {
653 .domain[nv_clk_src_gpc] = 230400,
654 .voltage = 2,
655 },
656 },
657 {
658 .base = {
659 .domain[nv_clk_src_gpc] = 307200,
660 .voltage = 3,
661 },
662 },
663 {
664 .base = {
665 .domain[nv_clk_src_gpc] = 384000,
666 .voltage = 4,
667 },
668 },
669 {
670 .base = {
671 .domain[nv_clk_src_gpc] = 460800,
672 .voltage = 5,
673 },
674 },
675 {
676 .base = {
677 .domain[nv_clk_src_gpc] = 537600,
678 .voltage = 6,
679 },
680 },
681 {
682 .base = {
683 .domain[nv_clk_src_gpc] = 614400,
684 .voltage = 7,
685 },
686 },
687 {
688 .base = {
689 .domain[nv_clk_src_gpc] = 691200,
690 .voltage = 8,
691 },
692 },
693 {
694 .base = {
695 .domain[nv_clk_src_gpc] = 768000,
696 .voltage = 9,
697 },
698 },
699 {
700 .base = {
701 .domain[nv_clk_src_gpc] = 844800,
702 .voltage = 10,
703 },
704 },
705 {
706 .base = {
707 .domain[nv_clk_src_gpc] = 921600,
708 .voltage = 11,
709 },
710 },
711 {
712 .base = {
713 .domain[nv_clk_src_gpc] = 998400,
714 .voltage = 12,
715 },
716 },
52829d4f
AC
717};
718
22b6c9e8
AC
719static void
720gm20b_clk_fini(struct nvkm_clk *base)
721{
722 struct nvkm_device *device = base->subdev.device;
723 struct gm20b_clk *clk = gm20b_clk(base);
724
725 /* slide to VCO min */
726 if (gk20a_pllg_is_enabled(&clk->base)) {
727 struct gk20a_pll pll;
728 u32 n_lo;
729
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);
733 }
734
735 gm20b_pllg_disable(clk);
736
737 /* set IDDQ */
738 nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_IDDQ, 1);
739}
740
741static int
742gm20b_clk_init_dvfs(struct gm20b_clk *clk)
743{
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 */
748 u32 data;
749 int ret;
750
751 /* Enable NA DVFS */
752 nvkm_mask(device, GPCPLL_DVFS1, GPCPLL_DVFS1_EN_DFS_BIT,
753 GPCPLL_DVFS1_EN_DFS_BIT);
754
755 /* Set VCO_CTRL */
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);
759
760 if (fused) {
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);
764
765 /* got uvdev parameters from fuse, skip calibration */
766 goto calibrated;
767 }
768
769 /*
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.
773 */
774 nvkm_mask(device, GPCPLL_DVFS1, GPCPLL_DVFS1_EN_DFS_CAL_BIT,
775 GPCPLL_DVFS1_EN_DFS_CAL_BIT);
776
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);
781 if (ret < 0) {
782 nvkm_error(subdev, "GPCPLL calibration timeout\n");
783 return -ETIMEDOUT;
784 }
785
786 data = nvkm_rd32(device, GPCPLL_CFG3) >>
787 GPCPLL_CFG3_PLL_DFS_TESTOUT_SHIFT;
788 data &= MASK(GPCPLL_CFG3_PLL_DFS_TESTOUT_WIDTH);
789
790 clk->uvdet_slope = ADC_SLOPE_UV;
791 clk->uvdet_offs = ((s32)clk->uv) - data * ADC_SLOPE_UV;
792
793 nvkm_debug(subdev, "calibrated DVFS parameters: offs %d, slope %d\n",
794 clk->uvdet_offs, clk->uvdet_slope);
795
796calibrated:
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);
803
804 return 0;
805}
806
807/* Forward declaration to detect speedo >=1 in gm20b_clk_init() */
808static const struct nvkm_clk_func gm20b_clk;
809
52829d4f
AC
810static int
811gm20b_clk_init(struct nvkm_clk *base)
812{
813 struct gk20a_clk *clk = gk20a_clk(base);
814 struct nvkm_subdev *subdev = &clk->base.subdev;
815 struct nvkm_device *device = subdev->device;
816 int ret;
22b6c9e8 817 u32 data;
52829d4f 818
22b6c9e8
AC
819 /* get out from IDDQ */
820 nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_IDDQ, 0);
821 nvkm_rd32(device, GPCPLL_CFG);
822 udelay(5);
823
824 nvkm_mask(device, GPC2CLK_OUT, GPC2CLK_OUT_INIT_MASK,
825 GPC2CLK_OUT_INIT_VAL);
f5f1b06e 826
52829d4f
AC
827 /* Set the global bypass control to VCO */
828 nvkm_mask(device, BYPASSCTRL_SYS,
829 MASK(BYPASSCTRL_SYS_GPCPLL_WIDTH) << BYPASSCTRL_SYS_GPCPLL_SHIFT,
830 0);
831
22b6c9e8
AC
832 ret = gk20a_clk_setup_slide(clk);
833 if (ret)
834 return ret;
835
836 /* If not fused, set RAM SVOP PDP data 0x2, and enable fuse override */
837 data = nvkm_rd32(device, 0x021944);
838 if (!(data & 0x3)) {
839 data |= 0x2;
840 nvkm_wr32(device, 0x021944, data);
841
842 data = nvkm_rd32(device, 0x021948);
843 data |= 0x1;
844 nvkm_wr32(device, 0x021948, data);
845 }
846
847 /* Disable idle slow down */
848 nvkm_mask(device, 0x20160, 0x003f0000, 0x0);
849
850 /* speedo >= 1? */
851 if (clk->base.func == &gm20b_clk) {
852 struct gm20b_clk *_clk = gm20b_clk(base);
853 struct nvkm_volt *volt = device->volt;
854
855 /* Get current voltage */
856 _clk->uv = nvkm_volt_get(volt);
857
858 /* Initialize DVFS */
859 ret = gm20b_clk_init_dvfs(_clk);
860 if (ret)
861 return ret;
862 }
863
52829d4f
AC
864 /* Start with lowest frequency */
865 base->func->calc(base, &base->func->pstates[0].base);
22b6c9e8 866 ret = base->func->prog(base);
52829d4f
AC
867 if (ret) {
868 nvkm_error(subdev, "cannot initialize clock\n");
869 return ret;
870 }
871
872 return 0;
873}
874
875static const struct nvkm_clk_func
876gm20b_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,
22b6c9e8 884 /* Speedo 0 only supports 12 voltages */
52829d4f
AC
885 .nr_pstates = ARRAY_SIZE(gm20b_pstates) - 1,
886 .domains = {
887 { nv_clk_src_crystal, 0xff },
888 { nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
889 { nv_clk_src_max },
890 },
891};
892
22b6c9e8
AC
893static const struct nvkm_clk_func
894gm20b_clk = {
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),
903 .domains = {
904 { nv_clk_src_crystal, 0xff },
905 { nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
906 { nv_clk_src_max },
907 },
908};
909
910static int
911gm20b_clk_new_speedo0(struct nvkm_device *device, int index,
912 struct nvkm_clk **pclk)
52829d4f
AC
913{
914 struct gk20a_clk *clk;
915 int ret;
916
917 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
918 if (!clk)
919 return -ENOMEM;
920 *pclk = &clk->base;
921
3786c415
AC
922 ret = gk20a_clk_ctor(device, index, &gm20b_clk_speedo0,
923 &gm20b_pllg_params, clk);
52829d4f
AC
924
925 clk->pl_to_div = pl_to_div;
926 clk->div_to_pl = div_to_pl;
927
928 return ret;
929}
22b6c9e8
AC
930
931/* FUSE register */
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
943
944static int
945gm20b_clk_init_fused_params(struct gm20b_clk *clk)
946{
947 struct nvkm_subdev *subdev = &clk->base.base.subdev;
948 u32 val = 0;
949 u32 rev = 0;
950
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);
955#endif
956
957 /* No fused parameters, we will calibrate later */
958 if (rev == 0)
959 return -EINVAL;
960
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));
966
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;
972
973 nvkm_debug(subdev, "fused calibration data: slope %d, offs %d\n",
974 clk->uvdet_slope, clk->uvdet_offs);
975 return 0;
976}
977
978static int
979gm20b_clk_init_safe_fmax(struct gm20b_clk *clk)
980{
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;
985 int vmin, id = 0;
986 u32 fmax = 0;
987 int i;
988
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;
995 }
996 }
997
998 /* find max frequency at this voltage */
999 for (i = 0; i < nr_pstates; i++)
1000 if (pstates[i].base.voltage == id)
1001 fmax = max(fmax,
1002 pstates[i].base.domain[nv_clk_src_gpc]);
1003
1004 if (!fmax) {
1005 nvkm_error(subdev, "failed to evaluate safe fmax\n");
1006 return -EINVAL;
1007 }
1008
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);
1012
1013 return 0;
1014}
1015
1016int
1017gm20b_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
1018{
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;
1023 int ret;
1024
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);
1028
1029 /* Speedo >= 1, use NAPLL */
1030 clk = kzalloc(sizeof(*clk) + sizeof(*clk_params), GFP_KERNEL);
1031 if (!clk)
1032 return -ENOMEM;
1033 *pclk = &clk->base.base;
1034 subdev = &clk->base.base.subdev;
1035
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,
1040 &clk->base);
1041 if (ret)
1042 return ret;
1043
1044 /*
1045 * NAPLL can only work with max_u, clamp the m range so
1046 * gk20a_pllg_calc_mnp always uses it
1047 */
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");
1052 kfree(clk);
1053 return gm20b_clk_new_speedo0(device, index, pclk);
1054 }
1055
1056 clk->base.pl_to_div = pl_to_div;
1057 clk->base.div_to_pl = div_to_pl;
1058
1059 clk->dvfs_params = &gm20b_dvfs_params;
1060
1061 ret = gm20b_clk_init_fused_params(clk);
1062 /*
1063 * we will calibrate during init - should never happen on
1064 * prod parts
1065 */
1066 if (ret)
1067 nvkm_warn(subdev, "no fused calibration parameters\n");
1068
1069 ret = gm20b_clk_init_safe_fmax(clk);
1070 if (ret)
1071 return ret;
1072
1073 return 0;
1074}
This page took 0.092983 seconds and 5 git commands to generate.