From 295ade2f1ea76f2cf61ab93465d251cabb681f49 Mon Sep 17 00:00:00 2001 From: Deepak Goyal Date: Thu, 21 Sep 2017 14:21:39 +0530 Subject: gpu: nvgpu: Add elcg/blcg/slcg enabled checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Power features should be enabled only if s/w flags xxcg_enabled are set for corresponding features. These flags control whether feature should be kept disabled in the hardware or not. For disable case, register programming will happen for CG registers and they will be set to disabled. For ELPG, init command will be sent to PMU, but “ELPG_ALLOW” will not be sent to PMU. Also these flags can be modified using sysfs. These flags are noop if corresponding can_xxxg flags are set to flase. S/w flags can_xxxg tell the ability of platform to support a power feature and cannot be modified by syfs. Setting these flags to false will avoid any HW register write or init sequence for the power feature from executing. For ELPG, no commands will be sent to PMU. -g->elcg_enabled flag should not be modified here. It should be modified only by sysfs. This will be cleaned up in follow up implementation where debug session will have some kind of lock where it will keep power features disabled as long as it wants to. Debugger cannot rely on this flag to keep power management disabled as these flags can be changed from sysfs. Due to this issue someone can easily break debugging session by accidentally changing something in sysfs. Proper fix for this is being tracked in NVGPU-320 Bug 1982434 Change-Id: I660ef02491f4df9910bf4dea3561ac8a0838e1b1 Signed-off-by: Deepak Goyal Reviewed-on: https://git-master.nvidia.com/r/1587205 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 62 +++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index f70cfdf8..6645e21f 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -151,10 +151,17 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) /* This function must be called with g->dbg_sessions_lock held */ - gk20a_dbg(gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d", + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d", g->name, powermode); switch (powermode) { + /* + * Powergate mode here refers to railgate+powergate+clockgate + * so in case slcg/blcg/elcg are disabled and railgating is enabled, + * disable railgating and then set is_pg_disabled = true + * Similarly re-enable railgating and not other features if they are not + * enabled when powermode=MODE_ENABLE + */ case NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE: /* save off current powergate, clk state. * set gpu module's can_powergate = 0. @@ -171,7 +178,8 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) if ((dbg_s->is_pg_disabled == false) && (g->dbg_powergating_disabled_refcount++ == 0)) { - gk20a_dbg(gpu_dbg_gpu_dbg | gpu_dbg_fn, "module busy"); + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, + "module busy"); err = gk20a_busy(g); if (err) return err; @@ -181,18 +189,16 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) if (g->ops.clock_gating.slcg_gr_load_gating_prod) g->ops.clock_gating.slcg_gr_load_gating_prod(g, - false); + false); if (g->ops.clock_gating.slcg_perf_load_gating_prod) g->ops.clock_gating.slcg_perf_load_gating_prod(g, - false); + false); if (g->ops.clock_gating.slcg_ltc_load_gating_prod) g->ops.clock_gating.slcg_ltc_load_gating_prod(g, - false); + false); gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN); - g->elcg_enabled = false; gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN); - } dbg_s->is_pg_disabled = true; @@ -210,23 +216,33 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) if (dbg_s->is_pg_disabled && --g->dbg_powergating_disabled_refcount == 0) { - g->elcg_enabled = true; - gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); - gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO); - - if (g->ops.clock_gating.slcg_ltc_load_gating_prod) - g->ops.clock_gating.slcg_ltc_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_perf_load_gating_prod) - g->ops.clock_gating.slcg_perf_load_gating_prod(g, - g->slcg_enabled); - if (g->ops.clock_gating.slcg_gr_load_gating_prod) - g->ops.clock_gating.slcg_gr_load_gating_prod(g, - g->slcg_enabled); - + if (g->elcg_enabled) + gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); + + if (g->blcg_enabled) + gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO); + + if (g->slcg_enabled) { + if (g->ops.clock_gating. + slcg_ltc_load_gating_prod) + g->ops.clock_gating. + slcg_ltc_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating. + slcg_perf_load_gating_prod) + g->ops.clock_gating. + slcg_perf_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating. + slcg_gr_load_gating_prod) + g->ops.clock_gating. + slcg_gr_load_gating_prod(g, + g->slcg_enabled); + } nvgpu_pmu_pg_global_enable(g, true); - gk20a_dbg(gpu_dbg_gpu_dbg | gpu_dbg_fn, "module idle"); + nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, + "module idle"); gk20a_idle(g); } @@ -241,7 +257,7 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) break; } - gk20a_dbg(gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d done", + nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d done", g->name, powermode); return err; } -- cgit v1.2.2