diff options
author | Dave Airlie <airlied@redhat.com> | 2014-09-03 21:20:00 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-09-03 21:20:00 -0400 |
commit | 3aacfda0ecd9040521fbfb4a2c53cd6bf77ae4ee (patch) | |
tree | 8bfa42674ac5534c2227199d270eb28de801e9b9 | |
parent | 0977f906791f0cea689bd2ccd5289e2258f015a5 (diff) | |
parent | bbfb44e8b688e778964275ab0862f67463ba4f84 (diff) |
Merge tag 'drm-intel-fixes-2014-09-03' of git://anongit.freedesktop.org/drm-intel into drm-fixes
here's a couple of display regression fixes for 3.17.
* tag 'drm-intel-fixes-2014-09-03' of git://anongit.freedesktop.org/drm-intel:
drm/i915: Fix lock dropping in intel_tv_detect()
drm/i915: handle G45/GM45 pulse detection connected state.
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 10 |
2 files changed, 44 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 67cfed6d911a..81d7681faa63 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -3661,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
3661 | return intel_dp_detect_dpcd(intel_dp); | 3661 | return intel_dp_detect_dpcd(intel_dp); |
3662 | } | 3662 | } |
3663 | 3663 | ||
3664 | static enum drm_connector_status | 3664 | static int g4x_digital_port_connected(struct drm_device *dev, |
3665 | g4x_dp_detect(struct intel_dp *intel_dp) | 3665 | struct intel_digital_port *intel_dig_port) |
3666 | { | 3666 | { |
3667 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
3668 | struct drm_i915_private *dev_priv = dev->dev_private; | 3667 | struct drm_i915_private *dev_priv = dev->dev_private; |
3669 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
3670 | uint32_t bit; | 3668 | uint32_t bit; |
3671 | 3669 | ||
3672 | /* Can't disconnect eDP, but you can close the lid... */ | ||
3673 | if (is_edp(intel_dp)) { | ||
3674 | enum drm_connector_status status; | ||
3675 | |||
3676 | status = intel_panel_detect(dev); | ||
3677 | if (status == connector_status_unknown) | ||
3678 | status = connector_status_connected; | ||
3679 | return status; | ||
3680 | } | ||
3681 | |||
3682 | if (IS_VALLEYVIEW(dev)) { | 3670 | if (IS_VALLEYVIEW(dev)) { |
3683 | switch (intel_dig_port->port) { | 3671 | switch (intel_dig_port->port) { |
3684 | case PORT_B: | 3672 | case PORT_B: |
@@ -3691,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
3691 | bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; | 3679 | bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; |
3692 | break; | 3680 | break; |
3693 | default: | 3681 | default: |
3694 | return connector_status_unknown; | 3682 | return -EINVAL; |
3695 | } | 3683 | } |
3696 | } else { | 3684 | } else { |
3697 | switch (intel_dig_port->port) { | 3685 | switch (intel_dig_port->port) { |
@@ -3705,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
3705 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; | 3693 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; |
3706 | break; | 3694 | break; |
3707 | default: | 3695 | default: |
3708 | return connector_status_unknown; | 3696 | return -EINVAL; |
3709 | } | 3697 | } |
3710 | } | 3698 | } |
3711 | 3699 | ||
3712 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) | 3700 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) |
3701 | return 0; | ||
3702 | return 1; | ||
3703 | } | ||
3704 | |||
3705 | static enum drm_connector_status | ||
3706 | g4x_dp_detect(struct intel_dp *intel_dp) | ||
3707 | { | ||
3708 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
3709 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
3710 | int ret; | ||
3711 | |||
3712 | /* Can't disconnect eDP, but you can close the lid... */ | ||
3713 | if (is_edp(intel_dp)) { | ||
3714 | enum drm_connector_status status; | ||
3715 | |||
3716 | status = intel_panel_detect(dev); | ||
3717 | if (status == connector_status_unknown) | ||
3718 | status = connector_status_connected; | ||
3719 | return status; | ||
3720 | } | ||
3721 | |||
3722 | ret = g4x_digital_port_connected(dev, intel_dig_port); | ||
3723 | if (ret == -EINVAL) | ||
3724 | return connector_status_unknown; | ||
3725 | else if (ret == 0) | ||
3713 | return connector_status_disconnected; | 3726 | return connector_status_disconnected; |
3714 | 3727 | ||
3715 | return intel_dp_detect_dpcd(intel_dp); | 3728 | return intel_dp_detect_dpcd(intel_dp); |
@@ -4066,8 +4079,14 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
4066 | intel_display_power_get(dev_priv, power_domain); | 4079 | intel_display_power_get(dev_priv, power_domain); |
4067 | 4080 | ||
4068 | if (long_hpd) { | 4081 | if (long_hpd) { |
4069 | if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) | 4082 | |
4070 | goto mst_fail; | 4083 | if (HAS_PCH_SPLIT(dev)) { |
4084 | if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) | ||
4085 | goto mst_fail; | ||
4086 | } else { | ||
4087 | if (g4x_digital_port_connected(dev, intel_dig_port) != 1) | ||
4088 | goto mst_fail; | ||
4089 | } | ||
4071 | 4090 | ||
4072 | if (!intel_dp_get_dpcd(intel_dp)) { | 4091 | if (!intel_dp_get_dpcd(intel_dp)) { |
4073 | goto mst_fail; | 4092 | goto mst_fail; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 32186a656816..c69d3ce1b3d6 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1311,6 +1311,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1311 | { | 1311 | { |
1312 | struct drm_display_mode mode; | 1312 | struct drm_display_mode mode; |
1313 | struct intel_tv *intel_tv = intel_attached_tv(connector); | 1313 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1314 | enum drm_connector_status status; | ||
1314 | int type; | 1315 | int type; |
1315 | 1316 | ||
1316 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", | 1317 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", |
@@ -1328,16 +1329,19 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1328 | if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { | 1329 | if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { |
1329 | type = intel_tv_detect_type(intel_tv, connector); | 1330 | type = intel_tv_detect_type(intel_tv, connector); |
1330 | intel_release_load_detect_pipe(connector, &tmp); | 1331 | intel_release_load_detect_pipe(connector, &tmp); |
1332 | status = type < 0 ? | ||
1333 | connector_status_disconnected : | ||
1334 | connector_status_connected; | ||
1331 | } else | 1335 | } else |
1332 | return connector_status_unknown; | 1336 | status = connector_status_unknown; |
1333 | 1337 | ||
1334 | drm_modeset_drop_locks(&ctx); | 1338 | drm_modeset_drop_locks(&ctx); |
1335 | drm_modeset_acquire_fini(&ctx); | 1339 | drm_modeset_acquire_fini(&ctx); |
1336 | } else | 1340 | } else |
1337 | return connector->status; | 1341 | return connector->status; |
1338 | 1342 | ||
1339 | if (type < 0) | 1343 | if (status != connector_status_connected) |
1340 | return connector_status_disconnected; | 1344 | return status; |
1341 | 1345 | ||
1342 | intel_tv->type = type; | 1346 | intel_tv->type = type; |
1343 | intel_tv_find_better_format(connector); | 1347 | intel_tv_find_better_format(connector); |