Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a69d13d authored by Jani Nikula's avatar Jani Nikula
Browse files

drm/i915: move VBT based LVDS presence check to intel_bios.c

parent 3bdd14d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3354,6 +3354,7 @@ extern void intel_i2c_reset(struct drm_device *dev);
int intel_bios_init(struct drm_i915_private *dev_priv);
bool intel_bios_is_valid_vbt(const void *buf, size_t size);
bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);

/* intel_opregion.c */
#ifdef CONFIG_ACPI
+50 −0
Original line number Diff line number Diff line
@@ -1472,3 +1472,53 @@ bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv)

	return false;
}

/**
 * intel_bios_is_lvds_present - is LVDS present in VBT
 * @dev_priv:	i915 device instance
 * @i2c_pin:	i2c pin for LVDS if present
 *
 * Return true if LVDS is present. If no child devices were parsed from VBT,
 * assume LVDS is present.
 */
bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
{
	int i;

	if (!dev_priv->vbt.child_dev_num)
		return true;

	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
		union child_device_config *uchild = dev_priv->vbt.child_dev + i;
		struct old_child_dev_config *child = &uchild->old;

		/* 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 (intel_gmbus_is_valid_pin(dev_priv, 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;
}
+1 −52
Original line number Diff line number Diff line
@@ -775,57 +775,6 @@ static const struct dmi_system_id intel_no_lvds[] = {
	{ }	/* terminating entry */
};

/*
 * 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_i915_private *dev_priv = dev->dev_private;
	int i;

	if (!dev_priv->vbt.child_dev_num)
		return true;

	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
		union child_device_config *uchild = dev_priv->vbt.child_dev + i;
		struct old_child_dev_config *child = &uchild->old;

		/* 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 (intel_gmbus_is_valid_pin(dev_priv, 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;
}

static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
{
	DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
@@ -982,7 +931,7 @@ void intel_lvds_init(struct drm_device *dev)
	}

	pin = GMBUS_PIN_PANEL;
	if (!lvds_is_present_in_vbt(dev, &pin)) {
	if (!intel_bios_is_lvds_present(dev_priv, &pin)) {
		if ((lvds & LVDS_PORT_EN) == 0) {
			DRM_DEBUG_KMS("LVDS is not present in VBT\n");
			return;