Reviewed-by: <manasi.d.navare@xxxxxxxxx> Manasi On Tue, Mar 28, 2017 at 05:59:07PM +0300, Jani Nikula wrote: > Now that source rates are static and sink rates are updated whenever > DPCD is updated, we can do and cache the intersection of them whenever > sink rates are updated. This reduces code complexity, as we don't have > to keep calling the functions to intersect. We also get rid of several > common rates arrays on stack. > > Limiting the common rates by a max link rate can be done by picking the > first N elements of the cached common rates. > > v2: get rid of the local common_rates variable (Manasi) > v3: don't clobber cached eDP rates on short pulse (Ville) > > Cc: Manasi Navare <manasi.d.navare@xxxxxxxxx> > Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > drivers/gpu/drm/i915/intel_dp.c | 75 ++++++++++++++++++++++------------------ > drivers/gpu/drm/i915/intel_drv.h | 3 ++ > 2 files changed, 45 insertions(+), 33 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index e4650f1625cc..1808af6d635d 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -284,17 +284,29 @@ static int intel_dp_rate_index(const int *rates, int len, int rate) > return -1; > } > > -static int intel_dp_common_rates(struct intel_dp *intel_dp, > - int *common_rates) > +static void intel_dp_set_common_rates(struct intel_dp *intel_dp) > { > - int max_rate = intel_dp->max_sink_link_rate; > - int i, common_len; > + WARN_ON(!intel_dp->num_source_rates || !intel_dp->num_sink_rates); > > - common_len = intersect_rates(intel_dp->source_rates, > - intel_dp->num_source_rates, > - intel_dp->sink_rates, > - intel_dp->num_sink_rates, > - common_rates); > + intel_dp->num_common_rates = intersect_rates(intel_dp->source_rates, > + intel_dp->num_source_rates, > + intel_dp->sink_rates, > + intel_dp->num_sink_rates, > + intel_dp->common_rates); > + > + /* Paranoia, there should always be something in common. */ > + if (WARN_ON(intel_dp->num_common_rates == 0)) { > + intel_dp->common_rates[0] = default_rates[0]; > + intel_dp->num_common_rates = 1; > + } > +} > + > +/* get length of common rates potentially limited by max_rate */ > +static int intel_dp_common_len_rate_limit(struct intel_dp *intel_dp, > + int max_rate) > +{ > + const int *common_rates = intel_dp->common_rates; > + int i, common_len = intel_dp->num_common_rates; > > /* Limit results by potentially reduced max rate */ > for (i = 0; i < common_len; i++) { > @@ -305,25 +317,23 @@ static int intel_dp_common_rates(struct intel_dp *intel_dp, > return 0; > } > > -static int intel_dp_link_rate_index(struct intel_dp *intel_dp, > - int *common_rates, int link_rate) > +static int intel_dp_link_rate_index(struct intel_dp *intel_dp, int link_rate) > { > int common_len; > > - common_len = intel_dp_common_rates(intel_dp, common_rates); > + common_len = intel_dp_common_len_rate_limit(intel_dp, > + intel_dp->max_sink_link_rate); > > - return intel_dp_rate_index(common_rates, common_len, link_rate); > + return intel_dp_rate_index(intel_dp->common_rates, common_len, link_rate); > } > > int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, > int link_rate, uint8_t lane_count) > { > - int common_rates[DP_MAX_SUPPORTED_RATES]; > + const int *common_rates = intel_dp->common_rates; > int link_rate_index; > > - link_rate_index = intel_dp_link_rate_index(intel_dp, > - common_rates, > - link_rate); > + link_rate_index = intel_dp_link_rate_index(intel_dp, link_rate); > if (link_rate_index > 0) { > intel_dp->max_sink_link_rate = common_rates[link_rate_index - 1]; > intel_dp->max_sink_lane_count = lane_count; > @@ -1506,8 +1516,6 @@ static void snprintf_int_array(char *str, size_t len, > > static void intel_dp_print_rates(struct intel_dp *intel_dp) > { > - int common_len; > - int common_rates[DP_MAX_SUPPORTED_RATES]; > char str[128]; /* FIXME: too big for stack? */ > > if ((drm_debug & DRM_UT_KMS) == 0) > @@ -1521,8 +1529,8 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp) > intel_dp->sink_rates, intel_dp->num_sink_rates); > DRM_DEBUG_KMS("sink rates: %s\n", str); > > - common_len = intel_dp_common_rates(intel_dp, common_rates); > - snprintf_int_array(str, sizeof(str), common_rates, common_len); > + snprintf_int_array(str, sizeof(str), > + intel_dp->common_rates, intel_dp->num_common_rates); > DRM_DEBUG_KMS("common rates: %s\n", str); > } > > @@ -1560,14 +1568,14 @@ bool intel_dp_read_desc(struct intel_dp *intel_dp) > int > intel_dp_max_link_rate(struct intel_dp *intel_dp) > { > - int rates[DP_MAX_SUPPORTED_RATES] = {}; > int len; > > - len = intel_dp_common_rates(intel_dp, rates); > + len = intel_dp_common_len_rate_limit(intel_dp, > + intel_dp->max_sink_link_rate); > if (WARN_ON(len <= 0)) > return 162000; > > - return rates[len - 1]; > + return intel_dp->common_rates[len - 1]; > } > > int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) > @@ -1636,11 +1644,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, > int link_rate_index; > int bpp, mode_rate; > int link_avail, link_clock; > - int common_rates[DP_MAX_SUPPORTED_RATES] = {}; > int common_len; > uint8_t link_bw, rate_select; > > - common_len = intel_dp_common_rates(intel_dp, common_rates); > + common_len = intel_dp_common_len_rate_limit(intel_dp, > + intel_dp->max_sink_link_rate); > > /* No common link rates between source and sink */ > WARN_ON(common_len <= 0); > @@ -1678,7 +1686,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, > /* Use values requested by Compliance Test Request */ > if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { > link_rate_index = intel_dp_link_rate_index(intel_dp, > - common_rates, > intel_dp->compliance.test_link_rate); > if (link_rate_index >= 0) > min_clock = max_clock = link_rate_index; > @@ -1686,7 +1693,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, > } > DRM_DEBUG_KMS("DP link computation with max lane count %i " > "max bw %d pixel clock %iKHz\n", > - max_lane_count, common_rates[max_clock], > + max_lane_count, intel_dp->common_rates[max_clock], > adjusted_mode->crtc_clock); > > /* Walk through all bpp values. Luckily they're all nicely spaced with 2 > @@ -1722,7 +1729,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, > lane_count <= max_lane_count; > lane_count <<= 1) { > > - link_clock = common_rates[clock]; > + link_clock = intel_dp->common_rates[clock]; > link_avail = intel_dp_max_data_rate(link_clock, > lane_count); > > @@ -1754,7 +1761,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, > pipe_config->lane_count = lane_count; > > pipe_config->pipe_bpp = bpp; > - pipe_config->port_clock = common_rates[clock]; > + pipe_config->port_clock = intel_dp->common_rates[clock]; > > intel_dp_compute_rate(intel_dp, pipe_config->port_clock, > &link_bw, &rate_select); > @@ -3715,6 +3722,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) > else > intel_dp_set_sink_rates(intel_dp); > > + intel_dp_set_common_rates(intel_dp); > + > return true; > } > > @@ -3726,8 +3735,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) > return false; > > /* Don't clobber cached eDP rates. */ > - if (!is_edp(intel_dp)) > + if (!is_edp(intel_dp)) { > intel_dp_set_sink_rates(intel_dp); > + intel_dp_set_common_rates(intel_dp); > + } > > if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT, > &intel_dp->sink_count, 1) < 0) > @@ -3950,7 +3961,6 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp) > { > int status = 0; > int min_lane_count = 1; > - int common_rates[DP_MAX_SUPPORTED_RATES] = {}; > int link_rate_index, test_link_rate; > uint8_t test_lane_count, test_link_bw; > /* (DP CTS 1.2) > @@ -3979,7 +3989,6 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp) > /* Validate the requested link rate */ > test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); > link_rate_index = intel_dp_link_rate_index(intel_dp, > - common_rates, > test_link_rate); > if (link_rate_index < 0) > return DP_TEST_NAK; > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index f8140b06679d..ec8985b20616 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -956,6 +956,9 @@ struct intel_dp { > int num_sink_rates; > int sink_rates[DP_MAX_SUPPORTED_RATES]; > bool use_rate_select; > + /* intersection of source and sink rates */ > + int num_common_rates; > + int common_rates[DP_MAX_SUPPORTED_RATES]; > /* Max lane count for the sink as per DPCD registers */ > uint8_t max_sink_lane_count; > /* Max link BW for the sink as per DPCD registers */ > -- > 2.1.4 > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx