aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorPrathyush K <prathyush.k@samsung.com>2012-12-06 09:46:04 -0500
committerInki Dae <daeinki@gmail.com>2012-12-13 09:05:44 -0500
commit01ce113ca5b18aea4c97dea62287394ca4f8ad7f (patch)
tree7dc50722fc164bd06c223244cf69e74877d00a38 /drivers/gpu
parent6e95d5e6f572d6bf1e1b0ff4c94ded8e4841d630 (diff)
drm/exynos: modify wait_for_vblank of fimd
It is more optimium to use wait queues while waiting for vsync so that the current task is put to sleep. This way, the task wont hog the CPU while waiting. We use wait_event_timeout and not an interruptible function since we dont want the function to exit when a signal is pending (e.g. drm release). This patch modifies the wait for vblank function of fimd. Signed-off-by: Prathyush K <prathyush.k@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 1d46286adb3..1517d15d5fa 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -100,6 +100,8 @@ struct fimd_context {
100 u32 vidcon1; 100 u32 vidcon1;
101 bool suspended; 101 bool suspended;
102 struct mutex lock; 102 struct mutex lock;
103 wait_queue_head_t wait_vsync_queue;
104 atomic_t wait_vsync_event;
103 105
104 struct exynos_drm_panel_info *panel; 106 struct exynos_drm_panel_info *panel;
105}; 107};
@@ -311,11 +313,19 @@ static void fimd_disable_vblank(struct device *dev)
311static void fimd_wait_for_vblank(struct device *dev) 313static void fimd_wait_for_vblank(struct device *dev)
312{ 314{
313 struct fimd_context *ctx = get_fimd_context(dev); 315 struct fimd_context *ctx = get_fimd_context(dev);
314 int ret;
315 316
316 ret = wait_for((__raw_readl(ctx->regs + VIDCON1) & 317 if (ctx->suspended)
317 VIDCON1_VSTATUS_VSYNC), 50); 318 return;
318 if (ret < 0) 319
320 atomic_set(&ctx->wait_vsync_event, 1);
321
322 /*
323 * wait for FIMD to signal VSYNC interrupt or return after
324 * timeout which is set to 50ms (refresh rate of 20).
325 */
326 if (!wait_event_timeout(ctx->wait_vsync_queue,
327 !atomic_read(&ctx->wait_vsync_event),
328 DRM_HZ/20))
319 DRM_DEBUG_KMS("vblank wait timed out.\n"); 329 DRM_DEBUG_KMS("vblank wait timed out.\n");
320} 330}
321 331
@@ -667,6 +677,11 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
667 drm_handle_vblank(drm_dev, manager->pipe); 677 drm_handle_vblank(drm_dev, manager->pipe);
668 fimd_finish_pageflip(drm_dev, manager->pipe); 678 fimd_finish_pageflip(drm_dev, manager->pipe);
669 679
680 /* set wait vsync event to zero and wake up queue. */
681 if (atomic_read(&ctx->wait_vsync_event)) {
682 atomic_set(&ctx->wait_vsync_event, 0);
683 DRM_WAKEUP(&ctx->wait_vsync_queue);
684 }
670out: 685out:
671 return IRQ_HANDLED; 686 return IRQ_HANDLED;
672} 687}
@@ -885,6 +900,8 @@ static int __devinit fimd_probe(struct platform_device *pdev)
885 ctx->vidcon1 = pdata->vidcon1; 900 ctx->vidcon1 = pdata->vidcon1;
886 ctx->default_win = pdata->default_win; 901 ctx->default_win = pdata->default_win;
887 ctx->panel = panel; 902 ctx->panel = panel;
903 DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue);
904 atomic_set(&ctx->wait_vsync_event, 0);
888 905
889 subdrv = &ctx->subdrv; 906 subdrv = &ctx->subdrv;
890 907