From patchwork Mon Jul 4 07:40:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ying Liu X-Patchwork-Id: 9211865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2F82560571 for ; Mon, 4 Jul 2016 08:16:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E2DD28586 for ; Mon, 4 Jul 2016 08:16:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12C6A28595; Mon, 4 Jul 2016 08:16:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA3BA28586 for ; Mon, 4 Jul 2016 08:16:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 054AE6E3C9; Mon, 4 Jul 2016 08:16:03 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: delayed 1163 seconds by postgrey-1.35 at gabe; Mon, 04 Jul 2016 08:16:01 UTC Received: from NAM01-SN1-obe.outbound.protection.outlook.com (mail-sn1nam01on0081.outbound.protection.outlook.com [104.47.32.81]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9818F6E3C9 for ; Mon, 4 Jul 2016 08:16:01 +0000 (UTC) Received: from BN3PR0301CA0027.namprd03.prod.outlook.com (10.160.180.165) by BLUPR03MB583.namprd03.prod.outlook.com (10.141.79.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.528.16; Mon, 4 Jul 2016 07:41:11 +0000 Received: from BL2FFO11FD051.protection.gbl (2a01:111:f400:7c09::149) by BN3PR0301CA0027.outlook.office365.com (2a01:111:e400:4000::37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.528.16 via Frontend Transport; Mon, 4 Jul 2016 07:41:11 +0000 Authentication-Results: spf=softfail (sender IP is 192.88.158.2) smtp.mailfrom=gmail.com; ffwll.ch; dkim=none (message not signed) header.d=none; ffwll.ch; dmarc=fail action=none header.from=gmail.com; Received-SPF: SoftFail (protection.outlook.com: domain of transitioning gmail.com discourages use of 192.88.158.2 as permitted sender) Received: from az84smr01.freescale.net (192.88.158.2) by BL2FFO11FD051.mail.protection.outlook.com (10.173.161.213) with Microsoft SMTP Server (TLS) id 15.1.523.9 via Frontend Transport; Mon, 4 Jul 2016 07:41:10 +0000 Received: from victor.ap.freescale.net (victor.ap.freescale.net [10.192.241.62]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id u647ep0W026135; Mon, 4 Jul 2016 00:41:08 -0700 From: Liu Ying To: Subject: [PATCH v3 07/10] drm/imx: atomic phase 3 step 1: Use atomic configuration Date: Mon, 4 Jul 2016 15:40:36 +0800 Message-ID: <1467618039-7457-8-git-send-email-gnuiyl@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1467618039-7457-1-git-send-email-gnuiyl@gmail.com> References: <1467618039-7457-1-git-send-email-gnuiyl@gmail.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131120916707449802; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.158.2; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(189002)(199003)(19580395003)(19580405001)(189998001)(69596002)(50986999)(76176999)(6260500002)(55446002)(36756003)(92566002)(4326007)(87572001)(68736007)(2906002)(586003)(82202001)(77096005)(5003940100001)(5890100001)(2950100001)(73972006)(83322999)(50226002)(81442002)(73392002)(50466002)(97736004)(105596002)(305945005)(33646002)(47776003)(86362001)(110136002)(48376002)(6806005)(104016004)(11100500001)(8936002)(106466001)(81166006)(229853001)(2351001)(7846002)(61266001)(8676002)(356003)(81156014)(87936001)(76482005); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR03MB583; H:az84smr01.freescale.net; FPR:; SPF:SoftFail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD051; 1:AUhYGnydRzWkVfVrW77FkZwzL9TQloW4ePAXZNB5rIU3jCIj2aQex+1+pDm5W7htYhqGfJix/XM1mr6jrO2v9UZy5PzwUm98TAFlscoYZ/G2kSKNDjVqc5eP1b7pVjL38L7ioAR6X05wuwFEkSNyRy1dKlcWswgDNR6aWANo1j2LGxmlMbXZUANotB/RsQAoE/mGzEDi/XF3snBzC7haTllTj077+RhT/EztT2Ft7x9oLbsvARAgisTRJ9XpagN8hPVGLH/4a44+EX5XoXoc0Lz46jpWEUm3aqJoQ2vv67K+3vadFvbcxu3OX0yn6SVw0gKavT7TR+eNgqbd18JTadE7xnoRdjVYu3SETf4BeggXBdW8gHaGhNmuIc/djRAEXY2LRk0CnEijG7SwVSCeiy4r0eGZnqc/5kSJPkDw2SLAWCrSlPlo0+vByxrPXbobkIc5lPOyxV0Tb/RTsyNFPLFyvat8J8Y3wc9E50Fh3tK4+w7BAM4x/Z38Pp7QiUXbAV8lbn9Nyhr5h3Yta1rDn/EckP92D+fNWN/srpdADuGemgNW94y0wmGjnjCIZVMHyGCNIuKF61TVBTTZTmCU1g== MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 4e843753-dd73-4819-90da-08d3a3de915c X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB583; 2:mwZNdDgZcPdKl7kjgnHDMmDmXfkui1lvYIpoAam/hrbT9LrZAIzzzyriOix5d/5Fay46xiNIxA2QdpcTq5fzfkOrlAUUkqzT6jJEj6lXYzzgrBnAUGVXwc35jCAUXK72ZhVNQP+O0fujLoHC5wS8lYNiRPKYa9PmRyYLIVuqoY3Zbqq4FkpLVsEHwzR9TZDQ; 3:ifdYAuMZYJA94bkXlJJrI7x8TbH6Ifqd9Gd/fVwwalLBRxc48tPCdtDm+064fJx90trhtvi/2dC1uHXTgCx+iACJYSBXEOVibRlGyt5WjnAdE457HN5w7UuucBlStHcUhGd72db7Yt0ANUcYPEjm3ZK/13iRy7cMx0pnatECWwPpOZfhB7iO59SE/0T07cN5eeNwrMbvMLUPleKjf2jFZn22nvZXWcygdi0FHIg8FHI= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB583; X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB583; 25:vZlsoW501wNVtR+OJH5+/PLflZSjMFGuDKZA1VhmFOxtS8w60qQvuj68PZQ2J2dKNclx9zALyh+NS9/5z2PewKV9mAlMMNgHoGj5KSmG9zI9JE0olh+wFex03HRue0TGLoiERZszEh+yRPacuzFjFZhSxr/DfBG79Yg0aqoi9MNUgq/Y7Pm4zsa7D+vfOR3y4B6/WYSAPQBgZ5kw4/GjQo/3vp7E14X1I1x454TX2i41aLND/1w1mV9Gj4FM4BDU9aWfnHK972F4KCCtbQ9HyeFm1zh7fDroR7Xq516E2z+NUqlyK4r4ESFqfzCiNDZbE1u8DCu4FMWl8Ejs8JxXjPARkMPBi905aO6ct1ZVPKMjN2TR0OeGXgwANxflm9wBc1axYzQnzXO9seUJ7mUMKt+qqLQfJiYCiytyaMmzEMAXLXUu4HCp55ZIHe8E5gAffGqXr0tdyrxjBLoPeivKEoPGkXn3/Tid3vbmexNJ4ReWmr7jbS5h7ZImREykALGIe3DZnlz+nH7L0Ahm2SDlfLvLMrncbKggaZa0Eiw/fEf3U9YmDIm5aYFzScicay+1n0G92V6XGlmHdWYU9jKhos+ovNsjktOozIlYsqMQm6JVws2xSnuLk9/xTARNdoe3c6+s7PMdVXbNMYdgmsdgOY0k+92YxHrgg/kpoAPtExRUzOpZqGPI5OqxchDUgDKD5vxQdjv6h848stbYRzlogD+F1plVizvvqrVOMo8WBaAe4rpiJ4v6YCYFdaw8VvNz X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB583; 31:xGSoc5MXtAXrM+VqGUE51w2leHMtpX4AZ3kla18i+jx7o4u15xAD4SZfLUfex6seQY/Mwryx6iX5/6OV8b8kKzDWg5acIQY+T+lYgPfOA5EosebvNUcYqikchX6xaAiuSYf5qb0uIf8W7qjKJBJbYUYdTVpKXL63D8EK4vdzJv+pINk0QBzzva2yQN2bN9Twq1X4eOFbtGbLTUqXKp9fCA==; 4:vZC8CHcQz267/R5lCCWq2eerNzd7g/wg+2psq+3JvLziyEVsw+VUQx2uaxAAf1lKlJg5TOFzIda2c4z0OKBtxqqRieJb2JpMk9gKoy7FXe7zfc9fb3EdYWm3WKAshm5ktw3XZa0rD1Yjya8huIACLZSe9ExSVSOIDupkLTtUcPDYJyfbERYfC5vPCGs/M23X+9iFb2xt0rA+qiIrSfMD49cWCavqxQdhRnfy3SxaVGSbiLaioLbx0E8jZeXI1Q+nP7nE3ug3OmaLDYwuszm7Z8fuYFmvRbN3P03uGBcZZhqy12SGw7g76TMBjArTktKN2wvVKRk+32Tfqk+NCUF7TlJHyjgwPMedhLDDMivvEERIWoapvdewMauVuJDIe+oqHI18UNUO3LC+WFVHy1EgDRhCsVdZfmdioDeBZWtbXpEVJwMVQze6BXpyHXVj6Fau/Y+lqSoBplMeiC1A3sUUANEpQnwjSufIHUNefTSwYbk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13015025)(13018025)(5005006)(8121501046)(13024025)(13023025)(13017025)(3002001)(10201501046)(6055026); SRVR:BLUPR03MB583; BCL:0; PCL:0; RULEID:(400006); SRVR:BLUPR03MB583; X-Forefront-PRVS: 0993689CD1 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR03MB583; 23:+qmT1JQjWHWFeBYpb+hPm4nWqh9j/OCLx3xt4aauO8?= =?us-ascii?Q?71+ledu2uTs5BVJYruZf2IaXETgMWWK6p8hA5Pp42+wProYt47/Sdhk2VVHN?= =?us-ascii?Q?LdpW7Ke5zOy4piSPih7cxcbTIlqzgUi81jj1iapfOnYcsObfoIBaidD10Y6g?= =?us-ascii?Q?0/X96oprcLFbvqjfLV2/SOxRuvYS+QoaZWTPxN6hYfjqL0dpu12ujV2yV8p1?= =?us-ascii?Q?9cmDCXMbj14fsQo7B04IXfIoSxkHMrP8Pi+s7V+DaDo1bla5I7YCO0k9jm8S?= =?us-ascii?Q?h46zw7HK0TTvPNb3Mfx3IUOIUx0az5t2PE1dH2XSPkvsWMLbVpHVtYX97f2d?= =?us-ascii?Q?FoQwGyixoM3lShUtFMB3+HXU2Phg7kUpzJ3To9lMnQN7PydTMLFvmwo/KTHp?= =?us-ascii?Q?O8SdxeTUEf8ZSojYRThCbF4Ek1JQHaaNu4p790UcILNWzuiyGz7b3/yCaeBD?= =?us-ascii?Q?Kxt7oie6PzrLjtyD1r3mIJlqiis3nt+/LCPSO5OM4HHiDgCD+WGryUNhwxVk?= =?us-ascii?Q?CweJnl99sJsNdykx8aPYzk7jXFP8V/NcWv4q8tBoikr5NdiH/deiGjJr5gsw?= =?us-ascii?Q?5LFGhFJLAuRlGVAL8zWAa3OMWXKPic+9iBqCOsXZZYk42nFgq8k+j95Fmymx?= =?us-ascii?Q?nZ6w6B6jxJTBEEtD3jflnr7FAYoe4+SIVhTWLJFBwJ27glubiygIat+jtTLq?= =?us-ascii?Q?UM7KISzXLs62QLJ4ErpaAYlFlRIpeVSj8HYOR36xyZlXFhjdnRhqVvgCDaTY?= =?us-ascii?Q?JtZ0AR0GUTwgAcbv/53b5TLE01PJFvkUEX16GeLoe6paafS9RAM3aX/iv3xA?= =?us-ascii?Q?y+PTH8WybH/D7ZeUgYGPcEHPolLsi7WVX5upZFMQwhpMheEwzA8qoPH/WIeo?= =?us-ascii?Q?qcz69OR8lyb9HuRGQ5BezQ+KSum4AM96HIkTnN6SS1tw6TZaMSlmlkOkt6eY?= =?us-ascii?Q?JL9JzJb9nHa/CWPaUCvM3yNbjop5G1lFGiOQxpClkeZ2+ICkcz9zaR4i8bL1?= =?us-ascii?Q?i+uhj39LVFwYgAYZXQegIRTnsQLmTZwxsjbVTtRwEKRUHAGkm3uVjG9rTsCZ?= =?us-ascii?Q?LWOm5wlgO0ejpuMh7J3ig9/TEJzJ/nUN4humn1DcdmqUca78NN6ZQnL1iI7m?= =?us-ascii?Q?rpq13qk6mgGQDsQqSIxssjmo3ZA9gkKUVho1kM3ZBD6uwiyXULuEr2T4i2Xd?= =?us-ascii?Q?GMYzLQQq9xcjTZlX78zzrW7ZILS7RoeHrS4jqwziCR0Qi7/7CcZQSIfaKH5Z?= =?us-ascii?Q?lvLUJPQvwAXxPiG5JTHmCAvuBlaSW8lPYfp4TM2+hiheGPrxddz/Z2jG9OVw?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB583; 6:wNQ/nGzCEemXX9o+v1HFz4s922yVa47i64J3efyoWKsoyg/p1GRaDDZKA7QUsVaUurkBFTxvfwMFie7G6tAV+pkZf1F4Kx8rPN8aZYpL3wP0BXow13jDiK2aKOF6Q6LEc07HS6n/PDpr/QoB2qW1z+qR6Ann1WtO3YWHETVZ/5R9+eY0uX5vVLL7Dfyj2tIMWrgjqrRfwWG/pAOezHUwgkd0h/RdPuyD+Wgc6SUSeTXHLwgF4bNVGvG7NxO4iaI1qOWf7PJJw/H6EqR2xt78idvjCAsExC7EuyFfFJYXLnI=; 5:SOAZtcBXrWxuN6SIZ1MxGyxGJxBXwTqVDQTYx52wUiCmjpOk2KXJbPO1McVEftk+S+o6xyBaPQNU3IKXu4qrvalHHyTIZMtoxR9RpIJNTyt0ggLAFBEd1LmOCjcO8ei6v1L01RxvD5PvKfd1J2KzdHM/1avamLhEFbeQZEu8LKk=; 24:09yhysX+rioJxd16UZp+qsEV9WHaqV05YNhZH2yzqMSAC6tmtLF8CAJ1tPm3MMZ92QkFm4xkkDCv0Hutf4i5iKr9M5+zxczb15zI0jO6wzQ=; 7:FPyhVv72KjJy2vmPiOhrHYHYtnn1Ez5Hcfdw59q2BTbiDiUtSziujbXuc/lQe91AjCqafdSGsnlJ2vQ8uw+4umrD++oejSk/o+gEyVWsRf28kkzeFUaxM9LM326s1qhZ5uoECndf5p+kU8UzH/mB/VmipRAr1Q1WZu1i4aivX2boy3yL5qJ+KyAMfIxub8FZERfphavZJoD9wUaUxy67seKfUYDlX9FvA6YSC0bUEry9Hqu+jUHQdCl4UREzl+jW SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Jul 2016 07:41:10.3861 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR03MB583 Cc: Russell King , Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Replacing drm_crtc_helper_set_config() by drm_atomic_helper_set_config() and converting the suspend/resume operations to atomic make us be able to use atomic configurations. All of these allow us to remove the crtc_funcs->mode_set callback as it is no longer used. Also, change the plane_funcs->update/disable_plane callbacks from the transitional version to the atomic version. Furthermore, switching to the pure atomic version of set_config callback means that we may implement CRTC/plane atomic checks by using the new CRTC/plane states instead of the legacy ones and we may remove the private ipu_crtc->enabled state which was left there for the transitional atomic helpers in phase 1. Page flip is also switched to the atomic version. Last, the legacy function drm_helper_disable_unused_functions() is removed from ->load in order not to confuse the atomic driver. Signed-off-by: Liu Ying --- v2->v3: * Newly introduced, but this contains some important logic in patch 06/10 , 07/10 and 09/10 of v2 to support nonblock atomic commit(including page flip) - the ->set_config and ->update_plane/disable_plane hooks are updated to be pure atomic version, and ->atomic_check/atomic_commit hooks of drm_mode_config_funcs are wired up. drivers/gpu/drm/imx/imx-drm-core.c | 76 +++++++++++++- drivers/gpu/drm/imx/ipuv3-crtc.c | 209 +++++-------------------------------- drivers/gpu/drm/imx/ipuv3-plane.c | 135 +++--------------------- drivers/gpu/drm/imx/ipuv3-plane.h | 2 - 4 files changed, 114 insertions(+), 308 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index f6e44c2..f14ad2b 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -15,10 +15,14 @@ */ #include #include +#include #include #include #include +#include #include +#include +#include #include #include #include @@ -41,6 +45,7 @@ struct imx_drm_device { struct imx_drm_crtc *crtc[MAX_CRTC]; unsigned int pipes; struct drm_fbdev_cma *fbhelper; + struct drm_atomic_state *state; }; struct imx_drm_crtc { @@ -169,6 +174,63 @@ static void imx_drm_output_poll_changed(struct drm_device *drm) static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { .fb_create = drm_fb_cma_create, .output_poll_changed = imx_drm_output_poll_changed, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) +{ + struct drm_device *dev = state->dev; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_plane_state *plane_state; + struct drm_gem_cma_object *cma_obj; + struct fence *excl; + unsigned shared_count; + struct fence **shared; + unsigned int i, j; + int ret; + + /* Wait for fences. */ + for_each_crtc_in_state(state, crtc, crtc_state, i) { + plane_state = crtc->primary->state; + if (plane_state->fb) { + cma_obj = drm_fb_cma_get_gem_obj(plane_state->fb, 0); + if (cma_obj->base.dma_buf) { + ret = reservation_object_get_fences_rcu( + cma_obj->base.dma_buf->resv, &excl, + &shared_count, &shared); + if (unlikely(ret)) + DRM_ERROR("failed to get fences " + "for buffer\n"); + + if (excl) { + fence_wait(excl, false); + fence_put(excl); + } + for (j = 0; j < shared_count; i++) { + fence_wait(shared[j], false); + fence_put(shared[j]); + } + } + } + } + + drm_atomic_helper_commit_modeset_disables(dev, state); + + drm_atomic_helper_commit_planes(dev, state, true); + + drm_atomic_helper_commit_modeset_enables(dev, state); + + drm_atomic_helper_commit_hw_done(state); + + drm_atomic_helper_wait_for_vblanks(dev, state); + + drm_atomic_helper_cleanup_planes(dev, state); +} + +static struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = { + .atomic_commit_tail = imx_drm_atomic_commit_tail, }; /* @@ -210,6 +272,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) drm->mode_config.max_width = 4096; drm->mode_config.max_height = 4096; drm->mode_config.funcs = &imx_drm_mode_config_funcs; + drm->mode_config.helper_private = &imx_drm_mode_config_helpers; drm_mode_config_init(drm); @@ -252,7 +315,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); legacyfb_depth = 16; } - drm_helper_disable_unused_functions(drm); imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, drm->mode_config.num_crtc, MAX_CRTC); if (IS_ERR(imxdrm->fbhelper)) { @@ -454,6 +516,7 @@ static int imx_drm_platform_remove(struct platform_device *pdev) static int imx_drm_suspend(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); + struct imx_drm_device *imxdrm; /* The drm_dev is NULL before .load hook is called */ if (drm_dev == NULL) @@ -461,17 +524,26 @@ static int imx_drm_suspend(struct device *dev) drm_kms_helper_poll_disable(drm_dev); + imxdrm = drm_dev->dev_private; + imxdrm->state = drm_atomic_helper_suspend(drm_dev); + if (IS_ERR(imxdrm->state)) { + drm_kms_helper_poll_enable(drm_dev); + return PTR_ERR(imxdrm->state); + } + return 0; } static int imx_drm_resume(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); + struct imx_drm_device *imx_drm; if (drm_dev == NULL) return 0; - drm_helper_resume_force_mode(drm_dev); + imx_drm = drm_dev->dev_private; + drm_atomic_helper_resume(drm_dev, imx_drm->state); drm_kms_helper_poll_enable(drm_dev); return 0; diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index f9d5d7c..3e82534 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -35,23 +33,6 @@ #define DRIVER_DESC "i.MX IPUv3 Graphics" -enum ipu_flip_status { - IPU_FLIP_NONE, - IPU_FLIP_PENDING, - IPU_FLIP_SUBMITTED, -}; - -struct ipu_flip_work { - struct work_struct unref_work; - struct drm_gem_object *bo; - struct drm_pending_vblank_event *page_flip_event; - struct work_struct fence_work; - struct ipu_crtc *crtc; - struct fence *excl; - unsigned shared_count; - struct fence **shared; -}; - struct ipu_crtc { struct device *dev; struct drm_crtc base; @@ -62,10 +43,6 @@ struct ipu_crtc { struct ipu_dc *dc; struct ipu_di *di; - int enabled; - enum ipu_flip_status flip_state; - struct workqueue_struct *flip_queue; - struct ipu_flip_work *flip_work; int irq; }; @@ -75,34 +52,26 @@ static void ipu_crtc_enable(struct ipu_crtc *ipu_crtc) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); - if (ipu_crtc->enabled) - return; - ipu_dc_enable(ipu); ipu_dc_enable_channel(ipu_crtc->dc); ipu_di_enable(ipu_crtc->di); - ipu_crtc->enabled = 1; - - /* - * In order not to be warned on enabling vblank failure, - * we should call drm_crtc_vblank_on() after ->enabled is set to 1. - */ - drm_crtc_vblank_on(&ipu_crtc->base); } static void ipu_crtc_disable(struct ipu_crtc *ipu_crtc) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); - - if (!ipu_crtc->enabled) - return; + struct drm_crtc *crtc = &ipu_crtc->base; ipu_dc_disable_channel(ipu_crtc->dc); ipu_di_disable(ipu_crtc->di); ipu_dc_disable(ipu); - ipu_crtc->enabled = 0; - drm_crtc_vblank_off(&ipu_crtc->base); + spin_lock_irq(&crtc->dev->event_lock); + if (crtc->state->event) { + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + } + spin_unlock_irq(&crtc->dev->event_lock); } static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) @@ -123,151 +92,21 @@ static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) } } -static void ipu_flip_unref_work_func(struct work_struct *__work) -{ - struct ipu_flip_work *work = - container_of(__work, struct ipu_flip_work, unref_work); - - drm_gem_object_unreference_unlocked(work->bo); - kfree(work); -} - -static void ipu_flip_fence_work_func(struct work_struct *__work) -{ - struct ipu_flip_work *work = - container_of(__work, struct ipu_flip_work, fence_work); - int i; - - /* wait for all fences attached to the FB obj to signal */ - if (work->excl) { - fence_wait(work->excl, false); - fence_put(work->excl); - } - for (i = 0; i < work->shared_count; i++) { - fence_wait(work->shared[i], false); - fence_put(work->shared[i]); - } - - work->crtc->flip_state = IPU_FLIP_SUBMITTED; -} - -static int ipu_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) -{ - struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - struct ipu_flip_work *flip_work; - int ret; - - if (ipu_crtc->flip_state != IPU_FLIP_NONE) - return -EBUSY; - - ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc); - if (ret) { - dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n"); - list_del(&event->base.link); - - return ret; - } - - flip_work = kzalloc(sizeof *flip_work, GFP_KERNEL); - if (!flip_work) { - ret = -ENOMEM; - goto put_vblank; - } - INIT_WORK(&flip_work->unref_work, ipu_flip_unref_work_func); - flip_work->page_flip_event = event; - - /* get BO backing the old framebuffer and take a reference */ - flip_work->bo = &drm_fb_cma_get_gem_obj(crtc->primary->fb, 0)->base; - drm_gem_object_reference(flip_work->bo); - - ipu_crtc->flip_work = flip_work; - /* - * If the object has a DMABUF attached, we need to wait on its fences - * if there are any. - */ - if (cma_obj->base.dma_buf) { - INIT_WORK(&flip_work->fence_work, ipu_flip_fence_work_func); - flip_work->crtc = ipu_crtc; - - ret = reservation_object_get_fences_rcu( - cma_obj->base.dma_buf->resv, &flip_work->excl, - &flip_work->shared_count, &flip_work->shared); - - if (unlikely(ret)) { - DRM_ERROR("failed to get fences for buffer\n"); - goto free_flip_work; - } - - /* No need to queue the worker if the are no fences */ - if (!flip_work->excl && !flip_work->shared_count) { - ipu_crtc->flip_state = IPU_FLIP_SUBMITTED; - } else { - ipu_crtc->flip_state = IPU_FLIP_PENDING; - queue_work(ipu_crtc->flip_queue, - &flip_work->fence_work); - } - } else { - ipu_crtc->flip_state = IPU_FLIP_SUBMITTED; - } - - if (crtc->primary->state) - drm_atomic_set_fb_for_plane(crtc->primary->state, fb); - - return 0; - -free_flip_work: - drm_gem_object_unreference_unlocked(flip_work->bo); - kfree(flip_work); - ipu_crtc->flip_work = NULL; -put_vblank: - imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc); - - return ret; -} - static const struct drm_crtc_funcs ipu_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, - .page_flip = ipu_page_flip, + .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; -static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc) -{ - unsigned long flags; - struct drm_device *drm = ipu_crtc->base.dev; - struct ipu_flip_work *work = ipu_crtc->flip_work; - - spin_lock_irqsave(&drm->event_lock, flags); - if (work->page_flip_event) - drm_crtc_send_vblank_event(&ipu_crtc->base, - work->page_flip_event); - imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc); - spin_unlock_irqrestore(&drm->event_lock, flags); -} - static irqreturn_t ipu_irq_handler(int irq, void *dev_id) { struct ipu_crtc *ipu_crtc = dev_id; imx_drm_handle_vblank(ipu_crtc->imx_crtc); - if (ipu_crtc->flip_state == IPU_FLIP_SUBMITTED) { - struct ipu_plane *plane = ipu_crtc->plane[0]; - - ipu_plane_set_base(plane, ipu_crtc->base.primary->fb); - ipu_crtc_handle_pageflip(ipu_crtc); - queue_work(ipu_crtc->flip_queue, - &ipu_crtc->flip_work->unref_work); - ipu_crtc->flip_state = IPU_FLIP_NONE; - } - return IRQ_HANDLED; } @@ -310,9 +149,26 @@ static void ipu_crtc_commit(struct drm_crtc *crtc) static int ipu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { + u32 primary_plane_mask = 1 << drm_plane_index(crtc->primary); + + if (state->active && (primary_plane_mask & state->plane_mask) == 0) + return -EINVAL; + return 0; } +static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state) +{ + spin_lock_irq(&crtc->dev->event_lock); + if (crtc->state->event) { + WARN_ON(drm_crtc_vblank_get(crtc)); + drm_crtc_arm_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + } + spin_unlock_irq(&crtc->dev->event_lock); +} + static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -371,25 +227,17 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) static const struct drm_crtc_helper_funcs ipu_helper_funcs = { .dpms = ipu_crtc_dpms, .mode_fixup = ipu_crtc_mode_fixup, - .mode_set = drm_helper_crtc_mode_set, .mode_set_nofb = ipu_crtc_mode_set_nofb, .prepare = ipu_crtc_prepare, .commit = ipu_crtc_commit, .atomic_check = ipu_crtc_atomic_check, + .atomic_begin = ipu_crtc_atomic_begin, }; static int ipu_enable_vblank(struct drm_crtc *crtc) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - /* - * ->commit is done after ->mode_set in drm_crtc_helper_set_mode(), - * so waiting for vblank in drm_plane_helper_commit() will timeout. - * Check the state here to avoid the waiting. - */ - if (!ipu_crtc->enabled) - return -EINVAL; - enable_irq(ipu_crtc->irq); return 0; @@ -508,8 +356,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, /* Only enable IRQ when we actually need it to trigger work. */ disable_irq(ipu_crtc->irq); - ipu_crtc->flip_queue = create_singlethread_workqueue("ipu-crtc-flip"); - return 0; err_put_plane1_res: @@ -554,7 +400,6 @@ static void ipu_drm_unbind(struct device *dev, struct device *master, imx_drm_remove_crtc(ipu_crtc->imx_crtc); - destroy_workqueue(ipu_crtc->flip_queue); ipu_put_resources(ipu_crtc); if (ipu_crtc->plane[1]) ipu_plane_put_resources(ipu_crtc->plane[1]); diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 1a126fe..164333b 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -55,122 +56,6 @@ int ipu_plane_irq(struct ipu_plane *ipu_plane) IPU_IRQ_EOF); } -int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb) -{ - struct drm_gem_cma_object *cma_obj[3], *old_cma_obj[3]; - struct drm_plane_state *state = ipu_plane->base.state; - struct drm_framebuffer *old_fb = state->fb; - unsigned long eba, ubo, vbo, old_eba, old_ubo, old_vbo; - int active, i; - int x = state->src_x >> 16; - int y = state->src_y >> 16; - - for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { - cma_obj[i] = drm_fb_cma_get_gem_obj(fb, i); - if (!cma_obj[i]) { - DRM_DEBUG_KMS("plane %d entry is null.\n", i); - return -EFAULT; - } - } - - for (i = 0; i < drm_format_num_planes(old_fb->pixel_format); i++) { - old_cma_obj[i] = drm_fb_cma_get_gem_obj(old_fb, i); - if (!old_cma_obj[i]) { - DRM_DEBUG_KMS("plane %d entry is null.\n", i); - return -EFAULT; - } - } - - eba = cma_obj[0]->paddr + fb->offsets[0] + - fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; - - if (eba & 0x7) { - DRM_DEBUG_KMS("base address must be a multiple of 8.\n"); - return -EINVAL; - } - - if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) { - DRM_DEBUG_KMS("pitches out of range.\n"); - return -EINVAL; - } - - if (fb->pitches[0] != old_fb->pitches[0]) { - DRM_DEBUG_KMS("pitches must not change while plane is enabled.\n"); - return -EINVAL; - } - - switch (fb->pixel_format) { - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - /* - * Multiplanar formats have to meet the following restrictions: - * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO - * - EBA, UBO and VBO are a multiple of 8 - * - UBO and VBO are unsigned and not larger than 0xfffff8 - * - Only EBA may be changed while scanout is active - * - The strides of U and V planes must be identical. - */ - ubo = cma_obj[1]->paddr + fb->offsets[1] + - fb->pitches[1] * y / 2 + x / 2 - eba; - vbo = cma_obj[2]->paddr + fb->offsets[2] + - fb->pitches[2] * y / 2 + x / 2 - eba; - - old_eba = old_cma_obj[0]->paddr + old_fb->offsets[0] + - old_fb->pitches[0] * y + - (old_fb->bits_per_pixel >> 3) * x; - old_ubo = old_cma_obj[1]->paddr + old_fb->offsets[1] + - old_fb->pitches[1] * y / 2 + x / 2 - old_eba; - old_vbo = old_cma_obj[2]->paddr + old_fb->offsets[2] + - old_fb->pitches[2] * y / 2 + x / 2 - old_eba; - - if ((ubo & 0x7) || (vbo & 0x7)) { - DRM_DEBUG_KMS("U/V buffer offsets must be a multiple of 8.\n"); - return -EINVAL; - } - - if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) { - DRM_DEBUG_KMS("U/V buffer offsets must be positive and not larger than 0xfffff8.\n"); - return -EINVAL; - } - - if (old_ubo != ubo || old_vbo != vbo) { - DRM_DEBUG_KMS("U/V buffer offsets must not change while plane is enabled.\n"); - return -EINVAL; - } - - if (fb->pitches[1] != fb->pitches[2]) { - DRM_DEBUG_KMS("U/V pitches must be identical.\n"); - return -EINVAL; - } - - if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) { - DRM_DEBUG_KMS("U/V pitches out of range.\n"); - return -EINVAL; - } - - if (old_fb->pitches[1] != fb->pitches[1]) { - DRM_DEBUG_KMS("U/V pitches must not change while plane is enabled.\n"); - return -EINVAL; - } - - dev_dbg(ipu_plane->base.dev->dev, - "phys = %pad %pad %pad, x = %d, y = %d", - &cma_obj[0]->paddr, &cma_obj[1]->paddr, - &cma_obj[2]->paddr, x, y); - break; - default: - dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", - &cma_obj[0]->paddr, x, y); - break; - } - - active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); - ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); - ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); - - return 0; -} - static inline unsigned long drm_plane_state_to_eba(struct drm_plane_state *state) { @@ -360,8 +245,8 @@ static void ipu_plane_destroy(struct drm_plane *plane) } static const struct drm_plane_funcs ipu_plane_funcs = { - .update_plane = drm_plane_helper_update, - .disable_plane = drm_plane_helper_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = ipu_plane_destroy, .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, @@ -380,10 +265,18 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, /* Ok to disable */ if (!fb) - return old_fb ? 0 : -EINVAL; + return 0; + + if (!state->crtc) + return -EINVAL; + + crtc_state = + drm_atomic_get_existing_crtc_state(state->state, state->crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; /* CRTC should be enabled */ - if (!state->crtc->enabled) + if (!crtc_state->enable) return -EINVAL; /* no scaling */ @@ -391,8 +284,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, state->src_h >> 16 != state->crtc_h) return -EINVAL; - crtc_state = state->crtc->state; - switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: /* full plane doesn't support partial off screen */ diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h index c51a44b..338b88a 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.h +++ b/drivers/gpu/drm/imx/ipuv3-plane.h @@ -37,8 +37,6 @@ int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, bool interlaced); -int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb); - int ipu_plane_get_resources(struct ipu_plane *plane); void ipu_plane_put_resources(struct ipu_plane *plane);