diff options
author | Deepak Goyal <dgoyal@nvidia.com> | 2017-09-21 04:51:39 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-11-07 00:27:46 -0500 |
commit | 295ade2f1ea76f2cf61ab93465d251cabb681f49 (patch) | |
tree | 4aad59f9a4282e679114cd4855a8aad9f73a8b5f /drivers/gpu/nvgpu/gk20a | |
parent | 973553069dcf4220484e6ea85f35646ab8a12094 (diff) |
gpu: nvgpu: Add elcg/blcg/slcg enabled checks
-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 <dgoyal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1587205
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 62 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 4 |
2 files changed, 42 insertions, 24 deletions
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) | |||
151 | 151 | ||
152 | /* This function must be called with g->dbg_sessions_lock held */ | 152 | /* This function must be called with g->dbg_sessions_lock held */ |
153 | 153 | ||
154 | gk20a_dbg(gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d", | 154 | nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d", |
155 | g->name, powermode); | 155 | g->name, powermode); |
156 | 156 | ||
157 | switch (powermode) { | 157 | switch (powermode) { |
158 | /* | ||
159 | * Powergate mode here refers to railgate+powergate+clockgate | ||
160 | * so in case slcg/blcg/elcg are disabled and railgating is enabled, | ||
161 | * disable railgating and then set is_pg_disabled = true | ||
162 | * Similarly re-enable railgating and not other features if they are not | ||
163 | * enabled when powermode=MODE_ENABLE | ||
164 | */ | ||
158 | case NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE: | 165 | case NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE: |
159 | /* save off current powergate, clk state. | 166 | /* save off current powergate, clk state. |
160 | * set gpu module's can_powergate = 0. | 167 | * set gpu module's can_powergate = 0. |
@@ -171,7 +178,8 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) | |||
171 | if ((dbg_s->is_pg_disabled == false) && | 178 | if ((dbg_s->is_pg_disabled == false) && |
172 | (g->dbg_powergating_disabled_refcount++ == 0)) { | 179 | (g->dbg_powergating_disabled_refcount++ == 0)) { |
173 | 180 | ||
174 | gk20a_dbg(gpu_dbg_gpu_dbg | gpu_dbg_fn, "module busy"); | 181 | nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, |
182 | "module busy"); | ||
175 | err = gk20a_busy(g); | 183 | err = gk20a_busy(g); |
176 | if (err) | 184 | if (err) |
177 | return err; | 185 | return err; |
@@ -181,18 +189,16 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) | |||
181 | 189 | ||
182 | if (g->ops.clock_gating.slcg_gr_load_gating_prod) | 190 | if (g->ops.clock_gating.slcg_gr_load_gating_prod) |
183 | g->ops.clock_gating.slcg_gr_load_gating_prod(g, | 191 | g->ops.clock_gating.slcg_gr_load_gating_prod(g, |
184 | false); | 192 | false); |
185 | if (g->ops.clock_gating.slcg_perf_load_gating_prod) | 193 | if (g->ops.clock_gating.slcg_perf_load_gating_prod) |
186 | g->ops.clock_gating.slcg_perf_load_gating_prod(g, | 194 | g->ops.clock_gating.slcg_perf_load_gating_prod(g, |
187 | false); | 195 | false); |
188 | if (g->ops.clock_gating.slcg_ltc_load_gating_prod) | 196 | if (g->ops.clock_gating.slcg_ltc_load_gating_prod) |
189 | g->ops.clock_gating.slcg_ltc_load_gating_prod(g, | 197 | g->ops.clock_gating.slcg_ltc_load_gating_prod(g, |
190 | false); | 198 | false); |
191 | 199 | ||
192 | gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN); | 200 | gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN); |
193 | g->elcg_enabled = false; | ||
194 | gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN); | 201 | gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN); |
195 | |||
196 | } | 202 | } |
197 | 203 | ||
198 | dbg_s->is_pg_disabled = true; | 204 | dbg_s->is_pg_disabled = true; |
@@ -210,23 +216,33 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) | |||
210 | if (dbg_s->is_pg_disabled && | 216 | if (dbg_s->is_pg_disabled && |
211 | --g->dbg_powergating_disabled_refcount == 0) { | 217 | --g->dbg_powergating_disabled_refcount == 0) { |
212 | 218 | ||
213 | g->elcg_enabled = true; | 219 | if (g->elcg_enabled) |
214 | gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); | 220 | gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); |
215 | gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO); | 221 | |
216 | 222 | if (g->blcg_enabled) | |
217 | if (g->ops.clock_gating.slcg_ltc_load_gating_prod) | 223 | gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO); |
218 | g->ops.clock_gating.slcg_ltc_load_gating_prod(g, | 224 | |
219 | g->slcg_enabled); | 225 | if (g->slcg_enabled) { |
220 | if (g->ops.clock_gating.slcg_perf_load_gating_prod) | 226 | if (g->ops.clock_gating. |
221 | g->ops.clock_gating.slcg_perf_load_gating_prod(g, | 227 | slcg_ltc_load_gating_prod) |
222 | g->slcg_enabled); | 228 | g->ops.clock_gating. |
223 | if (g->ops.clock_gating.slcg_gr_load_gating_prod) | 229 | slcg_ltc_load_gating_prod(g, |
224 | g->ops.clock_gating.slcg_gr_load_gating_prod(g, | 230 | g->slcg_enabled); |
225 | g->slcg_enabled); | 231 | if (g->ops.clock_gating. |
226 | 232 | slcg_perf_load_gating_prod) | |
233 | g->ops.clock_gating. | ||
234 | slcg_perf_load_gating_prod(g, | ||
235 | g->slcg_enabled); | ||
236 | if (g->ops.clock_gating. | ||
237 | slcg_gr_load_gating_prod) | ||
238 | g->ops.clock_gating. | ||
239 | slcg_gr_load_gating_prod(g, | ||
240 | g->slcg_enabled); | ||
241 | } | ||
227 | nvgpu_pmu_pg_global_enable(g, true); | 242 | nvgpu_pmu_pg_global_enable(g, true); |
228 | 243 | ||
229 | gk20a_dbg(gpu_dbg_gpu_dbg | gpu_dbg_fn, "module idle"); | 244 | nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, |
245 | "module idle"); | ||
230 | gk20a_idle(g); | 246 | gk20a_idle(g); |
231 | } | 247 | } |
232 | 248 | ||
@@ -241,7 +257,7 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) | |||
241 | break; | 257 | break; |
242 | } | 258 | } |
243 | 259 | ||
244 | gk20a_dbg(gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d done", | 260 | nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %d done", |
245 | g->name, powermode); | 261 | g->name, powermode); |
246 | return err; | 262 | return err; |
247 | } | 263 | } |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index f7db1ffa..3875ec5c 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -4170,7 +4170,9 @@ void gr_gk20a_init_cg_mode(struct gk20a *g, u32 cgmode, u32 mode_config) | |||
4170 | g->ops.gr.init_elcg_mode(g, mode_config, | 4170 | g->ops.gr.init_elcg_mode(g, mode_config, |
4171 | active_engine_id); | 4171 | active_engine_id); |
4172 | else | 4172 | else |
4173 | nvgpu_err(g, "invalid cg mode %d %d", cgmode, mode_config); | 4173 | nvgpu_err(g, "invalid cg mode %d, config %d for " |
4174 | "act_eng_id %d", | ||
4175 | cgmode, mode_config, active_engine_id); | ||
4174 | } | 4176 | } |
4175 | } | 4177 | } |
4176 | 4178 | ||