summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b/fifo_gv11b.c')
-rw-r--r--drivers/gpu/nvgpu/gv11b/fifo_gv11b.c149
1 files changed, 77 insertions, 72 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
index 8f0f6b0c..6df1d343 100644
--- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
@@ -652,29 +652,19 @@ static void gv11b_reset_pbdma_faulted_tsg(struct tsg_gk20a *tsg)
652} 652}
653 653
654void gv11b_fifo_reset_pbdma_and_eng_faulted(struct gk20a *g, 654void gv11b_fifo_reset_pbdma_and_eng_faulted(struct gk20a *g,
655 struct channel_gk20a *refch, 655 struct tsg_gk20a *tsg,
656 u32 faulted_pbdma, u32 faulted_engine) 656 u32 faulted_pbdma, u32 faulted_engine)
657{ 657{
658 struct tsg_gk20a *tsg; 658 if (!tsg)
659 return;
659 660
660 nvgpu_log(g, gpu_dbg_intr, "reset faulted pbdma:0x%x eng:0x%x", 661 nvgpu_log(g, gpu_dbg_intr, "reset faulted pbdma:0x%x eng:0x%x",
661 faulted_pbdma, faulted_engine); 662 faulted_pbdma, faulted_engine);
662 663
663 if (!refch) 664 if (faulted_pbdma != FIFO_INVAL_PBDMA_ID)
664 return; 665 gv11b_reset_pbdma_faulted_tsg(tsg);
665 666 if (faulted_engine != FIFO_INVAL_ENGINE_ID)
666 if (gk20a_is_channel_marked_as_tsg(refch)) { 667 gv11b_reset_eng_faulted_tsg(tsg);
667 tsg = &g->fifo.tsg[refch->tsgid];
668 if (faulted_pbdma != FIFO_INVAL_PBDMA_ID)
669 gv11b_reset_pbdma_faulted_tsg(tsg);
670 if (faulted_engine != FIFO_INVAL_ENGINE_ID)
671 gv11b_reset_eng_faulted_tsg(tsg);
672 } else {
673 if (faulted_pbdma != FIFO_INVAL_PBDMA_ID)
674 gv11b_reset_pbdma_faulted_ch(g, refch->chid);
675 if (faulted_engine != FIFO_INVAL_ENGINE_ID)
676 gv11b_reset_eng_faulted_ch(g, refch->chid);
677 }
678} 668}
679 669
680static u32 gv11b_fifo_get_runlists_mask(struct gk20a *g, u32 act_eng_bitmask, 670static u32 gv11b_fifo_get_runlists_mask(struct gk20a *g, u32 act_eng_bitmask,
@@ -992,12 +982,74 @@ int gv11b_fifo_preempt_ch_tsg(struct gk20a *g, u32 id,
992 982
993} 983}
994 984
985static void gv11b_fifo_locked_abort_runlist_active_tsgs(struct gk20a *g,
986 unsigned int rc_type,
987 u32 runlists_mask)
988{
989 bool verbose = false;
990 struct tsg_gk20a *tsg = NULL;
991 u32 rlid, tsgid;
992 struct fifo_runlist_info_gk20a *runlist = NULL;
993 u32 token = PMU_INVALID_MUTEX_OWNER_ID;
994 u32 mutex_ret = 0;
995 bool add = false, wait_for_finish = false;
996 int err;
997
998 nvgpu_err(g, "runlist id unknown, abort active tsgs in runlists");
999
1000 /* runlist_lock are locked by teardown */
1001 mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1002
1003 for (rlid = 0; rlid < g->fifo.max_runlists;
1004 rlid++) {
1005 if (!(runlists_mask & BIT(rlid)))
1006 continue;
1007 nvgpu_log(g, gpu_dbg_info, "abort runlist id %d",
1008 rlid);
1009 runlist = &g->fifo.runlist_info[rlid];
1010
1011 for_each_set_bit(tsgid, runlist->active_tsgs,
1012 g->fifo.num_channels) {
1013 nvgpu_log(g, gpu_dbg_info, "abort tsg id %d", tsgid);
1014 tsg = &g->fifo.tsg[tsgid];
1015 gk20a_disable_tsg(tsg);
1016
1017 /* assume all pbdma and eng faulted are set */
1018 nvgpu_log(g, gpu_dbg_info, "reset pbdma and eng faulted");
1019 gv11b_reset_pbdma_faulted_tsg(tsg);
1020 gv11b_reset_eng_faulted_tsg(tsg);
1021
1022#ifdef CONFIG_GK20A_CTXSW_TRACE
1023 gk20a_ctxsw_trace_tsg_reset(g, tsg);
1024#endif
1025 if (!g->fifo.deferred_reset_pending) {
1026 if (rc_type == RC_TYPE_MMU_FAULT) {
1027 gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg);
1028 verbose = gk20a_fifo_error_tsg(g, tsg);
1029 }
1030 }
1031
1032 /* (chid == ~0 && !add) remove all act ch from runlist*/
1033 err = gk20a_fifo_update_runlist_locked(g, rlid,
1034 FIFO_INVAL_CHANNEL_ID, add, wait_for_finish);
1035 if (err)
1036 nvgpu_err(g, "runlist id %d is not cleaned up",
1037 rlid);
1038
1039 gk20a_fifo_abort_tsg(g, tsg->tsgid, false);
1040
1041 nvgpu_log(g, gpu_dbg_info, "aborted tsg id %d", tsgid);
1042 }
1043 }
1044 if (!mutex_ret)
1045 nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token);
1046}
1047
995void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask, 1048void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
996 u32 id, unsigned int id_type, unsigned int rc_type, 1049 u32 id, unsigned int id_type, unsigned int rc_type,
997 struct mmu_fault_info *mmfault) 1050 struct mmu_fault_info *mmfault)
998{ 1051{
999 struct tsg_gk20a *tsg = NULL; 1052 struct tsg_gk20a *tsg = NULL;
1000 struct channel_gk20a *refch = NULL;
1001 u32 runlists_mask, rlid; 1053 u32 runlists_mask, rlid;
1002 struct fifo_runlist_info_gk20a *runlist = NULL; 1054 struct fifo_runlist_info_gk20a *runlist = NULL;
1003 u32 engine_id, client_type = ~0; 1055 u32 engine_id, client_type = ~0;
@@ -1022,21 +1074,6 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1022 } else { 1074 } else {
1023 nvgpu_log_fn(g, "id type is tsg but tsg id is inval"); 1075 nvgpu_log_fn(g, "id type is tsg but tsg id is inval");
1024 } 1076 }
1025 } else if (id_type == ID_TYPE_CHANNEL) {
1026 if (id != FIFO_INVAL_CHANNEL_ID) {
1027 runlist_id = f->channel[id].runlist_id;
1028 if (runlist_id != FIFO_INVAL_RUNLIST_ID)
1029 num_runlists++;
1030 else
1031 nvgpu_log_fn(g, "ch runlist id is invalid");
1032
1033 if ((u32)f->channel[id].tsgid != FIFO_INVAL_TSG_ID)
1034 tsg = &f->tsg[f->channel[id].tsgid];
1035 else
1036 nvgpu_log_fn(g, "tsgid for ch is invalid");
1037 } else {
1038 nvgpu_log_fn(g, "id type is ch but ch id is inval");
1039 }
1040 } else { 1077 } else {
1041 /* 1078 /*
1042 * id type is unknown, get runlist_id if eng mask is such that 1079 * id type is unknown, get runlist_id if eng mask is such that
@@ -1103,27 +1140,16 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1103 1140
1104 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN); 1141 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
1105 1142
1106 /* Get tsg/ch */
1107 if (rc_type == RC_TYPE_MMU_FAULT) { 1143 if (rc_type == RC_TYPE_MMU_FAULT) {
1108 gk20a_debug_dump(g); 1144 gk20a_debug_dump(g);
1109 refch = mmfault->refch;
1110 client_type = mmfault->client_type; 1145 client_type = mmfault->client_type;
1111 gv11b_fifo_reset_pbdma_and_eng_faulted(g, refch, 1146 gv11b_fifo_reset_pbdma_and_eng_faulted(g, tsg,
1112 mmfault->faulted_pbdma, 1147 mmfault->faulted_pbdma,
1113 mmfault->faulted_engine); 1148 mmfault->faulted_engine);
1114 } 1149 }
1115 1150
1116 if (id_type == ID_TYPE_TSG) {
1117 tsg = &g->fifo.tsg[id];
1118 } else if (id_type == ID_TYPE_CHANNEL) {
1119 if (refch == NULL)
1120 refch = gk20a_channel_get(&g->fifo.channel[id]);
1121 }
1122 /* Disable tsg/ch */
1123 if (tsg) 1151 if (tsg)
1124 gk20a_disable_tsg(tsg); 1152 gk20a_disable_tsg(tsg);
1125 else if (refch)
1126 g->ops.fifo.disable_channel(refch);
1127 1153
1128 /* 1154 /*
1129 * Even though TSG preempt timed out, the RC sequence would by design 1155 * Even though TSG preempt timed out, the RC sequence would by design
@@ -1134,7 +1160,7 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1134 * that all PBDMAs serving the engine are not loaded when engine is 1160 * that all PBDMAs serving the engine are not loaded when engine is
1135 * reset. 1161 * reset.
1136 */ 1162 */
1137 if (id_type == ID_TYPE_TSG || id_type == ID_TYPE_CHANNEL) { 1163 if (tsg) {
1138 int preempt_failed; 1164 int preempt_failed;
1139 1165
1140 preempt_failed = g->ops.fifo.preempt_ch_tsg(g, id, id_type); 1166 preempt_failed = g->ops.fifo.preempt_ch_tsg(g, id, id_type);
@@ -1156,7 +1182,7 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1156 1182
1157 for_each_set_bit(engine_id, &__reset_eng_bitmask, 1183 for_each_set_bit(engine_id, &__reset_eng_bitmask,
1158 g->fifo.max_engines) { 1184 g->fifo.max_engines) {
1159 if ((refch || tsg) && 1185 if (tsg &&
1160 gk20a_fifo_should_defer_engine_reset(g, 1186 gk20a_fifo_should_defer_engine_reset(g,
1161 engine_id, client_type, false)) { 1187 engine_id, client_type, false)) {
1162 1188
@@ -1188,13 +1214,9 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1188 } 1214 }
1189 1215
1190#ifdef CONFIG_GK20A_CTXSW_TRACE 1216#ifdef CONFIG_GK20A_CTXSW_TRACE
1191 /* tsg and refch both could be valid for mmu fault. Check tsg first */
1192 if (tsg) 1217 if (tsg)
1193 gk20a_ctxsw_trace_tsg_reset(g, tsg); 1218 gk20a_ctxsw_trace_tsg_reset(g, tsg);
1194 else if (refch)
1195 gk20a_ctxsw_trace_channel_reset(g, refch);
1196#endif 1219#endif
1197
1198 if (tsg) { 1220 if (tsg) {
1199 if (g->fifo.deferred_reset_pending) { 1221 if (g->fifo.deferred_reset_pending) {
1200 gk20a_disable_tsg(tsg); 1222 gk20a_disable_tsg(tsg);
@@ -1204,26 +1226,9 @@ void gv11b_fifo_teardown_ch_tsg(struct gk20a *g, u32 act_eng_bitmask,
1204 1226
1205 gk20a_fifo_abort_tsg(g, tsg->tsgid, false); 1227 gk20a_fifo_abort_tsg(g, tsg->tsgid, false);
1206 } 1228 }
1207 if (refch)
1208 gk20a_channel_put(refch);
1209 } else if (refch) {
1210 if (g->fifo.deferred_reset_pending) {
1211 g->ops.fifo.disable_channel(refch);
1212 } else {
1213 if (rc_type == RC_TYPE_MMU_FAULT)
1214 gk20a_fifo_set_ctx_mmu_error_ch(g, refch);
1215
1216 gk20a_channel_abort(refch, false);
1217 }
1218 gk20a_channel_put(refch);
1219 } else { 1229 } else {
1220 nvgpu_err(g, "id unknown, abort runlist"); 1230 gv11b_fifo_locked_abort_runlist_active_tsgs(g, rc_type,
1221 for (rlid = 0; rlid < g->fifo.max_runlists; 1231 runlists_mask);
1222 rlid++) {
1223 if (runlists_mask & BIT(rlid))
1224 g->ops.fifo.update_runlist(g, rlid,
1225 FIFO_INVAL_CHANNEL_ID, false, true);
1226 }
1227 } 1232 }
1228 1233
1229 gk20a_fifo_set_runlist_state(g, runlists_mask, RUNLIST_ENABLED); 1234 gk20a_fifo_set_runlist_state(g, runlists_mask, RUNLIST_ENABLED);