diff mbox series

drm/i915/dp: Poll for DDI Idle status to be 0 after enabling DDI Buf

Message ID 20200616193056.4817-1-manasi.d.navare@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/dp: Poll for DDI Idle status to be 0 after enabling DDI Buf | expand

Commit Message

Navare, Manasi June 16, 2020, 7:30 p.m. UTC
The Bspec sequence expects us to poll for DDI Idle status
to be 0 (not idle) with a timeout of 600usecs after enabling the
DDI BUF CTL. But currently in the driver we just wait for 600usecs
without polling so add that.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Ville Syrjala June 16, 2020, 7:42 p.m. UTC | #1
On Tue, Jun 16, 2020 at 12:30:56PM -0700, Manasi Navare wrote:
> The Bspec sequence expects us to poll for DDI Idle status
> to be 0 (not idle) with a timeout of 600usecs after enabling the
> DDI BUF CTL.

It only says that for newer platforms. We need to either keep
the fixed delay before starting to poll, or someone needs confirm 
how the idle bit really behaves on the older platforms.

> But currently in the driver we just wait for 600usecs
> without polling so add that.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index ca7bb2294d2b..de7e15de0bc5 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4023,7 +4023,11 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
>  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
>  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
>  
> -	udelay(600);
> +	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
> +			  DDI_BUF_IS_IDLE),
> +			600))
> +		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
> +			port_name(port));
>  }
>  
>  static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
> -- 
> 2.19.1
Ville Syrjala June 16, 2020, 7:54 p.m. UTC | #2
On Tue, Jun 16, 2020 at 10:42:44PM +0300, Ville Syrjälä wrote:
> On Tue, Jun 16, 2020 at 12:30:56PM -0700, Manasi Navare wrote:
> > The Bspec sequence expects us to poll for DDI Idle status
> > to be 0 (not idle) with a timeout of 600usecs after enabling the
> > DDI BUF CTL.
> 
> It only says that for newer platforms. We need to either keep
> the fixed delay before starting to poll, or someone needs confirm 
> how the idle bit really behaves on the older platforms.

In fact it says not to use this bit at all on BXT. So even our disable
sequence is potentially borked on BXT. Unfortunately the spec doesn't
say which way the bit is broken, so not clear if that's the case or
not.

> 
> > But currently in the driver we just wait for 600usecs
> > without polling so add that.
> > 
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Imre Deak <imre.deak@intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index ca7bb2294d2b..de7e15de0bc5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -4023,7 +4023,11 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
> >  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
> >  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
> >  
> > -	udelay(600);
> > +	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
> > +			  DDI_BUF_IS_IDLE),
> > +			600))
> > +		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
> > +			port_name(port));
> >  }
> >  
> >  static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
> > -- 
> > 2.19.1
> 
> -- 
> Ville Syrjälä
> Intel
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Navare, Manasi June 16, 2020, 8:07 p.m. UTC | #3
On Tue, Jun 16, 2020 at 10:54:22PM +0300, Ville Syrjälä wrote:
> On Tue, Jun 16, 2020 at 10:42:44PM +0300, Ville Syrjälä wrote:
> > On Tue, Jun 16, 2020 at 12:30:56PM -0700, Manasi Navare wrote:
> > > The Bspec sequence expects us to poll for DDI Idle status
> > > to be 0 (not idle) with a timeout of 600usecs after enabling the
> > > DDI BUF CTL.
> > 
> > It only says that for newer platforms. We need to either keep
> > the fixed delay before starting to poll, or someone needs confirm 
> > how the idle bit really behaves on the older platforms.
> 
> In fact it says not to use this bit at all on BXT. So even our disable
> sequence is potentially borked on BXT. Unfortunately the spec doesn't
> say which way the bit is broken, so not clear if that's the case or
> not.
>

I double checked on Gen 9, it is > 518 usecs timeout and Gen 10+
it is 500usecs and then gen 12, it is 600 usecs timeout.

Should we add this max timeout for Gen >=10, we def need this for
platforms starting Gen 10+

Manasi
 
> > 
> > > But currently in the driver we just wait for 600usecs
> > > without polling so add that.
> > > 
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Imre Deak <imre.deak@intel.com>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > index ca7bb2294d2b..de7e15de0bc5 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -4023,7 +4023,11 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
> > >  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
> > >  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
> > >  
> > > -	udelay(600);
> > > +	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
> > > +			  DDI_BUF_IS_IDLE),
> > > +			600))
> > > +		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
> > > +			port_name(port));
> > >  }
> > >  
> > >  static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
> > > -- 
> > > 2.19.1
> > 
> > -- 
> > Ville Syrjälä
> > Intel
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
Ville Syrjala June 16, 2020, 8:22 p.m. UTC | #4
On Tue, Jun 16, 2020 at 12:30:56PM -0700, Manasi Navare wrote:
> The Bspec sequence expects us to poll for DDI Idle status
> to be 0 (not idle) with a timeout of 600usecs after enabling the
> DDI BUF CTL. But currently in the driver we just wait for 600usecs
> without polling so add that.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index ca7bb2294d2b..de7e15de0bc5 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4023,7 +4023,11 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
>  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
>  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
>  
> -	udelay(600);
> +	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
> +			  DDI_BUF_IS_IDLE),
> +			600))
> +		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
> +			port_name(port));

Another thing I just noticed is that icl+ need this for HDMI as well.
The slightly odd thing is that glk is documented to need this for
DP but not HDMI. But I'm thinking doing it also for glk HDMI should
be fine.

So I guess to line up with the spec we should:
- fixed >518us enable delay for pre-glk (not sure if polling
  would be ok for hsw/bdw/skl)
- poll for enable on glk+
- fixed 16us disable delay for bxt
- poll for disable on !bxt

And do it for both DP and HDMI for consistency.


>  }
>  
>  static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
> -- 
> 2.19.1
Navare, Manasi June 16, 2020, 9:55 p.m. UTC | #5
On Tue, Jun 16, 2020 at 11:22:32PM +0300, Ville Syrjälä wrote:
> On Tue, Jun 16, 2020 at 12:30:56PM -0700, Manasi Navare wrote:
> > The Bspec sequence expects us to poll for DDI Idle status
> > to be 0 (not idle) with a timeout of 600usecs after enabling the
> > DDI BUF CTL. But currently in the driver we just wait for 600usecs
> > without polling so add that.
> > 
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Imre Deak <imre.deak@intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index ca7bb2294d2b..de7e15de0bc5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -4023,7 +4023,11 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
> >  	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
> >  	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
> >  
> > -	udelay(600);
> > +	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
> > +			  DDI_BUF_IS_IDLE),
> > +			600))
> > +		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
> > +			port_name(port));
> 
> Another thing I just noticed is that icl+ need this for HDMI as well.
> The slightly odd thing is that glk is documented to need this for
> DP but not HDMI. But I'm thinking doing it also for glk HDMI should
> be fine.
> 
> So I guess to line up with the spec we should:
> - fixed >518us enable delay for pre-glk (not sure if polling
>   would be ok for hsw/bdw/skl)
> - poll for enable on glk+
> - fixed 16us disable delay for bxt
> - poll for disable on !bxt
> 
> And do it for both DP and HDMI for consistency.

So since its different one each platform, should we create a per platform hook
like wait_for_non_idle_status or something per platform?

Manasi

> 
> 
> >  }
> >  
> >  static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
> > -- 
> > 2.19.1
> 
> -- 
> Ville Syrjälä
> Intel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index ca7bb2294d2b..de7e15de0bc5 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4023,7 +4023,11 @@  static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
 
-	udelay(600);
+	if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
+			  DDI_BUF_IS_IDLE),
+			600))
+		drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
+			port_name(port));
 }
 
 static void intel_ddi_set_link_train(struct intel_dp *intel_dp,