Hi.

Another follow-up... The story has got famous already:

http://www.phoronix.com/scan.php?page=news_item&px=Intel-Linux-Bay-Trail-Fail

But regardless pessimistic tone of the article, there are also good news,
at least for me. :)

The problem commit that introduced freezes was bisected to this:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8fb55197e64d5988ec57b54e973daeea72c3f2ff

In fact, it was mentioned earlier in bugzilla.kernel.org disscussion, but
I've missed it in those hundreds of comments.

And now good news. Mika Kuoppala has come with tentative patches...

https://bugzilla.kernel.org/show_bug.cgi?id=109051#c202

... that solve stability issues on my system. Diff against recent
DragonFly sources is attached.

I'm running this on my Baytrail system for a week now, with C6 and C7
enabled, and without a single freeze. Previously, it was freezing at least
each second day, sometimes two or three times a day.

If I read it correctly, the problem commit introduced "aggressive"
re-clocking on Valleyview, removing some specific thresholds. And
Mika's patches bring those "sane" thresholds back, in a different way,
with some additional safebelts. It touches just Valleyview-specific code
and should not affect driver behaviour on other chips. AFAICT it can
be safely imported to DragonFly, but Francois Tigeot may comment it
better.

--
                                                Dan
diff --git a/sys/dev/drm/i915/intel_pm.c b/sys/dev/drm/i915/intel_pm.c
index c327210..fe6e458 100644
--- a/sys/dev/drm/i915/intel_pm.c
+++ b/sys/dev/drm/i915/intel_pm.c
@@ -3991,6 +3991,13 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		break;
 	}
 
+	if (IS_VALLEYVIEW(dev_priv)) {
+		ei_up = 64000;
+		ei_down = 64000;
+		threshold_up = 90;
+		threshold_down = 70;
+	}
+
 	I915_WRITE(GEN6_RP_UP_EI,
 		GT_INTERVAL_FROM_US(dev_priv, ei_up));
 	I915_WRITE(GEN6_RP_UP_THRESHOLD,
@@ -4084,9 +4091,21 @@ static void valleyview_set_rps(struct drm_device *dev, u8 val)
 		val &= ~1;
 
 	if (val != dev_priv->rps.cur_freq) {
+		u32 ctrl;
+
+		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+		ctrl = 	I915_READ(GEN6_RC_CONTROL);
+		I915_WRITE(GEN6_RC_CONTROL, 0);
+
 		vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
 		if (!IS_CHERRYVIEW(dev_priv))
 			gen6_set_rps_thresholds(dev_priv, val);
+
+		I915_WRITE(GEN6_RC_CONTROL, ctrl);
+		POSTING_READ(GEN6_RC_CONTROL);
+
+		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 	}
 
 	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
@@ -4109,11 +4128,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
 	if (dev_priv->rps.cur_freq <= val)
 		return;
 
-	/* Wake up the media well, as that takes a lot less
-	 * power than the Render well. */
-	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA);
 	valleyview_set_rps(dev_priv->dev, val);
-	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA);
 }
 
 void gen6_rps_busy(struct drm_i915_private *dev_priv)

Reply via email to