diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c06d575ebd32..c132225ed61e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -357,15 +357,17 @@ static int intel_dp_get_max_common_lane_count(struct intel_dp *intel_dp) int intel_dp_max_lane_count(struct intel_dp *intel_dp) { struct intel_dp_link_caps *link_caps = intel_dp->link.caps; + struct intel_dp_link_config max_link_limits; struct intel_dp_link_config forced_params; int lane_count; + intel_dp_link_caps_get_max_limits(link_caps, &max_link_limits); intel_dp_link_caps_get_forced_params(link_caps, &forced_params); if (forced_params.lane_count) lane_count = forced_params.lane_count; else - lane_count = intel_dp->link.max_lane_count; + lane_count = max_link_limits.lane_count; switch (lane_count) { case 1: @@ -1539,6 +1541,7 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp) { struct intel_dp_link_caps *link_caps = intel_dp->link.caps; + struct intel_dp_link_config max_link_limits; struct intel_dp_link_config forced_params; int len; @@ -1547,7 +1550,8 @@ intel_dp_max_link_rate(struct intel_dp *intel_dp) if (forced_params.rate) return forced_params.rate; - len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate); + intel_dp_link_caps_get_max_limits(link_caps, &max_link_limits); + len = intel_dp_common_len_rate_limit(intel_dp, max_link_limits.rate); return intel_dp_common_rate(intel_dp, len - 1); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c index b227c9a55f63..fa7dabc94ddf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c @@ -151,6 +151,36 @@ static int intel_dp_link_config_lane_count(const struct intel_dp_link_config_ent return 1 << lc->lane_count_exp; } +/** + * intel_dp_link_caps_get_max_limits - get the current maximum link limits + * @link_caps: link capabilities state + * @max_link_limits: returned maximum link limits + * + * Return the current maximum rate and lane count limits in + * @max_link_limits. + * + * These limits constrain the set of allowed configurations. + * + * The limits are set to the maximum common supported values after + * intel_dp_link_caps_reset() is called, and can later be modified by + * intel_dp_link_caps_set_max_limits(). The max rate and lane count + * parameters are independent limits, so the pair does not necessarily + * define a valid configuration. + * + * This function may be called without serializing against updates to + * @link_caps. However, without such serialization the returned value may be + * an out-of-sync (link rate, lane count) tuple, i.e. the parameters may + * belong to different update snapshots in time. + */ +void intel_dp_link_caps_get_max_limits(struct intel_dp_link_caps *link_caps, + struct intel_dp_link_config *max_link_limits) +{ + struct intel_dp *intel_dp = link_caps->dp; + + max_link_limits->rate = intel_dp->link.max_rate; + max_link_limits->lane_count = intel_dp->link.max_lane_count; +} + static int intel_dp_link_config_bw(struct intel_dp *intel_dp, const struct intel_dp_link_config_entry *lc) { @@ -482,6 +512,7 @@ static int i915_dp_max_link_rate_show(void *data, u64 *val) struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_dp_link_config max_link_limits; int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -490,7 +521,8 @@ static int i915_dp_max_link_rate_show(void *data, u64 *val) intel_dp_flush_connector_commits(connector); - *val = intel_dp->link.max_rate; + intel_dp_link_caps_get_max_limits(intel_dp->link.caps, &max_link_limits); + *val = max_link_limits.rate; drm_modeset_unlock(&display->drm->mode_config.connection_mutex); @@ -503,6 +535,7 @@ static int i915_dp_max_lane_count_show(void *data, u64 *val) struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_dp_link_config max_link_limits; int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -511,7 +544,8 @@ static int i915_dp_max_lane_count_show(void *data, u64 *val) intel_dp_flush_connector_commits(connector); - *val = intel_dp->link.max_lane_count; + intel_dp_link_caps_get_max_limits(intel_dp->link.caps, &max_link_limits); + *val = max_link_limits.lane_count; drm_modeset_unlock(&display->drm->mode_config.connection_mutex); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h index 9218cb5de2c7..376dbd9bd5ab 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h @@ -27,6 +27,9 @@ void intel_dp_link_caps_get_forced_params(struct intel_dp_link_caps *link_caps, int intel_dp_link_config_index(struct intel_dp *intel_dp, int link_rate, int lane_count); void intel_dp_link_config_get(struct intel_dp *intel_dp, int idx, int *link_rate, int *lane_count); +void intel_dp_link_caps_get_max_limits(struct intel_dp_link_caps *link_caps, + struct intel_dp_link_config *max_link_limits); + bool intel_dp_link_caps_update(struct intel_dp *intel_dp, const int *rates, int num_rates, int max_lane_count); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index ec9bd9b4c800..7145f2d0ad6d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -2389,6 +2389,8 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp, bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, u8 lane_count) { + struct intel_dp_link_config max_link_limits; + /* * FIXME: we need to synchronize the current link parameters with * hardware readout. Currently fast link training doesn't work on @@ -2411,12 +2413,14 @@ bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, * configuration. Although that happens to be true for now, it will * stop being guaranteed once fallback depends only on disabled configs. */ + intel_dp_link_caps_get_max_limits(intel_dp->link.caps, &max_link_limits); + if (link_rate == 0 || - link_rate > intel_dp->link.max_rate) + link_rate > max_link_limits.rate) return false; if (lane_count == 0 || - lane_count > intel_dp_max_lane_count(intel_dp)) + lane_count > max_link_limits.lane_count) return false; return true;