diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 78 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h | 8 |
3 files changed, 61 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 | ||
1078 | static void gk20a_fifo_get_faulty_channel(struct gk20a *g, int engine_id, | 1078 | static 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 | ||
1093 | static void gk20a_fifo_trigger_mmu_fault(struct gk20a *g, | 1096 | static 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 | ||
1149 | u32 gk20a_fifo_engines_on_ch(struct gk20a *g, u32 hw_chid) | 1152 | static 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 | ||
1174 | void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose) | 1184 | void 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 | ||
1200 | void 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 | |||
1194 | void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, | 1220 | void 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)); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 04d22abb..e7560e27 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -163,6 +163,7 @@ int gk20a_fifo_suspend(struct gk20a *g); | |||
163 | bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); | 163 | bool gk20a_fifo_mmu_fault_pending(struct gk20a *g); |
164 | void gk20a_fifo_recover(struct gk20a *g, u32 engine_ids, bool verbose); | 164 | void gk20a_fifo_recover(struct gk20a *g, u32 engine_ids, bool verbose); |
165 | void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose); | 165 | void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose); |
166 | void gk20a_fifo_recover_tsg(struct gk20a *g, u32 tsgid, bool verbose); | ||
166 | int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); | 167 | int gk20a_init_fifo_reset_enable_hw(struct gk20a *g); |
167 | void gk20a_init_fifo(struct gpu_ops *gops); | 168 | void gk20a_init_fifo(struct gpu_ops *gops); |
168 | 169 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h index aa77d026..f549bac4 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_fifo_gk20a.h | |||
@@ -442,6 +442,10 @@ static inline u32 fifo_engine_status_id_type_chid_v(void) | |||
442 | { | 442 | { |
443 | return 0x00000000; | 443 | return 0x00000000; |
444 | } | 444 | } |
445 | static inline u32 fifo_engine_status_id_type_tsgid_v(void) | ||
446 | { | ||
447 | return 0x00000001; | ||
448 | } | ||
445 | static inline u32 fifo_engine_status_ctx_status_v(u32 r) | 449 | static inline u32 fifo_engine_status_ctx_status_v(u32 r) |
446 | { | 450 | { |
447 | return (r >> 13) & 0x7; | 451 | return (r >> 13) & 0x7; |
@@ -526,6 +530,10 @@ static inline u32 fifo_pbdma_status_id_type_chid_v(void) | |||
526 | { | 530 | { |
527 | return 0x00000000; | 531 | return 0x00000000; |
528 | } | 532 | } |
533 | static inline u32 fifo_pbdma_status_id_type_tsgid_v(void) | ||
534 | { | ||
535 | return 0x00000001; | ||
536 | } | ||
529 | static inline u32 fifo_pbdma_status_chan_status_v(u32 r) | 537 | static inline u32 fifo_pbdma_status_chan_status_v(u32 r) |
530 | { | 538 | { |
531 | return (r >> 13) & 0x7; | 539 | return (r >> 13) & 0x7; |