aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-09-03 21:20:00 -0400
committerDave Airlie <airlied@redhat.com>2014-09-03 21:20:00 -0400
commit3aacfda0ecd9040521fbfb4a2c53cd6bf77ae4ee (patch)
tree8bfa42674ac5534c2227199d270eb28de801e9b9
parent0977f906791f0cea689bd2ccd5289e2258f015a5 (diff)
parentbbfb44e8b688e778964275ab0862f67463ba4f84 (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.c55
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c10
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
3664static enum drm_connector_status 3664static int g4x_digital_port_connected(struct drm_device *dev,
3665g4x_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
3705static enum drm_connector_status
3706g4x_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);