summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
diff options
context:
space:
mode:
authorVijayakumar <vsubbu@nvidia.com>2015-08-04 07:44:54 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-09-16 12:44:00 -0400
commitb8faddfe2ad3d52837b0f766d74feb8e6d6f4ce5 (patch)
tree9cf25fcdd5e9ac2ff870f78c35213ce46b90ac7a /drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
parent2359f247d18fbde3220e463543193ab06f75fe81 (diff)
gpu: nvgpu: fix runlist update timeout handling
bug 1625901 1) disable ELPG before doing GR reset when runlist update times out 2) add mutex for GR reset to avoid multiple threads resetting GR 3) protect GR reset with FECS mutex so that no one else submits methods Change-Id: I02993fd1eabe6875ab1c58a40a06e6c79fcdeeae Signed-off-by: Vijayakumar <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/793643 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
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),