From patchwork Mon Aug 20 12:35:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 1348281 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 86D3ADFF0F for ; Mon, 20 Aug 2012 12:43:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B99C69E8F5 for ; Mon, 20 Aug 2012 05:43:36 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by gabe.freedesktop.org (Postfix) with ESMTP id 044A99E830 for ; Mon, 20 Aug 2012 05:36:00 -0700 (PDT) Received: from epcpsbgm2.samsung.com (mailout3.samsung.com [203.254.224.33]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M92002DC0BW5AW0@mailout3.samsung.com> for dri-devel@lists.freedesktop.org; Mon, 20 Aug 2012 21:35:59 +0900 (KST) X-AuditID: cbfee61b-b7faf6d00000476a-2c-50322f2ff5fc Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id BB.91.18282.F2F22305; Mon, 20 Aug 2012 21:35:59 +0900 (KST) Received: from daeinki-desktop.10.32.193.11 ([10.90.51.53]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0M9200B9O0BWMOD0@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Mon, 20 Aug 2012 21:35:59 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH 10/10] drm/exynos: update crtc to plane safely Date: Mon, 20 Aug 2012 21:35:55 +0900 Message-id: <1345466155-9154-11-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1345466155-9154-1-git-send-email-inki.dae@samsung.com> References: <1345466155-9154-1-git-send-email-inki.dae@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMJMWRmVeSWpSXmKPExsVy+t9jQV19faMAg9092hZXvr5nc2D0uN99 nCmAMYrLJiU1J7MstUjfLoErY/nWG4wFc6UqPuyeztLA+Eeki5GTQ0LARGL2vz3sELaYxIV7 69m6GLk4hASmM0p8ObsXylnPJLHgwkZGkCo2AVWJiSvus4HYIgKmEh2TlrKA2MwChRILe56C 2cICdhIfnzQzg9gsQPUHPk4Gi/MKuEh8m3WWEWKbgsSCe2/B5nACxVffeccKYgsJOEv8vLCP fQIj7wJGhlWMoqkFyQXFSem5RnrFibnFpXnpesn5uZsYwV5/Jr2DcVWDxSFGAQ5GJR7ewqmG AUKsiWXFlbmHGCU4mJVEeP+IGAUI8aYkVlalFuXHF5XmpBYfYpTmYFES5+XvA6oWSE8sSc1O TS1ILYLJMnFwSjUw1mswNk75py2W7yV5blbRnSerfR2XyT+4ev7W/nfMr7W8oucdOXJw27YF t8qXfl66/4Nsa3mEYXu5RmjeCo5Or/xY3iNSqa8XLrsR1dM0XdmU5UK1xlS729WucR52j+6V LDOterQlTNdliXpWqulv7f+LthxluPPebHYbI+euvn3PVui8fpTYr8RSnJFoqMVcVJwIAOzs qKX2AQAA X-TM-AS-MML: No Cc: kyungmin.park@samsung.com 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 if old_crtc isn't same as encoder->crtc then it means that user changed crtc id to another one so a plane to old_crtc should be disabled so that current plane can be updated safely and plane->crtc should be set to new crtc(encoder->crtc) Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 59 +++++++++++++++++++++++++- 1 files changed, 56 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 98d5576..80a649b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -45,6 +45,7 @@ * @dpms: store the encoder dpms value. */ struct exynos_drm_encoder { + struct drm_crtc *old_crtc; struct drm_encoder drm_encoder; struct exynos_drm_manager *manager; int dpms; @@ -124,22 +125,74 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, return true; } +static void disable_plane_to_crtc(struct drm_device *dev, + struct drm_crtc *old_crtc, + struct drm_crtc *new_crtc) +{ + struct drm_plane *plane; + + /* + * if old_crtc isn't same as encoder->crtc then it means that + * user changed crtc id to another one so the plane to old_crtc + * should be disabled and plane->crtc should be set to new_crtc + * (encoder->crtc) + */ + list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + if (plane->crtc == old_crtc) { + /* + * do not change below call order. + * + * plane->funcs->disable_plane call checks + * if encoder->crtc is same as plane->crtc and if same + * then overlay_ops->disable callback will be called + * to diasble current hw overlay so plane->crtc should + * have new_crtc because new_crtc was set to + * encoder->crtc in advance. + */ + plane->crtc = new_crtc; + plane->funcs->disable_plane(plane); + } + } +} + static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct drm_device *dev = encoder->dev; struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; + struct exynos_drm_manager *manager; + struct exynos_drm_manager_ops *manager_ops; DRM_DEBUG_KMS("%s\n", __FILE__); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) + if (connector->encoder == encoder) { + struct exynos_drm_encoder *exynos_encoder; + + exynos_encoder = to_exynos_encoder(encoder); + + if (exynos_encoder->old_crtc != encoder->crtc && + exynos_encoder->old_crtc) { + + /* + * disable a plane to old crtc and change + * crtc of the plane to new one. + */ + disable_plane_to_crtc(dev, + exynos_encoder->old_crtc, + encoder->crtc); + } + + manager = exynos_drm_get_manager(encoder); + manager_ops = manager->ops; + if (manager_ops && manager_ops->mode_set) manager_ops->mode_set(manager->dev, adjusted_mode); + + exynos_encoder->old_crtc = encoder->crtc; + } } }