[Intel-gfx] [CI 1/2] drm/i915: Try harder to reset the GPU
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 WilsonLink: 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
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 WilsonLink: 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