Re: [Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-09 Thread Manasi Navare
On Fri, Sep 09, 2016 at 10:11:06AM +0300, Jani Nikula wrote:
> On Thu, 08 Sep 2016, Manasi Navare  wrote:
> > According to the DisplayPort Spec, in case of Clock Recovery failure
> > the link training sequence should fall back to the lower link rate
> > followed by lower lane count until CR succeeds.
> > On CR success, the sequence proceeds with Channel EQ.
> > In case of Channel EQ failures, it should fallback to
> > lower link rate and lane count and start the CR phase again.
> >
> > v4:
> > * Fixed the link rate fallback loop (Manasi Navare)
> > v3:
> > * Fixed some rebase issues (Mika Kahola)
> > v2:
> > * Add a helper function to return index of requested link rate
> > into common_rates array
> > * Changed the link rate fallback loop to make use
> > of common_rates array (Mika Kahola)
> > * Changed INTEL_INFO to INTEL_GEN (David Weinehall)
> >
> > Signed-off-by: Manasi Navare 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c  | 109 
> > +++---
> >  drivers/gpu/drm/i915/intel_dp.c   |  15 
> >  drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
> >  drivers/gpu/drm/i915/intel_drv.h  |   6 +-
> >  4 files changed, 128 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> > b/drivers/gpu/drm/i915/intel_ddi.c
> > index 25e7973..1278daa 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct intel_encoder 
> > *encoder,
> > }
> >  }
> >  
> > -static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> > +static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
> > int link_rate, uint32_t lane_count,
> > -   struct intel_shared_dpll *pll,
> > -   bool link_mst)
> > +   struct intel_shared_dpll *pll)
> >  {
> > struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > enum port port = intel_ddi_get_encoder_port(encoder);
> >  
> > intel_dp_set_link_params(intel_dp, link_rate, lane_count,
> > -link_mst);
> > -   if (encoder->type == INTEL_OUTPUT_EDP)
> > -   intel_edp_panel_on(intel_dp);
> > +false);
> > +
> > +   intel_edp_panel_on(intel_dp);
> >  
> > intel_ddi_clk_select(encoder, pll);
> > intel_prepare_dp_ddi_buffers(encoder);
> > @@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct 
> > intel_encoder *encoder,
> > intel_dp_stop_link_train(intel_dp);
> >  }
> >  
> > +static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> > +   int link_rate, uint32_t lane_count,
> > +   struct intel_shared_dpll *pll,
> > +   bool link_mst)
> > +{
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> > +   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +   struct intel_shared_dpll_config tmp_pll_config;
> > +
> > +   /* Disable the PLL and obtain the PLL for Link Training
> > +* that starts with highest link rate and lane count.
> > +*/
> > +   tmp_pll_config = pll->config;
> > +   pll->funcs.disable(dev_priv, pll);
> > +   pll->config.crtc_mask = 0;
> > +
> > +   /* If Link Training fails, send a uevent to generate a hotplug */
> > +   if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count, link_mst)))
> 
> Redundant parens.
> 
> > +   drm_kms_helper_hotplug_event(encoder->base.dev);
> > +   pll->config = tmp_pll_config;
> > +}
> > +
> >  static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
> >   bool has_hdmi_sink,
> >   struct drm_display_mode *adjusted_mode,
> > @@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct 
> > intel_encoder *intel_encoder,
> > struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > int type = intel_encoder->type;
> >  
> > -   if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
> > +   if (type == INTEL_OUTPUT_EDP)
> > +   intel_ddi_pre_enable_edp(intel_encoder,
> > +   crtc->config->port_clock,
> > +   crtc->config->lane_count,
> > +   crtc->config->shared_dpll);
> > +
> > +   if (type == INTEL_OUTPUT_DP)
> > intel_ddi_pre_enable_dp(intel_encoder,
> > crtc->config->port_clock,
> > crtc->config->lane_count,
> > crtc->config->shared_dpll,
> > intel_crtc_has_type(crtc->config,
> >   

Re: [Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-09 Thread Jani Nikula
On Fri, 09 Sep 2016, Rodrigo Vivi  wrote:
> On Wed, Sep 7, 2016 at 5:30 PM, Manasi Navare  
> wrote:
>> According to the DisplayPort Spec, in case of Clock Recovery failure
>> the link training sequence should fall back to the lower link rate
>> followed by lower lane count until CR succeeds.
>> On CR success, the sequence proceeds with Channel EQ.
>> In case of Channel EQ failures, it should fallback to
>> lower link rate and lane count and start the CR phase again.
>>
>> v4:
>> * Fixed the link rate fallback loop (Manasi Navare)
>> v3:
>> * Fixed some rebase issues (Mika Kahola)
>> v2:
>> * Add a helper function to return index of requested link rate
>> into common_rates array
>> * Changed the link rate fallback loop to make use
>> of common_rates array (Mika Kahola)
>> * Changed INTEL_INFO to INTEL_GEN (David Weinehall)
>>
>> Signed-off-by: Manasi Navare 
>> ---
>>  drivers/gpu/drm/i915/intel_ddi.c  | 109 
>> +++---
>>  drivers/gpu/drm/i915/intel_dp.c   |  15 
>>  drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
>>  drivers/gpu/drm/i915/intel_drv.h  |   6 +-
>>  4 files changed, 128 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
>> b/drivers/gpu/drm/i915/intel_ddi.c
>> index 25e7973..1278daa 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct intel_encoder 
>> *encoder,
>> }
>>  }
>>
>> -static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
>> +static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
>> int link_rate, uint32_t lane_count,
>> -   struct intel_shared_dpll *pll,
>> -   bool link_mst)
>> +   struct intel_shared_dpll *pll)
>>  {
>> struct intel_dp *intel_dp = enc_to_intel_dp(>base);
>> struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> enum port port = intel_ddi_get_encoder_port(encoder);
>>
>> intel_dp_set_link_params(intel_dp, link_rate, lane_count,
>> -link_mst);
>> -   if (encoder->type == INTEL_OUTPUT_EDP)
>> -   intel_edp_panel_on(intel_dp);
>> +false);
>> +
>> +   intel_edp_panel_on(intel_dp);
>>
>> intel_ddi_clk_select(encoder, pll);
>> intel_prepare_dp_ddi_buffers(encoder);
>> @@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct 
>> intel_encoder *encoder,
>> intel_dp_stop_link_train(intel_dp);
>>  }
>>
>> +static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
>> +   int link_rate, uint32_t lane_count,
>> +   struct intel_shared_dpll *pll,
>> +   bool link_mst)
>> +{
>> +   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
>> +   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> +   struct intel_shared_dpll_config tmp_pll_config;
>> +
>> +   /* Disable the PLL and obtain the PLL for Link Training
>> +* that starts with highest link rate and lane count.
>> +*/
>> +   tmp_pll_config = pll->config;
>> +   pll->funcs.disable(dev_priv, pll);
>> +   pll->config.crtc_mask = 0;
>> +
>> +   /* If Link Training fails, send a uevent to generate a hotplug */
>> +   if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count, 
>> link_mst)))
>> +   drm_kms_helper_hotplug_event(encoder->base.dev);
>> +   pll->config = tmp_pll_config;
>> +}
>> +
>>  static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
>>   bool has_hdmi_sink,
>>   struct drm_display_mode *adjusted_mode,
>> @@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct 
>> intel_encoder *intel_encoder,
>> struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>> int type = intel_encoder->type;
>>
>> -   if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
>> +   if (type == INTEL_OUTPUT_EDP)
>> +   intel_ddi_pre_enable_edp(intel_encoder,
>> +   crtc->config->port_clock,
>> +   crtc->config->lane_count,
>> +   crtc->config->shared_dpll);
>> +
>> +   if (type == INTEL_OUTPUT_DP)
>> intel_ddi_pre_enable_dp(intel_encoder,
>> crtc->config->port_clock,
>> crtc->config->lane_count,
>> crtc->config->shared_dpll,
>> 

Re: [Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-09 Thread Jani Nikula
On Thu, 08 Sep 2016, Manasi Navare  wrote:
> According to the DisplayPort Spec, in case of Clock Recovery failure
> the link training sequence should fall back to the lower link rate
> followed by lower lane count until CR succeeds.
> On CR success, the sequence proceeds with Channel EQ.
> In case of Channel EQ failures, it should fallback to
> lower link rate and lane count and start the CR phase again.
>
> v4:
> * Fixed the link rate fallback loop (Manasi Navare)
> v3:
> * Fixed some rebase issues (Mika Kahola)
> v2:
> * Add a helper function to return index of requested link rate
> into common_rates array
> * Changed the link rate fallback loop to make use
> of common_rates array (Mika Kahola)
> * Changed INTEL_INFO to INTEL_GEN (David Weinehall)
>
> Signed-off-by: Manasi Navare 
> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 109 
> +++---
>  drivers/gpu/drm/i915/intel_dp.c   |  15 
>  drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
>  drivers/gpu/drm/i915/intel_drv.h  |   6 +-
>  4 files changed, 128 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 25e7973..1278daa 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct intel_encoder 
> *encoder,
>   }
>  }
>  
> -static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> +static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
>   int link_rate, uint32_t lane_count,
> - struct intel_shared_dpll *pll,
> - bool link_mst)
> + struct intel_shared_dpll *pll)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
>   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>   enum port port = intel_ddi_get_encoder_port(encoder);
>  
>   intel_dp_set_link_params(intel_dp, link_rate, lane_count,
> -  link_mst);
> - if (encoder->type == INTEL_OUTPUT_EDP)
> - intel_edp_panel_on(intel_dp);
> +  false);
> +
> + intel_edp_panel_on(intel_dp);
>  
>   intel_ddi_clk_select(encoder, pll);
>   intel_prepare_dp_ddi_buffers(encoder);
> @@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct 
> intel_encoder *encoder,
>   intel_dp_stop_link_train(intel_dp);
>  }
>  
> +static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> + int link_rate, uint32_t lane_count,
> + struct intel_shared_dpll *pll,
> + bool link_mst)
> +{
> + struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> + struct intel_shared_dpll_config tmp_pll_config;
> +
> + /* Disable the PLL and obtain the PLL for Link Training
> +  * that starts with highest link rate and lane count.
> +  */
> + tmp_pll_config = pll->config;
> + pll->funcs.disable(dev_priv, pll);
> + pll->config.crtc_mask = 0;
> +
> + /* If Link Training fails, send a uevent to generate a hotplug */
> + if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count, link_mst)))

Redundant parens.

> + drm_kms_helper_hotplug_event(encoder->base.dev);
> + pll->config = tmp_pll_config;
> +}
> +
>  static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
> bool has_hdmi_sink,
> struct drm_display_mode *adjusted_mode,
> @@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct intel_encoder 
> *intel_encoder,
>   struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>   int type = intel_encoder->type;
>  
> - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
> + if (type == INTEL_OUTPUT_EDP)
> + intel_ddi_pre_enable_edp(intel_encoder,
> + crtc->config->port_clock,
> + crtc->config->lane_count,
> + crtc->config->shared_dpll);
> +
> + if (type == INTEL_OUTPUT_DP)
>   intel_ddi_pre_enable_dp(intel_encoder,
>   crtc->config->port_clock,
>   crtc->config->lane_count,
>   crtc->config->shared_dpll,
>   intel_crtc_has_type(crtc->config,
>   
> INTEL_OUTPUT_DP_MST));
> - }
> - if (type == INTEL_OUTPUT_HDMI) {
> +
> + if (type == INTEL_OUTPUT_HDMI)
>   intel_ddi_pre_enable_hdmi(intel_encoder,

Re: [Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-08 Thread Rodrigo Vivi
On Wed, Sep 7, 2016 at 5:30 PM, Manasi Navare  wrote:
> According to the DisplayPort Spec, in case of Clock Recovery failure
> the link training sequence should fall back to the lower link rate
> followed by lower lane count until CR succeeds.
> On CR success, the sequence proceeds with Channel EQ.
> In case of Channel EQ failures, it should fallback to
> lower link rate and lane count and start the CR phase again.
>
> v4:
> * Fixed the link rate fallback loop (Manasi Navare)
> v3:
> * Fixed some rebase issues (Mika Kahola)
> v2:
> * Add a helper function to return index of requested link rate
> into common_rates array
> * Changed the link rate fallback loop to make use
> of common_rates array (Mika Kahola)
> * Changed INTEL_INFO to INTEL_GEN (David Weinehall)
>
> Signed-off-by: Manasi Navare 
> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 109 
> +++---
>  drivers/gpu/drm/i915/intel_dp.c   |  15 
>  drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
>  drivers/gpu/drm/i915/intel_drv.h  |   6 +-
>  4 files changed, 128 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 25e7973..1278daa 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct intel_encoder 
> *encoder,
> }
>  }
>
> -static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> +static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
> int link_rate, uint32_t lane_count,
> -   struct intel_shared_dpll *pll,
> -   bool link_mst)
> +   struct intel_shared_dpll *pll)
>  {
> struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> enum port port = intel_ddi_get_encoder_port(encoder);
>
> intel_dp_set_link_params(intel_dp, link_rate, lane_count,
> -link_mst);
> -   if (encoder->type == INTEL_OUTPUT_EDP)
> -   intel_edp_panel_on(intel_dp);
> +false);
> +
> +   intel_edp_panel_on(intel_dp);
>
> intel_ddi_clk_select(encoder, pll);
> intel_prepare_dp_ddi_buffers(encoder);
> @@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct 
> intel_encoder *encoder,
> intel_dp_stop_link_train(intel_dp);
>  }
>
> +static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> +   int link_rate, uint32_t lane_count,
> +   struct intel_shared_dpll *pll,
> +   bool link_mst)
> +{
> +   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> +   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +   struct intel_shared_dpll_config tmp_pll_config;
> +
> +   /* Disable the PLL and obtain the PLL for Link Training
> +* that starts with highest link rate and lane count.
> +*/
> +   tmp_pll_config = pll->config;
> +   pll->funcs.disable(dev_priv, pll);
> +   pll->config.crtc_mask = 0;
> +
> +   /* If Link Training fails, send a uevent to generate a hotplug */
> +   if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count, 
> link_mst)))
> +   drm_kms_helper_hotplug_event(encoder->base.dev);
> +   pll->config = tmp_pll_config;
> +}
> +
>  static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
>   bool has_hdmi_sink,
>   struct drm_display_mode *adjusted_mode,
> @@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct intel_encoder 
> *intel_encoder,
> struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> int type = intel_encoder->type;
>
> -   if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
> +   if (type == INTEL_OUTPUT_EDP)
> +   intel_ddi_pre_enable_edp(intel_encoder,
> +   crtc->config->port_clock,
> +   crtc->config->lane_count,
> +   crtc->config->shared_dpll);
> +
> +   if (type == INTEL_OUTPUT_DP)
> intel_ddi_pre_enable_dp(intel_encoder,
> crtc->config->port_clock,
> crtc->config->lane_count,
> crtc->config->shared_dpll,
> intel_crtc_has_type(crtc->config,
> 
> INTEL_OUTPUT_DP_MST));
> -   }
> -   if (type == INTEL_OUTPUT_HDMI) {
> +
> + 

Re: [Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-08 Thread Mika Kahola
Reviewed-by: Mika Kahola 

On Wed, 2016-09-07 at 17:30 -0700, Manasi Navare wrote:
> According to the DisplayPort Spec, in case of Clock Recovery failure
> the link training sequence should fall back to the lower link rate
> followed by lower lane count until CR succeeds.
> On CR success, the sequence proceeds with Channel EQ.
> In case of Channel EQ failures, it should fallback to
> lower link rate and lane count and start the CR phase again.
> 
> v4:
> * Fixed the link rate fallback loop (Manasi Navare)
> v3:
> * Fixed some rebase issues (Mika Kahola)
> v2:
> * Add a helper function to return index of requested link rate
> into common_rates array
> * Changed the link rate fallback loop to make use
> of common_rates array (Mika Kahola)
> * Changed INTEL_INFO to INTEL_GEN (David Weinehall)
> 
> Signed-off-by: Manasi Navare 
> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 109
> +++---
>  drivers/gpu/drm/i915/intel_dp.c   |  15 
>  drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
>  drivers/gpu/drm/i915/intel_drv.h  |   6 +-
>  4 files changed, 128 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 25e7973..1278daa 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct
> intel_encoder *encoder,
>   }
>  }
>  
> -static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> +static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
>   int link_rate, uint32_t
> lane_count,
> - struct intel_shared_dpll *pll,
> - bool link_mst)
> + struct intel_shared_dpll *pll)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
>   struct drm_i915_private *dev_priv = to_i915(encoder-
> >base.dev);
>   enum port port = intel_ddi_get_encoder_port(encoder);
>  
>   intel_dp_set_link_params(intel_dp, link_rate, lane_count,
> -  link_mst);
> - if (encoder->type == INTEL_OUTPUT_EDP)
> - intel_edp_panel_on(intel_dp);
> +  false);
> +
> + intel_edp_panel_on(intel_dp);
>  
>   intel_ddi_clk_select(encoder, pll);
>   intel_prepare_dp_ddi_buffers(encoder);
> @@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct
> intel_encoder *encoder,
>   intel_dp_stop_link_train(intel_dp);
>  }
>  
> +static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> + int link_rate, uint32_t
> lane_count,
> + struct intel_shared_dpll *pll,
> + bool link_mst)
> +{
> + struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> + struct drm_i915_private *dev_priv = to_i915(encoder-
> >base.dev);
> + struct intel_shared_dpll_config tmp_pll_config;
> +
> + /* Disable the PLL and obtain the PLL for Link Training
> +  * that starts with highest link rate and lane count.
> +  */
> + tmp_pll_config = pll->config;
> + pll->funcs.disable(dev_priv, pll);
> + pll->config.crtc_mask = 0;
> +
> + /* If Link Training fails, send a uevent to generate a
> hotplug */
> + if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count,
> link_mst)))
> + drm_kms_helper_hotplug_event(encoder->base.dev);
> + pll->config = tmp_pll_config;
> +}
> +
>  static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
>     bool has_hdmi_sink,
>     struct drm_display_mode
> *adjusted_mode,
> @@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct
> intel_encoder *intel_encoder,
>   struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>   int type = intel_encoder->type;
>  
> - if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
> + if (type == INTEL_OUTPUT_EDP)
> + intel_ddi_pre_enable_edp(intel_encoder,
> + crtc->config->port_clock,
> + crtc->config->lane_count,
> + crtc->config->shared_dpll);
> +
> + if (type == INTEL_OUTPUT_DP)
>   intel_ddi_pre_enable_dp(intel_encoder,
>   crtc->config->port_clock,
>   crtc->config->lane_count,
>   crtc->config->shared_dpll,
>   intel_crtc_has_type(crtc-
> >config,
>   INTEL_OU
> TPUT_DP_MST));
> - }
> - if (type == INTEL_OUTPUT_HDMI) {
> +
> + if (type == INTEL_OUTPUT_HDMI)
>   

[Intel-gfx] [PATCH v4 11/14] drm/i915: Fallback to lower link rate and lane count during link training

2016-09-07 Thread Manasi Navare
According to the DisplayPort Spec, in case of Clock Recovery failure
the link training sequence should fall back to the lower link rate
followed by lower lane count until CR succeeds.
On CR success, the sequence proceeds with Channel EQ.
In case of Channel EQ failures, it should fallback to
lower link rate and lane count and start the CR phase again.

v4:
* Fixed the link rate fallback loop (Manasi Navare)
v3:
* Fixed some rebase issues (Mika Kahola)
v2:
* Add a helper function to return index of requested link rate
into common_rates array
* Changed the link rate fallback loop to make use
of common_rates array (Mika Kahola)
* Changed INTEL_INFO to INTEL_GEN (David Weinehall)

Signed-off-by: Manasi Navare 
---
 drivers/gpu/drm/i915/intel_ddi.c  | 109 +++---
 drivers/gpu/drm/i915/intel_dp.c   |  15 
 drivers/gpu/drm/i915/intel_dp_link_training.c |  12 ++-
 drivers/gpu/drm/i915/intel_drv.h  |   6 +-
 4 files changed, 128 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 25e7973..1278daa 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1634,19 +1634,18 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
}
 }
 
-static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
+static void intel_ddi_pre_enable_edp(struct intel_encoder *encoder,
int link_rate, uint32_t lane_count,
-   struct intel_shared_dpll *pll,
-   bool link_mst)
+   struct intel_shared_dpll *pll)
 {
struct intel_dp *intel_dp = enc_to_intel_dp(>base);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = intel_ddi_get_encoder_port(encoder);
 
intel_dp_set_link_params(intel_dp, link_rate, lane_count,
-link_mst);
-   if (encoder->type == INTEL_OUTPUT_EDP)
-   intel_edp_panel_on(intel_dp);
+false);
+
+   intel_edp_panel_on(intel_dp);
 
intel_ddi_clk_select(encoder, pll);
intel_prepare_dp_ddi_buffers(encoder);
@@ -1657,6 +1656,28 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder 
*encoder,
intel_dp_stop_link_train(intel_dp);
 }
 
+static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
+   int link_rate, uint32_t lane_count,
+   struct intel_shared_dpll *pll,
+   bool link_mst)
+{
+   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+   struct intel_shared_dpll_config tmp_pll_config;
+
+   /* Disable the PLL and obtain the PLL for Link Training
+* that starts with highest link rate and lane count.
+*/
+   tmp_pll_config = pll->config;
+   pll->funcs.disable(dev_priv, pll);
+   pll->config.crtc_mask = 0;
+
+   /* If Link Training fails, send a uevent to generate a hotplug */
+   if (!(intel_ddi_link_train(intel_dp, link_rate, lane_count, link_mst)))
+   drm_kms_helper_hotplug_event(encoder->base.dev);
+   pll->config = tmp_pll_config;
+}
+
 static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
  bool has_hdmi_sink,
  struct drm_display_mode *adjusted_mode,
@@ -1690,20 +1711,26 @@ static void intel_ddi_pre_enable(struct intel_encoder 
*intel_encoder,
struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
int type = intel_encoder->type;
 
-   if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
+   if (type == INTEL_OUTPUT_EDP)
+   intel_ddi_pre_enable_edp(intel_encoder,
+   crtc->config->port_clock,
+   crtc->config->lane_count,
+   crtc->config->shared_dpll);
+
+   if (type == INTEL_OUTPUT_DP)
intel_ddi_pre_enable_dp(intel_encoder,
crtc->config->port_clock,
crtc->config->lane_count,
crtc->config->shared_dpll,
intel_crtc_has_type(crtc->config,

INTEL_OUTPUT_DP_MST));
-   }
-   if (type == INTEL_OUTPUT_HDMI) {
+
+   if (type == INTEL_OUTPUT_HDMI)
intel_ddi_pre_enable_hdmi(intel_encoder,
  crtc->config->has_hdmi_sink,
  >config->base.adjusted_mode,