[PATCH 8/8] drm/exynos: fimd: add complete_scanout function

Prathyush K prathyush.k at samsung.com
Wed Dec 26 03:27:45 PST 2012


The wait_for_vblank interface is modified to the complete_scanout
function in fimd. This patch adds the fimd_complete_scanout function

Inside fimd_complete_scanout, we read the shadow register for each
window and compare it with the dma address of the framebuffer. If
the dma_address is in the shadow register, then the function waits
for the next vblank and returns.

Signed-off-by: Prathyush K <prathyush.k at samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 32 +++++++++++++++++++++++++++++++-
 include/video/samsung_fimd.h             |  1 +
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 3aeedf5..190ffde9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -46,6 +46,7 @@
 #define VIDOSD_D(win)		(VIDOSD_BASE + 0x0C + (win) * 16)
 
 #define VIDWx_BUF_START(win, buf)	(VIDW_BUF_START(buf) + (win) * 8)
+#define VIDWx_BUF_START_S(win, buf)	(VIDW_BUF_START_S(buf) + (win) * 8)
 #define VIDWx_BUF_END(win, buf)		(VIDW_BUF_END(buf) + (win) * 8)
 #define VIDWx_BUF_SIZE(win, buf)	(VIDW_BUF_SIZE(buf) + (win) * 4)
 
@@ -363,13 +364,42 @@ static void fimd_wait_for_vblank(struct device *dev)
 		fimd_disable_vblank(dev);
 }
 
+static void fimd_complete_scanout(struct device *dev, dma_addr_t dma_addr,
+					unsigned long size)
+{
+	struct fimd_context *ctx = get_fimd_context(dev);
+	int win;
+	bool in_use = false;
+
+	if (ctx->suspended)
+		return;
+
+	for (win = 0; win < WINDOWS_NR; win++) {
+		dma_addr_t dma_addr_in_use;
+
+		if (!ctx->win_data[win].enabled)
+			continue;
+
+		dma_addr_in_use = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
+		if (dma_addr_in_use >= dma_addr &&
+			dma_addr_in_use < (dma_addr + size)) {
+				in_use = true;
+				break;
+		}
+	}
+
+	if (in_use)
+		fimd_wait_for_vblank(dev);
+	return;
+}
+
 static struct exynos_drm_manager_ops fimd_manager_ops = {
 	.dpms = fimd_dpms,
 	.apply = fimd_apply,
 	.commit = fimd_commit,
 	.enable_vblank = fimd_enable_vblank,
 	.disable_vblank = fimd_disable_vblank,
-	.wait_for_vblank = fimd_wait_for_vblank,
+	.complete_scanout = fimd_complete_scanout,
 };
 
 static void fimd_win_mode_set(struct device *dev,
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index 7ae6c07..382eaec 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -274,6 +274,7 @@
 
 /* Video buffer addresses */
 #define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START_S(_buff)			(0x40A0 + ((_buff) * 8))
 #define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
 #define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
 #define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
-- 
1.8.0



More information about the dri-devel mailing list