aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-26 19:44:59 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-27 20:09:34 -0400
commit3600836585e3fdef0a1410d63fe5ce4015007aac (patch)
tree21c28335d65a83913e8d187ba24cb67f452e1d9f /drivers/gpu/drm/i915
parent4e53c2e010e531b4a014692199e978482d471c7e (diff)
drm/i915: convert DP autodither code to new infrastructure
The old code only handled either 6bpc or 8bpc. Since it's easy to do, reorganize the code to be a bit more generic so that it can also handle 10bpc and 12bpc. Note that we still start with 8bpc, so there's no functional change. Also, since we no don't need to compute the 6BPC flag in the mode_valid callback, we can consolidate things a bit. That requires though that the link bw computation is moved up in the compute_config callback. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c103
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
3 files changed, 47 insertions, 63 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 14397726d3ac..e95c469afa6d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7485,10 +7485,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
7485 } 7485 }
7486 } 7486 }
7487 7487
7488 /* temporary hack until the DP code doesn't use the 6BPC flag any more */
7489 if (pipe_config->adjusted_mode.private_flags & INTEL_MODE_DP_FORCE_6BPC)
7490 pipe_config->pipe_bpp = 6*8;
7491
7492 if (!(intel_crtc_compute_config(crtc, pipe_config))) { 7488 if (!(intel_crtc_compute_config(crtc, pipe_config))) {
7493 DRM_DEBUG_KMS("CRTC fixup failed\n"); 7489 DRM_DEBUG_KMS("CRTC fixup failed\n");
7494 goto fail; 7490 goto fail;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 22c40d37c242..92a7c62c8aec 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -177,34 +177,6 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
177 return (max_link_clock * max_lanes * 8) / 10; 177 return (max_link_clock * max_lanes * 8) / 10;
178} 178}
179 179
180static bool
181intel_dp_adjust_dithering(struct intel_dp *intel_dp,
182 struct drm_display_mode *mode,
183 bool adjust_mode)
184{
185 int max_link_clock =
186 drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
187 int max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
188 int max_rate, mode_rate;
189
190 mode_rate = intel_dp_link_required(mode->clock, 24);
191 max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
192
193 if (mode_rate > max_rate) {
194 mode_rate = intel_dp_link_required(mode->clock, 18);
195 if (mode_rate > max_rate)
196 return false;
197
198 if (adjust_mode)
199 mode->private_flags
200 |= INTEL_MODE_DP_FORCE_6BPC;
201
202 return true;
203 }
204
205 return true;
206}
207
208static int 180static int
209intel_dp_mode_valid(struct drm_connector *connector, 181intel_dp_mode_valid(struct drm_connector *connector,
210 struct drm_display_mode *mode) 182 struct drm_display_mode *mode)
@@ -212,6 +184,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
212 struct intel_dp *intel_dp = intel_attached_dp(connector); 184 struct intel_dp *intel_dp = intel_attached_dp(connector);
213 struct intel_connector *intel_connector = to_intel_connector(connector); 185 struct intel_connector *intel_connector = to_intel_connector(connector);
214 struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; 186 struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
187 int target_clock = mode->clock;
188 int max_rate, mode_rate, max_lanes, max_link_clock;
215 189
216 if (is_edp(intel_dp) && fixed_mode) { 190 if (is_edp(intel_dp) && fixed_mode) {
217 if (mode->hdisplay > fixed_mode->hdisplay) 191 if (mode->hdisplay > fixed_mode->hdisplay)
@@ -221,7 +195,13 @@ intel_dp_mode_valid(struct drm_connector *connector,
221 return MODE_PANEL; 195 return MODE_PANEL;
222 } 196 }
223 197
224 if (!intel_dp_adjust_dithering(intel_dp, mode, false)) 198 max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
199 max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
200
201 max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
202 mode_rate = intel_dp_link_required(target_clock, 18);
203
204 if (mode_rate > max_rate)
225 return MODE_CLOCK_HIGH; 205 return MODE_CLOCK_HIGH;
226 206
227 if (mode->clock < 10000) 207 if (mode->clock < 10000)
@@ -693,6 +673,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
693 struct intel_crtc_config *pipe_config) 673 struct intel_crtc_config *pipe_config)
694{ 674{
695 struct drm_device *dev = encoder->base.dev; 675 struct drm_device *dev = encoder->base.dev;
676 struct drm_i915_private *dev_priv = dev->dev_private;
696 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; 677 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
697 struct drm_display_mode *mode = &pipe_config->requested_mode; 678 struct drm_display_mode *mode = &pipe_config->requested_mode;
698 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); 679 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@ -702,6 +683,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
702 int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; 683 int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
703 int bpp, mode_rate; 684 int bpp, mode_rate;
704 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; 685 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
686 int target_clock, link_avail, link_clock;
705 687
706 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp)) 688 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp))
707 pipe_config->has_pch_encoder = true; 689 pipe_config->has_pch_encoder = true;
@@ -713,6 +695,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
713 intel_connector->panel.fitting_mode, 695 intel_connector->panel.fitting_mode,
714 mode, adjusted_mode); 696 mode, adjusted_mode);
715 } 697 }
698 /* We need to take the panel's fixed mode into account. */
699 target_clock = adjusted_mode->clock;
716 700
717 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 701 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
718 return false; 702 return false;
@@ -721,11 +705,31 @@ intel_dp_compute_config(struct intel_encoder *encoder,
721 "max bw %02x pixel clock %iKHz\n", 705 "max bw %02x pixel clock %iKHz\n",
722 max_lane_count, bws[max_clock], adjusted_mode->clock); 706 max_lane_count, bws[max_clock], adjusted_mode->clock);
723 707
724 if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true)) 708 /* Walk through all bpp values. Luckily they're all nicely spaced with 2
725 return false; 709 * bpc in between. */
710 bpp = 8*3;
711 if (is_edp(intel_dp) && dev_priv->edp.bpp)
712 bpp = min_t(int, bpp, dev_priv->edp.bpp);
713
714 for (; bpp >= 6*3; bpp -= 2*3) {
715 mode_rate = intel_dp_link_required(target_clock, bpp);
716
717 for (clock = 0; clock <= max_clock; clock++) {
718 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
719 link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
720 link_avail = intel_dp_max_data_rate(link_clock,
721 lane_count);
722
723 if (mode_rate <= link_avail) {
724 goto found;
725 }
726 }
727 }
728 }
726 729
727 bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; 730 return false;
728 731
732found:
729 if (intel_dp->color_range_auto) { 733 if (intel_dp->color_range_auto) {
730 /* 734 /*
731 * See: 735 * See:
@@ -741,31 +745,18 @@ intel_dp_compute_config(struct intel_encoder *encoder,
741 if (intel_dp->color_range) 745 if (intel_dp->color_range)
742 pipe_config->limited_color_range = true; 746 pipe_config->limited_color_range = true;
743 747
744 mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); 748 intel_dp->link_bw = bws[clock];
745 749 intel_dp->lane_count = lane_count;
746 for (clock = 0; clock <= max_clock; clock++) { 750 adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
747 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { 751 pipe_config->pipe_bpp = bpp;
748 int link_bw_clock =
749 drm_dp_bw_code_to_link_rate(bws[clock]);
750 int link_avail = intel_dp_max_data_rate(link_bw_clock,
751 lane_count);
752
753 if (mode_rate <= link_avail) {
754 intel_dp->link_bw = bws[clock];
755 intel_dp->lane_count = lane_count;
756 adjusted_mode->clock = link_bw_clock;
757 DRM_DEBUG_KMS("DP link bw %02x lane "
758 "count %d clock %d bpp %d\n",
759 intel_dp->link_bw, intel_dp->lane_count,
760 adjusted_mode->clock, bpp);
761 DRM_DEBUG_KMS("DP link bw required %i available %i\n",
762 mode_rate, link_avail);
763 return true;
764 }
765 }
766 }
767 752
768 return false; 753 DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
754 intel_dp->link_bw, intel_dp->lane_count,
755 adjusted_mode->clock, bpp);
756 DRM_DEBUG_KMS("DP link bw required %i available %i\n",
757 mode_rate, link_avail);
758
759 return true;
769} 760}
770 761
771void 762void
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0ca0d7691e35..5c7b04b41702 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -101,9 +101,6 @@
101#define INTEL_DVO_CHIP_TMDS 2 101#define INTEL_DVO_CHIP_TMDS 2
102#define INTEL_DVO_CHIP_TVOUT 4 102#define INTEL_DVO_CHIP_TVOUT 4
103 103
104/* drm_display_mode->private_flags */
105#define INTEL_MODE_DP_FORCE_6BPC (0x10)
106
107struct intel_framebuffer { 104struct intel_framebuffer {
108 struct drm_framebuffer base; 105 struct drm_framebuffer base;
109 struct drm_i915_gem_object *obj; 106 struct drm_i915_gem_object *obj;