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