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 | /** |
