Commit 3aacfda0 authored by Dave Airlie's avatar Dave Airlie

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.
parents 0977f906 bbfb44e8
...@@ -3661,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp) ...@@ -3661,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
return intel_dp_detect_dpcd(intel_dp); return intel_dp_detect_dpcd(intel_dp);
} }
static enum drm_connector_status static int g4x_digital_port_connected(struct drm_device *dev,
g4x_dp_detect(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port)
{ {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
uint32_t bit; uint32_t bit;
/* Can't disconnect eDP, but you can close the lid... */
if (is_edp(intel_dp)) {
enum drm_connector_status status;
status = intel_panel_detect(dev);
if (status == connector_status_unknown)
status = connector_status_connected;
return status;
}
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
switch (intel_dig_port->port) { switch (intel_dig_port->port) {
case PORT_B: case PORT_B:
...@@ -3691,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) ...@@ -3691,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
break; break;
default: default:
return connector_status_unknown; return -EINVAL;
} }
} else { } else {
switch (intel_dig_port->port) { switch (intel_dig_port->port) {
...@@ -3705,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp) ...@@ -3705,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp)
bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
break; break;
default: default:
return connector_status_unknown; return -EINVAL;
} }
} }
if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
return 0;
return 1;
}
static enum drm_connector_status
g4x_dp_detect(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
int ret;
/* Can't disconnect eDP, but you can close the lid... */
if (is_edp(intel_dp)) {
enum drm_connector_status status;
status = intel_panel_detect(dev);
if (status == connector_status_unknown)
status = connector_status_connected;
return status;
}
ret = g4x_digital_port_connected(dev, intel_dig_port);
if (ret == -EINVAL)
return connector_status_unknown;
else if (ret == 0)
return connector_status_disconnected; return connector_status_disconnected;
return intel_dp_detect_dpcd(intel_dp); 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,8 +4079,14 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
intel_display_power_get(dev_priv, power_domain); intel_display_power_get(dev_priv, power_domain);
if (long_hpd) { if (long_hpd) {
if (HAS_PCH_SPLIT(dev)) {
if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
goto mst_fail; goto mst_fail;
} else {
if (g4x_digital_port_connected(dev, intel_dig_port) != 1)
goto mst_fail;
}
if (!intel_dp_get_dpcd(intel_dp)) { if (!intel_dp_get_dpcd(intel_dp)) {
goto mst_fail; goto mst_fail;
......
...@@ -1311,6 +1311,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1311,6 +1311,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
{ {
struct drm_display_mode mode; struct drm_display_mode mode;
struct intel_tv *intel_tv = intel_attached_tv(connector); struct intel_tv *intel_tv = intel_attached_tv(connector);
enum drm_connector_status status;
int type; int type;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
...@@ -1328,16 +1329,19 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1328,16 +1329,19 @@ intel_tv_detect(struct drm_connector *connector, bool force)
if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
type = intel_tv_detect_type(intel_tv, connector); type = intel_tv_detect_type(intel_tv, connector);
intel_release_load_detect_pipe(connector, &tmp); intel_release_load_detect_pipe(connector, &tmp);
status = type < 0 ?
connector_status_disconnected :
connector_status_connected;
} else } else
return connector_status_unknown; status = connector_status_unknown;
drm_modeset_drop_locks(&ctx); drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx); drm_modeset_acquire_fini(&ctx);
} else } else
return connector->status; return connector->status;
if (type < 0) if (status != connector_status_connected)
return connector_status_disconnected; return status;
intel_tv->type = type; intel_tv->type = type;
intel_tv_find_better_format(connector); intel_tv_find_better_format(connector);
......
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