diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ca68aa9f237..2a00cb828d20 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -121,6 +121,22 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) | |||
121 | return max_link_bw; | 121 | return max_link_bw; |
122 | } | 122 | } |
123 | 123 | ||
124 | static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp) | ||
125 | { | ||
126 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
127 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
128 | u8 source_max, sink_max; | ||
129 | |||
130 | source_max = 4; | ||
131 | if (HAS_DDI(dev) && intel_dig_port->port == PORT_A && | ||
132 | (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0) | ||
133 | source_max = 2; | ||
134 | |||
135 | sink_max = drm_dp_max_lane_count(intel_dp->dpcd); | ||
136 | |||
137 | return min(source_max, sink_max); | ||
138 | } | ||
139 | |||
124 | /* | 140 | /* |
125 | * The units on the numbers in the next two are... bizarre. Examples will | 141 | * The units on the numbers in the next two are... bizarre. Examples will |
126 | * make it clearer; this one parallels an example in the eDP spec. | 142 | * make it clearer; this one parallels an example in the eDP spec. |
@@ -171,7 +187,7 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
171 | } | 187 | } |
172 | 188 | ||
173 | max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); | 189 | max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); |
174 | max_lanes = drm_dp_max_lane_count(intel_dp->dpcd); | 190 | max_lanes = intel_dp_max_lane_count(intel_dp); |
175 | 191 | ||
176 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 192 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
177 | mode_rate = intel_dp_link_required(target_clock, 18); | 193 | mode_rate = intel_dp_link_required(target_clock, 18); |
@@ -751,8 +767,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
751 | struct intel_crtc *intel_crtc = encoder->new_crtc; | 767 | struct intel_crtc *intel_crtc = encoder->new_crtc; |
752 | struct intel_connector *intel_connector = intel_dp->attached_connector; | 768 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
753 | int lane_count, clock; | 769 | int lane_count, clock; |
754 | int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); | 770 | int min_lane_count = 1; |
771 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | ||
755 | /* Conveniently, the link BW constants become indices with a shift...*/ | 772 | /* Conveniently, the link BW constants become indices with a shift...*/ |
773 | int min_clock = 0; | ||
756 | int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; | 774 | int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; |
757 | int bpp, mode_rate; | 775 | int bpp, mode_rate; |
758 | static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; | 776 | static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; |
@@ -785,19 +803,38 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
785 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 | 803 | /* Walk through all bpp values. Luckily they're all nicely spaced with 2 |
786 | * bpc in between. */ | 804 | * bpc in between. */ |
787 | bpp = pipe_config->pipe_bpp; | 805 | bpp = pipe_config->pipe_bpp; |
788 | if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && | 806 | if (is_edp(intel_dp)) { |
789 | dev_priv->vbt.edp_bpp < bpp) { | 807 | if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) { |
790 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", | 808 | DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", |
791 | dev_priv->vbt.edp_bpp); | 809 | dev_priv->vbt.edp_bpp); |
792 | bpp = dev_priv->vbt.edp_bpp; | 810 | bpp = dev_priv->vbt.edp_bpp; |
811 | } | ||
812 | |||
813 | if (IS_BROADWELL(dev)) { | ||
814 | /* Yes, it's an ugly hack. */ | ||
815 | min_lane_count = max_lane_count; | ||
816 | DRM_DEBUG_KMS("forcing lane count to max (%u) on BDW\n", | ||
817 | min_lane_count); | ||
818 | } else if (dev_priv->vbt.edp_lanes) { | ||
819 | min_lane_count = min(dev_priv->vbt.edp_lanes, | ||
820 | max_lane_count); | ||
821 | DRM_DEBUG_KMS("using min %u lanes per VBT\n", | ||
822 | min_lane_count); | ||
823 | } | ||
824 | |||
825 | if (dev_priv->vbt.edp_rate) { | ||
826 | min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock); | ||
827 | DRM_DEBUG_KMS("using min %02x link bw per VBT\n", | ||
828 | bws[min_clock]); | ||
829 | } | ||
793 | } | 830 | } |
794 | 831 | ||
795 | for (; bpp >= 6*3; bpp -= 2*3) { | 832 | for (; bpp >= 6*3; bpp -= 2*3) { |
796 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, | 833 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, |
797 | bpp); | 834 | bpp); |
798 | 835 | ||
799 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 836 | for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) { |
800 | for (clock = 0; clock <= max_clock; clock++) { | 837 | for (clock = min_clock; clock <= max_clock; clock++) { |
801 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); | 838 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); |
802 | link_avail = intel_dp_max_data_rate(link_clock, | 839 | link_avail = intel_dp_max_data_rate(link_clock, |
803 | lane_count); | 840 | lane_count); |