summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-09-17 03:07:52 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:17 -0400
commite4a7bc1602cc9a041dabee4da4a16594f2f9552a (patch)
tree942729bd383bf86f4bfda339e76d996bcfa4c40b /drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
parentefcd608f80028f6c7b2075b07a1112cd944408ac (diff)
gpu: nvgpu: add API to recover TSG
- add and export API "gk20a_fifo_recover_tsg()" to recover a TSG - if TSG is running on any engine, then trigger MMU fault on those engines - otherwise, abort each channel in TSG - modify channel specific API engines_on_ch() to generic engines_on_id() which will take an ID and a flag to specify whether ID is for channel or TSG and return engines running on that ID - modify channel specific API get_faulty_channel() to generic get_faulty_id_type() which will take pointers to ID and type of ID (either a regular channel or TSG) - remove runlist update from recover_ch() since no need to touch runlist during recovery - set error notifier first and then only abort the channels for TSG recovery path - also, add necessary accessors to get engine status type as TSG Bug 1470692 Change-Id: I7137f611f80916b3d256d4b0dc6e5cf1e93eef6f Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/497873 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c78
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 6383b8c8..7a6f5608 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1075,19 +1075,22 @@ static bool gk20a_fifo_handle_mmu_fault(struct gk20a *g)
1075 return verbose; 1075 return verbose;
1076} 1076}
1077 1077
1078static void gk20a_fifo_get_faulty_channel(struct gk20a *g, int engine_id, 1078static void gk20a_fifo_get_faulty_id_type(struct gk20a *g, int engine_id,
1079 u32 *chid, bool *type_ch) 1079 u32 *id, u32 *type)
1080{ 1080{
1081 u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id)); 1081 u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id));
1082 u32 ctx_status = fifo_engine_status_ctx_status_v(status); 1082 u32 ctx_status = fifo_engine_status_ctx_status_v(status);
1083 1083
1084 *type_ch = fifo_pbdma_status_id_type_v(status) ==
1085 fifo_pbdma_status_id_type_chid_v();
1086 /* use next_id if context load is failing */ 1084 /* use next_id if context load is failing */
1087 *chid = (ctx_status == 1085 *id = (ctx_status ==
1088 fifo_engine_status_ctx_status_ctxsw_load_v()) ? 1086 fifo_engine_status_ctx_status_ctxsw_load_v()) ?
1089 fifo_engine_status_next_id_v(status) : 1087 fifo_engine_status_next_id_v(status) :
1090 fifo_engine_status_id_v(status); 1088 fifo_engine_status_id_v(status);
1089
1090 *type = (ctx_status ==
1091 fifo_engine_status_ctx_status_ctxsw_load_v()) ?
1092 fifo_engine_status_next_id_type_v(status) :
1093 fifo_engine_status_id_type_v(status);
1091} 1094}
1092 1095
1093static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, 1096static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g,
@@ -1146,7 +1149,7 @@ static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g,
1146 gk20a_writel(g, fifo_intr_en_0_r(), 0x7FFFFFFF); 1149 gk20a_writel(g, fifo_intr_en_0_r(), 0x7FFFFFFF);
1147} 1150}
1148 1151
1149u32 gk20a_fifo_engines_on_ch(struct gk20a *g, u32 hw_chid) 1152static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg)
1150{ 1153{
1151 int i; 1154 int i;
1152 u32 engines = 0; 1155 u32 engines = 0;
@@ -1155,17 +1158,24 @@ u32 gk20a_fifo_engines_on_ch(struct gk20a *g, u32 hw_chid)
1155 u32 status = gk20a_readl(g, fifo_engine_status_r(i)); 1158 u32 status = gk20a_readl(g, fifo_engine_status_r(i));
1156 u32 ctx_status = 1159 u32 ctx_status =
1157 fifo_engine_status_ctx_status_v(status); 1160 fifo_engine_status_ctx_status_v(status);
1158 bool type_ch = fifo_pbdma_status_id_type_v(status) == 1161 u32 ctx_id = (ctx_status ==
1159 fifo_pbdma_status_id_type_chid_v();
1160 bool busy = fifo_engine_status_engine_v(status) ==
1161 fifo_engine_status_engine_busy_v();
1162 u32 id = (ctx_status ==
1163 fifo_engine_status_ctx_status_ctxsw_load_v()) ? 1162 fifo_engine_status_ctx_status_ctxsw_load_v()) ?
1164 fifo_engine_status_next_id_v(status) : 1163 fifo_engine_status_next_id_v(status) :
1165 fifo_engine_status_id_v(status); 1164 fifo_engine_status_id_v(status);
1165 u32 type = (ctx_status ==
1166 fifo_engine_status_ctx_status_ctxsw_load_v()) ?
1167 fifo_engine_status_next_id_type_v(status) :
1168 fifo_engine_status_id_type_v(status);
1169 bool busy = fifo_engine_status_engine_v(status) ==
1170 fifo_engine_status_engine_busy_v();
1166 1171
1167 if (type_ch && busy && id == hw_chid) 1172 if (busy && ctx_id == id) {
1168 engines |= BIT(i); 1173 if ((is_tsg && type ==
1174 fifo_engine_status_id_type_tsgid_v()) ||
1175 (!is_tsg && type ==
1176 fifo_engine_status_id_type_chid_v()))
1177 engines |= BIT(i);
1178 }
1169 } 1179 }
1170 1180
1171 return engines; 1181 return engines;
@@ -1173,24 +1183,40 @@ u32 gk20a_fifo_engines_on_ch(struct gk20a *g, u32 hw_chid)
1173 1183
1174void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose) 1184void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose)
1175{ 1185{
1176 u32 engines = gk20a_fifo_engines_on_ch(g, hw_chid); 1186 u32 engines = gk20a_fifo_engines_on_id(g, hw_chid, false);
1177 if (engines) 1187 if (engines)
1178 gk20a_fifo_recover(g, engines, verbose); 1188 gk20a_fifo_recover(g, engines, verbose);
1179 else { 1189 else {
1180 int i;
1181 struct channel_gk20a *ch = 1190 struct channel_gk20a *ch =
1182 g->fifo.channel + hw_chid; 1191 g->fifo.channel + hw_chid;
1183 1192
1184 gk20a_channel_abort(ch); 1193 gk20a_channel_abort(ch);
1185 for (i = 0; i < g->fifo.max_runlists; i++)
1186 g->ops.fifo.update_runlist(g, i,
1187 hw_chid, false, false);
1188 1194
1189 if (gk20a_fifo_set_ctx_mmu_error(g, ch)) 1195 if (gk20a_fifo_set_ctx_mmu_error(g, ch))
1190 gk20a_debug_dump(g->dev); 1196 gk20a_debug_dump(g->dev);
1191 } 1197 }
1192} 1198}
1193 1199
1200void gk20a_fifo_recover_tsg(struct gk20a *g, u32 tsgid, bool verbose)
1201{
1202 u32 engines = gk20a_fifo_engines_on_id(g, tsgid, true);
1203 if (engines)
1204 gk20a_fifo_recover(g, engines, verbose);
1205 else {
1206 struct tsg_gk20a *tsg = &g->fifo.tsg[tsgid];
1207 struct channel_gk20a *ch;
1208
1209 mutex_lock(&tsg->ch_list_lock);
1210 list_for_each_entry(ch, &tsg->ch_list, ch_entry) {
1211 if (gk20a_fifo_set_ctx_mmu_error(g, ch))
1212 gk20a_debug_dump(g->dev);
1213
1214 gk20a_channel_abort(ch);
1215 }
1216 mutex_unlock(&tsg->ch_list_lock);
1217 }
1218}
1219
1194void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, 1220void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids,
1195 bool verbose) 1221 bool verbose)
1196{ 1222{
@@ -1207,18 +1233,18 @@ void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids,
1207 /* store faulted engines in advance */ 1233 /* store faulted engines in advance */
1208 g->fifo.mmu_fault_engines = 0; 1234 g->fifo.mmu_fault_engines = 0;
1209 for_each_set_bit(engine_id, &_engine_ids, 32) { 1235 for_each_set_bit(engine_id, &_engine_ids, 32) {
1210 bool ref_type_ch; 1236 u32 ref_type;
1211 int ref_chid; 1237 u32 ref_id;
1212 gk20a_fifo_get_faulty_channel(g, engine_id, &ref_chid, 1238 gk20a_fifo_get_faulty_id_type(g, engine_id, &ref_id,
1213 &ref_type_ch); 1239 &ref_type);
1214 1240
1215 /* Reset *all* engines that use the 1241 /* Reset *all* engines that use the
1216 * same channel as faulty engine */ 1242 * same channel as faulty engine */
1217 for (i = 0; i < g->fifo.max_engines; i++) { 1243 for (i = 0; i < g->fifo.max_engines; i++) {
1218 bool type_ch; 1244 u32 type;
1219 u32 chid; 1245 u32 id;
1220 gk20a_fifo_get_faulty_channel(g, i, &chid, &type_ch); 1246 gk20a_fifo_get_faulty_id_type(g, i, &id, &type);
1221 if (ref_type_ch == type_ch && ref_chid == chid) { 1247 if (ref_type == type && ref_id == id) {
1222 engine_ids |= BIT(i); 1248 engine_ids |= BIT(i);
1223 g->fifo.mmu_fault_engines |= 1249 g->fifo.mmu_fault_engines |=
1224 BIT(gk20a_engine_id_to_mmu_id(i)); 1250 BIT(gk20a_engine_id_to_mmu_id(i));