diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 45 |
2 files changed, 27 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 23d1ae67d279..7ef3e8b6864d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -306,6 +306,7 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
| 306 | struct drm_mode_config *mode_config = &dev->mode_config; | 306 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 307 | struct intel_encoder *encoder; | 307 | struct intel_encoder *encoder; |
| 308 | 308 | ||
| 309 | mutex_lock(&mode_config->mutex); | ||
| 309 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); | 310 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
| 310 | 311 | ||
| 311 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) | 312 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
| @@ -314,6 +315,8 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
| 314 | 315 | ||
| 315 | /* Just fire off a uevent and let userspace tell us what to do */ | 316 | /* Just fire off a uevent and let userspace tell us what to do */ |
| 316 | drm_helper_hpd_irq_event(dev); | 317 | drm_helper_hpd_irq_event(dev); |
| 318 | |||
| 319 | mutex_unlock(&mode_config->mutex); | ||
| 317 | } | 320 | } |
| 318 | 321 | ||
| 319 | static void i915_handle_rps_change(struct drm_device *dev) | 322 | static void i915_handle_rps_change(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f797fb58ba9c..52b79d9d5d2d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -52,7 +52,7 @@ struct intel_dp { | |||
| 52 | uint32_t color_range; | 52 | uint32_t color_range; |
| 53 | uint8_t link_bw; | 53 | uint8_t link_bw; |
| 54 | uint8_t lane_count; | 54 | uint8_t lane_count; |
| 55 | uint8_t dpcd[4]; | 55 | uint8_t dpcd[8]; |
| 56 | struct i2c_adapter adapter; | 56 | struct i2c_adapter adapter; |
| 57 | struct i2c_algo_dp_aux_data algo; | 57 | struct i2c_algo_dp_aux_data algo; |
| 58 | bool is_pch_edp; | 58 | bool is_pch_edp; |
| @@ -770,6 +770,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 770 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 770 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
| 771 | intel_dp->link_configuration[0] = intel_dp->link_bw; | 771 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
| 772 | intel_dp->link_configuration[1] = intel_dp->lane_count; | 772 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
| 773 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; | ||
| 773 | 774 | ||
| 774 | /* | 775 | /* |
| 775 | * Check for DPCD version > 1.1 and enhanced framing support | 776 | * Check for DPCD version > 1.1 and enhanced framing support |
| @@ -1597,10 +1598,22 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
| 1597 | } | 1598 | } |
| 1598 | 1599 | ||
| 1599 | static enum drm_connector_status | 1600 | static enum drm_connector_status |
| 1601 | i915_dp_detect_common(struct intel_dp *intel_dp) | ||
| 1602 | { | ||
| 1603 | enum drm_connector_status status = connector_status_disconnected; | ||
| 1604 | |||
| 1605 | if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, | ||
| 1606 | sizeof (intel_dp->dpcd)) && | ||
| 1607 | (intel_dp->dpcd[DP_DPCD_REV] != 0)) | ||
| 1608 | status = connector_status_connected; | ||
| 1609 | |||
| 1610 | return status; | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | static enum drm_connector_status | ||
| 1600 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1614 | ironlake_dp_detect(struct intel_dp *intel_dp) |
| 1601 | { | 1615 | { |
| 1602 | enum drm_connector_status status; | 1616 | enum drm_connector_status status; |
| 1603 | bool ret; | ||
| 1604 | 1617 | ||
| 1605 | /* Can't disconnect eDP, but you can close the lid... */ | 1618 | /* Can't disconnect eDP, but you can close the lid... */ |
| 1606 | if (is_edp(intel_dp)) { | 1619 | if (is_edp(intel_dp)) { |
| @@ -1610,15 +1623,7 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
| 1610 | return status; | 1623 | return status; |
| 1611 | } | 1624 | } |
| 1612 | 1625 | ||
| 1613 | status = connector_status_disconnected; | 1626 | return i915_dp_detect_common(intel_dp); |
| 1614 | ret = intel_dp_aux_native_read_retry(intel_dp, | ||
| 1615 | 0x000, intel_dp->dpcd, | ||
| 1616 | sizeof (intel_dp->dpcd)); | ||
| 1617 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) | ||
| 1618 | status = connector_status_connected; | ||
| 1619 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | ||
| 1620 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | ||
| 1621 | return status; | ||
| 1622 | } | 1627 | } |
| 1623 | 1628 | ||
| 1624 | static enum drm_connector_status | 1629 | static enum drm_connector_status |
| @@ -1626,7 +1631,6 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
| 1626 | { | 1631 | { |
| 1627 | struct drm_device *dev = intel_dp->base.base.dev; | 1632 | struct drm_device *dev = intel_dp->base.base.dev; |
| 1628 | struct drm_i915_private *dev_priv = dev->dev_private; | 1633 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1629 | enum drm_connector_status status; | ||
| 1630 | uint32_t temp, bit; | 1634 | uint32_t temp, bit; |
| 1631 | 1635 | ||
| 1632 | switch (intel_dp->output_reg) { | 1636 | switch (intel_dp->output_reg) { |
| @@ -1648,15 +1652,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
| 1648 | if ((temp & bit) == 0) | 1652 | if ((temp & bit) == 0) |
| 1649 | return connector_status_disconnected; | 1653 | return connector_status_disconnected; |
| 1650 | 1654 | ||
| 1651 | status = connector_status_disconnected; | 1655 | return i915_dp_detect_common(intel_dp); |
| 1652 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, | ||
| 1653 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | ||
| 1654 | { | ||
| 1655 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) | ||
| 1656 | status = connector_status_connected; | ||
| 1657 | } | ||
| 1658 | |||
| 1659 | return status; | ||
| 1660 | } | 1656 | } |
| 1661 | 1657 | ||
| 1662 | /** | 1658 | /** |
| @@ -1674,11 +1670,18 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
| 1674 | struct edid *edid = NULL; | 1670 | struct edid *edid = NULL; |
| 1675 | 1671 | ||
| 1676 | intel_dp->has_audio = false; | 1672 | intel_dp->has_audio = false; |
| 1673 | memset(intel_dp->dpcd, 0, sizeof(intel_dp->dpcd)); | ||
| 1677 | 1674 | ||
| 1678 | if (HAS_PCH_SPLIT(dev)) | 1675 | if (HAS_PCH_SPLIT(dev)) |
| 1679 | status = ironlake_dp_detect(intel_dp); | 1676 | status = ironlake_dp_detect(intel_dp); |
| 1680 | else | 1677 | else |
| 1681 | status = g4x_dp_detect(intel_dp); | 1678 | status = g4x_dp_detect(intel_dp); |
| 1679 | |||
| 1680 | DRM_DEBUG_KMS("DPCD: %02hx%02hx%02hx%02hx%02hx%02hx%02hx%02hx\n", | ||
| 1681 | intel_dp->dpcd[0], intel_dp->dpcd[1], intel_dp->dpcd[2], | ||
| 1682 | intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5], | ||
| 1683 | intel_dp->dpcd[6], intel_dp->dpcd[7]); | ||
| 1684 | |||
| 1682 | if (status != connector_status_connected) | 1685 | if (status != connector_status_connected) |
| 1683 | return status; | 1686 | return status; |
| 1684 | 1687 | ||
