From patchwork Tue Dec 4 14:26:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathyush K X-Patchwork-Id: 1837911 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 3E07EDF230 for ; Tue, 4 Dec 2012 14:13:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 185C8E6393 for ; Tue, 4 Dec 2012 06:13:11 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) by gabe.freedesktop.org (Postfix) with ESMTP id DBEC9E602A for ; Tue, 4 Dec 2012 06:05:08 -0800 (PST) Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MEI00EZSF4D4UP0@mailout2.samsung.com> for dri-devel@lists.freedesktop.org; Tue, 04 Dec 2012 23:05:07 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.126]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id DF.B9.01231.2130EB05; Tue, 04 Dec 2012 23:05:07 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-72-50be0312dc07 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 6F.B9.01231.2130EB05; Tue, 04 Dec 2012 23:05:06 +0900 (KST) Received: from localhost.localdomain ([107.108.73.106]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MEI00F96F2AW000@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Tue, 04 Dec 2012 23:05:06 +0900 (KST) From: Prathyush K To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/3] drm/exynos: move wait_for_vblank to manager_ops Date: Tue, 04 Dec 2012 19:56:50 +0530 Message-id: <1354631211-30346-2-git-send-email-prathyush.k@samsung.com> X-Mailer: git-send-email 1.7.0.4 In-reply-to: <1354631211-30346-1-git-send-email-prathyush.k@samsung.com> References: <1354631211-30346-1-git-send-email-prathyush.k@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrLLMWRmVeSWpSXmKPExsWyRsSkTleYeV+AwduzTBZXvr5nc2D0uN99 nCmAMYrLJiU1J7MstUjfLoEr4/mu+6wFO4Mr1q2dy9LA+Nm1i5GTQ0LARGLOvkMsELaYxIV7 69m6GLk4hASWMkq8O3qMDaaobd03dojEdEaJi98WQ1WtZpLYP+U7WDubgLbErzl3WUFsEQFl ib8TVzGC2MwCEhJH2s+CTRIWcJHYfXYGmM0ioCpx4ekRJhCbV8Bd4kLLaUaIbQoSrcsOsYPY nAIeEtuuLgGbKQRU83PrVaheAYlvk0HO5gCql5XYdIAZ5B4JgctsEm+WfISaIylxcMUNlgmM wgsYGVYxiqYWJBcUJ6XnGuoVJ+YWl+al6yXn525iBIbh6X/PpHYwrmywOMQowMGoxMM74+Ge ACHWxLLiytxDjBIczEoivAof9gYI8aYkVlalFuXHF5XmpBYfYvQBumQis5Rocj4wRvJK4g2N TcxNjU0tjYzMTE1xCCuJ8zZ7pAQICaQnlqRmp6YWpBbBjGPi4JRqYLQ8VTmfrbB0hfTCM3b3 nN/ffHs0y+Hhv5+M/Fv41K1aDW3M1xW+Xj37vpao1fF6N909FoeP3TJv7D8alid0XuSpKlfX v+LY6XLiFnMzUxa+fKr23IhboCJi7oN/Qks3OWc6OO3L2PFQ8M7mwLns8+7YFdd1HHRz+3Nv cuG8Q4cteANsxZZz7FJiKc5INNRiLipOBACbTSwWcAIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphkeLIzCtJLcpLzFFi42I5/e+xoK4Q874Ag2tdZhZXvr5nc2D0uN99 nCmAMaqB0SYjNTEltUghNS85PyUzL91WyTs43jne1MzAUNfQ0sJcSSEvMTfVVsnFJ0DXLTMH aKySQlliTilQKCCxuFhJ3w7ThNAQN10LmMYIXd+QILgeIwM0kLCGMeP5rvusBTuDK9atncvS wPjZtYuRk0NCwESibd03dghbTOLCvfVsXYxcHEIC0xklLn5bDOWsZpLYP+U7C0gVm4C2xK85 d1lBbBEBZYm/E1cxgtjMAhISR9rPsoHYwgIuErvPzgCzWQRUJS48PcIEYvMKuEtcaDnNCLFN QaJ12SGwzZwCHhLbri4BmykEVPNz61W2CYy8CxgZVjGKphYkFxQnpeca6hUn5haX5qXrJefn bmIEB/kzqR2MKxssDjEKcDAq8fDOeLgnQIg1say4MvcQowQHs5IIr8KHvQFCvCmJlVWpRfnx RaU5qcWHGH2ArprILCWanA+MwLySeENjE3NTY1NLEwsTM0scwkrivM0eKQFCAumJJanZqakF qUUw45g4OKUaGGff/FhYv79UeYZuOI/TzSrDjqIw1nv2n85W/HLK+ZMY+mRbSyqX0m5ujirH XZYHRSLyVf2n7r750DMtf3mYSG6Oxcn6hJ/F0h+a9FqbOQ+buvQqTq6qVK+KPNbWMKHt7eqA wHc3rsXtqba2/e2zme++hEf5h+6JDu2yz/RPpGt0pgoe//lUiaU4I9FQi7moOBEAJVaJep8C AAA= X-CFilter-Loop: Reflected X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Currently wait_for_vblank is set as an overlay_op which is not correct since wait for vblank is not dependant on any particular overlay. It should be grouped with enable/disable vblank calls inside manager_ops. Also if wait for vblank is a manager op, the check for DPMS_OFF of encoder can be removed inside exynos_drm_encoder_complete_scanout. This fixes the following issue while removing a fb. While removing the current fb (crtc->fb == fb) the encoder dpms off is called and then the framebuffer is removed. So in this case, the wait for vblank is not called thus leading to a crash (since fb might get removed before dma is finished). Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 6 ++-- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 15 +++-------- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 34 +++++++++++++------------- drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 22 ++++++++-------- drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 2 +- drivers/gpu/drm/exynos/exynos_mixer.c | 34 +++++++++++++------------- 6 files changed, 53 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 6bb8644..98597d7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -60,8 +60,6 @@ enum exynos_drm_output_type { * @commit: apply hardware specific overlay data to registers. * @enable: enable hardware specific overlay. * @disable: disable hardware specific overlay. - * @wait_for_vblank: wait for vblank interrupt to make sure that - * hardware overlay is disabled. */ struct exynos_drm_overlay_ops { void (*mode_set)(struct device *subdrv_dev, @@ -69,7 +67,6 @@ struct exynos_drm_overlay_ops { void (*commit)(struct device *subdrv_dev, int zpos); void (*enable)(struct device *subdrv_dev, int zpos); void (*disable)(struct device *subdrv_dev, int zpos); - void (*wait_for_vblank)(struct device *subdrv_dev); }; /* @@ -172,6 +169,8 @@ struct exynos_drm_display_ops { * @commit: set current hw specific display mode to hw. * @enable_vblank: specific driver callback for enabling vblank interrupt. * @disable_vblank: specific driver callback for disabling vblank interrupt. + * @wait_for_vblank: wait for vblank interrupt to make sure that + * hardware overlay is updated. */ struct exynos_drm_manager_ops { void (*dpms)(struct device *subdrv_dev, int mode); @@ -186,6 +185,7 @@ struct exynos_drm_manager_ops { void (*commit)(struct device *subdrv_dev); int (*enable_vblank)(struct device *subdrv_dev); void (*disable_vblank)(struct device *subdrv_dev); + void (*wait_for_vblank)(struct device *subdrv_dev); }; /* diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index d9afb11..3014852 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -237,8 +237,7 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb) { struct exynos_drm_encoder *exynos_encoder; - struct exynos_drm_overlay_ops *overlay_ops; - struct exynos_drm_manager *manager; + struct exynos_drm_manager_ops *ops; struct drm_device *dev = fb->dev; struct drm_encoder *encoder; @@ -248,21 +247,15 @@ void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb) */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { exynos_encoder = to_exynos_encoder(encoder); - - /* if exynos was disabled, just ignor it. */ - if (exynos_encoder->dpms > DRM_MODE_DPMS_ON) - continue; - - manager = exynos_encoder->manager; - overlay_ops = manager->overlay_ops; + ops = exynos_encoder->manager->ops; /* * wait for vblank interrupt * - this makes sure that overlay data are updated to * real hardware. */ - if (overlay_ops->wait_for_vblank) - overlay_ops->wait_for_vblank(manager->dev); + if (ops->wait_for_vblank) + ops->wait_for_vblank(exynos_encoder->manager->dev); } } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 63f0d0f..020eb86 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -320,12 +320,29 @@ 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); + + 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"); +} + 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, }; static void fimd_win_mode_set(struct device *dev, @@ -605,27 +622,10 @@ static void fimd_win_disable(struct device *dev, int zpos) win_data->enabled = false; } -static void fimd_wait_for_vblank(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - 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"); -} - static struct exynos_drm_overlay_ops fimd_overlay_ops = { .mode_set = fimd_win_mode_set, .commit = fimd_win_commit, .disable = fimd_win_disable, - .wait_for_vblank = fimd_wait_for_vblank, }; static struct exynos_drm_manager fimd_manager = { diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8b771a3..55793c4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -179,6 +179,16 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); } +static void drm_hdmi_wait_for_vblank(struct device *subdrv_dev) +{ + struct drm_hdmi_context *ctx = to_context(subdrv_dev); + + DRM_DEBUG_KMS("%s\n", __FILE__); + + if (mixer_ops && mixer_ops->wait_for_vblank) + mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx); +} + static void drm_hdmi_mode_fixup(struct device *subdrv_dev, struct drm_connector *connector, const struct drm_display_mode *mode, @@ -260,6 +270,7 @@ static struct exynos_drm_manager_ops drm_hdmi_manager_ops = { .apply = drm_hdmi_apply, .enable_vblank = drm_hdmi_enable_vblank, .disable_vblank = drm_hdmi_disable_vblank, + .wait_for_vblank = drm_hdmi_wait_for_vblank, .mode_fixup = drm_hdmi_mode_fixup, .mode_set = drm_hdmi_mode_set, .get_max_resol = drm_hdmi_get_max_resol, @@ -313,21 +324,10 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos) ctx->enabled[win] = false; } -static void drm_mixer_wait_for_vblank(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->wait_for_vblank) - mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx); -} - static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { .mode_set = drm_mixer_mode_set, .commit = drm_mixer_commit, .disable = drm_mixer_disable, - .wait_for_vblank = drm_mixer_wait_for_vblank, }; static struct exynos_drm_manager hdmi_manager = { diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 54b5223..fcc3093 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -65,10 +65,10 @@ struct exynos_mixer_ops { int (*iommu_on)(void *ctx, bool enable); int (*enable_vblank)(void *ctx, int pipe); void (*disable_vblank)(void *ctx); + void (*wait_for_vblank)(void *ctx); void (*dpms)(void *ctx, int mode); /* overlay */ - void (*wait_for_vblank)(void *ctx); void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); void (*win_commit)(void *ctx, int zpos); void (*win_disable)(void *ctx, int zpos); diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 972281e..e2083a9 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -769,6 +769,22 @@ static void mixer_disable_vblank(void *ctx) mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); } +static void mixer_wait_for_vblank(void *ctx) +{ + struct mixer_context *mixer_ctx = ctx; + + atomic_set(&mixer_ctx->wait_vsync_event, 1); + + /* + * wait for MIXER to signal VSYNC interrupt or return after + * timeout which is set to 50ms (refresh rate of 20). + */ + if (!wait_event_timeout(mixer_ctx->wait_vsync_queue, + !atomic_read(&mixer_ctx->wait_vsync_event), + DRM_HZ/20)) + DRM_DEBUG_KMS("vblank wait timed out.\n"); +} + static void mixer_dpms(void *ctx, int mode) { struct mixer_context *mixer_ctx = ctx; @@ -790,22 +806,6 @@ static void mixer_dpms(void *ctx, int mode) } } -static void mixer_wait_for_vblank(void *ctx) -{ - struct mixer_context *mixer_ctx = ctx; - - atomic_set(&mixer_ctx->wait_vsync_event, 1); - - /* - * wait for MIXER to signal VSYNC interrupt or return after - * timeout which is set to 50ms (refresh rate of 20). - */ - if (!wait_event_timeout(mixer_ctx->wait_vsync_queue, - !atomic_read(&mixer_ctx->wait_vsync_event), - DRM_HZ/20)) - DRM_DEBUG_KMS("vblank wait timed out.\n"); -} - static void mixer_win_mode_set(void *ctx, struct exynos_drm_overlay *overlay) { @@ -896,10 +896,10 @@ static struct exynos_mixer_ops mixer_ops = { .iommu_on = mixer_iommu_on, .enable_vblank = mixer_enable_vblank, .disable_vblank = mixer_disable_vblank, + .wait_for_vblank = mixer_wait_for_vblank, .dpms = mixer_dpms, /* overlay */ - .wait_for_vblank = mixer_wait_for_vblank, .win_mode_set = mixer_win_mode_set, .win_commit = mixer_win_commit, .win_disable = mixer_win_disable,