diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-26 19:44:59 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-27 20:09:34 -0400 |
commit | 3600836585e3fdef0a1410d63fe5ce4015007aac (patch) | |
tree | 21c28335d65a83913e8d187ba24cb67f452e1d9f /drivers/gpu/drm/i915 | |
parent | 4e53c2e010e531b4a014692199e978482d471c7e (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.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 103 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 |
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 | ||
180 | static bool | ||
181 | intel_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 | |||
208 | static int | 180 | static int |
209 | intel_dp_mode_valid(struct drm_connector *connector, | 181 | intel_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 | ||
732 | found: | ||
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 | ||
771 | void | 762 | void |
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 | |||
107 | struct intel_framebuffer { | 104 | struct 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; |