diff options
author | Ma Ling <ling.ma@intel.com> | 2009-04-02 01:13:26 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-04-08 13:18:17 -0400 |
commit | 9dff6af860d6b7f661d4360eb859837afaca0a1b (patch) | |
tree | 7634eec5ea79f3855746372e379703ff791c9ae4 | |
parent | 6115707be0e85a9b825f10e95143cb705b87fef8 (diff) |
drm/i915: sync hdmi detection by hdmi identifier with 2D
Currently we detect HDMI monitor by hardware detection, but if an HDMI-DVI
adapter is used to connect a DVI monitor, hardware detection will incorrectly
take monitor as HDMI. HDMI spec says any device containing IEEE registration
identifier will be treated as HDMI device. The patch intends to detect HDMI
monitor by drm_detect_hdmi_monitor function which follows that rule.
Signed-off-by: Ma Ling <ling.ma@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 22 |
2 files changed, 40 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index b06a4a3ff08d..550374225388 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -38,7 +38,7 @@ | |||
38 | struct intel_hdmi_priv { | 38 | struct intel_hdmi_priv { |
39 | u32 sdvox_reg; | 39 | u32 sdvox_reg; |
40 | u32 save_SDVOX; | 40 | u32 save_SDVOX; |
41 | int has_hdmi_sink; | 41 | bool has_hdmi_sink; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 44 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
@@ -128,6 +128,22 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
128 | return true; | 128 | return true; |
129 | } | 129 | } |
130 | 130 | ||
131 | static void | ||
132 | intel_hdmi_sink_detect(struct drm_connector *connector) | ||
133 | { | ||
134 | struct intel_output *intel_output = to_intel_output(connector); | ||
135 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
136 | struct edid *edid = NULL; | ||
137 | |||
138 | edid = drm_get_edid(&intel_output->base, | ||
139 | &intel_output->ddc_bus->adapter); | ||
140 | if (edid != NULL) { | ||
141 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
142 | kfree(edid); | ||
143 | intel_output->base.display_info.raw_edid = NULL; | ||
144 | } | ||
145 | } | ||
146 | |||
131 | static enum drm_connector_status | 147 | static enum drm_connector_status |
132 | intel_hdmi_detect(struct drm_connector *connector) | 148 | intel_hdmi_detect(struct drm_connector *connector) |
133 | { | 149 | { |
@@ -158,9 +174,10 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
158 | return connector_status_unknown; | 174 | return connector_status_unknown; |
159 | } | 175 | } |
160 | 176 | ||
161 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) | 177 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { |
178 | intel_hdmi_sink_detect(connector); | ||
162 | return connector_status_connected; | 179 | return connector_status_connected; |
163 | else | 180 | } else |
164 | return connector_status_disconnected; | 181 | return connector_status_disconnected; |
165 | } | 182 | } |
166 | 183 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7b31f55f55c8..9913651c1e17 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1357,6 +1357,23 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1357 | intel_sdvo_read_response(intel_output, &response, 2); | 1357 | intel_sdvo_read_response(intel_output, &response, 2); |
1358 | } | 1358 | } |
1359 | 1359 | ||
1360 | static void | ||
1361 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | ||
1362 | { | ||
1363 | struct intel_output *intel_output = to_intel_output(connector); | ||
1364 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1365 | struct edid *edid = NULL; | ||
1366 | |||
1367 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1368 | edid = drm_get_edid(&intel_output->base, | ||
1369 | &intel_output->ddc_bus->adapter); | ||
1370 | if (edid != NULL) { | ||
1371 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | ||
1372 | kfree(edid); | ||
1373 | intel_output->base.display_info.raw_edid = NULL; | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1360 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1377 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1361 | { | 1378 | { |
1362 | u8 response[2]; | 1379 | u8 response[2]; |
@@ -1371,9 +1388,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1371 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1388 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1372 | return connector_status_unknown; | 1389 | return connector_status_unknown; |
1373 | 1390 | ||
1374 | if ((response[0] != 0) || (response[1] != 0)) | 1391 | if ((response[0] != 0) || (response[1] != 0)) { |
1392 | intel_sdvo_hdmi_sink_detect(connector); | ||
1375 | return connector_status_connected; | 1393 | return connector_status_connected; |
1376 | else | 1394 | } else |
1377 | return connector_status_disconnected; | 1395 | return connector_status_disconnected; |
1378 | } | 1396 | } |
1379 | 1397 | ||