public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH 1/1] drm/i915: Adding Gfx Clock, Wake and Gunit save/restore logic in PM suspend/resume paths.
@ 2014-07-28 17:37 sagar.a.kamble
  2014-07-28 18:20 ` Sagar Arun Kamble
  2014-07-28 18:51 ` Daniel Vetter
  0 siblings, 2 replies; 23+ messages in thread
From: sagar.a.kamble @ 2014-07-28 17:37 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Sagar Kamble, Paulo Zanoni

From: Sagar Kamble <sagar.a.kamble@intel.com>

Sequence to get gfx clocks on/off, allow/disallow wake and save/restore of gunit registers need to be followed in
PM suspend and resume path similar to runtime suspend and resume.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c  | 84 ++++++++++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/i915_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_drv.h |  7 ++++
 3 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6c4b25c..fdfeccf 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -495,6 +495,26 @@ static int i915_drm_freeze(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc;
 	pci_power_t opregion_target_state;
+	u32 mask;
+	int err = 0;
+
+	/* Following sequence from vlv_runtime_suspend */
+	if (IS_VALLEYVIEW(dev)) {
+		/*
+		 * Bspec defines the following GT well on flags as debug only,
+		 * so don't treat them as hard failures.
+		 */
+		(void)vlv_wait_for_gt_wells(dev_priv, false);
+
+		mask = VLV_GTLC_RENDER_CTX_EXISTS | VLV_GTLC_MEDIA_CTX_EXISTS;
+		WARN_ON((I915_READ(VLV_GTLC_WAKE_CTRL) & mask) != mask);
+
+		vlv_check_no_gt_access(dev_priv);
+
+		err = vlv_force_gfx_clock(dev_priv, true);
+		if (err)
+			goto err1;
+	}
 
 	/* ignore lid events during suspend */
 	mutex_lock(&dev_priv->modeset_restore_lock);
@@ -542,6 +562,10 @@ static int i915_drm_freeze(struct drm_device *dev)
 
 	i915_gem_suspend_gtt_mappings(dev);
 
+	/* Save Gunit State */
+	if (IS_VALLEYVIEW(dev))
+		vlv_save_gunit_s0ix_state(dev_priv);
+
 	i915_save_state(dev);
 
 	opregion_target_state = PCI_D3cold;
@@ -562,7 +586,27 @@ static int i915_drm_freeze(struct drm_device *dev)
 
 	intel_display_set_init_power(dev_priv, false);
 
-	return 0;
+	/* Clear Allow Wake Bit so that none of the
+	 * force/demand wake requests
+	 */
+	if (IS_VALLEYVIEW(dev)) {
+		err = vlv_allow_gt_wake(dev_priv, false);
+		if (err)
+			goto err2;
+
+		/* Release graphics clocks */
+		vlv_force_gfx_clock(dev_priv, false);
+	}
+	return err;
+err2:
+	/* For safety always re-enable waking and disable gfx clock forcing */
+	if (IS_VALLEYVIEW(dev))
+		vlv_allow_gt_wake(dev_priv, true);
+err1:
+	if (IS_VALLEYVIEW(dev))
+		vlv_force_gfx_clock(dev_priv, false);
+
+	return err;
 }
 
 int i915_suspend(struct drm_device *dev, pm_message_t state)
@@ -610,6 +654,26 @@ void intel_console_resume(struct work_struct *work)
 static int i915_drm_thaw_early(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+	int err;
+
+	/*
+	 * Following sequence from vlv_runtime_resume. Clock is released
+	 * in i915_drm_thaw.
+	 * If any of the steps fail just try to continue, that's the best we
+	 * can do at this point. Return the first error code (which will also
+	 * leave RPM permanently disabled).
+	 */
+
+	if (IS_VALLEYVIEW(dev)) {
+		ret = vlv_force_gfx_clock(dev_priv, true);
+
+		vlv_restore_gunit_s0ix_state(dev_priv);
+
+		err = vlv_allow_gt_wake(dev_priv, true);
+		if (!ret)
+			ret = err;
+	}
 
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		hsw_disable_pc8(dev_priv);
@@ -618,7 +682,7 @@ static int i915_drm_thaw_early(struct drm_device *dev)
 	intel_uncore_sanitize(dev);
 	intel_power_domains_init_hw(dev_priv);
 
-	return 0;
+	return ret;
 }
 
 static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
@@ -695,6 +759,9 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
 
 	intel_opregion_notify_adapter(dev, PCI_D0);
 
+	/* Release graphics clocks turned on in thaw_early*/
+	vlv_force_gfx_clock(dev_priv, false);
+
 	return 0;
 }
 
@@ -1028,7 +1095,7 @@ static int hsw_runtime_resume(struct drm_i915_private *dev_priv)
  * a black-box for the driver. Further investigation is needed to reduce the
  * saved/restored registers even further, by following the same 3 criteria.
  */
-static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
+void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
 {
 	struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
 	int i;
@@ -1098,6 +1165,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
 	s->gu_ctl0		= I915_READ(VLV_GU_CTL0);
 	s->gu_ctl1		= I915_READ(VLV_GU_CTL1);
 	s->clock_gate_dis2	= I915_READ(VLV_GUNIT_CLOCK_GATE2);
+	s->dpio_cfg_data	= I915_READ(DPIO_CTL);
 
 	/*
 	 * Not saving any of:
@@ -1108,7 +1176,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
 	 */
 }
 
-static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
+void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
 {
 	struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
 	u32 val;
@@ -1192,6 +1260,8 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
 	I915_WRITE(VLV_GU_CTL0,			s->gu_ctl0);
 	I915_WRITE(VLV_GU_CTL1,			s->gu_ctl1);
 	I915_WRITE(VLV_GUNIT_CLOCK_GATE2,	s->clock_gate_dis2);
+	I915_WRITE(DPIO_CTL,			s->dpio_cfg_data);
+
 }
 
 int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
@@ -1231,7 +1301,7 @@ int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
 #undef COND
 }
 
-static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow)
+int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow)
 {
 	u32 val;
 	int err = 0;
@@ -1252,7 +1322,7 @@ static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow)
 #undef COND
 }
 
-static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
+int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
 				 bool wait_for_on)
 {
 	u32 mask;
@@ -1282,7 +1352,7 @@ static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
 #undef COND
 }
 
-static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv)
+void vlv_check_no_gt_access(struct drm_i915_private *dev_priv)
 {
 	if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR))
 		return;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ef38c3b..4167800 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -907,6 +907,7 @@ struct vlv_s0ix_state {
 	u32 gu_ctl0;
 	u32 gu_ctl1;
 	u32 clock_gate_dis2;
+	u32 dpio_cfg_data;
 };
 
 struct intel_rps_ei {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bdcc4a1..63cbb06 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1074,6 +1074,13 @@ void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
 
 
+int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
+				 bool wait_for_on);
+void vlv_check_no_gt_access(struct drm_i915_private *dev_priv);
+void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv);
+void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv);
+int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow);
+
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-08-14 14:14 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-28 17:37 [PATCH 1/1] drm/i915: Adding Gfx Clock, Wake and Gunit save/restore logic in PM suspend/resume paths sagar.a.kamble
2014-07-28 18:20 ` Sagar Arun Kamble
2014-07-28 18:51 ` Daniel Vetter
2014-07-31 12:36   ` [RFC 1/1] FOR_UPSTREAM [VPG]: " sagar.a.kamble
2014-08-01  7:04   ` [PATCH 1/1] " sagar.a.kamble
2014-08-04  8:07     ` Daniel Vetter
2014-08-08  6:52       ` Sagar Arun Kamble
2014-08-08  7:42         ` Daniel Vetter
2014-08-08  8:59           ` Sagar Arun Kamble
2014-08-08  9:14             ` Imre Deak
2014-08-08  9:15             ` Daniel Vetter
2014-08-08 10:24               ` Sagar Arun Kamble
2014-08-08 11:34                 ` Imre Deak
2014-08-08 13:43                   ` Daniel Vetter
2014-08-08 14:01                     ` Daniel Vetter
2014-08-12 10:51                       ` [PATCH v3 1/1] drm/i915: Sharing Gfx Clock, Wake and Gunit save/restore logic using common handler for runtime/system s/r paths sagar.a.kamble
2014-08-12 12:00                         ` Daniel Vetter
2014-08-13 13:47                         ` Imre Deak
2014-08-13 15:04                           ` Sagar Arun Kamble
2014-08-13 17:37                           ` [PATCH 1/2] drm/i915: Created common handler for platform specific suspend/resume sagar.a.kamble
2014-08-13 17:37                             ` [PATCH 2/2] drm/i915: Sharing platform specific sequence between runtime and system suspend/ resume paths sagar.a.kamble
2014-08-14 11:51                             ` [PATCH 1/2] drm/i915: Created common handler for platform specific suspend/resume Imre Deak
2014-08-14 14:14                               ` Daniel Vetter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox