On Wed, Jul 08, 2015 at 11:45:59PM +0300, ville.syrjala@xxxxxxxxxxxxxxx wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx