diff options
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 7 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 2 |
3 files changed, 24 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3618d29c79a2..09292193dafe 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -258,6 +258,17 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, | |||
258 | return ret == 2 ? 0 : -1; | 258 | return ret == 2 ? 0 : -1; |
259 | } | 259 | } |
260 | 260 | ||
261 | static bool drm_edid_is_zero(u8 *in_edid, int length) | ||
262 | { | ||
263 | int i; | ||
264 | u32 *raw_edid = (u32 *)in_edid; | ||
265 | |||
266 | for (i = 0; i < length / 4; i++) | ||
267 | if (*(raw_edid + i) != 0) | ||
268 | return false; | ||
269 | return true; | ||
270 | } | ||
271 | |||
261 | static u8 * | 272 | static u8 * |
262 | drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | 273 | drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) |
263 | { | 274 | { |
@@ -273,6 +284,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | |||
273 | goto out; | 284 | goto out; |
274 | if (drm_edid_block_valid(block)) | 285 | if (drm_edid_block_valid(block)) |
275 | break; | 286 | break; |
287 | if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { | ||
288 | connector->null_edid_counter++; | ||
289 | goto carp; | ||
290 | } | ||
276 | } | 291 | } |
277 | if (i == 4) | 292 | if (i == 4) |
278 | goto carp; | 293 | goto carp; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 9c2929c7e79f..c04e18ee8a87 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -836,6 +836,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
836 | if (!radeon_connector->edid) { | 836 | if (!radeon_connector->edid) { |
837 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", | 837 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
838 | drm_get_connector_name(connector)); | 838 | drm_get_connector_name(connector)); |
839 | /* rs690 seems to have a problem with connectors not existing and always | ||
840 | * return a block of 0's. If we see this just stop polling on this output */ | ||
841 | if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) { | ||
842 | ret = connector_status_disconnected; | ||
843 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); | ||
844 | radeon_connector->ddc_bus = NULL; | ||
845 | } | ||
839 | } else { | 846 | } else { |
840 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 847 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
841 | 848 | ||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 9573e0ce3120..33d12f87f0e0 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -520,6 +520,8 @@ struct drm_connector { | |||
520 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; | 520 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; |
521 | uint32_t force_encoder_id; | 521 | uint32_t force_encoder_id; |
522 | struct drm_encoder *encoder; /* currently active encoder */ | 522 | struct drm_encoder *encoder; /* currently active encoder */ |
523 | |||
524 | int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ | ||
523 | }; | 525 | }; |
524 | 526 | ||
525 | /** | 527 | /** |