Re: [Intel-gfx] [PATCH 2/3] drm/i915/dp: Fix sink-crc reads.

2018-04-24 Thread Dhinakaran Pandiyan



On Tue, 2018-04-24 at 13:55 -0700, Rodrigo Vivi wrote:
> On Mon, Apr 23, 2018 at 07:56:58PM -0700, Dhinakaran Pandiyan wrote:
> > Sink crc is calculated by the sink for static frames irrespective of
> > what the driver sets in TEST_SINK_START dpcd. Since PSR is the only use
> > case for sink crc, we don't really need the sink_crc_{start, stop} code.
> > 
> > The second problem with the current implementation is vblank waits.
> > Enabling vblank interrupts triggers PSR exit, which means we aren't
> > really reading the correct CRC values for PSR tests. vblank waits are
> > replaced by delays.
> > 
> > With the changes made in this patch, sink CRC is available only for
> > static frames. I have tested this on a SKL laptop with PSR panel.
> > 
> > Signed-off-by: Dhinakaran Pandiyan 
> > ---
> >  drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
> >  drivers/gpu/drm/i915/intel_dp.c | 114 
> > 
> >  drivers/gpu/drm/i915/intel_drv.h|   3 +-
> >  3 files changed, 15 insertions(+), 104 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> > b/drivers/gpu/drm/i915/i915_debugfs.c
> > index 2f05f5262bba..35fa1418cc07 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -2784,7 +2784,7 @@ static int i915_sink_crc(struct seq_file *m, void 
> > *data)
> >  
> > intel_dp = enc_to_intel_dp(state->best_encoder);
> >  
> > -   ret = intel_dp_sink_crc(intel_dp, crtc_state, crc);
> > +   ret = intel_dp_sink_crc(intel_dp, crc);
> > if (ret)
> > goto err;
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 7dcc874b7d8f..7352ab631ea8 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -3876,32 +3876,18 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
> > intel_dp->is_mst);
> >  }
> >  
> > -static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp,
> > - struct intel_crtc_state *crtc_state, bool 
> > disable_wa)
> > +int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
> >  {
> > -   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > -   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> > -   struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> > -   u8 buf;
> > -   int ret = 0;
> > -   int count = 0;
> > -   int attempts = 10;
> > +   int count = 0, ret = 0, attempts;
> >  
> > -   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) < 0) {
> > -   DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
> > -   ret = -EIO;
> > -   goto out;
> > -   }
> > +   for (attempts = 0; attempts < 3 && count == 0; attempts++) {
> > +   u8 buf;
> >  
> > -   if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_SINK,
> > -  buf & ~DP_TEST_SINK_START) < 0) {
> > -   DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
> > -   ret = -EIO;
> > -   goto out;
> > -   }
> > -
> > -   do {
> > -   intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
> > +   /* Wait for approximately half a frame, we cannot wait for a
> 
> that should be dependend on the mode timings right?!
> I mean, I'm not against some random value that matches most used cases,
> but I believe the statement should be different.
> 

I'll modify the comment, thanks!

Is there an existing function that provides this number in
milliseconds? 



> > +* vblank interrupt as it triggers PSR exit.
> > +*/
> > +   if (attempts)
> > +   usleep_range(8000, 8500);
> >  
> > if (drm_dp_dpcd_readb(_dp->aux,
> >   DP_TEST_SINK_MISC, ) < 0) {
> > @@ -3909,93 +3895,19 @@ static int intel_dp_sink_crc_stop(struct intel_dp 
> > *intel_dp,
> > goto out;
> > }
> > count = buf & DP_TEST_COUNT_MASK;
> > -   } while (--attempts && count);
> > -
> > -   if (attempts == 0) {
> > -   DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed after 
> > calculation is stopped\n");
> > -   ret = -ETIMEDOUT;
> > }
> >  
> > - out:
> > -   if (disable_wa)
> > -   hsw_enable_ips(crtc_state);
> > -   return ret;
> > -}
> > -
> > -static int intel_dp_sink_crc_start(struct intel_dp *intel_dp,
> > -  struct intel_crtc_state *crtc_state)
> > -{
> > -   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > -   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> > -   struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> > -   u8 buf;
> > -   int ret;
> > -
> > -   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK_MISC, ) < 0)
> > -   return -EIO;
> > -
> > -   if 

Re: [Intel-gfx] [PATCH 2/3] drm/i915/dp: Fix sink-crc reads.

2018-04-24 Thread Rodrigo Vivi
On Mon, Apr 23, 2018 at 07:56:58PM -0700, Dhinakaran Pandiyan wrote:
> Sink crc is calculated by the sink for static frames irrespective of
> what the driver sets in TEST_SINK_START dpcd. Since PSR is the only use
> case for sink crc, we don't really need the sink_crc_{start, stop} code.
> 
> The second problem with the current implementation is vblank waits.
> Enabling vblank interrupts triggers PSR exit, which means we aren't
> really reading the correct CRC values for PSR tests. vblank waits are
> replaced by delays.
> 
> With the changes made in this patch, sink CRC is available only for
> static frames. I have tested this on a SKL laptop with PSR panel.
> 
> Signed-off-by: Dhinakaran Pandiyan 
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
>  drivers/gpu/drm/i915/intel_dp.c | 114 
> 
>  drivers/gpu/drm/i915/intel_drv.h|   3 +-
>  3 files changed, 15 insertions(+), 104 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 2f05f5262bba..35fa1418cc07 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2784,7 +2784,7 @@ static int i915_sink_crc(struct seq_file *m, void *data)
>  
>   intel_dp = enc_to_intel_dp(state->best_encoder);
>  
> - ret = intel_dp_sink_crc(intel_dp, crtc_state, crc);
> + ret = intel_dp_sink_crc(intel_dp, crc);
>   if (ret)
>   goto err;
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 7dcc874b7d8f..7352ab631ea8 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3876,32 +3876,18 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
>   intel_dp->is_mst);
>  }
>  
> -static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp,
> -   struct intel_crtc_state *crtc_state, bool 
> disable_wa)
> +int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
>  {
> - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> - u8 buf;
> - int ret = 0;
> - int count = 0;
> - int attempts = 10;
> + int count = 0, ret = 0, attempts;
>  
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) < 0) {
> - DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
> - ret = -EIO;
> - goto out;
> - }
> + for (attempts = 0; attempts < 3 && count == 0; attempts++) {
> + u8 buf;
>  
> - if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_SINK,
> -buf & ~DP_TEST_SINK_START) < 0) {
> - DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
> - ret = -EIO;
> - goto out;
> - }
> -
> - do {
> - intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
> + /* Wait for approximately half a frame, we cannot wait for a

that should be dependend on the mode timings right?!
I mean, I'm not against some random value that matches most used cases,
but I believe the statement should be different.

> +  * vblank interrupt as it triggers PSR exit.
> +  */
> + if (attempts)
> + usleep_range(8000, 8500);
>  
>   if (drm_dp_dpcd_readb(_dp->aux,
> DP_TEST_SINK_MISC, ) < 0) {
> @@ -3909,93 +3895,19 @@ static int intel_dp_sink_crc_stop(struct intel_dp 
> *intel_dp,
>   goto out;
>   }
>   count = buf & DP_TEST_COUNT_MASK;
> - } while (--attempts && count);
> -
> - if (attempts == 0) {
> - DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed after 
> calculation is stopped\n");
> - ret = -ETIMEDOUT;
>   }
>  
> - out:
> - if (disable_wa)
> - hsw_enable_ips(crtc_state);
> - return ret;
> -}
> -
> -static int intel_dp_sink_crc_start(struct intel_dp *intel_dp,
> -struct intel_crtc_state *crtc_state)
> -{
> - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> - u8 buf;
> - int ret;
> -
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK_MISC, ) < 0)
> - return -EIO;
> -
> - if (!(buf & DP_TEST_CRC_SUPPORTED))
> - return -ENOTTY;
> -
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) < 0)
> - return -EIO;
> -
> - if (buf & DP_TEST_SINK_START) {
> - ret = intel_dp_sink_crc_stop(intel_dp, crtc_state, false);
> - if (ret)
> -  

Re: [Intel-gfx] [PATCH 2/3] drm/i915/dp: Fix sink-crc reads.

2018-04-24 Thread Dhinakaran Pandiyan
On Tue, 2018-04-24 at 16:26 +0300, Mika Kahola wrote:
> On Mon, 2018-04-23 at 19:56 -0700, Dhinakaran Pandiyan wrote:
> > Sink crc is calculated by the sink for static frames irrespective of
> > what the driver sets in TEST_SINK_START dpcd. Since PSR is the only
> > use
> > case for sink crc, we don't really need the sink_crc_{start, stop}
> > code.
> > 
> > The second problem with the current implementation is vblank waits.
> > Enabling vblank interrupts triggers PSR exit, which means we aren't
> > really reading the correct CRC values for PSR tests. vblank waits are
> > replaced by delays.
> > 
> > With the changes made in this patch, sink CRC is available only for
> > static frames. I have tested this on a SKL laptop with PSR panel.
> > 
> > Signed-off-by: Dhinakaran Pandiyan 
> > ---
> >  drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
> >  drivers/gpu/drm/i915/intel_dp.c | 114 
> > 
> >  drivers/gpu/drm/i915/intel_drv.h|   3 +-
> >  3 files changed, 15 insertions(+), 104 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> > b/drivers/gpu/drm/i915/i915_debugfs.c
> > index 2f05f5262bba..35fa1418cc07 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -2784,7 +2784,7 @@ static int i915_sink_crc(struct seq_file *m,
> > void *data)
> >  
> > intel_dp = enc_to_intel_dp(state->best_encoder);
> >  
> > -   ret = intel_dp_sink_crc(intel_dp, crtc_state, crc);
> > +   ret = intel_dp_sink_crc(intel_dp, crc);
> > if (ret)
> > goto err;
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 7dcc874b7d8f..7352ab631ea8 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -3876,32 +3876,18 @@ intel_dp_configure_mst(struct intel_dp
> > *intel_dp)
> > intel_dp->is_mst);
> >  }
> >  
> > -static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp,
> > - struct intel_crtc_state
> > *crtc_state, bool disable_wa)
> > +int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
> >  {
> > -   struct intel_digital_port *dig_port =
> > dp_to_dig_port(intel_dp);
> > -   struct drm_i915_private *dev_priv = to_i915(dig_port-
> > >base.base.dev);
> > -   struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> > >base.crtc);
> > -   u8 buf;
> > -   int ret = 0;
> > -   int count = 0;
> > -   int attempts = 10;
> > +   int count = 0, ret = 0, attempts;
> >  
> > -   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) <
> > 0) {
> > -   DRM_DEBUG_KMS("Sink CRC couldn't be stopped
> > properly\n");
> > -   ret = -EIO;
> > -   goto out;
> > -   }
> > +   for (attempts = 0; attempts < 3 && count == 0; attempts++) {
> A question. How did you end up with three attempts or one and a half
> frames? We used to try 6 times or 6 vblanks until we gave up trying.
> Well, I don't really know the history why we have ended up with 6
> attempts in the first place. 

CRC should be available within the next static frame. So the idea for a
tests is to do, for example, a page flip and immediately attempt to read
the CRC. Since we cannot exactly synchronize the flip getting committed,
debugfs read and CRC generation, all that the kernel can do correctly is
check if the CRC is available within a frame and read it.

I think the reason for trying 6 times was to somehow get a non-zero CRC.
But that means tests end up reading CRC of a different frame.


___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/3] drm/i915/dp: Fix sink-crc reads.

2018-04-24 Thread Mika Kahola
On Mon, 2018-04-23 at 19:56 -0700, Dhinakaran Pandiyan wrote:
> Sink crc is calculated by the sink for static frames irrespective of
> what the driver sets in TEST_SINK_START dpcd. Since PSR is the only
> use
> case for sink crc, we don't really need the sink_crc_{start, stop}
> code.
> 
> The second problem with the current implementation is vblank waits.
> Enabling vblank interrupts triggers PSR exit, which means we aren't
> really reading the correct CRC values for PSR tests. vblank waits are
> replaced by delays.
> 
> With the changes made in this patch, sink CRC is available only for
> static frames. I have tested this on a SKL laptop with PSR panel.
> 
> Signed-off-by: Dhinakaran Pandiyan 
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
>  drivers/gpu/drm/i915/intel_dp.c | 114 
> 
>  drivers/gpu/drm/i915/intel_drv.h|   3 +-
>  3 files changed, 15 insertions(+), 104 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 2f05f5262bba..35fa1418cc07 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2784,7 +2784,7 @@ static int i915_sink_crc(struct seq_file *m,
> void *data)
>  
>   intel_dp = enc_to_intel_dp(state->best_encoder);
>  
> - ret = intel_dp_sink_crc(intel_dp, crtc_state, crc);
> + ret = intel_dp_sink_crc(intel_dp, crc);
>   if (ret)
>   goto err;
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 7dcc874b7d8f..7352ab631ea8 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3876,32 +3876,18 @@ intel_dp_configure_mst(struct intel_dp
> *intel_dp)
>   intel_dp->is_mst);
>  }
>  
> -static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp,
> -   struct intel_crtc_state
> *crtc_state, bool disable_wa)
> +int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
>  {
> - struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> - struct drm_i915_private *dev_priv = to_i915(dig_port-
> >base.base.dev);
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
> - u8 buf;
> - int ret = 0;
> - int count = 0;
> - int attempts = 10;
> + int count = 0, ret = 0, attempts;
>  
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) <
> 0) {
> - DRM_DEBUG_KMS("Sink CRC couldn't be stopped
> properly\n");
> - ret = -EIO;
> - goto out;
> - }
> + for (attempts = 0; attempts < 3 && count == 0; attempts++) {
A question. How did you end up with three attempts or one and a half
frames? We used to try 6 times or 6 vblanks until we gave up trying.
Well, I don't really know the history why we have ended up with 6
attempts in the first place. 


> + u8 buf;
>  
> - if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_SINK,
> -    buf & ~DP_TEST_SINK_START) < 0) {
> - DRM_DEBUG_KMS("Sink CRC couldn't be stopped
> properly\n");
> - ret = -EIO;
> - goto out;
> - }
> -
> - do {
> - intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
> + /* Wait for approximately half a frame, we cannot
> wait for a
> +  * vblank interrupt as it triggers PSR exit.
> +  */
> + if (attempts)
> + usleep_range(8000, 8500);
>  
>   if (drm_dp_dpcd_readb(_dp->aux,
>     DP_TEST_SINK_MISC, ) < 0)
> {
> @@ -3909,93 +3895,19 @@ static int intel_dp_sink_crc_stop(struct
> intel_dp *intel_dp,
>   goto out;
>   }
>   count = buf & DP_TEST_COUNT_MASK;
> - } while (--attempts && count);
> -
> - if (attempts == 0) {
> - DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not
> zeroed after calculation is stopped\n");
> - ret = -ETIMEDOUT;
>   }
>  
> - out:
> - if (disable_wa)
> - hsw_enable_ips(crtc_state);
> - return ret;
> -}
> -
> -static int intel_dp_sink_crc_start(struct intel_dp *intel_dp,
> -    struct intel_crtc_state
> *crtc_state)
> -{
> - struct intel_digital_port *dig_port =
> dp_to_dig_port(intel_dp);
> - struct drm_i915_private *dev_priv = to_i915(dig_port-
> >base.base.dev);
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
> - u8 buf;
> - int ret;
> -
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK_MISC,
> ) < 0)
> - return -EIO;
> -
> - if (!(buf & DP_TEST_CRC_SUPPORTED))
> - return -ENOTTY;
> -
> - if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) <
> 0)
> - return -EIO;
> -
> - if (buf & DP_TEST_SINK_START) {
> -   

[Intel-gfx] [PATCH 2/3] drm/i915/dp: Fix sink-crc reads.

2018-04-23 Thread Dhinakaran Pandiyan
Sink crc is calculated by the sink for static frames irrespective of
what the driver sets in TEST_SINK_START dpcd. Since PSR is the only use
case for sink crc, we don't really need the sink_crc_{start, stop} code.

The second problem with the current implementation is vblank waits.
Enabling vblank interrupts triggers PSR exit, which means we aren't
really reading the correct CRC values for PSR tests. vblank waits are
replaced by delays.

With the changes made in this patch, sink CRC is available only for
static frames. I have tested this on a SKL laptop with PSR panel.

Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
 drivers/gpu/drm/i915/intel_dp.c | 114 
 drivers/gpu/drm/i915/intel_drv.h|   3 +-
 3 files changed, 15 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 2f05f5262bba..35fa1418cc07 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2784,7 +2784,7 @@ static int i915_sink_crc(struct seq_file *m, void *data)
 
intel_dp = enc_to_intel_dp(state->best_encoder);
 
-   ret = intel_dp_sink_crc(intel_dp, crtc_state, crc);
+   ret = intel_dp_sink_crc(intel_dp, crc);
if (ret)
goto err;
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7dcc874b7d8f..7352ab631ea8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3876,32 +3876,18 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
intel_dp->is_mst);
 }
 
-static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state, bool 
disable_wa)
+int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
-   u8 buf;
-   int ret = 0;
-   int count = 0;
-   int attempts = 10;
+   int count = 0, ret = 0, attempts;
 
-   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) < 0) {
-   DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
-   ret = -EIO;
-   goto out;
-   }
+   for (attempts = 0; attempts < 3 && count == 0; attempts++) {
+   u8 buf;
 
-   if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_SINK,
-  buf & ~DP_TEST_SINK_START) < 0) {
-   DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n");
-   ret = -EIO;
-   goto out;
-   }
-
-   do {
-   intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
+   /* Wait for approximately half a frame, we cannot wait for a
+* vblank interrupt as it triggers PSR exit.
+*/
+   if (attempts)
+   usleep_range(8000, 8500);
 
if (drm_dp_dpcd_readb(_dp->aux,
  DP_TEST_SINK_MISC, ) < 0) {
@@ -3909,93 +3895,19 @@ static int intel_dp_sink_crc_stop(struct intel_dp 
*intel_dp,
goto out;
}
count = buf & DP_TEST_COUNT_MASK;
-   } while (--attempts && count);
-
-   if (attempts == 0) {
-   DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed after 
calculation is stopped\n");
-   ret = -ETIMEDOUT;
}
 
- out:
-   if (disable_wa)
-   hsw_enable_ips(crtc_state);
-   return ret;
-}
-
-static int intel_dp_sink_crc_start(struct intel_dp *intel_dp,
-  struct intel_crtc_state *crtc_state)
-{
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
-   u8 buf;
-   int ret;
-
-   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK_MISC, ) < 0)
-   return -EIO;
-
-   if (!(buf & DP_TEST_CRC_SUPPORTED))
-   return -ENOTTY;
-
-   if (drm_dp_dpcd_readb(_dp->aux, DP_TEST_SINK, ) < 0)
-   return -EIO;
-
-   if (buf & DP_TEST_SINK_START) {
-   ret = intel_dp_sink_crc_stop(intel_dp, crtc_state, false);
-   if (ret)
-   return ret;
-   }
-
-   hsw_disable_ips(crtc_state);
-
-   if (drm_dp_dpcd_writeb(_dp->aux, DP_TEST_SINK,
-  buf | DP_TEST_SINK_START) < 0) {
-   hsw_enable_ips(crtc_state);
-   return -EIO;
-   }
-
-   intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
-   return