diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 14397726d3acc..e95c469afa6da 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, } } - /* temporary hack until the DP code doesn't use the 6BPC flag any more */ - if (pipe_config->adjusted_mode.private_flags & INTEL_MODE_DP_FORCE_6BPC) - pipe_config->pipe_bpp = 6*8; - if (!(intel_crtc_compute_config(crtc, pipe_config))) { DRM_DEBUG_KMS("CRTC fixup failed\n"); goto fail; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 22c40d37c242d..92a7c62c8aec9 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) return (max_link_clock * max_lanes * 8) / 10; } -static bool -intel_dp_adjust_dithering(struct intel_dp *intel_dp, - struct drm_display_mode *mode, - bool adjust_mode) -{ - int max_link_clock = - drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); - int max_lanes = drm_dp_max_lane_count(intel_dp->dpcd); - int max_rate, mode_rate; - - mode_rate = intel_dp_link_required(mode->clock, 24); - max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); - - if (mode_rate > max_rate) { - mode_rate = intel_dp_link_required(mode->clock, 18); - if (mode_rate > max_rate) - return false; - - if (adjust_mode) - mode->private_flags - |= INTEL_MODE_DP_FORCE_6BPC; - - return true; - } - - return true; -} - static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -212,6 +184,8 @@ intel_dp_mode_valid(struct drm_connector *connector, struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; + int target_clock = mode->clock; + int max_rate, mode_rate, max_lanes, max_link_clock; if (is_edp(intel_dp) && fixed_mode) { if (mode->hdisplay > fixed_mode->hdisplay) @@ -221,7 +195,13 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_PANEL; } - if (!intel_dp_adjust_dithering(intel_dp, mode, false)) + max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp)); + max_lanes = drm_dp_max_lane_count(intel_dp->dpcd); + + max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); + mode_rate = intel_dp_link_required(target_clock, 18); + + if (mode_rate > max_rate) return MODE_CLOCK_HIGH; if (mode->clock < 10000) @@ -693,6 +673,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) { struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; struct drm_display_mode *mode = &pipe_config->requested_mode; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); @@ -702,6 +683,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; int bpp, mode_rate; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; + int target_clock, link_avail, link_clock; if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp)) pipe_config->has_pch_encoder = true; @@ -713,6 +695,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_connector->panel.fitting_mode, mode, adjusted_mode); } + /* We need to take the panel's fixed mode into account. */ + target_clock = adjusted_mode->clock; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) return false; @@ -721,11 +705,31 @@ intel_dp_compute_config(struct intel_encoder *encoder, "max bw %02x pixel clock %iKHz\n", max_lane_count, bws[max_clock], adjusted_mode->clock); - if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true)) - return false; + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ + bpp = 8*3; + if (is_edp(intel_dp) && dev_priv->edp.bpp) + bpp = min_t(int, bpp, dev_priv->edp.bpp); + + for (; bpp >= 6*3; bpp -= 2*3) { + mode_rate = intel_dp_link_required(target_clock, bpp); + + for (clock = 0; clock <= max_clock; clock++) { + for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { + link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); + link_avail = intel_dp_max_data_rate(link_clock, + lane_count); + + if (mode_rate <= link_avail) { + goto found; + } + } + } + } - bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; + return false; +found: if (intel_dp->color_range_auto) { /* * See: @@ -741,31 +745,18 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (intel_dp->color_range) pipe_config->limited_color_range = true; - mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); - - for (clock = 0; clock <= max_clock; clock++) { - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { - int link_bw_clock = - drm_dp_bw_code_to_link_rate(bws[clock]); - int link_avail = intel_dp_max_data_rate(link_bw_clock, - lane_count); - - if (mode_rate <= link_avail) { - intel_dp->link_bw = bws[clock]; - intel_dp->lane_count = lane_count; - adjusted_mode->clock = link_bw_clock; - DRM_DEBUG_KMS("DP link bw %02x lane " - "count %d clock %d bpp %d\n", - intel_dp->link_bw, intel_dp->lane_count, - adjusted_mode->clock, bpp); - DRM_DEBUG_KMS("DP link bw required %i available %i\n", - mode_rate, link_avail); - return true; - } - } - } + intel_dp->link_bw = bws[clock]; + intel_dp->lane_count = lane_count; + adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); + pipe_config->pipe_bpp = bpp; - return false; + DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", + intel_dp->link_bw, intel_dp->lane_count, + adjusted_mode->clock, bpp); + DRM_DEBUG_KMS("DP link bw required %i available %i\n", + mode_rate, link_avail); + + return true; } void diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0ca0d7691e350..5c7b04b41702e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -101,9 +101,6 @@ #define INTEL_DVO_CHIP_TMDS 2 #define INTEL_DVO_CHIP_TVOUT 4 -/* drm_display_mode->private_flags */ -#define INTEL_MODE_DP_FORCE_6BPC (0x10) - struct intel_framebuffer { struct drm_framebuffer base; struct drm_i915_gem_object *obj;