diff mbox

drm/i915: Try to fix MST for SKL

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

Commit Message

Ville Syrjala Aug. 17, 2015, 3:46 p.m. UTC
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(-)

Comments

Jesse Barnes Nov. 10, 2015, 8:15 p.m. UTC | #1
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>
Ville Syrjala Nov. 10, 2015, 8:36 p.m. UTC | #2
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.
Kenneth Johansson Nov. 19, 2015, 9:28 p.m. UTC | #3
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
Bish, Jim Nov. 23, 2015, 11:38 p.m. UTC | #4
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 mbox

Patch

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);