diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 23a014d7..b025f4d6 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -39,6 +39,7 @@ | |||
39 | static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, | 39 | static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, |
40 | u32 hw_chid, bool add, | 40 | u32 hw_chid, bool add, |
41 | bool wait_for_finish); | 41 | bool wait_for_finish); |
42 | static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg); | ||
42 | 43 | ||
43 | u32 gk20a_fifo_get_engine_ids(struct gk20a *g, | 44 | u32 gk20a_fifo_get_engine_ids(struct gk20a *g, |
44 | u32 engine_id[], u32 engine_id_sz, | 45 | u32 engine_id[], u32 engine_id_sz, |
@@ -1269,6 +1270,42 @@ void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid, bool preempt) | |||
1269 | mutex_unlock(&tsg->ch_list_lock); | 1270 | mutex_unlock(&tsg->ch_list_lock); |
1270 | } | 1271 | } |
1271 | 1272 | ||
1273 | int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch) | ||
1274 | { | ||
1275 | u32 engine_id, engines; | ||
1276 | |||
1277 | mutex_lock(&g->dbg_sessions_lock); | ||
1278 | gr_gk20a_disable_ctxsw(g); | ||
1279 | |||
1280 | if (!g->fifo.deferred_reset_pending) | ||
1281 | goto clean_up; | ||
1282 | |||
1283 | if (gk20a_is_channel_marked_as_tsg(ch)) | ||
1284 | engines = gk20a_fifo_engines_on_id(g, ch->tsgid, true); | ||
1285 | else | ||
1286 | engines = gk20a_fifo_engines_on_id(g, ch->hw_chid, false); | ||
1287 | if (!engines) | ||
1288 | goto clean_up; | ||
1289 | |||
1290 | /* | ||
1291 | * If deferred reset is set for an engine, and channel is running | ||
1292 | * on that engine, reset it | ||
1293 | */ | ||
1294 | for_each_set_bit(engine_id, &g->fifo.deferred_fault_engines, 32) { | ||
1295 | if (BIT(engine_id) & engines) | ||
1296 | gk20a_fifo_reset_engine(g, engine_id); | ||
1297 | } | ||
1298 | |||
1299 | g->fifo.deferred_fault_engines = 0; | ||
1300 | g->fifo.deferred_reset_pending = false; | ||
1301 | |||
1302 | clean_up: | ||
1303 | gr_gk20a_enable_ctxsw(g); | ||
1304 | mutex_unlock(&g->dbg_sessions_lock); | ||
1305 | |||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1272 | static bool gk20a_fifo_handle_mmu_fault( | 1309 | static bool gk20a_fifo_handle_mmu_fault( |
1273 | struct gk20a *g, | 1310 | struct gk20a *g, |
1274 | u32 mmu_fault_engines, /* queried from HW if 0 */ | 1311 | u32 mmu_fault_engines, /* queried from HW if 0 */ |
@@ -1403,7 +1440,7 @@ static bool gk20a_fifo_handle_mmu_fault( | |||
1403 | /* check if engine reset should be deferred */ | 1440 | /* check if engine reset should be deferred */ |
1404 | if ((ch || tsg) && gk20a_fifo_should_defer_engine_reset(g, | 1441 | if ((ch || tsg) && gk20a_fifo_should_defer_engine_reset(g, |
1405 | engine_id, &f, fake_fault)) { | 1442 | engine_id, &f, fake_fault)) { |
1406 | g->fifo.deferred_fault_engines = fault_id; | 1443 | g->fifo.deferred_fault_engines |= BIT(engine_id); |
1407 | 1444 | ||
1408 | /* handled during channel free */ | 1445 | /* handled during channel free */ |
1409 | g->fifo.deferred_reset_pending = true; | 1446 | g->fifo.deferred_reset_pending = true; |