aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/gt/intel_reset.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/gt/intel_reset.c')
-rw-r--r--drivers/gpu/drm/i915/gt/intel_reset.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 4c478b38e420..3f907701ef4d 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -687,7 +687,6 @@ static void reset_prepare_engine(struct intel_engine_cs *engine)
687 * written to the powercontext is undefined and so we may lose 687 * written to the powercontext is undefined and so we may lose
688 * GPU state upon resume, i.e. fail to restart after a reset. 688 * GPU state upon resume, i.e. fail to restart after a reset.
689 */ 689 */
690 intel_engine_pm_get(engine);
691 intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL); 690 intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
692 engine->reset.prepare(engine); 691 engine->reset.prepare(engine);
693} 692}
@@ -718,16 +717,21 @@ static void revoke_mmaps(struct drm_i915_private *i915)
718 } 717 }
719} 718}
720 719
721static void reset_prepare(struct drm_i915_private *i915) 720static intel_engine_mask_t reset_prepare(struct drm_i915_private *i915)
722{ 721{
723 struct intel_engine_cs *engine; 722 struct intel_engine_cs *engine;
723 intel_engine_mask_t awake = 0;
724 enum intel_engine_id id; 724 enum intel_engine_id id;
725 725
726 intel_gt_pm_get(i915); 726 for_each_engine(engine, i915, id) {
727 for_each_engine(engine, i915, id) 727 if (intel_engine_pm_get_if_awake(engine))
728 awake |= engine->mask;
728 reset_prepare_engine(engine); 729 reset_prepare_engine(engine);
730 }
729 731
730 intel_uc_reset_prepare(i915); 732 intel_uc_reset_prepare(i915);
733
734 return awake;
731} 735}
732 736
733static void gt_revoke(struct drm_i915_private *i915) 737static void gt_revoke(struct drm_i915_private *i915)
@@ -761,20 +765,22 @@ static int gt_reset(struct drm_i915_private *i915,
761static void reset_finish_engine(struct intel_engine_cs *engine) 765static void reset_finish_engine(struct intel_engine_cs *engine)
762{ 766{
763 engine->reset.finish(engine); 767 engine->reset.finish(engine);
764 intel_engine_pm_put(engine);
765 intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL); 768 intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
769
770 intel_engine_signal_breadcrumbs(engine);
766} 771}
767 772
768static void reset_finish(struct drm_i915_private *i915) 773static void reset_finish(struct drm_i915_private *i915,
774 intel_engine_mask_t awake)
769{ 775{
770 struct intel_engine_cs *engine; 776 struct intel_engine_cs *engine;
771 enum intel_engine_id id; 777 enum intel_engine_id id;
772 778
773 for_each_engine(engine, i915, id) { 779 for_each_engine(engine, i915, id) {
774 reset_finish_engine(engine); 780 reset_finish_engine(engine);
775 intel_engine_signal_breadcrumbs(engine); 781 if (awake & engine->mask)
782 intel_engine_pm_put(engine);
776 } 783 }
777 intel_gt_pm_put(i915);
778} 784}
779 785
780static void nop_submit_request(struct i915_request *request) 786static void nop_submit_request(struct i915_request *request)
@@ -798,6 +804,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
798{ 804{
799 struct i915_gpu_error *error = &i915->gpu_error; 805 struct i915_gpu_error *error = &i915->gpu_error;
800 struct intel_engine_cs *engine; 806 struct intel_engine_cs *engine;
807 intel_engine_mask_t awake;
801 enum intel_engine_id id; 808 enum intel_engine_id id;
802 809
803 if (test_bit(I915_WEDGED, &error->flags)) 810 if (test_bit(I915_WEDGED, &error->flags))
@@ -817,7 +824,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
817 * rolling the global seqno forward (since this would complete requests 824 * rolling the global seqno forward (since this would complete requests
818 * for which we haven't set the fence error to EIO yet). 825 * for which we haven't set the fence error to EIO yet).
819 */ 826 */
820 reset_prepare(i915); 827 awake = reset_prepare(i915);
821 828
822 /* Even if the GPU reset fails, it should still stop the engines */ 829 /* Even if the GPU reset fails, it should still stop the engines */
823 if (!INTEL_INFO(i915)->gpu_reset_clobbers_display) 830 if (!INTEL_INFO(i915)->gpu_reset_clobbers_display)
@@ -841,7 +848,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
841 for_each_engine(engine, i915, id) 848 for_each_engine(engine, i915, id)
842 engine->cancel_requests(engine); 849 engine->cancel_requests(engine);
843 850
844 reset_finish(i915); 851 reset_finish(i915, awake);
845 852
846 GEM_TRACE("end\n"); 853 GEM_TRACE("end\n");
847} 854}
@@ -951,6 +958,21 @@ static int do_reset(struct drm_i915_private *i915,
951 return gt_reset(i915, stalled_mask); 958 return gt_reset(i915, stalled_mask);
952} 959}
953 960
961static int resume(struct drm_i915_private *i915)
962{
963 struct intel_engine_cs *engine;
964 enum intel_engine_id id;
965 int ret;
966
967 for_each_engine(engine, i915, id) {
968 ret = engine->resume(engine);
969 if (ret)
970 return ret;
971 }
972
973 return 0;
974}
975
954/** 976/**
955 * i915_reset - reset chip after a hang 977 * i915_reset - reset chip after a hang
956 * @i915: #drm_i915_private to reset 978 * @i915: #drm_i915_private to reset
@@ -973,6 +995,7 @@ void i915_reset(struct drm_i915_private *i915,
973 const char *reason) 995 const char *reason)
974{ 996{
975 struct i915_gpu_error *error = &i915->gpu_error; 997 struct i915_gpu_error *error = &i915->gpu_error;
998 intel_engine_mask_t awake;
976 int ret; 999 int ret;
977 1000
978 GEM_TRACE("flags=%lx\n", error->flags); 1001 GEM_TRACE("flags=%lx\n", error->flags);
@@ -989,7 +1012,7 @@ void i915_reset(struct drm_i915_private *i915,
989 dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason); 1012 dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
990 error->reset_count++; 1013 error->reset_count++;
991 1014
992 reset_prepare(i915); 1015 awake = reset_prepare(i915);
993 1016
994 if (!intel_has_gpu_reset(i915)) { 1017 if (!intel_has_gpu_reset(i915)) {
995 if (i915_modparams.reset) 1018 if (i915_modparams.reset)
@@ -1024,13 +1047,17 @@ void i915_reset(struct drm_i915_private *i915,
1024 if (ret) { 1047 if (ret) {
1025 DRM_ERROR("Failed to initialise HW following reset (%d)\n", 1048 DRM_ERROR("Failed to initialise HW following reset (%d)\n",
1026 ret); 1049 ret);
1027 goto error; 1050 goto taint;
1028 } 1051 }
1029 1052
1053 ret = resume(i915);
1054 if (ret)
1055 goto taint;
1056
1030 i915_queue_hangcheck(i915); 1057 i915_queue_hangcheck(i915);
1031 1058
1032finish: 1059finish:
1033 reset_finish(i915); 1060 reset_finish(i915, awake);
1034unlock: 1061unlock:
1035 mutex_unlock(&error->wedge_mutex); 1062 mutex_unlock(&error->wedge_mutex);
1036 return; 1063 return;
@@ -1081,7 +1108,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
1081 GEM_TRACE("%s flags=%lx\n", engine->name, error->flags); 1108 GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
1082 GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags)); 1109 GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
1083 1110
1084 if (!intel_wakeref_active(&engine->wakeref)) 1111 if (!intel_engine_pm_get_if_awake(engine))
1085 return 0; 1112 return 0;
1086 1113
1087 reset_prepare_engine(engine); 1114 reset_prepare_engine(engine);
@@ -1116,12 +1143,11 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
1116 * process to program RING_MODE, HWSP and re-enable submission. 1143 * process to program RING_MODE, HWSP and re-enable submission.
1117 */ 1144 */
1118 ret = engine->resume(engine); 1145 ret = engine->resume(engine);
1119 if (ret)
1120 goto out;
1121 1146
1122out: 1147out:
1123 intel_engine_cancel_stop_cs(engine); 1148 intel_engine_cancel_stop_cs(engine);
1124 reset_finish_engine(engine); 1149 reset_finish_engine(engine);
1150 intel_engine_pm_put(engine);
1125 return ret; 1151 return ret;
1126} 1152}
1127 1153