summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c12
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c31
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c22
4 files changed, 47 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index dae9c8cb..c18a4e5d 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -719,7 +719,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
719 struct vm_gk20a *ch_vm = ch->vm; 719 struct vm_gk20a *ch_vm = ch->vm;
720 unsigned long timeout = gk20a_get_gr_idle_timeout(g); 720 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
721 struct dbg_session_gk20a *dbg_s; 721 struct dbg_session_gk20a *dbg_s;
722 722 bool was_reset;
723 gk20a_dbg_fn(""); 723 gk20a_dbg_fn("");
724 724
725 WARN_ON(ch->g == NULL); 725 WARN_ON(ch->g == NULL);
@@ -764,7 +764,15 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
764 if (g->fifo.deferred_reset_pending) { 764 if (g->fifo.deferred_reset_pending) {
765 gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "engine reset was" 765 gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "engine reset was"
766 " deferred, running now"); 766 " deferred, running now");
767 gk20a_fifo_reset_engine(g, g->fifo.deferred_fault_engines); 767 was_reset = mutex_is_locked(&g->fifo.gr_reset_mutex);
768 mutex_lock(&g->fifo.gr_reset_mutex);
769 /* if lock is already taken, a reset is taking place
770 so no need to repeat */
771 if (!was_reset) {
772 gk20a_fifo_reset_engine(g,
773 g->fifo.deferred_fault_engines);
774 }
775 mutex_unlock(&g->fifo.gr_reset_mutex);
768 g->fifo.deferred_fault_engines = 0; 776 g->fifo.deferred_fault_engines = 0;
769 g->fifo.deferred_reset_pending = false; 777 g->fifo.deferred_reset_pending = false;
770 } 778 }
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),
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index 7385f9be..3eb193f6 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -109,6 +109,7 @@ struct fifo_gk20a {
109 /* zero-kref'd channels here */ 109 /* zero-kref'd channels here */
110 struct list_head free_chs; 110 struct list_head free_chs;
111 struct mutex free_chs_mutex; 111 struct mutex free_chs_mutex;
112 struct mutex gr_reset_mutex;
112 113
113 struct tsg_gk20a *tsg; 114 struct tsg_gk20a *tsg;
114 struct mutex tsg_inuse_mutex; 115 struct mutex tsg_inuse_mutex;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 512a7d6b..0ae44c6f 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -4320,12 +4320,6 @@ static int gr_gk20a_init_ctxsw(struct gk20a *g)
4320 if (err) 4320 if (err)
4321 goto out; 4321 goto out;
4322 4322
4323 /* this appears query for sw states but fecs actually init
4324 ramchain, etc so this is hw init */
4325 err = g->ops.gr.init_ctx_state(g);
4326 if (err)
4327 goto out;
4328
4329out: 4323out:
4330 if (err) 4324 if (err)
4331 gk20a_err(dev_from_gk20a(g), "fail"); 4325 gk20a_err(dev_from_gk20a(g), "fail");
@@ -4553,6 +4547,12 @@ int gk20a_init_gr_support(struct gk20a *g)
4553 if (err) 4547 if (err)
4554 return err; 4548 return err;
4555 4549
4550 /* this appears query for sw states but fecs actually init
4551 ramchain, etc so this is hw init */
4552 err = g->ops.gr.init_ctx_state(g);
4553 if (err)
4554 return err;
4555
4556 err = gk20a_init_gr_setup_sw(g); 4556 err = gk20a_init_gr_setup_sw(g);
4557 if (err) 4557 if (err)
4558 return err; 4558 return err;
@@ -4776,6 +4776,8 @@ int gk20a_gr_reset(struct gk20a *g)
4776 int err; 4776 int err;
4777 u32 size; 4777 u32 size;
4778 4778
4779 mutex_lock(&g->gr.fecs_mutex);
4780
4779 err = gk20a_enable_gr_hw(g); 4781 err = gk20a_enable_gr_hw(g);
4780 if (err) 4782 if (err)
4781 return err; 4783 return err;
@@ -4788,6 +4790,14 @@ int gk20a_gr_reset(struct gk20a *g)
4788 if (err) 4790 if (err)
4789 return err; 4791 return err;
4790 4792
4793 mutex_unlock(&g->gr.fecs_mutex);
4794
4795 /* this appears query for sw states but fecs actually init
4796 ramchain, etc so this is hw init */
4797 err = g->ops.gr.init_ctx_state(g);
4798 if (err)
4799 return err;
4800
4791 size = 0; 4801 size = 0;
4792 err = gr_gk20a_fecs_get_reglist_img_size(g, &size); 4802 err = gr_gk20a_fecs_get_reglist_img_size(g, &size);
4793 if (err) { 4803 if (err) {