summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk.c
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2016-11-04 01:01:32 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:52 -0500
commit2f258670e40be1c92ab57b6fe77908add768ad9d (patch)
tree77e4fe65923a4e6667ac6956d1e2de158655c5e8 /drivers/gpu/nvgpu/clk/clk.c
parent2ebf09920755daeb7e1be71bf317f88ec9d533e1 (diff)
gpu: nvgpu: p-state bound arbiter
Modification of the ARBITER clocks to be P-State aware Up to now the arbiter just considered the whole range of the GPC and MCLK domains, which could end up on illegal combinations of MCLK, GPC2CLK, and set the SYSCLK and XBARCLK domains below their minimum VCO The following has been implemented: (1) Modified VF tables to add which PState are supported on each point. (2) Return and store the current PState on the arbiter state. (3) Modified logic to prevent illegal combinations of MCLK and GPC2CLK. (4) Modified logic to prevent setting VF points for XBAR and SYS domains below VCO limits. (5) Modified voltage calculation to account for increased values of XBAR and SYS on some VF points. (6) Modified arbiter clock target logic to prevent an application that has not requested a particular VF point to set target to default targets. (7) Remove unnecesary mutexes from critical path JIRA DNVGPU-182 JIRA DNVGPU-183 Change-Id: I3d1c30903278f848681b8da833a867835acc99bb Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1247937 (cherry picked from commit b8bcc07eb3b5b70ec1ee19ace237df99d6170138) Reviewed-on: http://git-master/r/1268063 Tested-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk.c136
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
25struct clkrpc_pmucmdhandler_params { 26struct 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
258int clk_program_fll_clks(struct gk20a *g, struct change_fll_clk *fllclk) 259int 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;
309done:
310 return status;
311}
312
313int 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;
376done: 366done:
377 return status; 367 return status;
378} 368}