Message ID | 20190222155251.16730-1-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/4] drm/i915: Disable LP1+ watermarks on Lenovo Thinkpad T431s | expand |
On Fri, 22 Feb 2019, Ville Syrjala <ville.syrjala@linux.intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Lenovo Thinkpad T431s (ivb) apparently can't handle LP1+ watermarks > being enabled. It underruns severly enough that the screen is > unusable. The latency values and watemarks look as expected. > And sadly updating the BIOS to the latest version (BIOS GHET41WW > (1.26 ) 11/21/2018) did not help. > > One glimmer of hope I had was the VBT. It seems to have some sort > of flag for "self refresh = yes/no", but when I looked at a bunch > of VBTs I had lying around most of them had that field set to "no". > So if we used that we'd end up disabling LP1+ on most machines. > That seems a bit harsh since we know LP1+ works just fine on > most machines. > > Since I have no better ideas let's just disable LP1+ watermarks > on this particular machine via a quirk. > > Cc: stable@vger.kernel.org > Cc: Andrea <andreatclist@gmail.com> > Reported-by: Andrea <andreatclist@gmail.com> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109477 > Fixes: a46a7350b1e8 ("drm/i915: Fix ilk+ watermarks when disabling pipes") > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Does what it says on the box, though I'm saddened we have to resort to a quirk. Reviewed-by: Jani Nikula <jani.nikula@intel.com> > --- > drivers/gpu/drm/i915/intel_pm.c | 51 +++++++++++++++++++++++++-------- > 1 file changed, 39 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index 4c0e43caa5cd..75dceac19950 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -3015,6 +3015,29 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) > intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); > } > > +static void ilk_wm_disable_quirk(struct drm_i915_private *dev_priv, > + int level) > +{ > + int max_level = ilk_wm_max_level(dev_priv); > + > + if (dev_priv->wm.pri_latency[level] == 0 && > + dev_priv->wm.spr_latency[level] == 0 && > + dev_priv->wm.cur_latency[level] == 0) > + return; > + > + DRM_DEBUG_KMS("LP%d+ watermarks disabled by quirk\n", level); > + > + for (; level <= max_level; level++) { > + dev_priv->wm.pri_latency[level] = 0; > + dev_priv->wm.spr_latency[level] = 0; > + dev_priv->wm.cur_latency[level] = 0; > + } > + > + intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); > + intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); > + intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); > +} > + > static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) > { > /* > @@ -3028,23 +3051,18 @@ static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) > * interrupts only. To play it safe we disable LP3 > * watermarks entirely. > */ > - if (dev_priv->wm.pri_latency[3] == 0 && > - dev_priv->wm.spr_latency[3] == 0 && > - dev_priv->wm.cur_latency[3] == 0) > - return; > - > - dev_priv->wm.pri_latency[3] = 0; > - dev_priv->wm.spr_latency[3] = 0; > - dev_priv->wm.cur_latency[3] = 0; > + ilk_wm_disable_quirk(dev_priv, 3); > +} > > - DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n"); > - intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); > - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); > - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); > +static void ilk_wm_disable_lp1_quirk(struct drm_i915_private *dev_priv) > +{ > + ilk_wm_disable_quirk(dev_priv, 1); > } > > static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) > { > + struct pci_dev *pdev = dev_priv->drm.pdev; > + > intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency); > > memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, > @@ -3063,6 +3081,15 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) > snb_wm_latency_quirk(dev_priv); > snb_wm_lp3_irq_quirk(dev_priv); > } > + > + /* > + * Lenovo Thinkpad T431s (ivb) > + * Massive underruns. > + */ > + if (pdev->device == 0x0166 && > + pdev->subsystem_vendor == 0x17aa && > + pdev->subsystem_device == 0x2208) > + ilk_wm_disable_lp1_quirk(dev_priv); > } > > static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4c0e43caa5cd..75dceac19950 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3015,6 +3015,29 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); } +static void ilk_wm_disable_quirk(struct drm_i915_private *dev_priv, + int level) +{ + int max_level = ilk_wm_max_level(dev_priv); + + if (dev_priv->wm.pri_latency[level] == 0 && + dev_priv->wm.spr_latency[level] == 0 && + dev_priv->wm.cur_latency[level] == 0) + return; + + DRM_DEBUG_KMS("LP%d+ watermarks disabled by quirk\n", level); + + for (; level <= max_level; level++) { + dev_priv->wm.pri_latency[level] = 0; + dev_priv->wm.spr_latency[level] = 0; + dev_priv->wm.cur_latency[level] = 0; + } + + intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); + intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); + intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); +} + static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) { /* @@ -3028,23 +3051,18 @@ static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) * interrupts only. To play it safe we disable LP3 * watermarks entirely. */ - if (dev_priv->wm.pri_latency[3] == 0 && - dev_priv->wm.spr_latency[3] == 0 && - dev_priv->wm.cur_latency[3] == 0) - return; - - dev_priv->wm.pri_latency[3] = 0; - dev_priv->wm.spr_latency[3] = 0; - dev_priv->wm.cur_latency[3] = 0; + ilk_wm_disable_quirk(dev_priv, 3); +} - DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n"); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); +static void ilk_wm_disable_lp1_quirk(struct drm_i915_private *dev_priv) +{ + ilk_wm_disable_quirk(dev_priv, 1); } static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) { + struct pci_dev *pdev = dev_priv->drm.pdev; + intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency); memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, @@ -3063,6 +3081,15 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) snb_wm_latency_quirk(dev_priv); snb_wm_lp3_irq_quirk(dev_priv); } + + /* + * Lenovo Thinkpad T431s (ivb) + * Massive underruns. + */ + if (pdev->device == 0x0166 && + pdev->subsystem_vendor == 0x17aa && + pdev->subsystem_device == 0x2208) + ilk_wm_disable_lp1_quirk(dev_priv); } static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)