On Wed, Oct 24, 2012 at 12:32 PM, Egbert Eich eich@suse.de wrote:
The Radeon driver uses the analog/digital flag to determine if the DAC or the TMDS encoder should be enabled on a DVI-I connector. If the EDID is bogus this flag is no longer reliable. This fix adds a fallback to DAC load detection to determine if anything is connected to the DAC. If not and a (bogus) EDID is found it assumes a digital display is connected. This works around problems with some crappy IPMI devices using Radeon ES1000.
Looks good. Added to by -fixes queue.
Thanks!
Alex
Signed-off-by: Egbert Eich eich@suse.de
drivers/gpu/drm/radeon/radeon_connectors.c | 28 +++++++++++++++++++++------- 1 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 67cfc17..b884c36 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct drm_mode_object *obj; int i; enum drm_connector_status ret = connector_status_disconnected;
bool dret = false;
bool dret = false, broken_edid = false; if (!force && radeon_check_hpd_status_unchanged(connector)) return connector->status;
@@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); radeon_connector->ddc_bus = NULL;
} else {
ret = connector_status_connected;
broken_edid = true; /* defer use_digital to later */ } } else { radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
@@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
encoder_funcs = encoder->helper_private; if (encoder_funcs->detect) {
if (ret != connector_status_connected) {
ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital = false;
if (!broken_edid) {
if (ret != connector_status_connected) {
/* deal with analog monitors without DDC */
ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital = false;
}
if (ret != connector_status_disconnected)
radeon_connector->detected_by_load = true; }
if (ret != connector_status_disconnected)
radeon_connector->detected_by_load = true;
} else {
enum drm_connector_status lret;
/* assume digital unless load detected otherwise */
radeon_connector->use_digital = true;
lret = encoder_funcs->detect(encoder, connector);
DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
if (lret == connector_status_connected)
radeon_connector->use_digital = false; } break; }
-- 1.7.6.3