[PATCH v4 8/9] drm/i915/guc: Restore GuC interrupts across suspend/reset if enabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In order to override the disable/enable control of GuC interrupts during
suspend/reset cycle we are creating two new functions suspend/restore
guc_interrupts which check if interrupts were enabled and disable them
on suspend and enable them on resume. They are used to restore interrupts
across reset as well.

Further restructuring of runtime_pm_enable/disable_interrupts and
suspend/restore_guc_interrupts will be done in upcoming patches.

v2: Rebase.

v3: Updated suspend/restore with the new low level get/put functions.
(Tvrtko)

v4: Rebase. s/intel_*_guc_interrupts/intel_guc_*_interrupts (Michal)

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx>
Cc: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx>
Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx>
Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
---
 drivers/gpu/drm/i915/intel_display.c |  2 ++
 drivers/gpu/drm/i915/intel_guc.c     | 30 ++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_guc.h     |  2 ++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0cd3559..fe5e71a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3676,8 +3676,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 		 * The display has been reset as well,
 		 * so need a full re-initialization.
 		 */
+		intel_guc_suspend_interrupts(&dev_priv->guc);
 		intel_runtime_pm_disable_interrupts(dev_priv);
 		intel_runtime_pm_enable_interrupts(dev_priv);
+		intel_guc_restore_interrupts(&dev_priv->guc);
 
 		intel_pps_unlock_regs_wa(dev_priv);
 		intel_modeset_init_hw(dev);
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index 7d66ee5..0a33eda 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -406,7 +406,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
 	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
-	intel_guc_log_disable_interrupts(guc);
+	intel_guc_suspend_interrupts(guc);
 
 	data[0] = INTEL_GUC_ACTION_ENTER_S_STATE;
 	/* any value greater than GUC_POWER_D0 */
@@ -451,7 +451,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
 	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
-	intel_guc_log_enable_interrupts(guc);
+	intel_guc_restore_interrupts(guc);
 
 	data[0] = INTEL_GUC_ACTION_EXIT_S_STATE;
 	data[1] = GUC_POWER_D0;
@@ -547,6 +547,16 @@ void intel_guc_enable_interrupts(struct intel_guc *guc,
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
 
+void intel_guc_restore_interrupts(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (guc->interrupt_clients)
+		__intel_guc_enable_interrupts(guc);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
 static void __intel_guc_disable_interrupts(struct intel_guc *guc)
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
@@ -576,6 +586,22 @@ void intel_guc_disable_interrupts(struct intel_guc *guc,
 	intel_guc_reset_interrupts(guc);
 }
 
+void intel_guc_suspend_interrupts(struct intel_guc *guc)
+{
+	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (!guc->interrupt_clients) {
+		spin_unlock_irq(&dev_priv->irq_lock);
+		return;
+	}
+	__intel_guc_disable_interrupts(guc);
+	spin_unlock_irq(&dev_priv->irq_lock);
+	synchronize_irq(dev_priv->drm.irq);
+
+	intel_guc_reset_interrupts(guc);
+}
+
 void intel_guc_irq_handler(struct intel_guc *guc, u32 gt_iir)
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index f248565..ef7d2fd 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -142,5 +142,7 @@ void intel_guc_enable_interrupts(struct intel_guc *guc,
 void intel_guc_disable_interrupts(struct intel_guc *guc,
 				  enum intel_guc_intr_client id);
 void intel_guc_irq_handler(struct intel_guc *guc, u32 pm_iir);
+void intel_guc_suspend_interrupts(struct intel_guc *guc);
+void intel_guc_restore_interrupts(struct intel_guc *guc);
 
 #endif
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux