Message ID | 1439826380-18403-1-git-send-email-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 08/17/2015 08:46 AM, ville.syrjala@linux.intel.com wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Set up the DDI->PLL mapping on SKL also for MST links. Might help make > MST operational on SKL. > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/intel_ddi.c | 49 ++++++++++++++++++++++--------------- > drivers/gpu/drm/i915/intel_dp_mst.c | 8 +----- > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > 3 files changed, 32 insertions(+), 27 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index 5dff8b7..10a5a98 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -2258,30 +2258,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) > return DDI_BUF_TRANS_SELECT(level); > } > > -static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > +void intel_ddi_clk_select(struct intel_encoder *encoder, > + const struct intel_crtc_state *pipe_config) > { > - struct drm_encoder *encoder = &intel_encoder->base; > - struct drm_device *dev = encoder->dev; > - struct drm_i915_private *dev_priv = dev->dev_private; > - struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > - enum port port = intel_ddi_get_encoder_port(intel_encoder); > - int type = intel_encoder->type; > - int hdmi_level; > - > - if (type == INTEL_OUTPUT_EDP) { > - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > - intel_edp_panel_on(intel_dp); > - } > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + enum port port = intel_ddi_get_encoder_port(encoder); > > - if (IS_SKYLAKE(dev)) { > - uint32_t dpll = crtc->config->ddi_pll_sel; > + if (IS_SKYLAKE(dev_priv)) { > + uint32_t dpll = pipe_config->ddi_pll_sel; > uint32_t val; > > /* > * DPLL0 is used for eDP and is the only "private" DPLL (as > * opposed to shared) on SKL > */ > - if (type == INTEL_OUTPUT_EDP) { > + if (encoder->type == INTEL_OUTPUT_EDP) { > WARN_ON(dpll != SKL_DPLL0); > > val = I915_READ(DPLL_CTRL1); > @@ -2289,7 +2280,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | > DPLL_CTRL1_SSC(dpll) | > DPLL_CTRL1_LINK_RATE_MASK(dpll)); > - val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6); > + val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6); > > I915_WRITE(DPLL_CTRL1, val); > POSTING_READ(DPLL_CTRL1); > @@ -2305,11 +2296,29 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > > I915_WRITE(DPLL_CTRL2, val); > > - } else if (INTEL_INFO(dev)->gen < 9) { > - WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE); > - I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel); > + } else if (INTEL_INFO(dev_priv)->gen < 9) { > + WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE); > + I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel); > + } > +} > + > +static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > +{ > + struct drm_encoder *encoder = &intel_encoder->base; > + struct drm_device *dev = encoder->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > + enum port port = intel_ddi_get_encoder_port(intel_encoder); > + int type = intel_encoder->type; > + int hdmi_level; > + > + if (type == INTEL_OUTPUT_EDP) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + intel_edp_panel_on(intel_dp); > } > > + intel_ddi_clk_select(intel_encoder, crtc->config); > + > if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { > struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > index ebf2054..fd25aeb7 100644 > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > @@ -163,20 +163,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) > intel_mst->port = found->port; > > if (intel_dp->active_mst_links == 0) { > - enum port port = intel_ddi_get_encoder_port(encoder); > + intel_ddi_clk_select(encoder, intel_crtc->config); > > intel_dp_set_link_params(intel_dp, intel_crtc->config); > > - /* FIXME: add support for SKL */ > - if (INTEL_INFO(dev)->gen < 9) > - I915_WRITE(PORT_CLK_SEL(port), > - intel_crtc->config->ddi_pll_sel); > - > intel_ddi_init_dp_buf_reg(&intel_dig_port->base); > > intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); > > - > intel_dp_start_link_train(intel_dp); > intel_dp_complete_link_train(intel_dp); > intel_dp_stop_link_train(intel_dp); > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 71a2e18..a97908a 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -938,6 +938,8 @@ void intel_crt_init(struct drm_device *dev); > > > /* intel_ddi.c */ > +void intel_ddi_clk_select(struct intel_encoder *encoder, > + const struct intel_crtc_state *pipe_config); > void intel_prepare_ddi(struct drm_device *dev); > void hsw_fdi_link_train(struct drm_crtc *crtc); > void intel_ddi_init(struct drm_device *dev, enum port port); > Looks like an improvement over current code and fixes the hard hang in https://bugs.freedesktop.org/show_bug.cgi?id=91791, so I think we should push it. Sounds like we need more than just this to fix MST on SKL though. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
On Tue, Nov 10, 2015 at 12:15:40PM -0800, Jesse Barnes wrote: > On 08/17/2015 08:46 AM, ville.syrjala@linux.intel.com wrote: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > Set up the DDI->PLL mapping on SKL also for MST links. Might help make > > MST operational on SKL. > > > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > drivers/gpu/drm/i915/intel_ddi.c | 49 ++++++++++++++++++++++--------------- > > drivers/gpu/drm/i915/intel_dp_mst.c | 8 +----- > > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > > 3 files changed, 32 insertions(+), 27 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > > index 5dff8b7..10a5a98 100644 > > --- a/drivers/gpu/drm/i915/intel_ddi.c > > +++ b/drivers/gpu/drm/i915/intel_ddi.c > > @@ -2258,30 +2258,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) > > return DDI_BUF_TRANS_SELECT(level); > > } > > > > -static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > > +void intel_ddi_clk_select(struct intel_encoder *encoder, > > + const struct intel_crtc_state *pipe_config) > > { > > - struct drm_encoder *encoder = &intel_encoder->base; > > - struct drm_device *dev = encoder->dev; > > - struct drm_i915_private *dev_priv = dev->dev_private; > > - struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > > - enum port port = intel_ddi_get_encoder_port(intel_encoder); > > - int type = intel_encoder->type; > > - int hdmi_level; > > - > > - if (type == INTEL_OUTPUT_EDP) { > > - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > - intel_edp_panel_on(intel_dp); > > - } > > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > + enum port port = intel_ddi_get_encoder_port(encoder); > > > > - if (IS_SKYLAKE(dev)) { > > - uint32_t dpll = crtc->config->ddi_pll_sel; > > + if (IS_SKYLAKE(dev_priv)) { > > + uint32_t dpll = pipe_config->ddi_pll_sel; > > uint32_t val; > > > > /* > > * DPLL0 is used for eDP and is the only "private" DPLL (as > > * opposed to shared) on SKL > > */ > > - if (type == INTEL_OUTPUT_EDP) { > > + if (encoder->type == INTEL_OUTPUT_EDP) { > > WARN_ON(dpll != SKL_DPLL0); > > > > val = I915_READ(DPLL_CTRL1); > > @@ -2289,7 +2280,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > > val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | > > DPLL_CTRL1_SSC(dpll) | > > DPLL_CTRL1_LINK_RATE_MASK(dpll)); > > - val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6); > > + val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6); > > > > I915_WRITE(DPLL_CTRL1, val); > > POSTING_READ(DPLL_CTRL1); > > @@ -2305,11 +2296,29 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > > > > I915_WRITE(DPLL_CTRL2, val); > > > > - } else if (INTEL_INFO(dev)->gen < 9) { > > - WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE); > > - I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel); > > + } else if (INTEL_INFO(dev_priv)->gen < 9) { > > + WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE); > > + I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel); > > + } > > +} > > + > > +static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) > > +{ > > + struct drm_encoder *encoder = &intel_encoder->base; > > + struct drm_device *dev = encoder->dev; > > + struct drm_i915_private *dev_priv = dev->dev_private; > > + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > > + enum port port = intel_ddi_get_encoder_port(intel_encoder); > > + int type = intel_encoder->type; > > + int hdmi_level; > > + > > + if (type == INTEL_OUTPUT_EDP) { > > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > + intel_edp_panel_on(intel_dp); > > } > > > > + intel_ddi_clk_select(intel_encoder, crtc->config); > > + > > if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { > > struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > > index ebf2054..fd25aeb7 100644 > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > > @@ -163,20 +163,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) > > intel_mst->port = found->port; > > > > if (intel_dp->active_mst_links == 0) { > > - enum port port = intel_ddi_get_encoder_port(encoder); > > + intel_ddi_clk_select(encoder, intel_crtc->config); > > > > intel_dp_set_link_params(intel_dp, intel_crtc->config); > > > > - /* FIXME: add support for SKL */ > > - if (INTEL_INFO(dev)->gen < 9) > > - I915_WRITE(PORT_CLK_SEL(port), > > - intel_crtc->config->ddi_pll_sel); > > - > > intel_ddi_init_dp_buf_reg(&intel_dig_port->base); > > > > intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); > > > > - > > intel_dp_start_link_train(intel_dp); > > intel_dp_complete_link_train(intel_dp); > > intel_dp_stop_link_train(intel_dp); > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > index 71a2e18..a97908a 100644 > > --- a/drivers/gpu/drm/i915/intel_drv.h > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > @@ -938,6 +938,8 @@ void intel_crt_init(struct drm_device *dev); > > > > > > /* intel_ddi.c */ > > +void intel_ddi_clk_select(struct intel_encoder *encoder, > > + const struct intel_crtc_state *pipe_config); > > void intel_prepare_ddi(struct drm_device *dev); > > void hsw_fdi_link_train(struct drm_crtc *crtc); > > void intel_ddi_init(struct drm_device *dev, enum port port); > > > > Looks like an improvement over current code and fixes the hard hang in > https://bugs.freedesktop.org/show_bug.cgi?id=91791, so I think we should > push it. > > Sounds like we need more than just this to fix MST on SKL though. > > Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Patch merged to dinq with an improved subject: "drm/i915: Setup DDI clk for MST on SKL" ... which apparently made the patchwork link invalid somehow: "remote: Updating patchwork state for http://patchwork.freedesktop.org/project/intel-gfx/list/ remote: E: failed to find patch for rev e404ba8d06ff2a1bdb916a9e5d2c09cacd7e5ca3 remote: I: 0 patch(es) updated to state Accepted." Anyway, thanks for the r-b.
On 2015-11-10 21:15, Jesse Barnes wrote: > On 08/17/2015 08:46 AM, ville.syrjala@linux.intel.com wrote: >> From: Ville Syrjälä <ville.syrjala@linux.intel.com> >> >> Set up the DDI->PLL mapping on SKL also for MST links. Might help make >> MST operational on SKL. >> >> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> >> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> >> --- >> drivers/gpu/drm/i915/intel_ddi.c | 49 ++++++++++++++++++++++--------------- >> drivers/gpu/drm/i915/intel_dp_mst.c | 8 +----- >> drivers/gpu/drm/i915/intel_drv.h | 2 ++ >> 3 files changed, 32 insertions(+), 27 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c >> index 5dff8b7..10a5a98 100644 >> --- a/drivers/gpu/drm/i915/intel_ddi.c >> +++ b/drivers/gpu/drm/i915/intel_ddi.c >> @@ -2258,30 +2258,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) >> return DDI_BUF_TRANS_SELECT(level); >> } >> >> -static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) >> +void intel_ddi_clk_select(struct intel_encoder *encoder, >> + const struct intel_crtc_state *pipe_config) >> { >> - struct drm_encoder *encoder = &intel_encoder->base; >> - struct drm_device *dev = encoder->dev; >> - struct drm_i915_private *dev_priv = dev->dev_private; >> - struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); >> - enum port port = intel_ddi_get_encoder_port(intel_encoder); >> - int type = intel_encoder->type; >> - int hdmi_level; >> - >> - if (type == INTEL_OUTPUT_EDP) { >> - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); >> - intel_edp_panel_on(intel_dp); >> - } >> + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); >> + enum port port = intel_ddi_get_encoder_port(encoder); >> >> - if (IS_SKYLAKE(dev)) { >> - uint32_t dpll = crtc->config->ddi_pll_sel; >> + if (IS_SKYLAKE(dev_priv)) { >> + uint32_t dpll = pipe_config->ddi_pll_sel; >> uint32_t val; >> >> /* >> * DPLL0 is used for eDP and is the only "private" DPLL (as >> * opposed to shared) on SKL >> */ >> - if (type == INTEL_OUTPUT_EDP) { >> + if (encoder->type == INTEL_OUTPUT_EDP) { >> WARN_ON(dpll != SKL_DPLL0); >> >> val = I915_READ(DPLL_CTRL1); >> @@ -2289,7 +2280,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) >> val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | >> DPLL_CTRL1_SSC(dpll) | >> DPLL_CTRL1_LINK_RATE_MASK(dpll)); >> - val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6); >> + val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6); >> >> I915_WRITE(DPLL_CTRL1, val); >> POSTING_READ(DPLL_CTRL1); >> @@ -2305,11 +2296,29 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) >> >> I915_WRITE(DPLL_CTRL2, val); >> >> - } else if (INTEL_INFO(dev)->gen < 9) { >> - WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE); >> - I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel); >> + } else if (INTEL_INFO(dev_priv)->gen < 9) { >> + WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE); >> + I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel); >> + } >> +} >> + >> +static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) >> +{ >> + struct drm_encoder *encoder = &intel_encoder->base; >> + struct drm_device *dev = encoder->dev; >> + struct drm_i915_private *dev_priv = dev->dev_private; >> + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); >> + enum port port = intel_ddi_get_encoder_port(intel_encoder); >> + int type = intel_encoder->type; >> + int hdmi_level; >> + >> + if (type == INTEL_OUTPUT_EDP) { >> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); >> + intel_edp_panel_on(intel_dp); >> } >> >> + intel_ddi_clk_select(intel_encoder, crtc->config); >> + >> if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { >> struct intel_dp *intel_dp = enc_to_intel_dp(encoder); >> >> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c >> index ebf2054..fd25aeb7 100644 >> --- a/drivers/gpu/drm/i915/intel_dp_mst.c >> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c >> @@ -163,20 +163,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) >> intel_mst->port = found->port; >> >> if (intel_dp->active_mst_links == 0) { >> - enum port port = intel_ddi_get_encoder_port(encoder); >> + intel_ddi_clk_select(encoder, intel_crtc->config); >> >> intel_dp_set_link_params(intel_dp, intel_crtc->config); >> >> - /* FIXME: add support for SKL */ >> - if (INTEL_INFO(dev)->gen < 9) >> - I915_WRITE(PORT_CLK_SEL(port), >> - intel_crtc->config->ddi_pll_sel); >> - >> intel_ddi_init_dp_buf_reg(&intel_dig_port->base); >> >> intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); >> >> - >> intel_dp_start_link_train(intel_dp); >> intel_dp_complete_link_train(intel_dp); >> intel_dp_stop_link_train(intel_dp); >> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h >> index 71a2e18..a97908a 100644 >> --- a/drivers/gpu/drm/i915/intel_drv.h >> +++ b/drivers/gpu/drm/i915/intel_drv.h >> @@ -938,6 +938,8 @@ void intel_crt_init(struct drm_device *dev); >> >> >> /* intel_ddi.c */ >> +void intel_ddi_clk_select(struct intel_encoder *encoder, >> + const struct intel_crtc_state *pipe_config); >> void intel_prepare_ddi(struct drm_device *dev); >> void hsw_fdi_link_train(struct drm_crtc *crtc); >> void intel_ddi_init(struct drm_device *dev, enum port port); >> > Looks like an improvement over current code and fixes the hard hang in > https://bugs.freedesktop.org/show_bug.cgi?id=91791, so I think we should > push it. > > Sounds like we need more than just this to fix MST on SKL though. I tested against dell 4k UP3214Q and I still have a hard hang so yes MST on skylake is not in a good shape. > > Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Thu, 2015-11-19 at 22:28 +0100, Kenneth Johansson wrote: > On 2015-11-10 21:15, Jesse Barnes wrote: > > On 08/17/2015 08:46 AM, ville.syrjala@linux.intel.com wrote: > > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > > > Set up the DDI->PLL mapping on SKL also for MST links. Might help > > > make > > > MST operational on SKL. > > > > > > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > --- > > > drivers/gpu/drm/i915/intel_ddi.c | 49 ++++++++++++++++++++++ > > > --------------- > > > drivers/gpu/drm/i915/intel_dp_mst.c | 8 +----- > > > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > > > 3 files changed, 32 insertions(+), 27 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c > > > b/drivers/gpu/drm/i915/intel_ddi.c > > > index 5dff8b7..10a5a98 100644 > > > --- a/drivers/gpu/drm/i915/intel_ddi.c > > > +++ b/drivers/gpu/drm/i915/intel_ddi.c > > > @@ -2258,30 +2258,21 @@ uint32_t ddi_signal_levels(struct > > > intel_dp *intel_dp) > > > return DDI_BUF_TRANS_SELECT(level); > > > } > > > > > > -static void intel_ddi_pre_enable(struct intel_encoder > > > *intel_encoder) > > > +void intel_ddi_clk_select(struct intel_encoder *encoder, > > > + const struct intel_crtc_state > > > *pipe_config) > > > { > > > - struct drm_encoder *encoder = &intel_encoder->base; > > > - struct drm_device *dev = encoder->dev; > > > - struct drm_i915_private *dev_priv = dev->dev_private; > > > - struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > > > - enum port port = > > > intel_ddi_get_encoder_port(intel_encoder); > > > - int type = intel_encoder->type; > > > - int hdmi_level; > > > - > > > - if (type == INTEL_OUTPUT_EDP) { > > > - struct intel_dp *intel_dp = > > > enc_to_intel_dp(encoder); > > > - intel_edp_panel_on(intel_dp); > > > - } > > > + struct drm_i915_private *dev_priv = to_i915(encoder > > > ->base.dev); > > > + enum port port = intel_ddi_get_encoder_port(encoder); > > > > > > - if (IS_SKYLAKE(dev)) { > > > - uint32_t dpll = crtc->config->ddi_pll_sel; > > > + if (IS_SKYLAKE(dev_priv)) { > > > + uint32_t dpll = pipe_config->ddi_pll_sel; > > > uint32_t val; > > > > > > /* > > > * DPLL0 is used for eDP and is the only > > > "private" DPLL (as > > > * opposed to shared) on SKL > > > */ > > > - if (type == INTEL_OUTPUT_EDP) { > > > + if (encoder->type == INTEL_OUTPUT_EDP) { > > > WARN_ON(dpll != SKL_DPLL0); > > > > > > val = I915_READ(DPLL_CTRL1); > > > @@ -2289,7 +2280,7 @@ static void intel_ddi_pre_enable(struct > > > intel_encoder *intel_encoder) > > > val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | > > > DPLL_CTRL1_SSC(dpll) | > > > DPLL_CTRL1_LINK_RATE_MASK(dpll > > > )); > > > - val |= crtc->config->dpll_hw_state.ctrl1 > > > << (dpll * 6); > > > + val |= pipe_config->dpll_hw_state.ctrl1 > > > << (dpll * 6); > > > > > > I915_WRITE(DPLL_CTRL1, val); > > > POSTING_READ(DPLL_CTRL1); > > > @@ -2305,11 +2296,29 @@ static void intel_ddi_pre_enable(struct > > > intel_encoder *intel_encoder) > > > > > > I915_WRITE(DPLL_CTRL2, val); > > > > > > - } else if (INTEL_INFO(dev)->gen < 9) { > > > - WARN_ON(crtc->config->ddi_pll_sel == > > > PORT_CLK_SEL_NONE); > > > - I915_WRITE(PORT_CLK_SEL(port), crtc->config > > > ->ddi_pll_sel); > > > + } else if (INTEL_INFO(dev_priv)->gen < 9) { > > > + WARN_ON(pipe_config->ddi_pll_sel == > > > PORT_CLK_SEL_NONE); > > > + I915_WRITE(PORT_CLK_SEL(port), pipe_config > > > ->ddi_pll_sel); > > > + } > > > +} > > > + > > > +static void intel_ddi_pre_enable(struct intel_encoder > > > *intel_encoder) > > > +{ > > > + struct drm_encoder *encoder = &intel_encoder->base; > > > + struct drm_device *dev = encoder->dev; > > > + struct drm_i915_private *dev_priv = dev->dev_private; > > > + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); > > > + enum port port = > > > intel_ddi_get_encoder_port(intel_encoder); > > > + int type = intel_encoder->type; > > > + int hdmi_level; > > > + > > > + if (type == INTEL_OUTPUT_EDP) { > > > + struct intel_dp *intel_dp = > > > enc_to_intel_dp(encoder); > > > + intel_edp_panel_on(intel_dp); > > > } > > > > > > + intel_ddi_clk_select(intel_encoder, crtc->config); > > > + > > > if (type == INTEL_OUTPUT_DISPLAYPORT || type == > > > INTEL_OUTPUT_EDP) { > > > struct intel_dp *intel_dp = > > > enc_to_intel_dp(encoder); > > > > > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c > > > b/drivers/gpu/drm/i915/intel_dp_mst.c > > > index ebf2054..fd25aeb7 100644 > > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > > > @@ -163,20 +163,14 @@ static void intel_mst_pre_enable_dp(struct > > > intel_encoder *encoder) > > > intel_mst->port = found->port; > > > > > > if (intel_dp->active_mst_links == 0) { > > > - enum port port = > > > intel_ddi_get_encoder_port(encoder); > > > + intel_ddi_clk_select(encoder, intel_crtc > > > ->config); > > > > > > intel_dp_set_link_params(intel_dp, intel_crtc > > > ->config); > > > > > > - /* FIXME: add support for SKL */ > > > - if (INTEL_INFO(dev)->gen < 9) > > > - I915_WRITE(PORT_CLK_SEL(port), > > > - intel_crtc->config > > > ->ddi_pll_sel); > > > - > > > intel_ddi_init_dp_buf_reg(&intel_dig_port > > > ->base); > > > > > > intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); > > > > > > - > > > intel_dp_start_link_train(intel_dp); > > > intel_dp_complete_link_train(intel_dp); > > > intel_dp_stop_link_train(intel_dp); > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > > > b/drivers/gpu/drm/i915/intel_drv.h > > > index 71a2e18..a97908a 100644 > > > --- a/drivers/gpu/drm/i915/intel_drv.h > > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > > @@ -938,6 +938,8 @@ void intel_crt_init(struct drm_device *dev); > > > > > > > > > /* intel_ddi.c */ > > > +void intel_ddi_clk_select(struct intel_encoder *encoder, > > > + const struct intel_crtc_state > > > *pipe_config); > > > void intel_prepare_ddi(struct drm_device *dev); > > > void hsw_fdi_link_train(struct drm_crtc *crtc); > > > void intel_ddi_init(struct drm_device *dev, enum port port); > > > > > Looks like an improvement over current code and fixes the hard hang > > in > > https://bugs.freedesktop.org/show_bug.cgi?id=91791, so I think we > > should > > push it. > > > > Sounds like we need more than just this to fix MST on SKL though. > > I tested against dell 4k UP3214Q and I still have a hard hang so yes > MST on skylake is not in a good shape. Just tested on special kernel for yoga 900 with USB Type C to DP adapter connected to Club 3D MST Hub (CSV-5200). Mostly works with 2560x1440 on local display and dual head Samsung 4k monitors - same resolution on all. I am writing this e-mail on one of the samsung monitors. have pictures if you are interested. Also, I am getting watermark stack traces and periodic drops of the MST displays - blank then re-appear. Jim > > > > Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > _______________________________________________ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5dff8b7..10a5a98 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2258,30 +2258,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) return DDI_BUF_TRANS_SELECT(level); } -static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) +void intel_ddi_clk_select(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config) { - struct drm_encoder *encoder = &intel_encoder->base; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_ddi_get_encoder_port(intel_encoder); - int type = intel_encoder->type; - int hdmi_level; - - if (type == INTEL_OUTPUT_EDP) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_edp_panel_on(intel_dp); - } + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); - if (IS_SKYLAKE(dev)) { - uint32_t dpll = crtc->config->ddi_pll_sel; + if (IS_SKYLAKE(dev_priv)) { + uint32_t dpll = pipe_config->ddi_pll_sel; uint32_t val; /* * DPLL0 is used for eDP and is the only "private" DPLL (as * opposed to shared) on SKL */ - if (type == INTEL_OUTPUT_EDP) { + if (encoder->type == INTEL_OUTPUT_EDP) { WARN_ON(dpll != SKL_DPLL0); val = I915_READ(DPLL_CTRL1); @@ -2289,7 +2280,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) | DPLL_CTRL1_LINK_RATE_MASK(dpll)); - val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6); + val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6); I915_WRITE(DPLL_CTRL1, val); POSTING_READ(DPLL_CTRL1); @@ -2305,11 +2296,29 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) I915_WRITE(DPLL_CTRL2, val); - } else if (INTEL_INFO(dev)->gen < 9) { - WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE); - I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel); + } else if (INTEL_INFO(dev_priv)->gen < 9) { + WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE); + I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel); + } +} + +static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) +{ + struct drm_encoder *encoder = &intel_encoder->base; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); + enum port port = intel_ddi_get_encoder_port(intel_encoder); + int type = intel_encoder->type; + int hdmi_level; + + if (type == INTEL_OUTPUT_EDP) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + intel_edp_panel_on(intel_dp); } + intel_ddi_clk_select(intel_encoder, crtc->config); + if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index ebf2054..fd25aeb7 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -163,20 +163,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) intel_mst->port = found->port; if (intel_dp->active_mst_links == 0) { - enum port port = intel_ddi_get_encoder_port(encoder); + intel_ddi_clk_select(encoder, intel_crtc->config); intel_dp_set_link_params(intel_dp, intel_crtc->config); - /* FIXME: add support for SKL */ - if (INTEL_INFO(dev)->gen < 9) - I915_WRITE(PORT_CLK_SEL(port), - intel_crtc->config->ddi_pll_sel); - intel_ddi_init_dp_buf_reg(&intel_dig_port->base); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 71a2e18..a97908a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -938,6 +938,8 @@ void intel_crt_init(struct drm_device *dev); /* intel_ddi.c */ +void intel_ddi_clk_select(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config); void intel_prepare_ddi(struct drm_device *dev); void hsw_fdi_link_train(struct drm_crtc *crtc); void intel_ddi_init(struct drm_device *dev, enum port port);