aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ee3942f0b068..fdff1d420c14 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1631,6 +1631,10 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
1631 1631
1632 pipe_config->adjusted_mode.flags |= flags; 1632 pipe_config->adjusted_mode.flags |= flags;
1633 1633
1634 if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
1635 tmp & DP_COLOR_RANGE_16_235)
1636 pipe_config->limited_color_range = true;
1637
1634 pipe_config->has_dp_encoder = true; 1638 pipe_config->has_dp_encoder = true;
1635 1639
1636 intel_dp_get_m_n(crtc, pipe_config); 1640 intel_dp_get_m_n(crtc, pipe_config);
@@ -3553,6 +3557,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
3553 if (WARN_ON(!intel_encoder->base.crtc)) 3557 if (WARN_ON(!intel_encoder->base.crtc))
3554 return; 3558 return;
3555 3559
3560 if (!to_intel_crtc(intel_encoder->base.crtc)->active)
3561 return;
3562
3556 /* Try to read receiver status if the link appears to be up */ 3563 /* Try to read receiver status if the link appears to be up */
3557 if (!intel_dp_get_link_status(intel_dp, link_status)) { 3564 if (!intel_dp_get_link_status(intel_dp, link_status)) {
3558 return; 3565 return;
@@ -3658,24 +3665,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
3658 return intel_dp_detect_dpcd(intel_dp); 3665 return intel_dp_detect_dpcd(intel_dp);
3659} 3666}
3660 3667
3661static enum drm_connector_status 3668static int g4x_digital_port_connected(struct drm_device *dev,
3662g4x_dp_detect(struct intel_dp *intel_dp) 3669 struct intel_digital_port *intel_dig_port)
3663{ 3670{
3664 struct drm_device *dev = intel_dp_to_dev(intel_dp);
3665 struct drm_i915_private *dev_priv = dev->dev_private; 3671 struct drm_i915_private *dev_priv = dev->dev_private;
3666 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3667 uint32_t bit; 3672 uint32_t bit;
3668 3673
3669 /* Can't disconnect eDP, but you can close the lid... */
3670 if (is_edp(intel_dp)) {
3671 enum drm_connector_status status;
3672
3673 status = intel_panel_detect(dev);
3674 if (status == connector_status_unknown)
3675 status = connector_status_connected;
3676 return status;
3677 }
3678
3679 if (IS_VALLEYVIEW(dev)) { 3674 if (IS_VALLEYVIEW(dev)) {
3680 switch (intel_dig_port->port) { 3675 switch (intel_dig_port->port) {
3681 case PORT_B: 3676 case PORT_B:
@@ -3688,7 +3683,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
3688 bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; 3683 bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
3689 break; 3684 break;
3690 default: 3685 default:
3691 return connector_status_unknown; 3686 return -EINVAL;
3692 } 3687 }
3693 } else { 3688 } else {
3694 switch (intel_dig_port->port) { 3689 switch (intel_dig_port->port) {
@@ -3702,11 +3697,36 @@ g4x_dp_detect(struct intel_dp *intel_dp)
3702 bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; 3697 bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
3703 break; 3698 break;
3704 default: 3699 default:
3705 return connector_status_unknown; 3700 return -EINVAL;
3706 } 3701 }
3707 } 3702 }
3708 3703
3709 if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) 3704 if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
3705 return 0;
3706 return 1;
3707}
3708
3709static enum drm_connector_status
3710g4x_dp_detect(struct intel_dp *intel_dp)
3711{
3712 struct drm_device *dev = intel_dp_to_dev(intel_dp);
3713 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3714 int ret;
3715
3716 /* Can't disconnect eDP, but you can close the lid... */
3717 if (is_edp(intel_dp)) {
3718 enum drm_connector_status status;
3719
3720 status = intel_panel_detect(dev);
3721 if (status == connector_status_unknown)
3722 status = connector_status_connected;
3723 return status;
3724 }
3725
3726 ret = g4x_digital_port_connected(dev, intel_dig_port);
3727 if (ret == -EINVAL)
3728 return connector_status_unknown;
3729 else if (ret == 0)
3710 return connector_status_disconnected; 3730 return connector_status_disconnected;
3711 3731
3712 return intel_dp_detect_dpcd(intel_dp); 3732 return intel_dp_detect_dpcd(intel_dp);
@@ -4003,6 +4023,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
4003 kfree(intel_dig_port); 4023 kfree(intel_dig_port);
4004} 4024}
4005 4025
4026static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
4027{
4028 struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
4029
4030 if (!is_edp(intel_dp))
4031 return;
4032
4033 edp_panel_vdd_off_sync(intel_dp);
4034}
4035
4006static void intel_dp_encoder_reset(struct drm_encoder *encoder) 4036static void intel_dp_encoder_reset(struct drm_encoder *encoder)
4007{ 4037{
4008 intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); 4038 intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
@@ -4037,18 +4067,30 @@ bool
4037intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) 4067intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
4038{ 4068{
4039 struct intel_dp *intel_dp = &intel_dig_port->dp; 4069 struct intel_dp *intel_dp = &intel_dig_port->dp;
4070 struct intel_encoder *intel_encoder = &intel_dig_port->base;
4040 struct drm_device *dev = intel_dig_port->base.base.dev; 4071 struct drm_device *dev = intel_dig_port->base.base.dev;
4041 struct drm_i915_private *dev_priv = dev->dev_private; 4072 struct drm_i915_private *dev_priv = dev->dev_private;
4042 int ret; 4073 enum intel_display_power_domain power_domain;
4074 bool ret = true;
4075
4043 if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) 4076 if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
4044 intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; 4077 intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
4045 4078
4046 DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port, 4079 DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port,
4047 long_hpd ? "long" : "short"); 4080 long_hpd ? "long" : "short");
4048 4081
4082 power_domain = intel_display_port_power_domain(intel_encoder);
4083 intel_display_power_get(dev_priv, power_domain);
4084
4049 if (long_hpd) { 4085 if (long_hpd) {
4050 if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) 4086
4051 goto mst_fail; 4087 if (HAS_PCH_SPLIT(dev)) {
4088 if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
4089 goto mst_fail;
4090 } else {
4091 if (g4x_digital_port_connected(dev, intel_dig_port) != 1)
4092 goto mst_fail;
4093 }
4052 4094
4053 if (!intel_dp_get_dpcd(intel_dp)) { 4095 if (!intel_dp_get_dpcd(intel_dp)) {
4054 goto mst_fail; 4096 goto mst_fail;
@@ -4061,8 +4103,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
4061 4103
4062 } else { 4104 } else {
4063 if (intel_dp->is_mst) { 4105 if (intel_dp->is_mst) {
4064 ret = intel_dp_check_mst_status(intel_dp); 4106 if (intel_dp_check_mst_status(intel_dp) == -EINVAL)
4065 if (ret == -EINVAL)
4066 goto mst_fail; 4107 goto mst_fail;
4067 } 4108 }
4068 4109
@@ -4076,7 +4117,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
4076 drm_modeset_unlock(&dev->mode_config.connection_mutex); 4117 drm_modeset_unlock(&dev->mode_config.connection_mutex);
4077 } 4118 }
4078 } 4119 }
4079 return false; 4120 ret = false;
4121 goto put_power;
4080mst_fail: 4122mst_fail:
4081 /* if we were in MST mode, and device is not there get out of MST mode */ 4123 /* if we were in MST mode, and device is not there get out of MST mode */
4082 if (intel_dp->is_mst) { 4124 if (intel_dp->is_mst) {
@@ -4084,7 +4126,10 @@ mst_fail:
4084 intel_dp->is_mst = false; 4126 intel_dp->is_mst = false;
4085 drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); 4127 drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
4086 } 4128 }
4087 return true; 4129put_power:
4130 intel_display_power_put(dev_priv, power_domain);
4131
4132 return ret;
4088} 4133}
4089 4134
4090/* Return which DP Port should be selected for Transcoder DP control */ 4135/* Return which DP Port should be selected for Transcoder DP control */
@@ -4722,6 +4767,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
4722 intel_encoder->disable = intel_disable_dp; 4767 intel_encoder->disable = intel_disable_dp;
4723 intel_encoder->get_hw_state = intel_dp_get_hw_state; 4768 intel_encoder->get_hw_state = intel_dp_get_hw_state;
4724 intel_encoder->get_config = intel_dp_get_config; 4769 intel_encoder->get_config = intel_dp_get_config;
4770 intel_encoder->suspend = intel_dp_encoder_suspend;
4725 if (IS_CHERRYVIEW(dev)) { 4771 if (IS_CHERRYVIEW(dev)) {
4726 intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; 4772 intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
4727 intel_encoder->pre_enable = chv_pre_enable_dp; 4773 intel_encoder->pre_enable = chv_pre_enable_dp;