From patchwork Fri Aug 17 09:50:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 1338331 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 693CC3FC71 for ; Fri, 17 Aug 2012 09:59:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 54051A0E02 for ; Fri, 17 Aug 2012 02:59:52 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) by gabe.freedesktop.org (Postfix) with ESMTP id 0DCB3A0E24 for ; Fri, 17 Aug 2012 02:51:07 -0700 (PDT) Received: from epcpsbgm1.samsung.com (mailout4.samsung.com [203.254.224.34]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M8W00CDO8OS0300@mailout4.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 17 Aug 2012 18:51:03 +0900 (KST) X-AuditID: cbfee61a-b7fc66d0000043b7-98-502e14078e9e Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id FE.04.17335.7041E205; Fri, 17 Aug 2012 18:51:03 +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 <0M8W005HH8OZZTB0@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Fri, 17 Aug 2012 18:51:03 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH 10/13] drm/exynos: update crtc to plane safely Date: Fri, 17 Aug 2012 18:50:56 +0900 Message-id: <1345197059-25583-11-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1345197059-25583-1-git-send-email-inki.dae@samsung.com> References: <1345197059-25583-1-git-send-email-inki.dae@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrAJMWRmVeSWpSXmKPExsVy+t9jQV12Eb0Ag2v9hhZXvr5nc2D0uN99 nCmAMYrLJiU1J7MstUjfLoErY8K0BywFc6Uqfh58xtLA+Eeki5GDQ0LAROJJc1YXIyeQKSZx 4d56NhBbSGA6o8SeKZZdjFxA9nomiUl/lrOCJNgEVCUmrrgPViQiYCrRMWkpC4jNLFAosbDn KZgtLGAnMX1HJyPIfBag+ulzBUHCvAKuEp9PLGeC2KUgseDeW7AxnEDxu8snM0HsdZFo3NzD OoGRdwEjwypG0dSC5ILipPRcQ73ixNzi0rx0veT83E2MYH8/k9rBuLLB4hCjAAejEg+vQJFu gBBrYllxZe4hRgkOZiUR3hUfgUK8KYmVValF+fFFpTmpxYcYpTlYlMR5vf4DpQTSE0tSs1NT C1KLYLJMHJxSDYwFv39bli740KDvXOU5NXm5ttIHbf37WSxq3uJHqqdd+xv1I3+nz9aVu/za gjjYG3fKO57yzn3zoDd2tUPXIp7L17f2aPQtriueHz37vbXD/9dXs2IOnPmXlNCrubnqRXhi k1eI1r0Kve/XzrtMErjwa2sW34nl/LJJE1LXLe9/L+CjmM75p1uJpTgj0VCLuag4EQC/s+GC 8wEAAA== 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 a562a94..7bcace8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -44,6 +44,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; @@ -106,22 +107,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; + } } }