VIGS: Fix fence ack losses 40/16640/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Thu, 20 Feb 2014 07:51:51 +0000 (11:51 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Thu, 20 Feb 2014 07:51:51 +0000 (11:51 +0400)
It's incorrect to have vblank enable/disable flag
in INT register, it can cause fence ack losses, consider
the following scenario:
1. Fence interrupt is set on host, fence_pending bit is
   set in INT register
2. vblank is turned off on guest, INT register is being
   written to and since fence_pending bit is 1 it's
   CLEARED on host
3. Now guest handles fence IRQ, but fence_pending bit
   is 0, thus, fence ack is lost

The solution is to have separate register - CON and
vblank enable/disable bit should be there

Change-Id: Ieb3f1a0bd1722fa05fd4e7ca425079fb8799e533

drivers/gpu/drm/vigs/vigs_irq.c
drivers/gpu/drm/vigs/vigs_regs.h

index 6ac7fd388f8ae8de96dcebe1e5c6a308c53142eb..41c70b9a8c704f06b559ade056d54fc1f592408d 100644 (file)
@@ -55,13 +55,9 @@ int vigs_enable_vblank(struct drm_device *drm_dev, int crtc)
         return -EINVAL;
     }
 
-    value = readl(vigs_dev->io_map->handle + VIGS_REG_INT);
+    value = VIGS_REG_CON_VBLANK_ENABLE;
 
-    BUG_ON(value & VIGS_REG_INT_VBLANK_PENDING);
-
-    value |= VIGS_REG_INT_VBLANK_ENABLE;
-
-    writel(value, vigs_dev->io_map->handle + VIGS_REG_INT);
+    writel(value, vigs_dev->io_map->handle + VIGS_REG_CON);
 
     return 0;
 }
@@ -77,11 +73,9 @@ void vigs_disable_vblank(struct drm_device *drm_dev, int crtc)
         DRM_ERROR("bad crtc = %d", crtc);
     }
 
-    value = readl(vigs_dev->io_map->handle + VIGS_REG_INT);
-
-    value &= ~VIGS_REG_INT_VBLANK_ENABLE;
+    value = 0;
 
-    writel(value, vigs_dev->io_map->handle + VIGS_REG_INT);
+    writel(value, vigs_dev->io_map->handle + VIGS_REG_CON);
 }
 
 irqreturn_t vigs_irq_handler(DRM_IRQ_ARGS)
index 0272f2bc21bec1ca6f4eca0d830fde6fe456b631..003479c041233540f3b4441c75d13f4dfc4d7ba3 100644 (file)
@@ -2,12 +2,14 @@
 #define _VIGS_REGS_H_
 
 #define VIGS_REG_EXEC 0
-#define VIGS_REG_INT 8
-#define VIGS_REG_FENCE_LOWER 16
-#define VIGS_REG_FENCE_UPPER 24
+#define VIGS_REG_CON 8
+#define VIGS_REG_INT 16
+#define VIGS_REG_FENCE_LOWER 24
+#define VIGS_REG_FENCE_UPPER 32
 
-#define VIGS_REG_INT_VBLANK_ENABLE 1
-#define VIGS_REG_INT_VBLANK_PENDING 2
-#define VIGS_REG_INT_FENCE_ACK_PENDING 4
+#define VIGS_REG_CON_VBLANK_ENABLE 1
+
+#define VIGS_REG_INT_VBLANK_PENDING 1
+#define VIGS_REG_INT_FENCE_ACK_PENDING 2
 
 #endif