[Intel-gfx] [CI 1/2] drm/i915: Try harder to reset the GPU

2017-05-18 Thread Chris Wilson
Repeat the reset a couple of times if at first we do not succeed.

v2: differentiate which path/engine failed with a debug message

Signed-off-by: Chris Wilson 
Link: 
http://patchwork.freedesktop.org/patch/msgid/20170513083726.502-1-ch...@chris-wilson.co.uk
Reviewed-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/intel_uncore.c | 67 +
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 08d7d08438c0..b27cc00ebf83 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1427,9 +1427,10 @@ int i915_reg_read_ioctl(struct drm_device *dev,
return ret;
 }
 
-static int i915_reset_complete(struct pci_dev *pdev)
+static bool i915_reset_complete(struct pci_dev *pdev)
 {
u8 gdrst;
+
pci_read_config_byte(pdev, I915_GDRST, );
return (gdrst & GRDOM_RESET_STATUS) == 0;
 }
@@ -1440,15 +1441,16 @@ static int i915_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask
 
/* assert reset for at least 20 usec */
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
-   udelay(20);
+   usleep_range(50, 200);
pci_write_config_byte(pdev, I915_GDRST, 0);
 
return wait_for(i915_reset_complete(pdev), 500);
 }
 
-static int g4x_reset_complete(struct pci_dev *pdev)
+static bool g4x_reset_complete(struct pci_dev *pdev)
 {
u8 gdrst;
+
pci_read_config_byte(pdev, I915_GDRST, );
return (gdrst & GRDOM_RESET_ENABLE) == 0;
 }
@@ -1456,6 +1458,7 @@ static int g4x_reset_complete(struct pci_dev *pdev)
 static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned 
engine_mask)
 {
struct pci_dev *pdev = dev_priv->drm.pdev;
+
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
return wait_for(g4x_reset_complete(pdev), 500);
 }
@@ -1468,8 +1471,10 @@ static int g4x_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask)
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_RENDER | GRDOM_RESET_ENABLE);
ret =  wait_for(g4x_reset_complete(pdev), 500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for render reset failed\n");
+   goto out;
+   }
 
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | 
VCP_UNIT_CLOCK_GATE_DISABLE);
@@ -1478,16 +1483,17 @@ static int g4x_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask)
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_MEDIA | GRDOM_RESET_ENABLE);
ret =  wait_for(g4x_reset_complete(pdev), 500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for media reset failed\n");
+   }
 
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & 
~VCP_UNIT_CLOCK_GATE_DISABLE);
POSTING_READ(VDECCLK_GATE_D);
 
+out:
pci_write_config_byte(pdev, I915_GDRST, 0);
-
-   return 0;
+   return ret;
 }
 
 static int ironlake_do_reset(struct drm_i915_private *dev_priv,
@@ -1495,31 +1501,36 @@ static int ironlake_do_reset(struct drm_i915_private 
*dev_priv,
 {
int ret;
 
-   I915_WRITE(ILK_GDSR,
-  ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
+   I915_WRITE(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
ret = intel_wait_for_register(dev_priv,
  ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
  500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for render reset failed\n");
+   goto out;
+   }
 
-   I915_WRITE(ILK_GDSR,
-  ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
+   I915_WRITE(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
ret = intel_wait_for_register(dev_priv,
  ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
  500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for media reset failed\n");
+   goto out;
+   }
 
+out:
I915_WRITE(ILK_GDSR, 0);
-
-   return 0;
+   POSTING_READ(ILK_GDSR);
+   return ret;
 }
 
 /* Reset the hardware domains (GENX_GRDOM_*) specified by mask */
 static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv,
u32 hw_domain_mask)
 {
+   int err;
+
/* GEN6_GDRST is not in the gt power well, no need to check
 * for fifo space for the write or forcewake the chip for
 * the read
@@ -1527,9 +1538,14 @@ static int 

[Intel-gfx] [CI 1/2] drm/i915: Try harder to reset the GPU

2017-05-18 Thread Chris Wilson
Repeat the reset a couple of times if at first we do not succeed.

v2: differentiate which path/engine failed with a debug message

Signed-off-by: Chris Wilson 
Link: 
http://patchwork.freedesktop.org/patch/msgid/20170513083726.502-1-ch...@chris-wilson.co.uk
Reviewed-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/intel_uncore.c | 67 +
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index 71b9b387ad04..c50aa97bc7d8 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -1463,9 +1463,10 @@ int i915_reg_read_ioctl(struct drm_device *dev,
return ret;
 }
 
-static int i915_reset_complete(struct pci_dev *pdev)
+static bool i915_reset_complete(struct pci_dev *pdev)
 {
u8 gdrst;
+
pci_read_config_byte(pdev, I915_GDRST, );
return (gdrst & GRDOM_RESET_STATUS) == 0;
 }
@@ -1476,15 +1477,16 @@ static int i915_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask
 
/* assert reset for at least 20 usec */
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
-   udelay(20);
+   usleep_range(50, 200);
pci_write_config_byte(pdev, I915_GDRST, 0);
 
return wait_for(i915_reset_complete(pdev), 500);
 }
 
-static int g4x_reset_complete(struct pci_dev *pdev)
+static bool g4x_reset_complete(struct pci_dev *pdev)
 {
u8 gdrst;
+
pci_read_config_byte(pdev, I915_GDRST, );
return (gdrst & GRDOM_RESET_ENABLE) == 0;
 }
@@ -1492,6 +1494,7 @@ static int g4x_reset_complete(struct pci_dev *pdev)
 static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned 
engine_mask)
 {
struct pci_dev *pdev = dev_priv->drm.pdev;
+
pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
return wait_for(g4x_reset_complete(pdev), 500);
 }
@@ -1504,8 +1507,10 @@ static int g4x_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask)
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_RENDER | GRDOM_RESET_ENABLE);
ret =  wait_for(g4x_reset_complete(pdev), 500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for render reset failed\n");
+   goto out;
+   }
 
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | 
VCP_UNIT_CLOCK_GATE_DISABLE);
@@ -1514,16 +1519,17 @@ static int g4x_do_reset(struct drm_i915_private 
*dev_priv, unsigned engine_mask)
pci_write_config_byte(pdev, I915_GDRST,
  GRDOM_MEDIA | GRDOM_RESET_ENABLE);
ret =  wait_for(g4x_reset_complete(pdev), 500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for media reset failed\n");
+   }
 
/* WaVcpClkGateDisableForMediaReset:ctg,elk */
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & 
~VCP_UNIT_CLOCK_GATE_DISABLE);
POSTING_READ(VDECCLK_GATE_D);
 
+out:
pci_write_config_byte(pdev, I915_GDRST, 0);
-
-   return 0;
+   return ret;
 }
 
 static int ironlake_do_reset(struct drm_i915_private *dev_priv,
@@ -1531,31 +1537,36 @@ static int ironlake_do_reset(struct drm_i915_private 
*dev_priv,
 {
int ret;
 
-   I915_WRITE(ILK_GDSR,
-  ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
+   I915_WRITE(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE);
ret = intel_wait_for_register(dev_priv,
  ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
  500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for render reset failed\n");
+   goto out;
+   }
 
-   I915_WRITE(ILK_GDSR,
-  ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
+   I915_WRITE(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE);
ret = intel_wait_for_register(dev_priv,
  ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0,
  500);
-   if (ret)
-   return ret;
+   if (ret) {
+   DRM_DEBUG_DRIVER("Wait for media reset failed\n");
+   goto out;
+   }
 
+out:
I915_WRITE(ILK_GDSR, 0);
-
-   return 0;
+   POSTING_READ(ILK_GDSR);
+   return ret;
 }
 
 /* Reset the hardware domains (GENX_GRDOM_*) specified by mask */
 static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv,
u32 hw_domain_mask)
 {
+   int err;
+
/* GEN6_GDRST is not in the gt power well, no need to check
 * for fifo space for the write or forcewake the chip for
 * the read
@@ -1563,9 +1574,14 @@ static int