drm/i915: Addin-offset is an unreliable indicator of LVDS presence (v2)
My Samsung N210 has a VBT with DEVICE_TYPE_INT_LFP with a zero addin-offset. With the check in place, the panel was declared absent. v2: Only trust BIOS writers that have graduated to writing OpRegions. (We are all doomed.) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Zhao Yakui <yakui.zhao@intel.com> Cc: Adam Jackson <ajax@redhat.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
@@ -777,38 +777,44 @@ static void intel_find_lvds_downclock(struct drm_device *dev,
|
|||||||
* If it is present, return 1.
|
* If it is present, return 1.
|
||||||
* If it is not present, return false.
|
* If it is not present, return false.
|
||||||
* If no child dev is parsed from VBT, it assumes that the LVDS is present.
|
* If no child dev is parsed from VBT, it assumes that the LVDS is present.
|
||||||
* Note: The addin_offset should also be checked for LVDS panel.
|
|
||||||
* Only when it is non-zero, it is assumed that it is present.
|
|
||||||
*/
|
*/
|
||||||
static int lvds_is_present_in_vbt(struct drm_device *dev)
|
static bool lvds_is_present_in_vbt(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct child_device_config *p_child;
|
int i;
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
if (!dev_priv->child_dev_num)
|
if (!dev_priv->child_dev_num)
|
||||||
return 1;
|
return true;
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
for (i = 0; i < dev_priv->child_dev_num; i++) {
|
for (i = 0; i < dev_priv->child_dev_num; i++) {
|
||||||
p_child = dev_priv->child_dev + i;
|
struct child_device_config *child = dev_priv->child_dev + i;
|
||||||
/*
|
|
||||||
* If the device type is not LFP, continue.
|
/* If the device type is not LFP, continue.
|
||||||
* If the device type is 0x22, it is also regarded as LFP.
|
* We have to check both the new identifiers as well as the
|
||||||
|
* old for compatibility with some BIOSes.
|
||||||
*/
|
*/
|
||||||
if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
|
if (child->device_type != DEVICE_TYPE_INT_LFP &&
|
||||||
p_child->device_type != DEVICE_TYPE_LFP)
|
child->device_type != DEVICE_TYPE_LFP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* The addin_offset should be checked. Only when it is
|
/* However, we cannot trust the BIOS writers to populate
|
||||||
* non-zero, it is regarded as present.
|
* 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 (p_child->addin_offset) {
|
if (child->addin_offset)
|
||||||
ret = 1;
|
return true;
|
||||||
break;
|
|
||||||
}
|
/* 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 ret;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user