diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 4 |
3 files changed, 24 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index f5d5e467..9492d646 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -406,17 +406,36 @@ static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add) | |||
406 | return gk20a_fifo_update_runlist(c->g, 0, c->hw_chid, add, true); | 406 | return gk20a_fifo_update_runlist(c->g, 0, c->hw_chid, add, true); |
407 | } | 407 | } |
408 | 408 | ||
409 | void gk20a_disable_channel_no_update(struct channel_gk20a *ch) | 409 | void gk20a_channel_abort(struct channel_gk20a *ch) |
410 | { | 410 | { |
411 | struct channel_gk20a_job *job, *n; | ||
412 | bool released_job_semaphore = false; | ||
413 | |||
411 | /* ensure no fences are pending */ | 414 | /* ensure no fences are pending */ |
412 | if (ch->sync) | 415 | if (ch->sync) |
413 | ch->sync->set_min_eq_max(ch->sync); | 416 | ch->sync->set_min_eq_max(ch->sync); |
414 | 417 | ||
418 | /* release all job semaphores (applies only to jobs that use | ||
419 | semaphore synchronization) */ | ||
420 | mutex_lock(&ch->jobs_lock); | ||
421 | list_for_each_entry_safe(job, n, &ch->jobs, list) { | ||
422 | if (job->post_fence.semaphore) { | ||
423 | gk20a_semaphore_release(job->post_fence.semaphore); | ||
424 | released_job_semaphore = true; | ||
425 | } | ||
426 | } | ||
427 | mutex_unlock(&ch->jobs_lock); | ||
428 | |||
415 | /* disable channel */ | 429 | /* disable channel */ |
416 | gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), | 430 | gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), |
417 | gk20a_readl(ch->g, | 431 | gk20a_readl(ch->g, |
418 | ccsr_channel_r(ch->hw_chid)) | | 432 | ccsr_channel_r(ch->hw_chid)) | |
419 | ccsr_channel_enable_clr_true_f()); | 433 | ccsr_channel_enable_clr_true_f()); |
434 | |||
435 | if (released_job_semaphore) { | ||
436 | wake_up_interruptible_all(&ch->semaphore_wq); | ||
437 | gk20a_channel_update(ch, 0); | ||
438 | } | ||
420 | } | 439 | } |
421 | 440 | ||
422 | int gk20a_wait_channel_idle(struct channel_gk20a *ch) | 441 | int gk20a_wait_channel_idle(struct channel_gk20a *ch) |
@@ -455,7 +474,7 @@ void gk20a_disable_channel(struct channel_gk20a *ch, | |||
455 | } | 474 | } |
456 | 475 | ||
457 | /* disable the channel from hw and increment syncpoints */ | 476 | /* disable the channel from hw and increment syncpoints */ |
458 | gk20a_disable_channel_no_update(ch); | 477 | gk20a_channel_abort(ch); |
459 | 478 | ||
460 | gk20a_wait_channel_idle(ch); | 479 | gk20a_wait_channel_idle(ch); |
461 | 480 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 84983cc6..60437e66 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -153,7 +153,7 @@ bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, | |||
153 | void gk20a_disable_channel(struct channel_gk20a *ch, | 153 | void gk20a_disable_channel(struct channel_gk20a *ch, |
154 | bool wait_for_finish, | 154 | bool wait_for_finish, |
155 | unsigned long finish_timeout); | 155 | unsigned long finish_timeout); |
156 | void gk20a_disable_channel_no_update(struct channel_gk20a *ch); | 156 | void gk20a_channel_abort(struct channel_gk20a *ch); |
157 | int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout); | 157 | int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout); |
158 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); | 158 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); |
159 | void gk20a_channel_semaphore_wakeup(struct gk20a *g); | 159 | void gk20a_channel_semaphore_wakeup(struct gk20a *g); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 2d09a840..f246c73e 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -1043,7 +1043,7 @@ static bool gk20a_fifo_handle_mmu_fault(struct gk20a *g) | |||
1043 | if (ch->in_use) { | 1043 | if (ch->in_use) { |
1044 | /* disable the channel from hw and increment | 1044 | /* disable the channel from hw and increment |
1045 | * syncpoints */ | 1045 | * syncpoints */ |
1046 | gk20a_disable_channel_no_update(ch); | 1046 | gk20a_channel_abort(ch); |
1047 | 1047 | ||
1048 | /* remove the channel from runlist */ | 1048 | /* remove the channel from runlist */ |
1049 | clear_bit(ch->hw_chid, | 1049 | clear_bit(ch->hw_chid, |
@@ -1180,7 +1180,7 @@ void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose) | |||
1180 | struct channel_gk20a *ch = | 1180 | struct channel_gk20a *ch = |
1181 | g->fifo.channel + hw_chid; | 1181 | g->fifo.channel + hw_chid; |
1182 | 1182 | ||
1183 | gk20a_disable_channel_no_update(ch); | 1183 | gk20a_channel_abort(ch); |
1184 | for (i = 0; i < g->fifo.max_runlists; i++) | 1184 | for (i = 0; i < g->fifo.max_runlists; i++) |
1185 | gk20a_fifo_update_runlist(g, i, | 1185 | gk20a_fifo_update_runlist(g, i, |
1186 | hw_chid, false, false); | 1186 | hw_chid, false, false); |