diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 12 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 31 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 22 |
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 | |||
4329 | out: | 4323 | out: |
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) { |