diff options
author | Adam Jackson <ajax@redhat.com> | 2010-04-29 14:05:18 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-05-10 16:38:30 -0400 |
commit | 149c36a346f63fa4be7d1432d7b1b3095a95bf47 (patch) | |
tree | 0fd4f866320067e545a46e91c72bbec65c51745d /drivers/gpu | |
parent | b1083333de5357577c5ec55df6c7efa17bee41c7 (diff) |
drm/i915: Be extra careful about A/D matching for multifunction SDVO
If we're both RGB and TMDS capable, we'll have set up one connector for
each. When determining connectivity, require analog/digital state in
the EDID block to match analog/digital support in the connector.
Otherwise, both DVI and VGA will appear to be connected.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5192723637b5..5ad5a098b5bb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1504,16 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | enum drm_connector_status | 1506 | enum drm_connector_status |
1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1508 | { | 1508 | { |
1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1512 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1513 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1512 | enum drm_connector_status status = connector_status_connected; | 1514 | enum drm_connector_status status = connector_status_connected; |
1513 | struct edid *edid = NULL; | 1515 | struct edid *edid = NULL; |
1514 | 1516 | ||
1515 | edid = drm_get_edid(connector, | 1517 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1516 | intel_encoder->ddc_bus); | ||
1517 | 1518 | ||
1518 | /* This is only applied to SDVO cards with multiple outputs */ | 1519 | /* This is only applied to SDVO cards with multiple outputs */ |
1519 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1520 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { |
@@ -1526,8 +1527,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1526 | */ | 1527 | */ |
1527 | while(temp_ddc > 1) { | 1528 | while(temp_ddc > 1) { |
1528 | sdvo_priv->ddc_bus = temp_ddc; | 1529 | sdvo_priv->ddc_bus = temp_ddc; |
1529 | edid = drm_get_edid(connector, | 1530 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1530 | intel_encoder->ddc_bus); | ||
1531 | if (edid) { | 1531 | if (edid) { |
1532 | /* | 1532 | /* |
1533 | * When we can get the EDID, maybe it is the | 1533 | * When we can get the EDID, maybe it is the |
@@ -1544,28 +1544,25 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1544 | /* when there is no edid and no monitor is connected with VGA | 1544 | /* when there is no edid and no monitor is connected with VGA |
1545 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1545 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1546 | */ | 1546 | */ |
1547 | if (edid == NULL && | 1547 | if (edid == NULL && sdvo_priv->analog_ddc_bus && |
1548 | sdvo_priv->analog_ddc_bus && | ||
1549 | !intel_analog_is_connected(connector->dev)) | 1548 | !intel_analog_is_connected(connector->dev)) |
1550 | edid = drm_get_edid(connector, | 1549 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); |
1551 | sdvo_priv->analog_ddc_bus); | 1550 | |
1552 | if (edid != NULL) { | 1551 | if (edid != NULL) { |
1553 | /* Don't report the output as connected if it's a DVI-I | 1552 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
1554 | * connector with a non-digital EDID coming out. | 1553 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); |
1555 | */ | ||
1556 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1557 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1558 | sdvo_priv->is_hdmi = | ||
1559 | drm_detect_hdmi_monitor(edid); | ||
1560 | else | ||
1561 | status = connector_status_disconnected; | ||
1562 | } | ||
1563 | 1554 | ||
1564 | kfree(edid); | 1555 | /* DDC bus is shared, match EDID to connector type */ |
1565 | connector->display_info.raw_edid = NULL; | 1556 | if (is_digital && need_digital) |
1557 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | ||
1558 | else if (is_digital != need_digital) | ||
1559 | status = connector_status_disconnected; | ||
1566 | 1560 | ||
1567 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1561 | connector->display_info.raw_edid = NULL; |
1562 | } else | ||
1568 | status = connector_status_disconnected; | 1563 | status = connector_status_disconnected; |
1564 | |||
1565 | kfree(edid); | ||
1569 | 1566 | ||
1570 | return status; | 1567 | return status; |
1571 | } | 1568 | } |
@@ -1601,8 +1598,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1601 | 1598 | ||
1602 | if ((sdvo_connector->output_flag & response) == 0) | 1599 | if ((sdvo_connector->output_flag & response) == 0) |
1603 | ret = connector_status_disconnected; | 1600 | ret = connector_status_disconnected; |
1604 | else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1601 | else if (response & SDVO_TMDS_MASK) |
1605 | ret = intel_sdvo_hdmi_sink_detect(connector, response); | 1602 | ret = intel_sdvo_hdmi_sink_detect(connector); |
1606 | else | 1603 | else |
1607 | ret = connector_status_connected; | 1604 | ret = connector_status_connected; |
1608 | 1605 | ||