aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2012-08-16 10:55:06 -0400
committerDave Airlie <airlied@redhat.com>2012-09-12 21:23:11 -0400
commit14f77fdd58773245a0eae4243c039a420a52c820 (patch)
tree965f113d955d2577da2b8a45ba216034f069e653
parent8504072a2a47c80344c1cf81537d1d433a979fc6 (diff)
drm: edid: Refactor HDMI VSDB detection
There are two slightly different pieces of code for HDMI VSDB detection. Unify the code into a single helper function. Also fix a bug where drm_detect_hdmi_monitor() would stop looking for the HDMI VSDB after the first vendor specific block is found, whether or not that block happened to be the HDMI VSDB. The standard allows for any number of vendor specific blocks to be present. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_edid.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index eadaf4800f46..265a0862a961 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1621,6 +1621,21 @@ monitor_name(struct detailed_timing *t, void *data)
1621 *(u8 **)data = t->data.other_data.data.str.str; 1621 *(u8 **)data = t->data.other_data.data.str.str;
1622} 1622}
1623 1623
1624static bool cea_db_is_hdmi_vsdb(const u8 *db)
1625{
1626 int hdmi_id;
1627
1628 if (cea_db_tag(db) != VENDOR_BLOCK)
1629 return false;
1630
1631 if (cea_db_payload_len(db) < 5)
1632 return false;
1633
1634 hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
1635
1636 return hdmi_id == HDMI_IDENTIFIER;
1637}
1638
1624/** 1639/**
1625 * drm_edid_to_eld - build ELD from EDID 1640 * drm_edid_to_eld - build ELD from EDID
1626 * @connector: connector corresponding to the HDMI/DP sink 1641 * @connector: connector corresponding to the HDMI/DP sink
@@ -1693,7 +1708,7 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
1693 break; 1708 break;
1694 case VENDOR_BLOCK: 1709 case VENDOR_BLOCK:
1695 /* HDMI Vendor-Specific Data Block */ 1710 /* HDMI Vendor-Specific Data Block */
1696 if (dbl >= 5 && db[1] == 0x03 && db[2] == 0x0c && db[3] == 0) 1711 if (cea_db_is_hdmi_vsdb(db))
1697 parse_hdmi_vsdb(connector, db); 1712 parse_hdmi_vsdb(connector, db);
1698 break; 1713 break;
1699 default: 1714 default:
@@ -1778,35 +1793,26 @@ EXPORT_SYMBOL(drm_select_eld);
1778bool drm_detect_hdmi_monitor(struct edid *edid) 1793bool drm_detect_hdmi_monitor(struct edid *edid)
1779{ 1794{
1780 u8 *edid_ext; 1795 u8 *edid_ext;
1781 int i, hdmi_id; 1796 int i;
1782 int start_offset, end_offset; 1797 int start_offset, end_offset;
1783 bool is_hdmi = false;
1784 1798
1785 edid_ext = drm_find_cea_extension(edid); 1799 edid_ext = drm_find_cea_extension(edid);
1786 if (!edid_ext) 1800 if (!edid_ext)
1787 goto end; 1801 return false;
1788 1802
1789 if (cea_db_offsets(edid_ext, &start_offset, &end_offset)) 1803 if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
1790 goto end; 1804 return false;
1791 1805
1792 /* 1806 /*
1793 * Because HDMI identifier is in Vendor Specific Block, 1807 * Because HDMI identifier is in Vendor Specific Block,
1794 * search it from all data blocks of CEA extension. 1808 * search it from all data blocks of CEA extension.
1795 */ 1809 */
1796 for_each_cea_db(edid_ext, i, start_offset, end_offset) { 1810 for_each_cea_db(edid_ext, i, start_offset, end_offset) {
1797 /* Find vendor specific block */ 1811 if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
1798 if (cea_db_tag(&edid_ext[i]) == VENDOR_BLOCK) { 1812 return true;
1799 hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
1800 edid_ext[i + 3] << 16;
1801 /* Find HDMI identifier */
1802 if (hdmi_id == HDMI_IDENTIFIER)
1803 is_hdmi = true;
1804 break;
1805 }
1806 } 1813 }
1807 1814
1808end: 1815 return false;
1809 return is_hdmi;
1810} 1816}
1811EXPORT_SYMBOL(drm_detect_hdmi_monitor); 1817EXPORT_SYMBOL(drm_detect_hdmi_monitor);
1812 1818