diff options
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk.c')
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk.c | 136 |
1 files changed, 63 insertions, 73 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk.c b/drivers/gpu/nvgpu/clk/clk.c index bec5fad1..07c80e22 100644 --- a/drivers/gpu/nvgpu/clk/clk.c +++ b/drivers/gpu/nvgpu/clk/clk.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "volt/volt.h" | 20 | #include "volt/volt.h" |
21 | #include "gk20a/pmu_gk20a.h" | 21 | #include "gk20a/pmu_gk20a.h" |
22 | 22 | ||
23 | #define BOOT_GPC2CLK_MHZ 2581 | ||
23 | #define BOOT_MCLK_MHZ 3003 | 24 | #define BOOT_MCLK_MHZ 3003 |
24 | 25 | ||
25 | struct clkrpc_pmucmdhandler_params { | 26 | struct clkrpc_pmucmdhandler_params { |
@@ -255,7 +256,61 @@ static int get_regime_id(struct gk20a *g, u32 domain, u32 *regimeid) | |||
255 | return -EINVAL; | 256 | return -EINVAL; |
256 | } | 257 | } |
257 | 258 | ||
258 | int clk_program_fll_clks(struct gk20a *g, struct change_fll_clk *fllclk) | 259 | int clk_set_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk) |
260 | { | ||
261 | int status = -EINVAL; | ||
262 | |||
263 | /*set regime ids */ | ||
264 | status = get_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, | ||
265 | &setfllclk->current_regime_id_gpc); | ||
266 | if (status) | ||
267 | goto done; | ||
268 | |||
269 | setfllclk->target_regime_id_gpc = find_regime_id(g, | ||
270 | CTRL_CLK_DOMAIN_GPC2CLK, setfllclk->gpc2clkmhz); | ||
271 | |||
272 | status = get_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, | ||
273 | &setfllclk->current_regime_id_sys); | ||
274 | if (status) | ||
275 | goto done; | ||
276 | |||
277 | setfllclk->target_regime_id_sys = find_regime_id(g, | ||
278 | CTRL_CLK_DOMAIN_SYS2CLK, setfllclk->sys2clkmhz); | ||
279 | |||
280 | status = get_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, | ||
281 | &setfllclk->current_regime_id_xbar); | ||
282 | if (status) | ||
283 | goto done; | ||
284 | |||
285 | setfllclk->target_regime_id_xbar = find_regime_id(g, | ||
286 | CTRL_CLK_DOMAIN_XBAR2CLK, setfllclk->xbar2clkmhz); | ||
287 | |||
288 | status = clk_pmu_vf_inject(g, setfllclk); | ||
289 | |||
290 | if (status) | ||
291 | gk20a_err(dev_from_gk20a(g), | ||
292 | "vf inject to change clk failed"); | ||
293 | |||
294 | /* save regime ids */ | ||
295 | status = set_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, | ||
296 | setfllclk->target_regime_id_xbar); | ||
297 | if (status) | ||
298 | goto done; | ||
299 | |||
300 | status = set_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, | ||
301 | setfllclk->target_regime_id_gpc); | ||
302 | if (status) | ||
303 | goto done; | ||
304 | |||
305 | status = set_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, | ||
306 | setfllclk->target_regime_id_sys); | ||
307 | if (status) | ||
308 | goto done; | ||
309 | done: | ||
310 | return status; | ||
311 | } | ||
312 | |||
313 | int clk_get_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk) | ||
259 | { | 314 | { |
260 | int status = -EINVAL; | 315 | int status = -EINVAL; |
261 | struct clk_domain *pdomain; | 316 | struct clk_domain *pdomain; |
@@ -265,25 +320,14 @@ int clk_program_fll_clks(struct gk20a *g, struct change_fll_clk *fllclk) | |||
265 | struct clk_domain_3x_master *p3xmaster; | 320 | struct clk_domain_3x_master *p3xmaster; |
266 | struct clk_domain_3x_slave *p3xslave; | 321 | struct clk_domain_3x_slave *p3xslave; |
267 | unsigned long slaveidxmask; | 322 | unsigned long slaveidxmask; |
268 | struct set_fll_clk setfllclk; | ||
269 | bool foundxbar2clk = false; | ||
270 | bool foundsys2clk = false; | ||
271 | 323 | ||
272 | memset(&setfllclk, 0, sizeof(setfllclk)); | 324 | if (setfllclk->gpc2clkmhz == 0) |
273 | if (fllclk->api_clk_domain != CTRL_CLK_DOMAIN_GPC2CLK) | ||
274 | return -EINVAL; | ||
275 | if (fllclk->voltuv == 0) | ||
276 | return -EINVAL; | 325 | return -EINVAL; |
277 | if (fllclk->clkmhz == 0) | ||
278 | return -EINVAL; | ||
279 | |||
280 | setfllclk.voltuv = fllclk->voltuv; | ||
281 | setfllclk.gpc2clkmhz = fllclk->clkmhz; | ||
282 | 326 | ||
283 | BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), | 327 | BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super), |
284 | struct clk_domain *, pdomain, i) { | 328 | struct clk_domain *, pdomain, i) { |
285 | 329 | ||
286 | if (pdomain->api_domain == fllclk->api_clk_domain) { | 330 | if (pdomain->api_domain == CTRL_CLK_DOMAIN_GPC2CLK) { |
287 | 331 | ||
288 | if (!pdomain->super.implements(g, &pdomain->super, | 332 | if (!pdomain->super.implements(g, &pdomain->super, |
289 | CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { | 333 | CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) { |
@@ -305,74 +349,20 @@ int clk_program_fll_clks(struct gk20a *g, struct change_fll_clk *fllclk) | |||
305 | pclk, | 349 | pclk, |
306 | (struct clk_domain *)p3xslave, | 350 | (struct clk_domain *)p3xslave, |
307 | &clkmhz, | 351 | &clkmhz, |
308 | fllclk->clkmhz); | 352 | setfllclk->gpc2clkmhz); |
309 | if (status) { | 353 | if (status) { |
310 | status = -EINVAL; | 354 | status = -EINVAL; |
311 | goto done; | 355 | goto done; |
312 | } | 356 | } |
313 | if (p3xslave->super.super.super.api_domain == | 357 | if (p3xslave->super.super.super.api_domain == |
314 | CTRL_CLK_DOMAIN_XBAR2CLK) { | 358 | CTRL_CLK_DOMAIN_XBAR2CLK) |
315 | setfllclk.xbar2clkmhz = clkmhz; | 359 | setfllclk->xbar2clkmhz = clkmhz; |
316 | foundxbar2clk = true; | ||
317 | } | ||
318 | if (p3xslave->super.super.super.api_domain == | 360 | if (p3xslave->super.super.super.api_domain == |
319 | CTRL_CLK_DOMAIN_SYS2CLK) { | 361 | CTRL_CLK_DOMAIN_SYS2CLK) |
320 | setfllclk.sys2clkmhz = clkmhz; | 362 | setfllclk->sys2clkmhz = clkmhz; |
321 | foundsys2clk = true; | ||
322 | } | ||
323 | } | 363 | } |
324 | } | 364 | } |
325 | } | 365 | } |
326 | if (!(foundxbar2clk && foundsys2clk)) { | ||
327 | status = -EINVAL; | ||
328 | goto done; | ||
329 | } | ||
330 | /*set regime ids */ | ||
331 | status = get_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, | ||
332 | &setfllclk.current_regime_id_gpc); | ||
333 | if (status) | ||
334 | goto done; | ||
335 | |||
336 | setfllclk.target_regime_id_gpc = find_regime_id(g, | ||
337 | CTRL_CLK_DOMAIN_GPC2CLK, setfllclk.gpc2clkmhz); | ||
338 | |||
339 | status = get_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, | ||
340 | &setfllclk.current_regime_id_sys); | ||
341 | if (status) | ||
342 | goto done; | ||
343 | |||
344 | setfllclk.target_regime_id_sys = find_regime_id(g, | ||
345 | CTRL_CLK_DOMAIN_SYS2CLK, setfllclk.sys2clkmhz); | ||
346 | |||
347 | status = get_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, | ||
348 | &setfllclk.current_regime_id_xbar); | ||
349 | if (status) | ||
350 | goto done; | ||
351 | |||
352 | setfllclk.target_regime_id_xbar = find_regime_id(g, | ||
353 | CTRL_CLK_DOMAIN_XBAR2CLK, setfllclk.xbar2clkmhz); | ||
354 | |||
355 | status = clk_pmu_vf_inject(g, &setfllclk); | ||
356 | |||
357 | if (status) | ||
358 | gk20a_err(dev_from_gk20a(g), | ||
359 | "vf inject to change clk failed"); | ||
360 | |||
361 | /* save regime ids */ | ||
362 | status = set_regime_id(g, CTRL_CLK_DOMAIN_XBAR2CLK, | ||
363 | setfllclk.target_regime_id_xbar); | ||
364 | if (status) | ||
365 | goto done; | ||
366 | |||
367 | status = set_regime_id(g, CTRL_CLK_DOMAIN_GPC2CLK, | ||
368 | setfllclk.target_regime_id_gpc); | ||
369 | if (status) | ||
370 | goto done; | ||
371 | |||
372 | status = set_regime_id(g, CTRL_CLK_DOMAIN_SYS2CLK, | ||
373 | setfllclk.target_regime_id_sys); | ||
374 | if (status) | ||
375 | goto done; | ||
376 | done: | 366 | done: |
377 | return status; | 367 | return status; |
378 | } | 368 | } |