gma500: panel presence check
authorAlan Cox <alan@linux.intel.com>
Wed, 25 Apr 2012 13:37:27 +0000 (14:37 +0100)
committerDave Airlie <airlied@redhat.com>
Fri, 27 Apr 2012 08:23:56 +0000 (09:23 +0100)
Introduce a panel presence check for Cedartrail. Non netbook devices don't
necessarily have a panel attached.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/gma500/cdv_intel_lvds.c

index 8359c1a3f45f79b4edecbb8bb2b2e14b63bfb3b9..c87b179eadfdcb6e39ce595f931e7c896bdfb13b 100644 (file)
@@ -556,6 +556,56 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
        .destroy = cdv_intel_lvds_enc_destroy,
 };
 
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ */
+static bool lvds_is_present_in_vbt(struct drm_device *dev,
+                                  u8 *i2c_pin)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       int i;
+
+       if (!dev_priv->child_dev_num)
+               return true;
+
+       for (i = 0; i < dev_priv->child_dev_num; i++) {
+               struct child_device_config *child = dev_priv->child_dev + i;
+
+               /* If the device type is not LFP, continue.
+                * We have to check both the new identifiers as well as the
+                * old for compatibility with some BIOSes.
+                */
+               if (child->device_type != DEVICE_TYPE_INT_LFP &&
+                   child->device_type != DEVICE_TYPE_LFP)
+                       continue;
+
+               if (child->i2c_pin)
+                   *i2c_pin = child->i2c_pin;
+
+               /* However, we cannot trust the BIOS writers to populate
+                * the VBT correctly.  Since LVDS requires additional
+                * information from AIM blocks, a non-zero addin offset is
+                * a good indicator that the LVDS is actually present.
+                */
+               if (child->addin_offset)
+                       return true;
+
+               /* But even then some BIOS writers perform some black magic
+                * and instantiate the device without reference to any
+                * additional data.  Trust that if the VBT was written into
+                * the OpRegion then they have validated the LVDS's existence.
+                */
+               if (dev_priv->opregion.vbt)
+                       return true;
+       }
+
+       return false;
+}
+
 /**
  * cdv_intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -576,6 +626,13 @@ void cdv_intel_lvds_init(struct drm_device *dev,
        struct drm_psb_private *dev_priv = dev->dev_private;
        u32 lvds;
        int pipe;
+       u8 pin;
+
+       pin = GMBUS_PORT_PANEL;
+       if (!lvds_is_present_in_vbt(dev, &pin)) {
+               DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+               return;
+       }
 
        psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
                                    GFP_KERNEL);