提交 149c36a3 编写于 作者: A Adam Jackson 提交者: Eric Anholt

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: NAdam Jackson <ajax@redhat.com>
Signed-off-by: NEric Anholt <eric@anholt.net>
上级 b1083333
...@@ -1504,16 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev) ...@@ -1504,16 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev)
} }
enum drm_connector_status enum drm_connector_status
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
{ {
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
enum drm_connector_status status = connector_status_connected; enum drm_connector_status status = connector_status_connected;
struct edid *edid = NULL; struct edid *edid = NULL;
edid = drm_get_edid(connector, edid = drm_get_edid(connector, intel_encoder->ddc_bus);
intel_encoder->ddc_bus);
/* This is only applied to SDVO cards with multiple outputs */ /* This is only applied to SDVO cards with multiple outputs */
if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { 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,8 +1527,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
*/ */
while(temp_ddc > 1) { while(temp_ddc > 1) {
sdvo_priv->ddc_bus = temp_ddc; sdvo_priv->ddc_bus = temp_ddc;
edid = drm_get_edid(connector, edid = drm_get_edid(connector, intel_encoder->ddc_bus);
intel_encoder->ddc_bus);
if (edid) { if (edid) {
/* /*
* When we can get the EDID, maybe it is the * 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,28 +1544,25 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
/* when there is no edid and no monitor is connected with VGA /* when there is no edid and no monitor is connected with VGA
* port, try to use the CRT ddc to read the EDID for DVI-connector * port, try to use the CRT ddc to read the EDID for DVI-connector
*/ */
if (edid == NULL && if (edid == NULL && sdvo_priv->analog_ddc_bus &&
sdvo_priv->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev)) !intel_analog_is_connected(connector->dev))
edid = drm_get_edid(connector, edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus);
sdvo_priv->analog_ddc_bus);
if (edid != NULL) { if (edid != NULL) {
/* Don't report the output as connected if it's a DVI-I bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
* connector with a non-digital EDID coming out. bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK);
*/
if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
if (edid->input & DRM_EDID_INPUT_DIGITAL)
sdvo_priv->is_hdmi =
drm_detect_hdmi_monitor(edid);
else
status = connector_status_disconnected;
}
kfree(edid); /* DDC bus is shared, match EDID to connector type */
connector->display_info.raw_edid = NULL; if (is_digital && need_digital)
sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
else if (is_digital != need_digital)
status = connector_status_disconnected;
} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) connector->display_info.raw_edid = NULL;
} else
status = connector_status_disconnected; status = connector_status_disconnected;
kfree(edid);
return status; return status;
} }
...@@ -1601,8 +1598,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect ...@@ -1601,8 +1598,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
if ((sdvo_connector->output_flag & response) == 0) if ((sdvo_connector->output_flag & response) == 0)
ret = connector_status_disconnected; ret = connector_status_disconnected;
else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) else if (response & SDVO_TMDS_MASK)
ret = intel_sdvo_hdmi_sink_detect(connector, response); ret = intel_sdvo_hdmi_sink_detect(connector);
else else
ret = connector_status_connected; ret = connector_status_connected;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册