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.c55
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
124static 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);