On Fri, 22 Feb 2019, Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx> wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxxxx > Cc: Andrea <andreatclist@xxxxxxxxx> > Reported-by: Andrea <andreatclist@xxxxxxxxx> > 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@xxxxxxxxxxxxxxx> Does what it says on the box, though I'm saddened we have to resort to a quirk. Reviewed-by: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > 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) -- Jani Nikula, Intel Open Source Graphics Center