From c19795cb76b961842fb16f5de11c32c9be56eb63 Mon Sep 17 00:00:00 2001 From: Prathyush K Date: Thu, 6 Dec 2012 20:16:04 +0530 Subject: [PATCH] --- yaml --- r: 345611 b: refs/heads/master c: 01ce113ca5b18aea4c97dea62287394ca4f8ad7f h: refs/heads/master i: 345609: 8da45d9f5fe6276e0ba7e2d5cfacdce6a5cfcd6f 345607: 361b53bce22efff7324079b57367d15b0d1a882e v: v3 --- [refs] | 2 +- .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ad23a06dbcb7..3febf8f819da 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6e95d5e6f572d6bf1e1b0ff4c94ded8e4841d630 +refs/heads/master: 01ce113ca5b18aea4c97dea62287394ca4f8ad7f diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 1d46286adb30..1517d15d5fa6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -100,6 +100,8 @@ struct fimd_context { u32 vidcon1; bool suspended; struct mutex lock; + wait_queue_head_t wait_vsync_queue; + atomic_t wait_vsync_event; struct exynos_drm_panel_info *panel; }; @@ -311,11 +313,19 @@ static void fimd_disable_vblank(struct device *dev) static void fimd_wait_for_vblank(struct device *dev) { struct fimd_context *ctx = get_fimd_context(dev); - int ret; - ret = wait_for((__raw_readl(ctx->regs + VIDCON1) & - VIDCON1_VSTATUS_VSYNC), 50); - if (ret < 0) + if (ctx->suspended) + return; + + atomic_set(&ctx->wait_vsync_event, 1); + + /* + * wait for FIMD to signal VSYNC interrupt or return after + * timeout which is set to 50ms (refresh rate of 20). + */ + if (!wait_event_timeout(ctx->wait_vsync_queue, + !atomic_read(&ctx->wait_vsync_event), + DRM_HZ/20)) DRM_DEBUG_KMS("vblank wait timed out.\n"); } @@ -667,6 +677,11 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) drm_handle_vblank(drm_dev, manager->pipe); fimd_finish_pageflip(drm_dev, manager->pipe); + /* set wait vsync event to zero and wake up queue. */ + if (atomic_read(&ctx->wait_vsync_event)) { + atomic_set(&ctx->wait_vsync_event, 0); + DRM_WAKEUP(&ctx->wait_vsync_queue); + } out: return IRQ_HANDLED; } @@ -885,6 +900,8 @@ static int __devinit fimd_probe(struct platform_device *pdev) ctx->vidcon1 = pdata->vidcon1; ctx->default_win = pdata->default_win; ctx->panel = panel; + DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue); + atomic_set(&ctx->wait_vsync_event, 0); subdrv = &ctx->subdrv;