From 9bfe76d15704a680559d573d00d074a47eea764d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 11 Jul 2019 17:52:26 +0300 Subject: [PATCH] drm/i915: Try to use fast+narrow link on eDP again and fall back to the old max strategy on failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some new eDP panels don't like to operate at the max parameters, and instead we need to go for an optimal confiugration. That unfortunately doesn't work with older eDP panels which are generally only guaranteed to work at the max parameters. To solve these two conflicting requirements let's start with the optimal setup, and if that fails we start again with the max parameters. The downside is probably an extra modeset when we switch strategies but I don't see a good way to avoid that. For a bit of history we first tried to go for the fast+narrow in commit 7769db588384 ("drm/i915/dp: optimize eDP 1.4+ link config fast and narrow"). but that had to be reverted due to regression on older panels in commit f11cb1c19ad0 ("drm/i915/dp: revert back to max link rate and lane count on eDP"). So now we try to get the best of both worlds by using both strategies. Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Manasi Navare Cc: Albert Astals Cid # v5.0 backport Cc: Emanuele Panigati # v5.0 backport Cc: Matteo Iervasi # v5.0 backport References: https://bugs.freedesktop.org/show_bug.cgi?id=105267 References: https://bugs.freedesktop.org/show_bug.cgi?id=109959 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110511 Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_dp.c | 72 +++++++++++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a9db16de2999..729f52cd7aa7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -462,6 +462,12 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, { int index; + if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) { + DRM_DEBUG_KMS("Retrying Link training for eDP with max parameters\n"); + intel_dp->use_max_params = true; + return 0; + } + index = intel_dp_rate_index(intel_dp->common_rates, intel_dp->num_common_rates, link_rate); @@ -1879,6 +1885,42 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return -EINVAL; } +/* Optimize link config in order: max bpp, min lanes, min clock */ +static int +intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + const struct link_config_limits *limits) +{ + struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; + int bpp, clock, lane_count; + int mode_rate, link_clock, link_avail; + + for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { + mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, + bpp); + + for (lane_count = limits->min_lane_count; + lane_count <= limits->max_lane_count; + lane_count <<= 1) { + for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { + link_clock = intel_dp->common_rates[clock]; + link_avail = intel_dp_max_data_rate(link_clock, + lane_count); + + if (mode_rate <= link_avail) { + pipe_config->lane_count = lane_count; + pipe_config->pipe_bpp = bpp; + pipe_config->port_clock = link_clock; + + return 0; + } + } + } + } + + return -EINVAL; +} + static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) { int i, num_bpc; @@ -2026,13 +2068,14 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.min_bpp = intel_dp_min_bpp(pipe_config); limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); - if (intel_dp_is_edp(intel_dp)) { + if (intel_dp->use_max_params) { /* * Use the maximum clock and number of lanes the eDP panel - * advertizes being capable of. The panels are generally + * advertizes being capable of in case the initial fast + * optimal params failed us. The panels are generally * designed to support only a single clock and lane - * configuration, and typically these values correspond to the - * native resolution of the panel. + * configuration, and typically on older panels these + * values correspond to the native resolution of the panel. */ limits.min_lane_count = limits.max_lane_count; limits.min_clock = limits.max_clock; @@ -2046,11 +2089,22 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, intel_dp->common_rates[limits.max_clock], limits.max_bpp, adjusted_mode->crtc_clock); - /* - * Optimize for slow and wide. This is the place to add alternative - * optimization policy. - */ - ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); + if (intel_dp_is_edp(intel_dp)) + /* + * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 + * section A.1: "It is recommended that the minimum number of + * lanes be used, using the minimum link rate allowed for that + * lane configuration." + * + * Note that we fall back to the max clock and lane count for eDP + * panels that fail at the fast optimal settings (see + * intel_dp->use_max_paramss) so and fast vs. wide is irrelevant + * there. + */ + ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, &limits); + else + /* Optimize for slow and wide. */ + ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); /* enable compression if the mode doesn't fit available BW */ DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 770f9f6aad84..1197f38c52df 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1130,6 +1130,7 @@ struct intel_dp { bool link_trained; bool has_audio; bool reset_link_params; + bool use_max_params; u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE]; u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; -- 2.21.0