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.
This commit is contained in:
commit
3aacfda0ec
2 changed files with 44 additions and 21 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
intel_display_power_get(dev_priv, power_domain);
|
intel_display_power_get(dev_priv, power_domain);
|
||||||
|
|
||||||
if (long_hpd) {
|
if (long_hpd) {
|
||||||
if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
|
|
||||||
goto mst_fail;
|
if (HAS_PCH_SPLIT(dev)) {
|
||||||
|
if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue