summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 68c0ddcb..0bd75026 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -476,6 +476,7 @@ static int gk20a_init_fifo_setup_sw(struct gk20a *g)
476 f->g = g; 476 f->g = g;
477 477
478 mutex_init(&f->intr.isr.mutex); 478 mutex_init(&f->intr.isr.mutex);
479 mutex_init(&f->gr_reset_mutex);
479 gk20a_init_fifo_pbdma_intr_descs(f); /* just filling in data/tables */ 480 gk20a_init_fifo_pbdma_intr_descs(f); /* just filling in data/tables */
480 481
481 f->num_channels = g->ops.fifo.get_num_fifos(g); 482 f->num_channels = g->ops.fifo.get_num_fifos(g);
@@ -767,12 +768,15 @@ void gk20a_fifo_reset_engine(struct gk20a *g, u32 engine_id)
767 gk20a_dbg_fn(""); 768 gk20a_dbg_fn("");
768 769
769 if (engine_id == top_device_info_type_enum_graphics_v()) { 770 if (engine_id == top_device_info_type_enum_graphics_v()) {
770 /*HALT_PIPELINE method, halt GR engine*/ 771 if (support_gk20a_pmu(g->dev) && g->elpg_enabled)
771 if (gr_gk20a_halt_pipe(g)) 772 gk20a_pmu_disable_elpg(g);
772 gk20a_err(dev_from_gk20a(g), "failed to HALT gr pipe"); 773 /*HALT_PIPELINE method, halt GR engine*/
773 /* resetting engine using mc_enable_r() is not enough, 774 if (gr_gk20a_halt_pipe(g))
774 * we do full init sequence */ 775 gk20a_err(dev_from_gk20a(g),
775 gk20a_gr_reset(g); 776 "failed to HALT gr pipe");
777 /* resetting engine using mc_enable_r() is not
778 enough, we do full init sequence */
779 gk20a_gr_reset(g);
776 } 780 }
777 if (engine_id == top_device_info_type_enum_copy0_v()) 781 if (engine_id == top_device_info_type_enum_copy0_v())
778 gk20a_reset(g, mc_enable_ce2_m()); 782 gk20a_reset(g, mc_enable_ce2_m());
@@ -950,6 +954,7 @@ static bool gk20a_fifo_handle_mmu_fault(
950 struct channel_gk20a *ch = NULL; 954 struct channel_gk20a *ch = NULL;
951 struct tsg_gk20a *tsg = NULL; 955 struct tsg_gk20a *tsg = NULL;
952 struct channel_gk20a *referenced_channel = NULL; 956 struct channel_gk20a *referenced_channel = NULL;
957 bool was_reset;
953 /* read and parse engine status */ 958 /* read and parse engine status */
954 u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id)); 959 u32 status = gk20a_readl(g, fifo_engine_status_r(engine_id));
955 u32 ctx_status = fifo_engine_status_ctx_status_v(status); 960 u32 ctx_status = fifo_engine_status_ctx_status_v(status);
@@ -1029,9 +1034,15 @@ static bool gk20a_fifo_handle_mmu_fault(
1029 1034
1030 /* handled during channel free */ 1035 /* handled during channel free */
1031 g->fifo.deferred_reset_pending = true; 1036 g->fifo.deferred_reset_pending = true;
1032 } else if (engine_id != ~0) 1037 } else if (engine_id != ~0) {
1033 gk20a_fifo_reset_engine(g, engine_id); 1038 was_reset = mutex_is_locked(&g->fifo.gr_reset_mutex);
1034 1039 mutex_lock(&g->fifo.gr_reset_mutex);
1040 /* if lock is already taken, a reset is taking place
1041 so no need to repeat */
1042 if (!was_reset)
1043 gk20a_fifo_reset_engine(g, engine_id);
1044 mutex_unlock(&g->fifo.gr_reset_mutex);
1045 }
1035 /* disable the channel/TSG from hw and increment 1046 /* disable the channel/TSG from hw and increment
1036 * syncpoints */ 1047 * syncpoints */
1037 1048
@@ -2120,12 +2131,10 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
2120 gk20a_fifo_runlist_reset_engines(g, runlist_id); 2131 gk20a_fifo_runlist_reset_engines(g, runlist_id);
2121 2132
2122 /* engine reset needs the lock. drop it */ 2133 /* engine reset needs the lock. drop it */
2123 mutex_unlock(&runlist->mutex);
2124 /* wait until the runlist is active again */ 2134 /* wait until the runlist is active again */
2125 ret = gk20a_fifo_runlist_wait_pending(g, runlist_id); 2135 ret = gk20a_fifo_runlist_wait_pending(g, runlist_id);
2126 /* get the lock back. at this point everything should 2136 /* get the lock back. at this point everything should
2127 * should be fine */ 2137 * should be fine */
2128 mutex_lock(&runlist->mutex);
2129 2138
2130 if (ret) 2139 if (ret)
2131 gk20a_err(dev_from_gk20a(g), 2140 gk20a_err(dev_from_gk20a(g),