drm/i915: Consult VBT "LVDS config" bits to determine whether internal LVDS is present
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 18 May 2018 15:01:38 +0000 (18:01 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 25 May 2018 15:00:26 +0000 (18:00 +0300)
VBT seems to have some bits to tell us whether the internal LVDS port
has something hooked up. In theory one might expect the VBT to not have
a child device for the LVDS port if there's no panel hooked up, but
in practice many VBTs still add the child device. The "LVDS config" bits
seem more reliable though, so let's check those.

So far we've used the "LVDS config" bits to check for eDP support on
ILK+, and disable the internal LVDS when the value is 3. That value
is actually documented as "Both internal LVDS and SDVO LVDS", but in
practice it looks to mean "eDP" on all the ilk+ VBTs I've seen. So let's
keep that interpretation, but for pre-ILK we will consider the value
3 to also indicate the presence of the internal LVDS.

Currently we have 25 DMI matches for the "no internal LVDS" quirk. In an
effort to reduce that let's toss in a WARN when the DMI match and VBT
both tell us that the internal LVDS is not present. The hope is that
people will report a bug, and then we can just nuke the corresponding
entry from the DMI quirk list. Credits to Jani for this idea.

v2: Split the basic int_lvds_support thing to a separate patch (Jani)
v3: Rebase
v4: Limit this to VBT version >= 134

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180518150138.18361-1-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_vbt_defs.h

index ea7ae8bc0ea0e3dd85a9bb4d11bc9ffbd9741a77..1cf073b6ac8a78fb9c0e66ade3a5e3e9419ed2a8 100644 (file)
@@ -516,9 +516,31 @@ parse_driver_features(struct drm_i915_private *dev_priv,
        if (!driver)
                return;
 
-       if (INTEL_GEN(dev_priv) >= 5 &&
-           driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
-               dev_priv->vbt.int_lvds_support = 0;
+       if (INTEL_GEN(dev_priv) >= 5) {
+               /*
+                * Note that we consider BDB_DRIVER_FEATURE_INT_SDVO_LVDS
+                * to mean "eDP". The VBT spec doesn't agree with that
+                * interpretation, but real world VBTs seem to.
+                */
+               if (driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS)
+                       dev_priv->vbt.int_lvds_support = 0;
+       } else {
+               /*
+                * FIXME it's not clear which BDB version has the LVDS config
+                * bits defined. Revision history in the VBT spec says:
+                * "0.92 | Add two definitions for VBT value of LVDS Active
+                *  Config (00b and 11b values defined) | 06/13/2005"
+                * but does not the specify the BDB version.
+                *
+                * So far version 134 (on i945gm) is the oldest VBT observed
+                * in the wild with the bits correctly populated. Version
+                * 108 (on i85x) does not have the bits correctly populated.
+                */
+               if (bdb->version >= 134 &&
+                   driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS &&
+                   driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS)
+                       dev_priv->vbt.int_lvds_support = 0;
+       }
 
        DRM_DEBUG_KMS("DRRS State Enabled:%d\n", driver->drrs_enabled);
        /*
index bacad88ad7ae5e86d609bc80a62754e76c100805..e05c12e7629cc35bc0728997fc94fc9cc0415d16 100644 (file)
@@ -1000,8 +1000,11 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
                return;
 
        /* Skip init on machines we know falsely report LVDS */
-       if (dmi_check_system(intel_no_lvds))
+       if (dmi_check_system(intel_no_lvds)) {
+               WARN(!dev_priv->vbt.int_lvds_support,
+                    "Useless DMI match. Internal LVDS support disabled by VBT\n");
                return;
+       }
 
        if (!dev_priv->vbt.int_lvds_support) {
                DRM_DEBUG_KMS("Internal LVDS support disabled by VBT\n");
index 458468237b5f94d4572e421194459c7ea150fb66..39c80462417931cc0bca9d23291a4a7fef5fba46 100644 (file)
@@ -635,7 +635,7 @@ struct bdb_sdvo_lvds_options {
 #define BDB_DRIVER_FEATURE_NO_LVDS             0
 #define BDB_DRIVER_FEATURE_INT_LVDS            1
 #define BDB_DRIVER_FEATURE_SDVO_LVDS           2
-#define BDB_DRIVER_FEATURE_EDP                 3
+#define BDB_DRIVER_FEATURE_INT_SDVO_LVDS       3
 
 struct bdb_driver_features {
        u8 boot_dev_algorithm:1;