aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-02-09 15:03:42 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-02-19 18:21:39 -0500
commit1d7aaa0cfe3d1b5ee23958fce71973e3ae9e52e4 (patch)
tree6e9a369e4ab6a10d8fe038899cb69706a854d377
parentf73f760725636b9d0c3786273e185b053516d1eb (diff)
drm/i915: detect wrong MCH watermark values
Some early bios versions seem to ship with the wrong tuning values for the MCH, possible resulting in pipe underruns under load. Especially on DP outputs this can lead to black screen, since DP really doesn't like an occasional whack from an underrun. Unfortunately the registers seem to be locked after boot, so the only thing we can do is politely point out issues and suggest a BIOS upgrade. Arthur Runyan pointed us at this issue while discussion DP bugs - thus far no confirmation from a bug report yet that it helps. But at least some of my machines here have wrong values, so this might be useful in understanding bug reports. v2: After a bit more discussion with Art and Ben we've decided to only the check the watermark values, since the OREF ones could be be a notch more aggressive on certain machines. Cc: Ben Widawsky <ben@bwidawsk.net> Cc: Runyan, Arthur J <arthur.j.runyan@intel.com> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c17
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b9fdc9963817..d7542cd4abfa 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1235,6 +1235,10 @@
1235#define MAD_DIMM_A_SIZE_SHIFT 0 1235#define MAD_DIMM_A_SIZE_SHIFT 0
1236#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) 1236#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT)
1237 1237
1238/** snb MCH registers for priority tuning */
1239#define MCH_SSKPD (MCHBAR_MIRROR_BASE_SNB + 0x5d10)
1240#define MCH_SSKPD_WM0_MASK 0x3f
1241#define MCH_SSKPD_WM0_VAL 0xc
1238 1242
1239/* Clocking configuration register */ 1243/* Clocking configuration register */
1240#define CLKCFG 0x10c00 1244#define CLKCFG 0x10c00
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7c9a6d11700e..3bcc7451e0dc 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3584,6 +3584,19 @@ static void cpt_init_clock_gating(struct drm_device *dev)
3584 } 3584 }
3585} 3585}
3586 3586
3587static void gen6_check_mch_setup(struct drm_device *dev)
3588{
3589 struct drm_i915_private *dev_priv = dev->dev_private;
3590 uint32_t tmp;
3591
3592 tmp = I915_READ(MCH_SSKPD);
3593 if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) {
3594 DRM_INFO("Wrong MCH_SSKPD value: 0x%08x\n", tmp);
3595 DRM_INFO("This can cause pipe underruns and display issues.\n");
3596 DRM_INFO("Please upgrade your BIOS to fix this.\n");
3597 }
3598}
3599
3587static void gen6_init_clock_gating(struct drm_device *dev) 3600static void gen6_init_clock_gating(struct drm_device *dev)
3588{ 3601{
3589 struct drm_i915_private *dev_priv = dev->dev_private; 3602 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3676,6 +3689,8 @@ static void gen6_init_clock_gating(struct drm_device *dev)
3676 I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI)); 3689 I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
3677 3690
3678 cpt_init_clock_gating(dev); 3691 cpt_init_clock_gating(dev);
3692
3693 gen6_check_mch_setup(dev);
3679} 3694}
3680 3695
3681static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) 3696static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
@@ -3861,6 +3876,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
3861 I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); 3876 I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
3862 3877
3863 cpt_init_clock_gating(dev); 3878 cpt_init_clock_gating(dev);
3879
3880 gen6_check_mch_setup(dev);
3864} 3881}
3865 3882
3866static void valleyview_init_clock_gating(struct drm_device *dev) 3883static void valleyview_init_clock_gating(struct drm_device *dev)