summaryrefslogtreecommitdiffstats
path: root/queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch
diff options
context:
space:
mode:
Diffstat (limited to 'queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch')
-rw-r--r--queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch92
1 files changed, 92 insertions, 0 deletions
diff --git a/queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch b/queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch
new file mode 100644
index 0000000000..5f1d7ce222
--- /dev/null
+++ b/queue-3.0/drm-radeon-kms-don-t-try-to-be-smart-in-the-hpd-handler.patch
@@ -0,0 +1,92 @@
+From d5811e8731213f80c80d89e980505052f16aca1c Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Sat, 13 Aug 2011 13:36:13 -0400
+Subject: drm/radeon/kms: don't try to be smart in the hpd handler
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit d5811e8731213f80c80d89e980505052f16aca1c upstream.
+
+Attempting to try and turn off disconnected display hw in the
+hotput handler lead to more problems than it helped. For
+now just register an event and only attempt the do something
+interesting with DP. Other connectors are just too problematic:
+- Some systems have an HPD pin assigned to LVDS, but it's rarely
+if ever connected properly and we don't really care about hpd
+events on LVDS anyway since it's always connected.
+- The HPD pin is wired up correctly for eDP, but we don't really
+have to do anything since the events since it's always connected.
+- Some HPD pins fire more than once when you connect/disconnect
+- etc.
+
+Fixes:
+https://bugs.freedesktop.org/show_bug.cgi?id=39882
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/atombios_dp.c | 12 ++++++++++++
+ drivers/gpu/drm/radeon/radeon_connectors.c | 14 ++++++--------
+ drivers/gpu/drm/radeon/radeon_mode.h | 1 +
+ 3 files changed, 19 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_dp.c
++++ b/drivers/gpu/drm/radeon/atombios_dp.c
+@@ -613,6 +613,18 @@ static bool radeon_dp_get_link_status(st
+ return true;
+ }
+
++bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
++{
++ u8 link_status[DP_LINK_STATUS_SIZE];
++ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
++
++ if (!radeon_dp_get_link_status(radeon_connector, link_status))
++ return false;
++ if (dp_channel_eq_ok(link_status, dig->dp_lane_count))
++ return false;
++ return true;
++}
++
+ struct radeon_dp_link_train_info {
+ struct radeon_device *rdev;
+ struct drm_encoder *encoder;
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -64,18 +64,16 @@ void radeon_connector_hotplug(struct drm
+ if (connector->dpms != DRM_MODE_DPMS_ON)
+ return;
+
+- /* powering up/down the eDP panel generates hpd events which
+- * can interfere with modesetting.
+- */
+- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+- return;
++ /* just deal with DP (not eDP) here. */
++ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
++ int saved_dpms = connector->dpms;
+
+- /* pre-r600 did not always have the hpd pins mapped accurately to connectors */
+- if (rdev->family >= CHIP_R600) {
+- if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
++ if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
++ radeon_dp_needs_link_train(radeon_connector))
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+ else
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
++ connector->dpms = saved_dpms;
+ }
+ }
+
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -476,6 +476,7 @@ extern void radeon_dp_set_link_config(st
+ struct drm_display_mode *mode);
+ extern void radeon_dp_link_train(struct drm_encoder *encoder,
+ struct drm_connector *connector);
++extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
+ extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
+ extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+ extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);