summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk.c
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2016-10-07 19:25:04 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:52 -0500
commitc4bb19d46e1c9121a0948fa506098cbf2f64e2a6 (patch)
tree29647922e8374377c05ab976c7616410d85eda4d /drivers/gpu/nvgpu/clk/clk.c
parentbfc12d25a41c2b5a4d06f233f16331e43c489d8e (diff)
nvgpu: gpu: arbiter for vf switch management
JIRA DNVGPU-143 The arbiter is charged with selecting the proper frequencies when multiple applications submit simultaneously clock change requests On the current implementation, the arbiter guarantees that the selected frequency will be always higher or equal to the request, as long as the request is in range. The current code is not yet realtime friendly, as requests are not pre-allocated. Summary of changes: (1) pstate/vf switch no longer selects boot frequency (2) changed mclk code change to accept input freq (3) added arbiter (4) now a single session can submit concurrent requests the last request is the one that applies for that session (5) modified locking mechanism to reduce lock contention (6) Added callback to notify the arbiter that the VF table has changed and is no longer valid (PMU/Thermals must call this when VF table is invalid) (7) changed internal API to work with MHz (8) added debugfs for stats Change-Id: I6a7b05c9447761e8536f84ef86b5ab0793164d63 Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1239461 Reviewed-by: Thomas Fleury <tfleury@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1267120 Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk.c61
1 files changed, 1 insertions, 60 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk.c b/drivers/gpu/nvgpu/clk/clk.c
index ef0834f4..bec5fad1 100644
--- a/drivers/gpu/nvgpu/clk/clk.c
+++ b/drivers/gpu/nvgpu/clk/clk.c
@@ -255,7 +255,7 @@ static int get_regime_id(struct gk20a *g, u32 domain, u32 *regimeid)
255 return -EINVAL; 255 return -EINVAL;
256} 256}
257 257
258int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk) 258int clk_program_fll_clks(struct gk20a *g, struct change_fll_clk *fllclk)
259{ 259{
260 int status = -EINVAL; 260 int status = -EINVAL;
261 struct clk_domain *pdomain; 261 struct clk_domain *pdomain;
@@ -277,8 +277,6 @@ int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk)
277 if (fllclk->clkmhz == 0) 277 if (fllclk->clkmhz == 0)
278 return -EINVAL; 278 return -EINVAL;
279 279
280 mutex_lock(&pclk->changeclkmutex);
281
282 setfllclk.voltuv = fllclk->voltuv; 280 setfllclk.voltuv = fllclk->voltuv;
283 setfllclk.gpc2clkmhz = fllclk->clkmhz; 281 setfllclk.gpc2clkmhz = fllclk->clkmhz;
284 282
@@ -376,63 +374,6 @@ int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk)
376 if (status) 374 if (status)
377 goto done; 375 goto done;
378done: 376done:
379 mutex_unlock(&pclk->changeclkmutex);
380 return status;
381}
382
383int clk_set_boot_fll_clk(struct gk20a *g)
384{
385 int status;
386 struct change_fll_clk bootfllclk;
387 u16 gpc2clk_clkmhz = BOOT_GPC2CLK_MHZ;
388 u32 gpc2clk_voltuv = 0;
389 u32 gpc2clk_voltuv_sram = 0;
390 u16 mclk_clkmhz = BOOT_MCLK_MHZ;
391 u32 mclk_voltuv = 0;
392 u32 mclk_voltuv_sram = 0;
393 u32 voltuv = 0;
394 u32 voltuv_sram = 0;
395
396 mutex_init(&g->clk_pmu.changeclkmutex);
397 status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPC2CLK,
398 &gpc2clk_clkmhz, &gpc2clk_voltuv, CTRL_VOLT_DOMAIN_LOGIC);
399 if (status)
400 return status;
401 status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPC2CLK,
402 &gpc2clk_clkmhz, &gpc2clk_voltuv_sram, CTRL_VOLT_DOMAIN_SRAM);
403 if (status)
404 return status;
405 status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_MCLK,
406 &mclk_clkmhz, &mclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC);
407 if (status)
408 return status;
409 status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_MCLK,
410 &mclk_clkmhz, &mclk_voltuv_sram, CTRL_VOLT_DOMAIN_SRAM);
411 if (status)
412 return status;
413
414 voltuv = ((gpc2clk_voltuv) > (mclk_voltuv)) ? (gpc2clk_voltuv)
415 : (mclk_voltuv);
416
417 voltuv_sram = ((gpc2clk_voltuv_sram) > (mclk_voltuv_sram)) ?
418 (gpc2clk_voltuv_sram) : (mclk_voltuv_sram);
419
420 status = volt_set_voltage(g, voltuv, voltuv_sram);
421 if (status)
422 gk20a_err(dev_from_gk20a(g),
423 "attempt to set boot voltage failed %d %d",
424 voltuv, voltuv_sram);
425
426 bootfllclk.api_clk_domain = CTRL_CLK_DOMAIN_GPC2CLK;
427 bootfllclk.clkmhz = gpc2clk_clkmhz;
428 bootfllclk.voltuv = voltuv;
429 status = clk_program_fllclks(g, &bootfllclk);
430 if (status)
431 gk20a_err(dev_from_gk20a(g), "attempt to set boot gpc2clk failed");
432 status = g->clk_pmu.clk_mclk.change(g, DEFAULT_BOOT_MCLK_SPEED);
433 if (status)
434 gk20a_err(dev_from_gk20a(g), "attempt to set boot mclk failed");
435
436 return status; 377 return status;
437} 378}
438 379