From 1c7dcfdeef3b0672317fca947cb2097e97c623a9 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 10 Sep 2014 16:34:32 +0530 Subject: gpu: nvgpu: use TSG recover API Use TSG specific API gk20a_fifo_recover_tsg() in following cases : - IOCTL_CHANNEL_FORCE_RESET to force reset a channel in TSG, reset all the channels - handle pbdma intr while resetting in case of pbdma intr, if channel is part of TSG, recover entire TSG - TSG preempt failure when TSG preempt times out, use TSG recover API Use preempt_tsg() API to preempt if channel is part of TSG Add below two generic APIs which will take care of preempting/ recovering either of channel or TSG as required gk20a_fifo_preempt() gk20a_fifo_force_reset_ch() Bug 1470692 Change-Id: I8d46e252af79136be85a9a2accf8b51bd924ca8c Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/497875 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 66 +++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 3f35e7b2..617245b8 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -1291,6 +1291,29 @@ void gk20a_fifo_recover(struct gk20a *g, u32 __engine_ids, g->ops.fifo.trigger_mmu_fault(g, engine_ids); } +int gk20a_fifo_force_reset_ch(struct channel_gk20a *ch, bool verbose) +{ + struct tsg_gk20a *tsg = NULL; + struct channel_gk20a *ch_tsg = NULL; + + if (gk20a_is_channel_marked_as_tsg(ch)) { + tsg = &ch->g->fifo.tsg[ch->hw_chid]; + + mutex_lock(&tsg->ch_list_lock); + list_for_each_entry(ch_tsg, &tsg->ch_list, ch_entry) { + gk20a_set_error_notifier(ch_tsg, + NVHOST_CHANNEL_RESETCHANNEL_VERIF_ERROR); + } + mutex_unlock(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(ch->g, ch->tsgid, verbose); + } else { + gk20a_set_error_notifier(ch, + NVHOST_CHANNEL_RESETCHANNEL_VERIF_ERROR); + gk20a_fifo_recover_ch(ch->g, ch->hw_chid, verbose); + } + + return 0; +} static bool gk20a_fifo_handle_sched_error(struct gk20a *g) { @@ -1482,13 +1505,26 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev, if (reset) { /* Remove the channel from runlist */ u32 status = gk20a_readl(g, fifo_pbdma_status_r(pbdma_id)); - u32 hw_chid = fifo_pbdma_status_id_v(status); + u32 id = fifo_pbdma_status_id_v(status); if (fifo_pbdma_status_id_type_v(status) == fifo_pbdma_status_id_type_chid_v()) { - struct channel_gk20a *ch = &f->channel[hw_chid]; + struct channel_gk20a *ch = &f->channel[id]; + gk20a_set_error_notifier(ch, NVHOST_CHANNEL_PBDMA_ERROR); - gk20a_fifo_recover_ch(g, hw_chid, true); + gk20a_fifo_recover_ch(g, id, true); + } else if (fifo_pbdma_status_id_type_v(status) + == fifo_pbdma_status_id_type_tsgid_v()) { + struct tsg_gk20a *tsg = &f->tsg[id]; + struct channel_gk20a *ch = NULL; + + mutex_lock(&tsg->ch_list_lock); + list_for_each_entry(ch, &tsg->ch_list, ch_entry) { + gk20a_set_error_notifier(ch, + NVHOST_CHANNEL_PBDMA_ERROR); + } + mutex_unlock(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, id, true); } } @@ -1606,9 +1642,19 @@ static int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) if (ret) { if (is_tsg) { - /* TODO: recovery for TSG */ + struct tsg_gk20a *tsg = &g->fifo.tsg[id]; + struct channel_gk20a *ch = NULL; + gk20a_err(dev_from_gk20a(g), "preempt TSG %d timeout\n", id); + + mutex_lock(&tsg->ch_list_lock); + list_for_each_entry(ch, &tsg->ch_list, ch_entry) { + gk20a_set_error_notifier(ch, + NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT); + } + mutex_unlock(&tsg->ch_list_lock); + gk20a_fifo_recover_tsg(g, id, true); } else { struct channel_gk20a *ch = &g->fifo.channel[id]; @@ -1678,6 +1724,18 @@ int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) return ret; } +int gk20a_fifo_preempt(struct gk20a *g, struct channel_gk20a *ch) +{ + int err; + + if (gk20a_is_channel_marked_as_tsg(ch)) + err = gk20a_fifo_preempt_tsg(ch->g, ch->tsgid); + else + err = gk20a_fifo_preempt_channel(ch->g, ch->hw_chid); + + return err; +} + int gk20a_fifo_enable_engine_activity(struct gk20a *g, struct fifo_engine_info_gk20a *eng_info) { -- cgit v1.2.2