All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kahola <mika.kahola@intel.com>
To: Manasi Navare <manasi.d.navare@intel.com>,
	intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v13 13/14] drm/i915/dp: Enable Upfront link training for typeC DP support on HSW/BDW/SKL/BXT (DDI platforms)
Date: Thu, 08 Sep 2016 15:10:43 +0300	[thread overview]
Message-ID: <1473336643.9143.2.camel@intel.com> (raw)
In-Reply-To: <1473272883-28520-4-git-send-email-manasi.d.navare@intel.com>

On Wed, 2016-09-07 at 11:28 -0700, Manasi Navare wrote:
> From: Durgadoss R <durgadoss.r@intel.com>
> 
> To support USB type C alternate DP mode, the display driver needs to
> know the number of lanes required by the DP panel as well as number
> of lanes that can be supported by the type-C cable. Sometimes, the
> type-C cable may limit the bandwidth even if Panel can support
> more lanes. To address these scenarios, the display driver will
> start link training with max lanes, and if that fails, the driver
> falls back to x2 lanes; and repeats this procedure for all
> bandwidth/lane configurations.
> 
> * Since link training is done before modeset only the port
>   (and not pipe/planes) and its associated PLLs are enabled.
> * On DP hotplug: Directly start link training on the DP encoder.
> * On Connected boot scenarios: When booted with an LFP and a DP,
>   sometimes BIOS brings up DP. In these cases, we disable the
>   crtc and then do upfront link training; and bring it back up.
> * All local changes made for upfront link training are reset
>   to their previous values once it is done; so that the
>   subsequent modeset is not aware of these changes.
> 
> Changes since v12:
> * Fix Rebase issues (Mika Kahola)
> Changes since v11:
> * Change the fallback link rate logic (Manasi)
> Changes since v10:
> * Use the ddi link train function that loops through all the link
> rates
> and lane counts starting from the highest supported (Manasi)
> * For upfront link training, set the upfront flag so that the link
> can
> be disabled after caching upfront values (Manasi)
> Changes since v9:
> * Change the macros to use dev_priv in place of dev (David Weinehall)
> Changes since v8:
> * Reset upfront lane count and link rate values on HPD
> for DP connector physical disconnect (Manasi)
> Changes since v7:
> * Move the upfront link training to intel_dp_mode_valid()
>   to avoid a race condition with DP MST sideband comms. (Ville)
> Changes since v6:
> * Fix some initialization bugs on link_rate (Jim Bride)
> * Use link_rate (and not link_bw) for upfront (Ville)
> * Make intel_dp_upfront*() as a vfunc (Ander)
> * The train_set_valid variable in intel_dp was removed due to
>   issues in fast link training. So, to indicate the link train
>   status, move the channel_eq inside intel_dp.
> Changes since v5:
> * Moved retry logic in upfront to intel_dp.c so that it
>   can be used for all platforms.
> Changes since v4:
> * Removed usage of crtc_state in upfront link training;
>   Hence no need to find free crtc to do upfront now.
> * Re-enable crtc if it was disabled for upfront.
> * Use separate variables to track max lane count
>   and link rate found by upfront, without modifying
>   the original DPCD read from panel.
> Changes since v3:
> * Fixed a return value on BXT check
> * Reworked on top of bxt_ddi_pll_select split from Ander
> * Renamed from ddi_upfront to bxt_upfront since the
>   upfront logic includes BXT specific functions for now.
> Changes since v2:
> * Rebased on top of latest dpll_mgr.c code and
>   latest HPD related clean ups.
> * Corrected return values from upfront (Ander)
> * Corrected atomic locking for upfront in intel_dp.c (Ville)
> Changes since v1:
> *  all pll related functions inside ddi.c
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c              |  21 +-
>  drivers/gpu/drm/i915/intel_dp.c               | 376
> +++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_dp_link_training.c |   1 -
>  drivers/gpu/drm/i915/intel_drv.h              |  14 +-
>  4 files changed, 310 insertions(+), 102 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index da2b804..b32f7ba 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1673,7 +1673,8 @@ static void intel_ddi_pre_enable_dp(struct
> intel_encoder *encoder,
>  	pll->config.crtc_mask = 0;
>  
>  	/* If Link Training fails, send a uevent to generate a
> hotplug */
> -	if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count,
> link_mst)))
> +	if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count,
> link_mst,
> +				   false)))
>  		drm_kms_helper_hotplug_event(encoder->base.dev);
>  	pll->config = tmp_pll_config;
>  }
> @@ -2460,7 +2461,7 @@ intel_ddi_get_link_dpll(struct intel_dp
> *intel_dp, int clock)
>  
>  bool
>  intel_ddi_link_train(struct intel_dp *intel_dp, int max_link_rate,
> -		     uint8_t max_lane_count, bool link_mst)
> +		     uint8_t max_lane_count, bool link_mst, bool
> is_upfront)
>  {
>  	struct intel_connector *connector = intel_dp-
> >attached_connector;
>  	struct intel_encoder *encoder = connector->encoder;
> @@ -2506,6 +2507,7 @@ intel_ddi_link_train(struct intel_dp *intel_dp,
> int max_link_rate,
>  			pll->funcs.disable(dev_priv, pll);
>  			pll->config = tmp_pll_config;
>  		}
> +
>  		if (ret) {
>  			DRM_DEBUG_KMS("Link Training successful at
> link rate: "
>  				      "%d lane:%d\n", link_rate,
> lane_count);
> @@ -2514,6 +2516,21 @@ intel_ddi_link_train(struct intel_dp
> *intel_dp, int max_link_rate,
>  	}
>  	intel_dp_stop_link_train(intel_dp);
>  
> +	if (is_upfront) {
> +		DRM_DEBUG_KMS("Upfront link train %s: link_clock:%d
> lanes:%d\n",
> +			      ret ? "Passed" : "Failed",
> +			      link_rate, lane_count);
> +		/* Disable port followed by PLL for next retry/clean
> up */
> +		intel_ddi_post_disable(encoder, NULL, NULL);
> +		pll->funcs.disable(dev_priv, pll);
> +		pll->config = tmp_pll_config;
> +		if (ret) {
> +			/* Save the upfront values */
> +			intel_dp->max_lanes_upfront = lane_count;
> +			intel_dp->max_link_rate_upfront = link_rate;
> +		}
> +	}
> +
>  	if (!lane_count)
>  		DRM_ERROR("Link Training Failed\n");
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 714fbe3..7794180 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -153,12 +153,21 @@ intel_dp_max_link_bw(struct
> intel_dp  *intel_dp)
>  static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
>  {
>  	struct intel_digital_port *intel_dig_port =
> dp_to_dig_port(intel_dp);
> -	u8 source_max, sink_max;
> +	u8 temp, source_max, sink_max;
>  
>  	source_max = intel_dig_port->max_lanes;
>  	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
>  
> -	return min(source_max, sink_max);
> +	temp = min(source_max, sink_max);
> +
> +	/*
> +	 * Limit max lanes w.r.t to the max value found
> +	 * using Upfront link training also.
> +	 */
> +	if (intel_dp->max_lanes_upfront)
> +		return min(temp, intel_dp->max_lanes_upfront);
> +	else
> +		return temp;
>  }
>  
>  /*
> @@ -190,6 +199,229 @@ intel_dp_max_data_rate(int max_link_clock, int
> max_lanes)
>  	return (max_link_clock * max_lanes * 8) / 10;
>  }
>  
> +static int intel_dp_upfront_crtc_disable(struct intel_crtc *crtc,
> +				struct drm_modeset_acquire_ctx *ctx,
> +				bool enable)
Indentation seems a bit off.

> +{
> +	int ret;
> +	struct drm_atomic_state *state;
> +	struct intel_crtc_state *crtc_state;
> +	struct drm_device *dev = crtc->base.dev;
> +	enum pipe pipe = crtc->pipe;
> +
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state)
> +		return -ENOMEM;
> +
> +	state->acquire_ctx = ctx;
> +
> +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> +	if (IS_ERR(crtc_state)) {
> +		ret = PTR_ERR(crtc_state);
> +		drm_atomic_state_free(state);
> +		return ret;
> +	}
> +
> +	DRM_DEBUG_KMS("%sabling crtc %c %s upfront link train\n",
> +			enable ? "En" : "Dis",
> +			pipe_name(pipe),
> +			enable ? "after" : "before");
> +
> +	crtc_state->base.active = enable;
> +	ret = drm_atomic_commit(state);
> +	if (ret)
> +		drm_atomic_state_free(state);
> +
> +	return ret;
> +}
> +
> +static int
> +intel_dp_sink_rates(struct intel_dp *intel_dp, const int
> **sink_rates)
> +{
> +	if (intel_dp->num_sink_rates) {
> +		*sink_rates = intel_dp->sink_rates;
> +		return intel_dp->num_sink_rates;
> +	}
> +
> +	*sink_rates = default_rates;
> +
> +	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> +}
> +
> +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> +	struct drm_i915_private *dev_priv = to_i915(dig_port-
> >base.base.dev);
> +
> +	/* WaDisableHBR2:skl */
> +	if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0))
> +		return false;
> +
> +	if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) ||
> +	    IS_BROADWELL(dev_priv) || (INTEL_GEN(dev_priv) >= 9))
> +		return true;
> +	else
> +		return false;
> +}
> +
> +static int
> +intel_dp_source_rates(struct intel_dp *intel_dp, const int
> **source_rates)
> +{
> +	struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> +	struct drm_i915_private *dev_priv = to_i915(dig_port-
> >base.base.dev);
> +	int size;
> +
> +	if (IS_BROXTON(dev_priv)) {
> +		*source_rates = bxt_rates;
> +		size = ARRAY_SIZE(bxt_rates);
> +	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> +		*source_rates = skl_rates;
> +		size = ARRAY_SIZE(skl_rates);
> +	} else {
> +		*source_rates = default_rates;
> +		size = ARRAY_SIZE(default_rates);
> +	}
> +
> +	/* This depends on the fact that 5.4 is last value in the
> array */
> +	if (!intel_dp_source_supports_hbr2(intel_dp))
> +		size--;
> +
> +	return size;
> +}
> +
> +static int intersect_rates(const int *source_rates, int source_len,
> +			   const int *sink_rates, int sink_len,
> +			   int *common_rates)
> +{
> +	int i = 0, j = 0, k = 0;
> +
> +	while (i < source_len && j < sink_len) {
> +		if (source_rates[i] == sink_rates[j]) {
> +			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> +				return k;
> +			common_rates[k] = source_rates[i];
> +			++k;
> +			++i;
> +			++j;
> +		} else if (source_rates[i] < sink_rates[j]) {
> +			++i;
> +		} else {
> +			++j;
> +		}
> +	}
> +	return k;
> +}
> +
> +static int intel_dp_common_rates(struct intel_dp *intel_dp,
> +				 int *common_rates)
> +{
> +	const int *source_rates, *sink_rates;
> +	int source_len, sink_len;
> +
> +	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> +
> +	/* Cap sink rates w.r.t upfront values */
> +	if (intel_dp->max_link_rate_upfront) {
> +		int len = sink_len - 1;
> +		while (len > 0 && sink_rates[len] >
> +		       intel_dp->max_link_rate_upfront)
> +			len--;
> +		sink_len = len + 1;
> +	}
> +
> +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> +
> +	return intersect_rates(source_rates, source_len,
> +			       sink_rates, sink_len,
> +			       common_rates);
> +}
> +
> +static bool intel_dp_upfront_link_train(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *intel_dig_port =
> dp_to_dig_port(intel_dp);
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	struct drm_device *dev = intel_encoder->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct intel_crtc *intel_crtc;
> +	struct drm_crtc *crtc = NULL;
> +	struct intel_shared_dpll *pll;
> +	struct intel_shared_dpll_config tmp_pll_config;
> +	bool disable_dpll = false;
> +	int ret;
> +	bool done = false, has_mst = false;
> +	uint8_t max_lanes;
> +	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
> +	int common_len;
> +	enum intel_display_power_domain power_domain;
> +
> +	power_domain =
> intel_display_port_power_domain(intel_encoder);
> +	intel_display_power_get(dev_priv, power_domain);
> +
> +	common_len = intel_dp_common_rates(intel_dp, common_rates);
> +	max_lanes = intel_dp_max_lane_count(intel_dp);
> +	if (WARN_ON(common_len <= 0))
> +		return true;
> +
> +	drm_modeset_acquire_init(&ctx, 0);
> +retry:
> +	ret = drm_modeset_lock(&config->connection_mutex, &ctx);
> +	if (ret)
> +		goto exit_fail;
> +
> +	if (intel_encoder->base.crtc) {
> +		crtc = intel_encoder->base.crtc;
> +
> +		ret = drm_modeset_lock(&crtc->mutex, &ctx);
> +		if (ret)
> +			goto exit_fail;
> +
> +		ret = drm_modeset_lock(&crtc->primary->mutex, &ctx);
> +		if (ret)
> +			goto exit_fail;
> +
> +		intel_crtc = to_intel_crtc(crtc);
> +		pll = intel_crtc->config->shared_dpll;
> +		disable_dpll = true;
> +		has_mst = intel_crtc_has_type(intel_crtc->config,
> +					      INTEL_OUTPUT_DP_MST);
> +		ret = intel_dp_upfront_crtc_disable(intel_crtc,
> &ctx, false);
> +		if (ret)
> +			goto exit_fail;
> +	}
> +
> +	mutex_lock(&dev_priv->dpll_lock);
> +	if (disable_dpll) {
> +		/* Clear the PLL config state */
> +		tmp_pll_config = pll->config;
> +		pll->config.crtc_mask = 0;
> +	}
> +
> +	done = intel_dp->upfront_link_train(intel_dp,
> +					    common_rates[common_len-
> 1],
> +					    max_lanes,
> +					    has_mst,
> +					    true);
> +	if (disable_dpll)
> +		pll->config = tmp_pll_config;
> +
> +	mutex_unlock(&dev_priv->dpll_lock);
> +
> +	if (crtc)
> +		ret = intel_dp_upfront_crtc_disable(intel_crtc,
> &ctx, true);
> +
> +exit_fail:
> +	if (ret == -EDEADLK) {
> +		drm_modeset_backoff(&ctx);
> +		goto retry;
> +	}
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +	intel_display_power_put(dev_priv, power_domain);
> +	return done;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -211,6 +443,19 @@ intel_dp_mode_valid(struct drm_connector
> *connector,
>  		target_clock = fixed_mode->clock;
>  	}
>  
> +	if (intel_dp->upfront_link_train && !intel_dp->upfront_done) 
> {
> +		bool do_upfront_link_train;
> +		/* Do not do upfront link train, if it is a
> compliance
> +		 * request
> +		 */
> +		do_upfront_link_train = !intel_dp->upfront_done &&
> +			(intel_dp->compliance_test_type !=
> +			 DP_TEST_LINK_TRAINING);
> +
> +		if (do_upfront_link_train)
> +			intel_dp->upfront_done =
> intel_dp_upfront_link_train(intel_dp);
> +	}
> +
>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>  
> @@ -1256,60 +1501,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp,
> struct intel_connector *connector)
>  	intel_dp->aux.transfer = intel_dp_aux_transfer;
>  }
>  
> -static int
> -intel_dp_sink_rates(struct intel_dp *intel_dp, const int
> **sink_rates)
> -{
> -	if (intel_dp->num_sink_rates) {
> -		*sink_rates = intel_dp->sink_rates;
> -		return intel_dp->num_sink_rates;
> -	}
> -
> -	*sink_rates = default_rates;
> -
> -	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> -}
> -
> -bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
> -{
> -	struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -
> -	/* WaDisableHBR2:skl */
> -	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
> -		return false;
> -
> -	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) ||
> IS_BROADWELL(dev) ||
> -	    (INTEL_INFO(dev)->gen >= 9))
> -		return true;
> -	else
> -		return false;
> -}
> -
> -static int
> -intel_dp_source_rates(struct intel_dp *intel_dp, const int
> **source_rates)
> -{
> -	struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -	int size;
> -
> -	if (IS_BROXTON(dev)) {
> -		*source_rates = bxt_rates;
> -		size = ARRAY_SIZE(bxt_rates);
> -	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> -		*source_rates = skl_rates;
> -		size = ARRAY_SIZE(skl_rates);
> -	} else {
> -		*source_rates = default_rates;
> -		size = ARRAY_SIZE(default_rates);
> -	}
> -
> -	/* This depends on the fact that 5.4 is last value in the
> array */
> -	if (!intel_dp_source_supports_hbr2(intel_dp))
> -		size--;
> -
> -	return size;
> -}
> -
>  static void
>  intel_dp_set_clock(struct intel_encoder *encoder,
>  		   struct intel_crtc_state *pipe_config)
> @@ -1343,42 +1534,6 @@ intel_dp_set_clock(struct intel_encoder
> *encoder,
>  	}
>  }
>  
> -static int intersect_rates(const int *source_rates, int source_len,
> -			   const int *sink_rates, int sink_len,
> -			   int *common_rates)
> -{
> -	int i = 0, j = 0, k = 0;
> -
> -	while (i < source_len && j < sink_len) {
> -		if (source_rates[i] == sink_rates[j]) {
> -			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> -				return k;
> -			common_rates[k] = source_rates[i];
> -			++k;
> -			++i;
> -			++j;
> -		} else if (source_rates[i] < sink_rates[j]) {
> -			++i;
> -		} else {
> -			++j;
> -		}
> -	}
> -	return k;
> -}
> -
> -static int intel_dp_common_rates(struct intel_dp *intel_dp,
> -				 int *common_rates)
> -{
> -	const int *source_rates, *sink_rates;
> -	int source_len, sink_len;
> -
> -	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> -	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> -
> -	return intersect_rates(source_rates, source_len,
> -			       sink_rates, sink_len,
> -			       common_rates);
> -}
>  
>  static void snprintf_int_array(char *str, size_t len,
>  			       const int *array, int nelem)
> @@ -1436,6 +1591,9 @@ intel_dp_max_link_rate(struct intel_dp
> *intel_dp)
>  	int rates[DP_MAX_SUPPORTED_RATES] = {};
>  	int len;
>  
> +	if (intel_dp->max_link_rate_upfront)
> +		return intel_dp->max_link_rate_upfront;
> +
>  	len = intel_dp_common_rates(intel_dp, rates);
>  	if (WARN_ON(len <= 0))
>  		return 162000;
> @@ -1488,7 +1646,7 @@ intel_dp_compute_config(struct intel_encoder
> *encoder,
>  	enum port port = dp_to_dig_port(intel_dp)->port;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config-
> >base.crtc);
>  	struct intel_connector *intel_connector = intel_dp-
> >attached_connector;
> -	int lane_count, clock;
> +	int lane_count, clock = 0;
>  	int min_lane_count = 1;
>  	int max_lane_count = intel_dp_max_lane_count(intel_dp);
>  	/* Conveniently, the link BW constants become indices with a
> shift...*/
> @@ -1567,11 +1725,24 @@ intel_dp_compute_config(struct intel_encoder
> *encoder,
>  	for (; bpp >= 6*3; bpp -= 2*3) {
>  		mode_rate = intel_dp_link_required(adjusted_mode-
> >crtc_clock,
>  						   bpp);
> +		if (!is_edp(intel_dp) && intel_dp->upfront_done) {
> +			clock = max_clock;
> +			lane_count = intel_dp->max_lanes_upfront;
> +			link_clock = intel_dp-
> >max_link_rate_upfront;
> +			link_avail =
> intel_dp_max_data_rate(link_clock,
> +							    lane_cou
> nt);
> +			mode_rate =
> intel_dp_link_required(adjusted_mode->crtc_clock,
> +							   bpp);
> +			if (mode_rate <= link_avail)
> +				goto found;
> +			else
> +				continue;
> +		}
> +
>  		for (clock = max_clock; clock >= max_clock; clock--)
> {
>  			for (lane_count = max_lane_count;
>  			     lane_count >= min_lane_count;
>  			     lane_count >>= 1) {
> -
>  				link_clock = common_rates[clock];
>  				link_avail =
> intel_dp_max_data_rate(link_clock,
>  								    
> lane_count);
> @@ -1600,7 +1771,6 @@ found:
>  	}
>  
>  	pipe_config->lane_count = lane_count;
> -
>  	pipe_config->pipe_bpp = bpp;
>  	pipe_config->port_clock = common_rates[clock];
>  
> @@ -4284,7 +4454,7 @@ intel_dp_long_pulse(struct intel_connector
> *intel_connector)
>  	struct drm_device *dev = connector->dev;
>  	enum drm_connector_status status;
>  	enum intel_display_power_domain power_domain;
> -	u8 sink_irq_vector = 0;
> +	u8 sink_irq_vector;
>  
>  	power_domain =
> intel_display_port_aux_power_domain(intel_encoder);
>  	intel_display_power_get(to_i915(dev), power_domain);
> @@ -4377,9 +4547,12 @@ intel_dp_long_pulse(struct intel_connector
> *intel_connector)
>  	}
>  
>  out:
> -	if ((status != connector_status_connected) &&
> -	    (intel_dp->is_mst == false))
> +	if (status != connector_status_connected) {
>  		intel_dp_unset_edid(intel_dp);
> +		intel_dp->upfront_done = false;
> +		intel_dp->max_lanes_upfront = 0;
> +		intel_dp->max_link_rate_upfront = 0;
> +	}
>  
>  	intel_display_power_put(to_i915(dev), power_domain);
>  	return;
> @@ -5623,6 +5796,13 @@ intel_dp_init_connector(struct
> intel_digital_port *intel_dig_port,
>  	if (type == DRM_MODE_CONNECTOR_eDP)
>  		intel_encoder->type = INTEL_OUTPUT_EDP;
>  
> +	/* Initialize upfront link training vfunc for DP */
> +	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> +		if (IS_BROXTON(dev_priv) || IS_SKYLAKE(dev_priv) ||
> +		    IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
> +			intel_dp->upfront_link_train =
> intel_ddi_link_train;
> +	}
> +
>  	/* eDP only on port B and/or C on vlv/chv */
>  	if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
>  		    is_edp(intel_dp) && port != PORT_B && port !=
> PORT_C))
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c
> b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index f1e08f0..b6f380b 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -304,7 +304,6 @@
> intel_dp_link_training_channel_equalization(struct intel_dp
> *intel_dp)
>  	intel_dp_set_idle_link_train(intel_dp);
>  
>  	return intel_dp->channel_eq_status;
> -
>  }
>  
>  void intel_dp_stop_link_train(struct intel_dp *intel_dp)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index c571baf..a2bbf68 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -882,6 +882,12 @@ struct intel_dp {
>  	enum hdmi_force_audio force_audio;
>  	bool limited_color_range;
>  	bool color_range_auto;
> +
> +	/* Upfront link train parameters */
> +	int max_link_rate_upfront;
> +	uint8_t max_lanes_upfront;
> +	bool upfront_done;
> +
>  	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
>  	uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
>  	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
> @@ -939,6 +945,11 @@ struct intel_dp {
>  	/* This is called before a link training is starterd */
>  	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
>  
> +	/* For Upfront link training */
> +	bool (*upfront_link_train)(struct intel_dp *intel_dp, int
> clock,
> +				   uint8_t lane_count, bool
> link_mst,
> +				   bool is_upfront);
> +
>  	/* Displayport compliance testing */
>  	unsigned long compliance_test_type;
>  	unsigned long compliance_test_data;
> @@ -1161,7 +1172,8 @@ void intel_ddi_clock_get(struct intel_encoder
> *encoder,
>  void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool
> state);
>  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
>  bool intel_ddi_link_train(struct intel_dp *intel_dp, int
> max_link_rate,
> -			  uint8_t max_lane_count, bool link_mst);
> +			  uint8_t max_lane_count, bool link_mst,
> +			  bool is_upfront);
>  struct intel_shared_dpll *intel_ddi_get_link_dpll(struct intel_dp
> *intel_dp,
>  						  int clock);
>  unsigned int intel_fb_align_height(struct drm_device *dev,
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-09-08 12:10 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-01 22:08 [PATCH 00/14] Enable Upfront Link Training on DDI platforms Manasi Navare
2016-09-01 22:08 ` [PATCH v2 01/14] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
2016-09-01 22:08 ` [PATCH v2 02/14] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
2016-09-01 22:08 ` [PATCH v3 03/14] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
2016-09-01 22:08 ` [PATCH v2 04/14] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
2016-09-01 22:08 ` [PATCH 05/14] drm/i915: Split skl_get_dpll() Manasi Navare
2016-09-01 22:08 ` [PATCH 06/14] drm/i915: Split hsw_get_dpll() Manasi Navare
2016-09-01 22:08 ` [PATCH v3 07/14] drm/i915/dp: Add a standalone function to obtain shared dpll for HSW/BDW/SKL/BXT Manasi Navare
2016-09-02 20:06   ` Pandiyan, Dhinakaran
2016-09-07 22:08     ` Manasi Navare
2016-09-07 22:47   ` [PATCH v4 7/14] " Manasi Navare
2016-09-01 22:08 ` [PATCH 08/14] drm/i915/dp: Move max. vswing check to it's own function Manasi Navare
2016-09-02  8:05   ` Mika Kahola
2016-09-06  9:58     ` Mika Kahola
2016-09-06 21:25       ` Manasi Navare
2016-09-07  0:13   ` [PATCH v2 8/14] " Manasi Navare
2016-09-07  7:00     ` Mika Kahola
2016-09-07 18:28     ` [PATCH v3 " Manasi Navare
2016-09-08  7:38       ` Mika Kahola
2016-09-13 11:44         ` Jani Nikula
2016-09-01 22:08 ` [PATCH 09/14] drm/dp/i915: Make clock recovery in the link training compliant with DP Spec 1.2 Manasi Navare
2016-09-02  9:16   ` Mika Kahola
2016-09-02 17:55     ` Pandiyan, Dhinakaran
2016-09-07  0:13   ` [PATCH v2 9/14] " Manasi Navare
2016-09-07  7:33     ` Mika Kahola
2016-09-07 18:28     ` [PATCH v3 " Manasi Navare
2016-09-08  8:20       ` Mika Kahola
2016-09-01 22:08 ` [PATCH 10/14] drm/i915: Make DP link training channel equalization DP 1.2 Spec compliant Manasi Navare
2016-09-02 11:20   ` Mika Kahola
2016-09-02 19:05     ` Pandiyan, Dhinakaran
2016-09-07  7:50       ` Mika Kahola
2016-09-13 16:09         ` Rodrigo Vivi
2016-09-01 22:08 ` [PATCH 11/14] drm/i915: Fallback to lower link rate and lane count during link training Manasi Navare
2016-09-02 12:03   ` David Weinehall
2016-09-06 17:34     ` Manasi Navare
2016-09-02 12:49   ` David Weinehall
2016-09-06 17:54     ` Manasi Navare
2016-09-02 13:00   ` Mika Kahola
2016-09-06 18:01     ` Manasi Navare
2016-09-02 19:52   ` Pandiyan, Dhinakaran
2016-09-02 20:01     ` Jim Bride
2016-09-07  0:13   ` [PATCH v2 " Manasi Navare
2016-09-07  9:47     ` Mika Kahola
2016-09-07 16:47       ` Jim Bride
2016-09-07 16:48       ` Manasi Navare
2016-09-07 18:28     ` [PATCH v3 " Manasi Navare
2016-09-08  0:30       ` [PATCH v4 " Manasi Navare
2016-09-08  9:32         ` Mika Kahola
2016-09-09  1:05         ` Rodrigo Vivi
2016-09-09  7:11           ` Jani Nikula
2016-09-09  7:11         ` Jani Nikula
2016-09-09 17:13           ` Manasi Navare
2016-09-09 23:29         ` [PATCH v5 " Manasi Navare
2016-09-01 22:08 ` [PATCH 12/14] drm/i915: Reverse the loop in intel_dp_compute_config Manasi Navare
2016-09-02 13:08   ` Mika Kahola
2016-09-08 14:47     ` Manasi Navare
2016-09-02 20:24   ` Pandiyan, Dhinakaran
2016-09-08 20:02   ` [PATCH v2 12/14] drm/i915: Remove the link rate and lane count loop in compute config Manasi Navare
2016-09-13  1:14     ` Pandiyan, Dhinakaran
2016-09-14  1:05       ` Manasi Navare
2016-09-01 22:08 ` [PATCH v11 13/14] drm/i915/dp: Enable Upfront link training for typeC DP support on HSW/BDW/SKL/BXT (DDI platforms) Manasi Navare
2016-09-07  0:13   ` [PATCH v12 " Manasi Navare
2016-09-07 18:28     ` [PATCH v13 " Manasi Navare
2016-09-08 12:10       ` Mika Kahola [this message]
2016-09-08 15:06         ` Manasi Navare
2016-09-08 17:22       ` [PATCH v14 " Manasi Navare
2016-09-08 20:02         ` [PATCH v15 " Manasi Navare
2016-09-09  7:34           ` Jani Nikula
2016-09-09 23:29           ` [PATCH 13-1/14] drm/i915: Change the placement of some static functions in intel_dp.c Manasi Navare
2016-09-12 23:21             ` Rodrigo Vivi
2016-09-09 23:29           ` [PATCH v16 13-2/14] drm/i915/dp: Enable Upfront link training on HSW/BDW/SKL/BXT Manasi Navare
2016-09-13  0:22             ` Rodrigo Vivi
2016-09-09  7:31         ` [PATCH v14 13/14] drm/i915/dp: Enable Upfront link training for typeC DP support on HSW/BDW/SKL/BXT (DDI platforms) Jani Nikula
2016-09-01 22:08 ` [PATCH 14/14] drm/i915/dp/mst: Add support for upfront link training for DP MST Manasi Navare
2016-09-07  0:13   ` [PATCH v2 " Manasi Navare
2016-09-07 10:53     ` Mika Kahola
2016-09-07 16:40       ` Jim Bride
2016-09-08 10:21         ` Mika Kahola
2016-09-08 11:50       ` Mika Kahola
2016-09-01 22:48 ` ✗ Fi.CI.BAT: failure for Enable upfront link training on DDI platforms (rev3) Patchwork
2016-09-07  0:54 ` ✗ Fi.CI.BAT: warning for Enable upfront link training on DDI platforms (rev8) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1473336643.9143.2.camel@intel.com \
    --to=mika.kahola@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=manasi.d.navare@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.