drm/i915: Ignore LVDS presence in VBT flag if the LVDS is enabled by BIOS
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 19 Jun 2015 12:57:43 +0000 (13:57 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 22 Jun 2015 14:13:48 +0000 (16:13 +0200)
On older gen, pre-Ironlake, parts there is no hardwired pin to report
the presence of an LVDS panel. Instead, we have to rely on the VBT to
declare whether the machine has a panel or not. Though notoriously
unreliable, so far we have erred on the side of false-positives and have
required a list of machines which end up falsely reporting a panel as
present. However, we now have reports of false-negatives, machines with
an LVDS that are being ignored due to the VBT not declaring the panel.
This patch ignores the VBT setting if the BIOS has already enabled the
LVDS panel (and on Ironlake+ we also have the hardware presence pin).

It fixes the Samsung NP680Z5E-X01FR in the bug report, but is likely to
result in more false-positives, and since we rely on the BIOS to enable
the panel, there are likely different circumstances where the BIOS will
not enable that panel (and so we may see the same machine with and
without a panel all on the whim of the BIOS).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90979
Reported-and-tested-by: lysxia@gmail.com
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_lvds.c

index 161ab26f81fb8b2a8b56a87f5b0605875f924fc6..bf1702a6e33d0343248f5ca0a0da90faae2940e8 100644 (file)
@@ -942,12 +942,6 @@ void intel_lvds_init(struct drm_device *dev)
        if (dmi_check_system(intel_no_lvds))
                return;
 
-       pin = GMBUS_PIN_PANEL;
-       if (!lvds_is_present_in_vbt(dev, &pin)) {
-               DRM_DEBUG_KMS("LVDS is not present in VBT\n");
-               return;
-       }
-
        if (HAS_PCH_SPLIT(dev)) {
                if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
                        return;
@@ -957,6 +951,16 @@ void intel_lvds_init(struct drm_device *dev)
                }
        }
 
+       pin = GMBUS_PIN_PANEL;
+       if (!lvds_is_present_in_vbt(dev, &pin)) {
+               u32 reg = HAS_PCH_SPLIT(dev) ? PCH_LVDS : LVDS;
+               if ((I915_READ(reg) & LVDS_PORT_EN) == 0) {
+                       DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+                       return;
+               }
+               DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
+       }
+
        lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
        if (!lvds_encoder)
                return;