diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 71 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 2 |
2 files changed, 40 insertions, 33 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 928d80cb..58aa233f 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5203,29 +5203,31 @@ int gk20a_gr_reset(struct gk20a *g) | |||
5203 | static void gk20a_gr_set_error_notifier(struct gk20a *g, | 5203 | static void gk20a_gr_set_error_notifier(struct gk20a *g, |
5204 | struct gr_gk20a_isr_data *isr_data, u32 error_notifier) | 5204 | struct gr_gk20a_isr_data *isr_data, u32 error_notifier) |
5205 | { | 5205 | { |
5206 | struct fifo_gk20a *f = &g->fifo; | ||
5207 | struct channel_gk20a *ch; | 5206 | struct channel_gk20a *ch; |
5208 | struct tsg_gk20a *tsg; | 5207 | struct tsg_gk20a *tsg; |
5209 | struct channel_gk20a *ch_tsg; | 5208 | struct channel_gk20a *ch_tsg; |
5210 | 5209 | ||
5211 | if (isr_data->chid != FIFO_INVAL_CHANNEL_ID) { | 5210 | ch = isr_data->ch; |
5212 | ch = &f->channel[isr_data->chid]; | 5211 | |
5213 | 5212 | if (ch == NULL) { | |
5214 | if (gk20a_is_channel_marked_as_tsg(ch)) { | 5213 | return; |
5215 | tsg = &g->fifo.tsg[ch->tsgid]; | 5214 | } |
5216 | nvgpu_rwsem_down_read(&tsg->ch_list_lock); | 5215 | |
5217 | nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, | 5216 | if (gk20a_is_channel_marked_as_tsg(ch)) { |
5218 | channel_gk20a, ch_entry) { | 5217 | tsg = &g->fifo.tsg[ch->tsgid]; |
5219 | if (gk20a_channel_get(ch_tsg)) { | 5218 | nvgpu_rwsem_down_read(&tsg->ch_list_lock); |
5220 | g->ops.fifo.set_error_notifier(ch_tsg, | 5219 | nvgpu_list_for_each_entry(ch_tsg, &tsg->ch_list, |
5221 | error_notifier); | 5220 | channel_gk20a, ch_entry) { |
5222 | gk20a_channel_put(ch_tsg); | 5221 | if (gk20a_channel_get(ch_tsg)) { |
5223 | } | 5222 | g->ops.fifo.set_error_notifier(ch_tsg, |
5223 | error_notifier); | ||
5224 | gk20a_channel_put(ch_tsg); | ||
5224 | } | 5225 | } |
5225 | nvgpu_rwsem_up_read(&tsg->ch_list_lock); | 5226 | |
5226 | } else { | ||
5227 | g->ops.fifo.set_error_notifier(ch, error_notifier); | ||
5228 | } | 5227 | } |
5228 | nvgpu_rwsem_up_read(&tsg->ch_list_lock); | ||
5229 | } else { | ||
5230 | g->ops.fifo.set_error_notifier(ch, error_notifier); | ||
5229 | } | 5231 | } |
5230 | } | 5232 | } |
5231 | 5233 | ||
@@ -5285,6 +5287,8 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, | |||
5285 | { | 5287 | { |
5286 | u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); | 5288 | u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); |
5287 | int ret = 0; | 5289 | int ret = 0; |
5290 | u32 chid = isr_data->ch != NULL ? | ||
5291 | isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; | ||
5288 | 5292 | ||
5289 | if (gr_fecs_intr == 0U) { | 5293 | if (gr_fecs_intr == 0U) { |
5290 | return 0; | 5294 | return 0; |
@@ -5302,7 +5306,7 @@ int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, | |||
5302 | gr_fecs_host_int_status_watchdog_active_f()) != 0U) { | 5306 | gr_fecs_host_int_status_watchdog_active_f()) != 0U) { |
5303 | /* currently, recovery is not initiated */ | 5307 | /* currently, recovery is not initiated */ |
5304 | nvgpu_err(g, "fecs watchdog triggered for channel %u, " | 5308 | nvgpu_err(g, "fecs watchdog triggered for channel %u, " |
5305 | "cannot ctxsw anymore !!", isr_data->chid); | 5309 | "cannot ctxsw anymore !!", chid); |
5306 | gk20a_fecs_dump_falcon_stats(g); | 5310 | gk20a_fecs_dump_falcon_stats(g); |
5307 | } else if ((gr_fecs_intr & | 5311 | } else if ((gr_fecs_intr & |
5308 | gr_fecs_host_int_status_ctxsw_intr_f(CTXSW_INTR0)) != 0U) { | 5312 | gr_fecs_host_int_status_ctxsw_intr_f(CTXSW_INTR0)) != 0U) { |
@@ -5337,6 +5341,8 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, | |||
5337 | struct gr_gk20a_isr_data *isr_data) | 5341 | struct gr_gk20a_isr_data *isr_data) |
5338 | { | 5342 | { |
5339 | u32 gr_class_error; | 5343 | u32 gr_class_error; |
5344 | u32 chid = isr_data->ch != NULL ? | ||
5345 | isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; | ||
5340 | 5346 | ||
5341 | nvgpu_log_fn(g, " "); | 5347 | nvgpu_log_fn(g, " "); |
5342 | 5348 | ||
@@ -5355,7 +5361,7 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, | |||
5355 | gk20a_readl(g, gr_trapped_data_mme_r())), | 5361 | gk20a_readl(g, gr_trapped_data_mme_r())), |
5356 | gr_trapped_addr_datahigh_v(isr_data->addr), | 5362 | gr_trapped_addr_datahigh_v(isr_data->addr), |
5357 | gr_trapped_addr_priv_v(isr_data->addr), | 5363 | gr_trapped_addr_priv_v(isr_data->addr), |
5358 | gr_class_error, isr_data->chid); | 5364 | gr_class_error, chid); |
5359 | 5365 | ||
5360 | nvgpu_err(g, "trapped data low 0x%08x", | 5366 | nvgpu_err(g, "trapped data low 0x%08x", |
5361 | gk20a_readl(g, gr_trapped_data_lo_r())); | 5367 | gk20a_readl(g, gr_trapped_data_lo_r())); |
@@ -5370,6 +5376,9 @@ static int gk20a_gr_handle_class_error(struct gk20a *g, | |||
5370 | static int gk20a_gr_handle_firmware_method(struct gk20a *g, | 5376 | static int gk20a_gr_handle_firmware_method(struct gk20a *g, |
5371 | struct gr_gk20a_isr_data *isr_data) | 5377 | struct gr_gk20a_isr_data *isr_data) |
5372 | { | 5378 | { |
5379 | u32 chid = isr_data->ch != NULL ? | ||
5380 | isr_data->ch->chid : FIFO_INVAL_CHANNEL_ID; | ||
5381 | |||
5373 | nvgpu_log_fn(g, " "); | 5382 | nvgpu_log_fn(g, " "); |
5374 | 5383 | ||
5375 | gk20a_gr_set_error_notifier(g, isr_data, | 5384 | gk20a_gr_set_error_notifier(g, isr_data, |
@@ -5377,15 +5386,14 @@ static int gk20a_gr_handle_firmware_method(struct gk20a *g, | |||
5377 | nvgpu_err(g, | 5386 | nvgpu_err(g, |
5378 | "firmware method 0x%08x, offset 0x%08x for channel %u", | 5387 | "firmware method 0x%08x, offset 0x%08x for channel %u", |
5379 | isr_data->class_num, isr_data->offset, | 5388 | isr_data->class_num, isr_data->offset, |
5380 | isr_data->chid); | 5389 | chid); |
5381 | return -EINVAL; | 5390 | return -EINVAL; |
5382 | } | 5391 | } |
5383 | 5392 | ||
5384 | int gk20a_gr_handle_semaphore_pending(struct gk20a *g, | 5393 | int gk20a_gr_handle_semaphore_pending(struct gk20a *g, |
5385 | struct gr_gk20a_isr_data *isr_data) | 5394 | struct gr_gk20a_isr_data *isr_data) |
5386 | { | 5395 | { |
5387 | struct fifo_gk20a *f = &g->fifo; | 5396 | struct channel_gk20a *ch = isr_data->ch; |
5388 | struct channel_gk20a *ch = &f->channel[isr_data->chid]; | ||
5389 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | 5397 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; |
5390 | 5398 | ||
5391 | g->ops.fifo.post_event_id(tsg, | 5399 | g->ops.fifo.post_event_id(tsg, |
@@ -5419,8 +5427,7 @@ static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g, | |||
5419 | int gk20a_gr_handle_notify_pending(struct gk20a *g, | 5427 | int gk20a_gr_handle_notify_pending(struct gk20a *g, |
5420 | struct gr_gk20a_isr_data *isr_data) | 5428 | struct gr_gk20a_isr_data *isr_data) |
5421 | { | 5429 | { |
5422 | struct fifo_gk20a *f = &g->fifo; | 5430 | struct channel_gk20a *ch = isr_data->ch; |
5423 | struct channel_gk20a *ch = &f->channel[isr_data->chid]; | ||
5424 | 5431 | ||
5425 | #if defined(CONFIG_GK20A_CYCLE_STATS) | 5432 | #if defined(CONFIG_GK20A_CYCLE_STATS) |
5426 | void *virtual_address; | 5433 | void *virtual_address; |
@@ -5965,6 +5972,7 @@ int gk20a_gr_isr(struct gk20a *g) | |||
5965 | struct tsg_gk20a *tsg = NULL; | 5972 | struct tsg_gk20a *tsg = NULL; |
5966 | u32 gr_engine_id; | 5973 | u32 gr_engine_id; |
5967 | u32 global_esr = 0; | 5974 | u32 global_esr = 0; |
5975 | u32 chid; | ||
5968 | 5976 | ||
5969 | nvgpu_log_fn(g, " "); | 5977 | nvgpu_log_fn(g, " "); |
5970 | nvgpu_log(g, gpu_dbg_intr, "pgraph intr %08x", gr_intr); | 5978 | nvgpu_log(g, gpu_dbg_intr, "pgraph intr %08x", gr_intr); |
@@ -5997,10 +6005,10 @@ int gk20a_gr_isr(struct gk20a *g) | |||
5997 | isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); | 6005 | isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); |
5998 | 6006 | ||
5999 | ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); | 6007 | ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); |
6000 | if (ch) { | 6008 | isr_data.ch = ch; |
6001 | isr_data.chid = ch->chid; | 6009 | chid = ch != NULL ? ch->chid : FIFO_INVAL_CHANNEL_ID; |
6002 | } else { | 6010 | |
6003 | isr_data.chid = FIFO_INVAL_CHANNEL_ID; | 6011 | if (ch == NULL) { |
6004 | nvgpu_err(g, "ch id is INVALID 0xffffffff"); | 6012 | nvgpu_err(g, "ch id is INVALID 0xffffffff"); |
6005 | } | 6013 | } |
6006 | 6014 | ||
@@ -6013,7 +6021,7 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6013 | "data 0x%08x 0x%08x," | 6021 | "data 0x%08x 0x%08x," |
6014 | "ctx 0x%08x, offset 0x%08x, " | 6022 | "ctx 0x%08x, offset 0x%08x, " |
6015 | "subchannel 0x%08x, class 0x%08x", | 6023 | "subchannel 0x%08x, class 0x%08x", |
6016 | isr_data.chid, isr_data.addr, | 6024 | chid, isr_data.addr, |
6017 | isr_data.data_hi, isr_data.data_lo, | 6025 | isr_data.data_hi, isr_data.data_lo, |
6018 | isr_data.curr_ctx, isr_data.offset, | 6026 | isr_data.curr_ctx, isr_data.offset, |
6019 | isr_data.sub_chan, isr_data.class_num); | 6027 | isr_data.sub_chan, isr_data.class_num); |
@@ -6190,10 +6198,9 @@ int gk20a_gr_isr(struct gk20a *g) | |||
6190 | nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, | 6198 | nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, |
6191 | "GPC exception pending"); | 6199 | "GPC exception pending"); |
6192 | 6200 | ||
6193 | fault_ch = gk20a_fifo_channel_from_chid(g, | 6201 | fault_ch = isr_data.ch; |
6194 | isr_data.chid); | ||
6195 | 6202 | ||
6196 | /*isr_data.chid can be ~0 and fault_ch can be NULL */ | 6203 | /* fault_ch can be NULL */ |
6197 | /* check if any gpc has an exception */ | 6204 | /* check if any gpc has an exception */ |
6198 | if (gk20a_gr_handle_gpc_exception(g, &post_event, | 6205 | if (gk20a_gr_handle_gpc_exception(g, &post_event, |
6199 | fault_ch, &global_esr) != 0) { | 6206 | fault_ch, &global_esr) != 0) { |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 9ccd555a..d795a3fc 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -239,7 +239,7 @@ struct gr_gk20a_isr_data { | |||
239 | u32 data_lo; | 239 | u32 data_lo; |
240 | u32 data_hi; | 240 | u32 data_hi; |
241 | u32 curr_ctx; | 241 | u32 curr_ctx; |
242 | u32 chid; | 242 | struct channel_gk20a *ch; |
243 | u32 offset; | 243 | u32 offset; |
244 | u32 sub_chan; | 244 | u32 sub_chan; |
245 | u32 class_num; | 245 | u32 class_num; |