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.

Signed-off-by: Egbert Eich <eich at 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

Reply via email to