Commit d5811e87 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: don't try to be smart in the hpd handler

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=39882Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bcc65fd8
...@@ -613,6 +613,18 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, ...@@ -613,6 +613,18 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector,
return true; 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_dp_link_train_info {
struct radeon_device *rdev; struct radeon_device *rdev;
struct drm_encoder *encoder; struct drm_encoder *encoder;
......
...@@ -64,18 +64,16 @@ void radeon_connector_hotplug(struct drm_connector *connector) ...@@ -64,18 +64,16 @@ void radeon_connector_hotplug(struct drm_connector *connector)
if (connector->dpms != DRM_MODE_DPMS_ON) if (connector->dpms != DRM_MODE_DPMS_ON)
return; return;
/* powering up/down the eDP panel generates hpd events which /* just deal with DP (not eDP) here. */
* can interfere with modesetting. if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
*/ int saved_dpms = connector->dpms;
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
return;
/* pre-r600 did not always have the hpd pins mapped accurately to connectors */ if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
if (rdev->family >= CHIP_R600) { radeon_dp_needs_link_train(radeon_connector))
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
else else
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
connector->dpms = saved_dpms;
} }
} }
......
...@@ -479,6 +479,7 @@ extern void radeon_dp_set_link_config(struct drm_connector *connector, ...@@ -479,6 +479,7 @@ extern void radeon_dp_set_link_config(struct drm_connector *connector,
struct drm_display_mode *mode); struct drm_display_mode *mode);
extern void radeon_dp_link_train(struct drm_encoder *encoder, extern void radeon_dp_link_train(struct drm_encoder *encoder,
struct drm_connector *connector); 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 u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern bool radeon_dp_getdpcd(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); extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment