drm/exynos: add wait_for_vblank callback interface.
authorInki Dae <inki.dae@samsung.com>
Mon, 20 Aug 2012 10:55:14 +0000 (19:55 +0900)
committerInki Dae <inki.dae@samsung.com>
Thu, 4 Oct 2012 01:05:59 +0000 (10:05 +0900)
Changelog v2:
fixed comments.

Changelog v1:
this interface can be used to make sure that hardware overlay is disabled
to avoid that memory region is accessed by dma after gem buffer was released.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_encoder.c

index 24c45d86bab01423c7a2281276e179764a8ea2a1..eec77aa6962f591e914ee9efd5afa23031ea869d 100644 (file)
 #define MAX_FB_BUFFER  4
 #define DEFAULT_ZPOS   -1
 
+#define _wait_for(COND, MS) ({ \
+       unsigned long timeout__ = jiffies + msecs_to_jiffies(MS);       \
+       int ret__ = 0;                                                  \
+       while (!(COND)) {                                               \
+               if (time_after(jiffies, timeout__)) {                   \
+                       ret__ = -ETIMEDOUT;                             \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+       ret__;                                                          \
+})
+
+#define wait_for(COND, MS) _wait_for(COND, MS)
+
 struct drm_device;
 struct exynos_drm_overlay;
 struct drm_connector;
@@ -61,6 +75,8 @@ enum exynos_drm_output_type {
  * @commit: apply hardware specific overlay data to registers.
  * @enable: enable hardware specific overlay.
  * @disable: disable hardware specific overlay.
+ * @wait_for_vblank: wait for vblank interrupt to make sure that
+ *     hardware overlay is disabled.
  */
 struct exynos_drm_overlay_ops {
        void (*mode_set)(struct device *subdrv_dev,
@@ -68,6 +84,7 @@ struct exynos_drm_overlay_ops {
        void (*commit)(struct device *subdrv_dev, int zpos);
        void (*enable)(struct device *subdrv_dev, int zpos);
        void (*disable)(struct device *subdrv_dev, int zpos);
+       void (*wait_for_vblank)(struct device *subdrv_dev);
 };
 
 /*
index 08ba62fe2f16ba39c32a70d01a8d35ea9e99fc52..f4531167fda686be058984c5c09dce70ae856315 100644 (file)
@@ -430,4 +430,14 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
 
        if (overlay_ops && overlay_ops->disable)
                overlay_ops->disable(manager->dev, zpos);
+
+       /*
+        * wait for vblank interrupt
+        * - this makes sure that hardware overlay is disabled to avoid
+        * for the dma accesses to memory after gem buffer was released
+        * because the setting for disabling the overlay will be updated
+        * at vsync.
+        */
+       if (overlay_ops->wait_for_vblank)
+               overlay_ops->wait_for_vblank(manager->dev);
 }