From f0c914fcbd1d178214b624438810ad32e3328fe2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 17 Nov 2009 15:44:01 -0500 Subject: [PATCH] drm/radeon/kms: deal with connectors sourced to the same encoder Some systems have multiple connectors connected to the same encoder; e.g., DVI and HDMI connected to the same encoder with the same ddc line. Since we expose connectors as xrandr outputs, randr treats them separately which results in it trying to source the same encoder to different crtcs. If we have an HDMI and DVI-D port on the same encoder, pick the one to be considered connected based on the edid (HDMI if edid indicates HDMI, DVI otherwise). Should fix fdo bug 25150 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_connectors.c | 33 ++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index ac54f90..a7a5e74 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -734,6 +734,39 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect ret = connector_status_disconnected; } else ret = connector_status_connected; + + /* multiple connectors on the same encoder with the same ddc line + * This tends to be HDMI and DVI on the same encoder with the + * same ddc line. If the edid says HDMI, consider the HDMI port + * connected and the DVI port disconnected. If the edid doesn't + * say HDMI, vice versa. + */ + if (radeon_connector->shared_ddc && connector_status_connected) { + struct drm_device *dev = connector->dev; + struct drm_connector *list_connector; + struct radeon_connector *list_radeon_connector; + list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { + if (connector == list_connector) + continue; + list_radeon_connector = to_radeon_connector(list_connector); + if (radeon_connector->devices == list_radeon_connector->devices) { + if (drm_detect_hdmi_monitor(radeon_connector->edid)) { + if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) { + kfree(radeon_connector->edid); + radeon_connector->edid = NULL; + ret = connector_status_disconnected; + } + } else { + if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) || + (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) { + kfree(radeon_connector->edid); + radeon_connector->edid = NULL; + ret = connector_status_disconnected; + } + } + } + } + } } } -- 1.5.6.3