drm/i915: Fix gen4 GPU reset
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 21 Nov 2014 19:54:25 +0000 (21:54 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 3 Dec 2014 08:29:36 +0000 (09:29 +0100)
On pre-ctg the reset bit directly controls the reset signal. We must
assert it for >=20usec and then deassert it. Bit 1 is a RO status bit
which should also go down when the reset is no longer asserted.

Tested-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_uncore.c

index 3102907a96a7fb4724ba38361568ff36a3368cb1..ff1e36f669a26800fe315bffbfb1ade6d7fa7fbb 100644 (file)
@@ -83,6 +83,7 @@
 #define  GRDOM_RENDER  (1<<2)
 #define  GRDOM_MEDIA   (3<<2)
 #define  GRDOM_MASK    (3<<2)
+#define  GRDOM_RESET_STATUS (1<<1)
 #define  GRDOM_RESET_ENABLE (1<<0)
 
 #define ILK_GDSR 0x2ca4 /* MCHBAR offset */
index f0230b0e8e11139fcff996ca90d54369290adeff..c333d9c37f110fbd16f986b187606821517c866b 100644 (file)
@@ -1349,37 +1349,24 @@ static int i965_reset_complete(struct drm_device *dev)
 {
        u8 gdrst;
        pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
-       return (gdrst & GRDOM_RESET_ENABLE) == 0;
+       return (gdrst & GRDOM_RESET_STATUS) == 0;
 }
 
 static int i965_do_reset(struct drm_device *dev)
 {
-       int ret;
-
-       /* FIXME: i965g/gm need a display save/restore for gpu reset. */
-       return -ENODEV;
-
-       /*
-        * Set the domains we want to reset (GRDOM/bits 2 and 3) as
-        * well as the reset bit (GR/bit 0).  Setting the GR bit
-        * triggers the reset; when done, the hardware will clear it.
-        */
-       pci_write_config_byte(dev->pdev, I965_GDRST,
-                             GRDOM_RENDER | GRDOM_RESET_ENABLE);
-       ret =  wait_for(i965_reset_complete(dev), 500);
-       if (ret)
-               return ret;
-
-       pci_write_config_byte(dev->pdev, I965_GDRST,
-                             GRDOM_MEDIA | GRDOM_RESET_ENABLE);
-
-       ret =  wait_for(i965_reset_complete(dev), 500);
-       if (ret)
-               return ret;
-
+       /* assert reset for at least 20 usec */
+       pci_write_config_byte(dev->pdev, I965_GDRST, GRDOM_RESET_ENABLE);
+       udelay(20);
        pci_write_config_byte(dev->pdev, I965_GDRST, 0);
 
-       return 0;
+       return wait_for(i965_reset_complete(dev), 500);
+}
+
+static int g4x_reset_complete(struct drm_device *dev)
+{
+       u8 gdrst;
+       pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
+       return (gdrst & GRDOM_RESET_ENABLE) == 0;
 }
 
 static int g4x_do_reset(struct drm_device *dev)
@@ -1389,7 +1376,7 @@ static int g4x_do_reset(struct drm_device *dev)
 
        pci_write_config_byte(dev->pdev, I965_GDRST,
                              GRDOM_RENDER | GRDOM_RESET_ENABLE);
-       ret =  wait_for(i965_reset_complete(dev), 500);
+       ret =  wait_for(g4x_reset_complete(dev), 500);
        if (ret)
                return ret;
 
@@ -1399,7 +1386,7 @@ static int g4x_do_reset(struct drm_device *dev)
 
        pci_write_config_byte(dev->pdev, I965_GDRST,
                              GRDOM_MEDIA | GRDOM_RESET_ENABLE);
-       ret =  wait_for(i965_reset_complete(dev), 500);
+       ret =  wait_for(g4x_reset_complete(dev), 500);
        if (ret)
                return ret;