|
@@ -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);
|