diff mbox

[13/15] drm/i915: Clean up CHV lane soft reset programming

Message ID 1436388361-11130-14-git-send-email-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjälä July 8, 2015, 8:45 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Currently we relesar the lane soft reset before lane stagger settings
have been programmed. I believe that means we don't actually do lane
staggering. So move the soft reset deassert to happen after lane
staggering has been programmed.

The one confusing thing in this is that when we remove the power down
override from the lanes, they power up with defaul register values,
which do not have the soft reset overrides enabled. And according to
some docs by default the data lane resets are tied to cmnreset. So that
would mean that lanes would come out of reset without staggering as
soon as the power down overrides are removed. But sine we can't access
either the lane stagger register nor the soft reset override registers
until the lanes are powered on, we can really do anything about it.
So let's just set the soft reset overrides as soon as the lane is
powered on and hope for the best.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   | 91 +++++++++++++++++++++------------------
 drivers/gpu/drm/i915/intel_hdmi.c | 91 ++++++++++++++++++++++-----------------
 2 files changed, 100 insertions(+), 82 deletions(-)

Comments

Daniel Vetter July 9, 2015, 4:27 p.m. UTC | #1
On Wed, Jul 08, 2015 at 11:45:59PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Currently we relesar the lane soft reset before lane stagger settings
               release

> have been programmed. I believe that means we don't actually do lane
> staggering. So move the soft reset deassert to happen after lane
> staggering has been programmed.
> 
> The one confusing thing in this is that when we remove the power down
> override from the lanes, they power up with defaul register values,
> which do not have the soft reset overrides enabled. And according to
> some docs by default the data lane resets are tied to cmnreset. So that
> would mean that lanes would come out of reset without staggering as
> soon as the power down overrides are removed. But sine we can't access
> either the lane stagger register nor the soft reset override registers
> until the lanes are powered on, we can really do anything about it.
                                     can't?

> So let's just set the soft reset overrides as soon as the lane is
> powered on and hope for the best.

Fun story in these patches ...
-Daniel

> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c   | 91 +++++++++++++++++++++------------------
>  drivers/gpu/drm/i915/intel_hdmi.c | 91 ++++++++++++++++++++++-----------------
>  2 files changed, 100 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 817df87..297bd14 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2389,42 +2389,62 @@ static void vlv_post_disable_dp(struct intel_encoder *encoder)
>  	intel_dp_link_down(intel_dp);
>  }
>  
> -static void chv_post_disable_dp(struct intel_encoder *encoder)
> +static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
> +				     bool reset)
>  {
> -	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> -	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = encoder->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(encoder->base.crtc);
> -	enum dpio_channel ch = vlv_dport_to_channel(dport);
> -	enum pipe pipe = intel_crtc->pipe;
> -	u32 val;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	enum pipe pipe = crtc->pipe;
> +	uint32_t val;
>  
> -	intel_dp_link_down(intel_dp);
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> +	if (reset)
> +		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +	else
> +		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> +		if (reset)
> +			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +		else
> +			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	}
>  
> -	/* Propagate soft reset to data lane reset */
>  	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
>  	val |= CHV_PCS_REQ_SOFTRESET_EN;
> +	if (reset)
> +		val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +	else
> +		val |= DPIO_PCS_CLK_SOFT_RESET;
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
>  
> -	if (intel_crtc->config->lane_count > 2) {
> +	if (crtc->config->lane_count > 2) {
>  		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
>  		val |= CHV_PCS_REQ_SOFTRESET_EN;
> +		if (reset)
> +			val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +		else
> +			val |= DPIO_PCS_CLK_SOFT_RESET;
>  		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
>  	}
> +}
>  
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> +static void chv_post_disable_dp(struct intel_encoder *encoder)
> +{
> +	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +	struct drm_device *dev = encoder->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -	}
> +	intel_dp_link_down(intel_dp);
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
>  
>  	mutex_unlock(&dev_priv->sb_lock);
>  }
> @@ -2802,27 +2822,6 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>  		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
>  	}
>  
> -	/* Deassert soft data lane reset*/
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -		val |= CHV_PCS_REQ_SOFTRESET_EN;
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -	}
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -		val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -	}
> -
>  	/* Program Tx lane latency optimal setting*/
>  	for (i = 0; i < intel_crtc->config->lane_count; i++) {
>  		/* Set the upar bit */
> @@ -2872,6 +2871,9 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>  			       DPIO_TX2_STAGGER_MULT(5));
>  	}
>  
> +	/* Deassert data lane reset */
> +	chv_data_lane_soft_reset(encoder, false);
> +
>  	mutex_unlock(&dev_priv->sb_lock);
>  
>  	intel_enable_dp(encoder);
> @@ -2910,6 +2912,9 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
>  
>  	mutex_lock(&dev_priv->sb_lock);
>  
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
> +
>  	/* program left/right clock distribution */
>  	if (pipe != PIPE_B) {
>  		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 4b604ee..176d681 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1612,6 +1612,50 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>  	mutex_unlock(&dev_priv->sb_lock);
>  }
>  
> +static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
> +				     bool reset)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	enum pipe pipe = crtc->pipe;
> +	uint32_t val;
> +
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> +	if (reset)
> +		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +	else
> +		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> +
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> +		if (reset)
> +			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +		else
> +			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	}
> +
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> +	val |= CHV_PCS_REQ_SOFTRESET_EN;
> +	if (reset)
> +		val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +	else
> +		val |= DPIO_PCS_CLK_SOFT_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> +
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> +		val |= CHV_PCS_REQ_SOFTRESET_EN;
> +		if (reset)
> +			val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +		else
> +			val |= DPIO_PCS_CLK_SOFT_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> +	}
> +}
> +
>  static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
> @@ -1637,6 +1681,9 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>  
>  	mutex_lock(&dev_priv->sb_lock);
>  
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
> +
>  	/* program left/right clock distribution */
>  	if (pipe != PIPE_B) {
>  		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
> @@ -1739,33 +1786,13 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
>  
>  static void chv_hdmi_post_disable(struct intel_encoder *encoder)
>  {
> -	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(encoder->base.crtc);
> -	enum dpio_channel ch = vlv_dport_to_channel(dport);
> -	enum pipe pipe = intel_crtc->pipe;
> -	u32 val;
>  
>  	mutex_lock(&dev_priv->sb_lock);
>  
> -	/* Propagate soft reset to data lane reset */
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
>  
>  	mutex_unlock(&dev_priv->sb_lock);
>  }
> @@ -1796,23 +1823,6 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
>  
> -	/* Deassert soft data lane reset*/
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -
>  	/* Program Tx latency optimal setting */
>  	for (i = 0; i < 4; i++) {
>  		/* Set the upar bit */
> @@ -1855,6 +1865,9 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>  		       DPIO_TX1_STAGGER_MULT(7) |
>  		       DPIO_TX2_STAGGER_MULT(5));
>  
> +	/* Deassert data lane reset */
> +	chv_data_lane_soft_reset(encoder, false);
> +
>  	/* Clear calc init */
>  	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
>  	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
> -- 
> 2.3.6
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
deepak.s@linux.intel.com Aug. 27, 2015, 4:25 a.m. UTC | #2
On 07/09/2015 02:15 AM, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Currently we relesar the lane soft reset before lane stagger settings
> have been programmed. I believe that means we don't actually do lane
> staggering. So move the soft reset deassert to happen after lane
> staggering has been programmed.
>
> The one confusing thing in this is that when we remove the power down
> override from the lanes, they power up with defaul register values,
> which do not have the soft reset overrides enabled. And according to
> some docs by default the data lane resets are tied to cmnreset. So that
> would mean that lanes would come out of reset without staggering as
> soon as the power down overrides are removed. But sine we can't access
> either the lane stagger register nor the soft reset override registers
> until the lanes are powered on, we can really do anything about it.
> So let's just set the soft reset overrides as soon as the lane is
> powered on and hope for the best.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c   | 91 +++++++++++++++++++++------------------
>   drivers/gpu/drm/i915/intel_hdmi.c | 91 ++++++++++++++++++++++-----------------
>   2 files changed, 100 insertions(+), 82 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 817df87..297bd14 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2389,42 +2389,62 @@ static void vlv_post_disable_dp(struct intel_encoder *encoder)
>   	intel_dp_link_down(intel_dp);
>   }
>   
> -static void chv_post_disable_dp(struct intel_encoder *encoder)
> +static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
> +				     bool reset)
>   {
> -	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> -	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = encoder->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(encoder->base.crtc);
> -	enum dpio_channel ch = vlv_dport_to_channel(dport);
> -	enum pipe pipe = intel_crtc->pipe;
> -	u32 val;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	enum pipe pipe = crtc->pipe;
> +	uint32_t val;
>   
> -	intel_dp_link_down(intel_dp);
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> +	if (reset)
> +		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +	else
> +		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
>   
> -	mutex_lock(&dev_priv->sb_lock);
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> +		if (reset)
> +			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +		else
> +			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	}
>   
> -	/* Propagate soft reset to data lane reset */
>   	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
>   	val |= CHV_PCS_REQ_SOFTRESET_EN;
> +	if (reset)
> +		val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +	else
> +		val |= DPIO_PCS_CLK_SOFT_RESET;
>   	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
>   
> -	if (intel_crtc->config->lane_count > 2) {
> +	if (crtc->config->lane_count > 2) {
>   		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
>   		val |= CHV_PCS_REQ_SOFTRESET_EN;
> +		if (reset)
> +			val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +		else
> +			val |= DPIO_PCS_CLK_SOFT_RESET;
>   		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
>   	}
> +}
>   
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> +static void chv_post_disable_dp(struct intel_encoder *encoder)
> +{
> +	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +	struct drm_device *dev = encoder->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>   
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -	}
> +	intel_dp_link_down(intel_dp);
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
>   
>   	mutex_unlock(&dev_priv->sb_lock);
>   }
> @@ -2802,27 +2822,6 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>   		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
>   	}
>   
> -	/* Deassert soft data lane reset*/
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -		val |= CHV_PCS_REQ_SOFTRESET_EN;
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -	}
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	if (intel_crtc->config->lane_count > 2) {
> -		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -		val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -	}
> -
>   	/* Program Tx lane latency optimal setting*/
>   	for (i = 0; i < intel_crtc->config->lane_count; i++) {
>   		/* Set the upar bit */
> @@ -2872,6 +2871,9 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>   			       DPIO_TX2_STAGGER_MULT(5));
>   	}
>   
> +	/* Deassert data lane reset */
> +	chv_data_lane_soft_reset(encoder, false);
> +
>   	mutex_unlock(&dev_priv->sb_lock);
>   
>   	intel_enable_dp(encoder);
> @@ -2910,6 +2912,9 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
>   
>   	mutex_lock(&dev_priv->sb_lock);
>   
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
> +
>   	/* program left/right clock distribution */
>   	if (pipe != PIPE_B) {
>   		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 4b604ee..176d681 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1612,6 +1612,50 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>   	mutex_unlock(&dev_priv->sb_lock);
>   }
>   
> +static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
> +				     bool reset)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	enum pipe pipe = crtc->pipe;
> +	uint32_t val;
> +
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> +	if (reset)
> +		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +	else
> +		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> +
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> +		if (reset)
> +			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> +		else
> +			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	}
> +
> +	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> +	val |= CHV_PCS_REQ_SOFTRESET_EN;
> +	if (reset)
> +		val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +	else
> +		val |= DPIO_PCS_CLK_SOFT_RESET;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> +
> +	if (crtc->config->lane_count > 2) {
> +		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> +		val |= CHV_PCS_REQ_SOFTRESET_EN;
> +		if (reset)
> +			val &= ~DPIO_PCS_CLK_SOFT_RESET;
> +		else
> +			val |= DPIO_PCS_CLK_SOFT_RESET;
> +		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> +	}
> +}
> +
>   static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>   {
>   	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
> @@ -1637,6 +1681,9 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>   
>   	mutex_lock(&dev_priv->sb_lock);
>   
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
> +
>   	/* program left/right clock distribution */
>   	if (pipe != PIPE_B) {
>   		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
> @@ -1739,33 +1786,13 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
>   
>   static void chv_hdmi_post_disable(struct intel_encoder *encoder)
>   {
> -	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>   	struct drm_device *dev = encoder->base.dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(encoder->base.crtc);
> -	enum dpio_channel ch = vlv_dport_to_channel(dport);
> -	enum pipe pipe = intel_crtc->pipe;
> -	u32 val;
>   
>   	mutex_lock(&dev_priv->sb_lock);
>   
> -	/* Propagate soft reset to data lane reset */
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> +	/* Assert data lane reset */
> +	chv_data_lane_soft_reset(encoder, true);
>   
>   	mutex_unlock(&dev_priv->sb_lock);
>   }
> @@ -1796,23 +1823,6 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>   	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
>   	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
>   
> -	/* Deassert soft data lane reset*/
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
> -	val |= CHV_PCS_REQ_SOFTRESET_EN;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
> -
> -	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
> -	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
> -
>   	/* Program Tx latency optimal setting */
>   	for (i = 0; i < 4; i++) {
>   		/* Set the upar bit */
> @@ -1855,6 +1865,9 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>   		       DPIO_TX1_STAGGER_MULT(7) |
>   		       DPIO_TX2_STAGGER_MULT(5));
>   
> +	/* Deassert data lane reset */
> +	chv_data_lane_soft_reset(encoder, false);
> +
>   	/* Clear calc init */
>   	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
>   	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
Changes looks fine
Reviewed-by: Deepak S <deepak.s@linux.intel.com>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 817df87..297bd14 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2389,42 +2389,62 @@  static void vlv_post_disable_dp(struct intel_encoder *encoder)
 	intel_dp_link_down(intel_dp);
 }
 
-static void chv_post_disable_dp(struct intel_encoder *encoder)
+static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
+				     bool reset)
 {
-	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = encoder->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc =
-		to_intel_crtc(encoder->base.crtc);
-	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
-	u32 val;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = crtc->pipe;
+	uint32_t val;
 
-	intel_dp_link_down(intel_dp);
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
+	if (reset)
+		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+	else
+		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
 
-	mutex_lock(&dev_priv->sb_lock);
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
+		if (reset)
+			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+		else
+			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
+	}
 
-	/* Propagate soft reset to data lane reset */
 	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
 	val |= CHV_PCS_REQ_SOFTRESET_EN;
+	if (reset)
+		val &= ~DPIO_PCS_CLK_SOFT_RESET;
+	else
+		val |= DPIO_PCS_CLK_SOFT_RESET;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc->config->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
 		val |= CHV_PCS_REQ_SOFTRESET_EN;
+		if (reset)
+			val &= ~DPIO_PCS_CLK_SOFT_RESET;
+		else
+			val |= DPIO_PCS_CLK_SOFT_RESET;
 		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
 	}
+}
 
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
-	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
+static void chv_post_disable_dp(struct intel_encoder *encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
-		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
-	}
+	intel_dp_link_down(intel_dp);
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
 
 	mutex_unlock(&dev_priv->sb_lock);
 }
@@ -2802,27 +2822,6 @@  static void chv_pre_enable_dp(struct intel_encoder *encoder)
 		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 	}
 
-	/* Deassert soft data lane reset*/
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
-	val |= CHV_PCS_REQ_SOFTRESET_EN;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
-
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
-		val |= CHV_PCS_REQ_SOFTRESET_EN;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
-	}
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
-	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
-
-	if (intel_crtc->config->lane_count > 2) {
-		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
-		val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
-	}
-
 	/* Program Tx lane latency optimal setting*/
 	for (i = 0; i < intel_crtc->config->lane_count; i++) {
 		/* Set the upar bit */
@@ -2872,6 +2871,9 @@  static void chv_pre_enable_dp(struct intel_encoder *encoder)
 			       DPIO_TX2_STAGGER_MULT(5));
 	}
 
+	/* Deassert data lane reset */
+	chv_data_lane_soft_reset(encoder, false);
+
 	mutex_unlock(&dev_priv->sb_lock);
 
 	intel_enable_dp(encoder);
@@ -2910,6 +2912,9 @@  static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
 
 	mutex_lock(&dev_priv->sb_lock);
 
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
 	/* program left/right clock distribution */
 	if (pipe != PIPE_B) {
 		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 4b604ee..176d681 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1612,6 +1612,50 @@  static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->sb_lock);
 }
 
+static void chv_data_lane_soft_reset(struct intel_encoder *encoder,
+				     bool reset)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	enum pipe pipe = crtc->pipe;
+	uint32_t val;
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
+	if (reset)
+		val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+	else
+		val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
+		if (reset)
+			val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
+		else
+			val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
+	val |= CHV_PCS_REQ_SOFTRESET_EN;
+	if (reset)
+		val &= ~DPIO_PCS_CLK_SOFT_RESET;
+	else
+		val |= DPIO_PCS_CLK_SOFT_RESET;
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
+
+	if (crtc->config->lane_count > 2) {
+		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
+		val |= CHV_PCS_REQ_SOFTRESET_EN;
+		if (reset)
+			val &= ~DPIO_PCS_CLK_SOFT_RESET;
+		else
+			val |= DPIO_PCS_CLK_SOFT_RESET;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
+	}
+}
+
 static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
@@ -1637,6 +1681,9 @@  static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 
 	mutex_lock(&dev_priv->sb_lock);
 
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
+
 	/* program left/right clock distribution */
 	if (pipe != PIPE_B) {
 		val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
@@ -1739,33 +1786,13 @@  static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
 
 static void chv_hdmi_post_disable(struct intel_encoder *encoder)
 {
-	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc =
-		to_intel_crtc(encoder->base.crtc);
-	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
-	u32 val;
 
 	mutex_lock(&dev_priv->sb_lock);
 
-	/* Propagate soft reset to data lane reset */
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
-	val |= CHV_PCS_REQ_SOFTRESET_EN;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
-	val |= CHV_PCS_REQ_SOFTRESET_EN;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
-	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
-	val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
+	/* Assert data lane reset */
+	chv_data_lane_soft_reset(encoder, true);
 
 	mutex_unlock(&dev_priv->sb_lock);
 }
@@ -1796,23 +1823,6 @@  static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 	val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
 
-	/* Deassert soft data lane reset*/
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
-	val |= CHV_PCS_REQ_SOFTRESET_EN;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
-	val |= CHV_PCS_REQ_SOFTRESET_EN;
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
-	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
-	val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
-
 	/* Program Tx latency optimal setting */
 	for (i = 0; i < 4; i++) {
 		/* Set the upar bit */
@@ -1855,6 +1865,9 @@  static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 		       DPIO_TX1_STAGGER_MULT(7) |
 		       DPIO_TX2_STAGGER_MULT(5));
 
+	/* Deassert data lane reset */
+	chv_data_lane_soft_reset(encoder, false);
+
 	/* Clear calc init */
 	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
 	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);