summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2018-06-18 15:04:13 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-20 02:40:49 -0400
commit06ceff1240902c7f4cdb01dcbc9c988fc5fd9495 (patch)
tree3dd1b088f7df458119cc8e7f00f75466a04f2d33 /drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
parent52f1ab0372af3907364dea8b9ff3d25eaa4cbd7f (diff)
gpu: nvgpu: PG refcount check moved to a wrapper function.
Moved PG refcount checking to a wrapper function, this function manages the refcount and decides whether to call dbg_set_powergate function. Instead of checking the dbg_s->is_pg_disabled variable, code is checking g->dbg_powergating_disabled_refcount variable to know if powergate is disabled or not. Updating hwpm ctxsw mode without disabling powergate will result in priv errors. Bug 200410871 Bug 2109765 Change-Id: I33c9022cb04cd39249c78e72584dfe6afb7212d0 Signed-off-by: Vinod G <vinodg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1753550 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c142
1 files changed, 78 insertions, 64 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index 97de7138..ddf2039b 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -169,6 +169,36 @@ int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch)
169 return 0; 169 return 0;
170} 170}
171 171
172u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s,
173 bool mode)
174{
175 u32 err = 0U;
176 struct gk20a *g = dbg_s->g;
177
178 if (dbg_s->is_pg_disabled != mode) {
179 if (mode == false) {
180 g->dbg_powergating_disabled_refcount--;
181 }
182
183 /*
184 * Allow powergate disable or enable only if
185 * the global pg disabled refcount is zero
186 */
187 if (g->dbg_powergating_disabled_refcount == 0) {
188 err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s,
189 mode);
190 }
191
192 if (mode) {
193 g->dbg_powergating_disabled_refcount++;
194 }
195
196 dbg_s->is_pg_disabled = mode;
197 }
198
199 return err;
200}
201
172int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate) 202int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
173{ 203{
174 int err = 0; 204 int err = 0;
@@ -194,36 +224,28 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
194 * clocking state changes allowed from mainline code (but they 224 * clocking state changes allowed from mainline code (but they
195 * should be saved). 225 * should be saved).
196 */ 226 */
197 /* Allow powergate disable if the current dbg_session doesn't
198 * call a powergate disable ioctl and the global
199 * powergating_disabled_refcount is zero
200 */
201 227
202 if ((dbg_s->is_pg_disabled == false) && 228 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
203 (g->dbg_powergating_disabled_refcount++ == 0)) { 229 "module busy");
204 230 err = gk20a_busy(g);
205 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, 231 if (err)
206 "module busy"); 232 return err;
207 err = gk20a_busy(g); 233
208 if (err) 234 /*do elpg disable before clock gating */
209 return err; 235 nvgpu_pmu_pg_global_enable(g, false);
210 236
211 /*do elpg disable before clock gating */ 237 if (g->ops.clock_gating.slcg_gr_load_gating_prod)
212 nvgpu_pmu_pg_global_enable(g, false); 238 g->ops.clock_gating.slcg_gr_load_gating_prod(g,
213 239 false);
214 if (g->ops.clock_gating.slcg_gr_load_gating_prod) 240 if (g->ops.clock_gating.slcg_perf_load_gating_prod)
215 g->ops.clock_gating.slcg_gr_load_gating_prod(g, 241 g->ops.clock_gating.slcg_perf_load_gating_prod(g,
216 false); 242 false);
217 if (g->ops.clock_gating.slcg_perf_load_gating_prod) 243 if (g->ops.clock_gating.slcg_ltc_load_gating_prod)
218 g->ops.clock_gating.slcg_perf_load_gating_prod(g, 244 g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
219 false); 245 false);
220 if (g->ops.clock_gating.slcg_ltc_load_gating_prod) 246
221 g->ops.clock_gating.slcg_ltc_load_gating_prod(g, 247 gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN);
222 false); 248 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
223
224 gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN);
225 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
226 }
227 249
228 dbg_s->is_pg_disabled = true; 250 dbg_s->is_pg_disabled = true;
229 } else { 251 } else {
@@ -231,42 +253,34 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
231 /* release pending exceptions to fault/be handled as usual */ 253 /* release pending exceptions to fault/be handled as usual */
232 /*TBD: ordering of these? */ 254 /*TBD: ordering of these? */
233 255
234 /* Re-enabling powergate as no other sessions want 256 if (g->elcg_enabled)
235 * powergate disabled and the current dbg-sessions had 257 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
236 * requested the powergate disable through ioctl 258
237 */ 259 if (g->blcg_enabled)
238 if (dbg_s->is_pg_disabled && 260 gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO);
239 --g->dbg_powergating_disabled_refcount == 0) { 261
240 262 if (g->slcg_enabled) {
241 if (g->elcg_enabled) 263 if (g->ops.clock_gating.
242 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO); 264 slcg_ltc_load_gating_prod)
243 265 g->ops.clock_gating.
244 if (g->blcg_enabled) 266 slcg_ltc_load_gating_prod(g,
245 gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO); 267 g->slcg_enabled);
246 268 if (g->ops.clock_gating.
247 if (g->slcg_enabled) { 269 slcg_perf_load_gating_prod)
248 if (g->ops.clock_gating. 270 g->ops.clock_gating.
249 slcg_ltc_load_gating_prod) 271 slcg_perf_load_gating_prod(g,
250 g->ops.clock_gating. 272 g->slcg_enabled);
251 slcg_ltc_load_gating_prod(g, 273 if (g->ops.clock_gating.
252 g->slcg_enabled); 274 slcg_gr_load_gating_prod)
253 if (g->ops.clock_gating. 275 g->ops.clock_gating.
254 slcg_perf_load_gating_prod) 276 slcg_gr_load_gating_prod(g,
255 g->ops.clock_gating. 277 g->slcg_enabled);
256 slcg_perf_load_gating_prod(g,
257 g->slcg_enabled);
258 if (g->ops.clock_gating.
259 slcg_gr_load_gating_prod)
260 g->ops.clock_gating.
261 slcg_gr_load_gating_prod(g,
262 g->slcg_enabled);
263 }
264 nvgpu_pmu_pg_global_enable(g, true);
265
266 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
267 "module idle");
268 gk20a_idle(g);
269 } 278 }
279 nvgpu_pmu_pg_global_enable(g, true);
280
281 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
282 "module idle");
283 gk20a_idle(g);
270 284
271 dbg_s->is_pg_disabled = false; 285 dbg_s->is_pg_disabled = false;
272 } 286 }