aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPrathyush K <prathyush.k@samsung.com>2012-12-06 09:46:03 -0500
committerInki Dae <daeinki@gmail.com>2012-12-13 09:05:44 -0500
commit6e95d5e6f572d6bf1e1b0ff4c94ded8e4841d630 (patch)
tree5c475c0c6b422e24a3716f42f1fb3c4ea38f84ee /drivers
parent0703397039de7e87f780ebbf6283df7d89997075 (diff)
drm/exynos: modify wait_for_vblank of mixer
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 mixer. Signed-off-by: Prathyush K <prathyush.k@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index b6f12fb54225..b20c063d0b08 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -93,6 +93,8 @@ struct mixer_context {
93 struct hdmi_win_data win_data[MIXER_WIN_NR]; 93 struct hdmi_win_data win_data[MIXER_WIN_NR];
94 enum mixer_version_id mxr_ver; 94 enum mixer_version_id mxr_ver;
95 void *parent_ctx; 95 void *parent_ctx;
96 wait_queue_head_t wait_vsync_queue;
97 atomic_t wait_vsync_event;
96}; 98};
97 99
98struct mixer_drv_data { 100struct mixer_drv_data {
@@ -876,12 +878,23 @@ static void mixer_win_disable(void *ctx, int win)
876static void mixer_wait_for_vblank(void *ctx) 878static void mixer_wait_for_vblank(void *ctx)
877{ 879{
878 struct mixer_context *mixer_ctx = ctx; 880 struct mixer_context *mixer_ctx = ctx;
879 struct mixer_resources *res = &mixer_ctx->mixer_res;
880 int ret;
881 881
882 ret = wait_for((mixer_reg_read(res, MXR_INT_STATUS) & 882 mutex_lock(&mixer_ctx->mixer_mutex);
883 MXR_INT_STATUS_VSYNC), 50); 883 if (!mixer_ctx->powered) {
884 if (ret < 0) 884 mutex_unlock(&mixer_ctx->mixer_mutex);
885 return;
886 }
887 mutex_unlock(&mixer_ctx->mixer_mutex);
888
889 atomic_set(&mixer_ctx->wait_vsync_event, 1);
890
891 /*
892 * wait for MIXER to signal VSYNC interrupt or return after
893 * timeout which is set to 50ms (refresh rate of 20).
894 */
895 if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
896 !atomic_read(&mixer_ctx->wait_vsync_event),
897 DRM_HZ/20))
885 DRM_DEBUG_KMS("vblank wait timed out.\n"); 898 DRM_DEBUG_KMS("vblank wait timed out.\n");
886} 899}
887 900
@@ -957,6 +970,12 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
957 970
958 drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe); 971 drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
959 mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe); 972 mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe);
973
974 /* set wait vsync event to zero and wake up queue. */
975 if (atomic_read(&ctx->wait_vsync_event)) {
976 atomic_set(&ctx->wait_vsync_event, 0);
977 DRM_WAKEUP(&ctx->wait_vsync_queue);
978 }
960 } 979 }
961 980
962out: 981out:
@@ -1139,6 +1158,8 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1139 drm_hdmi_ctx->ctx = (void *)ctx; 1158 drm_hdmi_ctx->ctx = (void *)ctx;
1140 ctx->vp_enabled = drv->is_vp_enabled; 1159 ctx->vp_enabled = drv->is_vp_enabled;
1141 ctx->mxr_ver = drv->version; 1160 ctx->mxr_ver = drv->version;
1161 DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue);
1162 atomic_set(&ctx->wait_vsync_event, 0);
1142 1163
1143 platform_set_drvdata(pdev, drm_hdmi_ctx); 1164 platform_set_drvdata(pdev, drm_hdmi_ctx);
1144 1165