From patchwork Tue May 24 10:10:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ying Liu X-Patchwork-Id: 9133383 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 C47DA607D5 for ; Tue, 24 May 2016 10:26:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BDE0B28233 for ; Tue, 24 May 2016 10:26:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B2D9428258; Tue, 24 May 2016 10:26:50 +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 1195A28233 for ; Tue, 24 May 2016 10:26:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0F5326E6F7; Tue, 24 May 2016 10:26:47 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1on0080.outbound.protection.outlook.com [157.56.110.80]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6EAE36E6F7 for ; Tue, 24 May 2016 10:26:44 +0000 (UTC) Received: from BN3PR0301CA0072.namprd03.prod.outlook.com (10.160.152.168) by BY2PR03MB476.namprd03.prod.outlook.com (10.141.141.153) with Microsoft SMTP Server (TLS) id 15.1.492.11; Tue, 24 May 2016 10:11:41 +0000 Received: from BN1AFFO11FD024.protection.gbl (2a01:111:f400:7c10::184) by BN3PR0301CA0072.outlook.office365.com (2a01:111:e400:401e::40) with Microsoft SMTP Server (TLS) id 15.1.501.7 via Frontend Transport; Tue, 24 May 2016 10:11:41 +0000 Authentication-Results: spf=softfail (sender IP is 192.88.168.50) smtp.mailfrom=gmail.com; arm.linux.org.uk; dkim=none (message not signed) header.d=none; arm.linux.org.uk; dmarc=fail action=none header.from=gmail.com; Received-SPF: SoftFail (protection.outlook.com: domain of transitioning gmail.com discourages use of 192.88.168.50 as permitted sender) Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1AFFO11FD024.mail.protection.outlook.com (10.58.52.84) with Microsoft SMTP Server (TLS) id 15.1.497.8 via Frontend Transport; Tue, 24 May 2016 10:11:40 +0000 Received: from victor.ap.freescale.net (victor.ap.freescale.net [10.192.241.62]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u4OABCMC024148; Tue, 24 May 2016 03:11:38 -0700 From: Liu Ying To: Subject: [PATCH 13/14] drm/imx: atomic phase 3 step 4: Use generic atomic page flip Date: Tue, 24 May 2016 18:10:52 +0800 Message-ID: <1464084653-16684-14-git-send-email-gnuiyl@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1464084653-16684-1-git-send-email-gnuiyl@gmail.com> References: <1464084653-16684-1-git-send-email-gnuiyl@gmail.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131085583009671996; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(199003)(189002)(9170700003)(2950100001)(33646002)(87936001)(47776003)(92566002)(81166006)(8936002)(8676002)(2906002)(104016004)(1220700001)(61266001)(86362001)(5890100001)(6806005)(77096005)(586003)(4326007)(50226002)(73972006)(5008740100001)(83322999)(76482005)(73392002)(87572001)(106466001)(105596002)(76176999)(50986999)(48376002)(50466002)(229853001)(82202001)(36756003)(2351001)(11100500001)(5003940100001)(19580395003)(19580405001)(110136002)(189998001)(81442002)(41533002); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR03MB476; H:tx30smr01.am.freescale.net; FPR:; SPF:SoftFail; MLV:sfv; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD024; 1:JG2mI6sEj1kXOm0B7wF23xabiZE4yhscyBz1rXWHW6WtXygBbd9NcGMgS5mLiMnpza5NMMHnPORSjld4M23ZxIuimHyS9MqXP2I+Gq/PBtrl/Bwdz1Y09nnXb9GKqDkhM9uBGOdPzj+LSK1Nj8SdrwKr4yin/JhOAvG7oBS0fx5E0d+XRpprV128fEdWMJr8TyaonXOicQTi5gabcyMq7kBBONWQqdHAowPUhXfPBozgGtxtZYKvoeqL0CEtJA98THAzlE8TqjR6+vocnMvs5UBLtATNO3djmcSByw2gpMf9eBwcoVAC9tLkPFiHx+AhHfqLOCW4rV1mfjCgswb1owyASN7T62ohcHBxLgTS/U2iqosEPO6ZN7X9rLHgWJLd09WBIZKw9t2fjp1ulCuCd9X9VsDwJw3iuciDNKyNHSKa/gc5NkgulkFlCRWbJno8ZeCPiIquKbiuQiByFufHtrZNXTsqxE1IFScmnabJqrRWYNmvBYldoTWuGFClYwjoH/dz1yIdAddmjd/jFckH3T8YDw9hsmlnQGYXU8oM8SVX9hSMNuBbSTeJK4yHdUjf MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: b8588583-99e1-4b62-09db-08d383bbccec X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 2:WQoN9j/Ir79O0i9/44nxVvEdokf+A3x4ktDLDiLo7LjV7Z9VZqgLQQlRfZiJssxVzATiOtiTPjITClrvPRsp8b4BPWSM99CP14LAPuYBkMMjupYQkksTFiTFjBvTmfCT/y8na/YHCGgelkS74gAjJfE7tfGvMR+P/L/PVWCDvo5zQyjn+xdinYiW+ORoOtx3; 3:ImFgkCjFePwR83R9k2bqIHa5mXvBLKPm7WIQUOd46yFzqfuOWVUpU8aCWd00aYRH7uxktGExoZH/G0ClDR9+HTTOvBbxBQSPD7qvKXRg9cY0OCVqi+Iag3kksE4+vi5Z1xbcLfv6HJd+0YP2x7l5eFQzyk/mTAr88Vb9XGxCL6/gFfS9mbOwHOcyf5VjLdcFO8UY7bvqm/lFU8XeiN5dyHBkqMigxtykcWHRKvK2B10= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB476; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 25:pV4nhbYwvhepEOxwnW07L1rZnHoqp4nroVcCVakZ9dUAB3sQENbZ6DeegsiO4UpLk4aiIIFpZF0ZbUtQRSSEQySMrL6wIkSy4zv+H1ugGPBAIXAMGEZcoEUaVc02UuLZY4QMRy5wgcvgJCjohvsHqja5/i6mvAzNYazInkkfoVcP2Uyc9OUZj/DNU1m4fEzF6Eni499LC6J1SH3OZOSUmQE3zGSy3c5fjna7SWSMWoHAb8MQIFRiBAxG1EfHUim88uBq2z08l5CVQUGOpMQgL2QK9MfgcXlpnxpWun8KS7Wyj557GBfeTkCh+VqKYVnKGxIox+yZO2R4GeFCVnFKq4Jt6Bne4WutGzfEfSvTlv03iskfB8+BNFiE3hlvzAeHQ+C/LDwarPyspfCd2RPBTxY1NcnTeWS6x4wkPpHH0ib7ylxxQ39d2CnMLtmgzW1m9mk0NtcH72xXbi8ru+Sm36uq2VMZtAfJY0A4GoWCKUCUlSyIDB5e2C9qoq+xm9WoDdvlnNqmUojVDXtT53ztvC+6y39jopuFQps/X4EcZvPESOtySm/odjo14o1/9RSfdVULImfLrPT5VzD7JsYa/F9Spw476eGKsQGovkTClXCZHG7bGAQ7mdk2cE83w+V0NwT8ugXLQzStq+yvVmo7St5Z3TtZn6N2mYj/U5bBFqwMqdwF3R1bsaqlcP3ygbqCUQRaZ8LsPUEnC5qAAySwka0v4uhq77ktynZQUhvOJNpARrr34XyeDIc3f3r+ghSQ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13024025)(8121501046)(13015025)(13023025)(5005006)(13018025)(13017025)(3002001)(10201501046)(6055026); SRVR:BY2PR03MB476; BCL:0; PCL:0; RULEID:(400006); SRVR:BY2PR03MB476; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 4:O4JgHV9lzdDoNRVAfPnbCd+wvK9F03NZgXN3VWTxX4cp2biycI09fRmYtWhEmu+2FfvmAKAXmoL+H6IP5CdsgjojGDl6RjuDdmmDuEvwT+PAE2k1CdKfVRMFq5ihabqig3fnqeSn2h2fIYlx4F8rT+1RRlXpkHzDLx67Qdjkd4Nyo0IozbtmOyfu8Qp0vgZ14/ZD6IvcQgTuvxthIpZJPwa2YcnwrFKFB20B2PzgpjxaEwzf/CxTaOMBP+pea5tHj5XPnggvvSi/NCeb8WavTl4BQPpjFMQ07P6GDt5Cmw4ZOE5kIiMdN81VIa4i5SapTVDs2EXaEpZ3nyOl8hxOMbmzaUTCyAoCFK9hqDId8NId/S+pcSv/sNvyNFxiUEGzInP7jOtO86uDEAitXH4QHAI84hFx465t7VYXh2B7Rga//fTP/wfAUUGfaVc5INgzsa8j0d+jrY05akh2jd8y1xCuUtarW/EQqNclacACln4= X-Forefront-PRVS: 09525C61DB X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR03MB476; 23:pRvmj9LM/uu70LLc2QfWsTspDByurKsbjFQ1T2ICp3?= =?us-ascii?Q?yllHAlsPI0A+UIlMgk0qk0ZTNEEwvZVS7K0V7FSqeeLWHYwWi3G8Q412xkVt?= =?us-ascii?Q?9GgP9r3jSOJ5v4VZVhrnJxSS3uWpUFDq3APB65uTbqMT5qPxmxQQUuzxF/hZ?= =?us-ascii?Q?bOJJ/HvIe2BeRpvk0/Uj9oq7xmu5H/gKIuNZNXSjyFTbZUBUpixMtobF0LuJ?= =?us-ascii?Q?UF2mTpNi61USh+8YDorXKrvvgyAopb3M4eXeoTnMp9eDfS+SXdeHKq0nI27p?= =?us-ascii?Q?BTsN/VUoVbdBanz18pQWHZ+m/qcFQdfssKUlkidUZ5fs7if5fKkE8AoBNLVs?= =?us-ascii?Q?suoqHU+Z05dGdcyeNB97agq2Lfss25WnzNH7BdT7AwVmROtfpEHu1F5fhrxt?= =?us-ascii?Q?o90T/kuO0ffQdJjqp12+1rKFvaXzTahHGuBAKXqw79W7mZwxikHi8HQ6/X3V?= =?us-ascii?Q?tw10ayvuemyf7KgMozYqQRFph6/48FeNUA8KffQMdesN/ScLGelj4L1F3x9P?= =?us-ascii?Q?FDtGR+Ip5l5hjm2SXkucWEUbvtrkuXliV+XwNIrEGxzktPB4AItD/SmSfBVz?= =?us-ascii?Q?QYtwjWO+WCbqAQbF46PJJU6F0pokyYzmy2Otlu1pcsniRNXBt4MJWn8u1xza?= =?us-ascii?Q?3b8B8W8jjwkGSpbX2fU0WXFGtmFJd9kCFz6ClFbwTGGceMjrUEi2AbCueytU?= =?us-ascii?Q?IL6KTF8OxLYnh2jxn7cTxXwT++MbJuwBwMY19VaNLE0pfcMp1DlPtgk4w+LH?= =?us-ascii?Q?NcVo58TKvfCrvDx1f7svV2uO5O/0kTwjSFHaTszAocfkjnieAMW0EMQwh5xl?= =?us-ascii?Q?4rjpB1PliuWUFV7HWfxoLGYsRPMb8cCHDJiQFTuTl71B6NQXos9WcX3n/vmD?= =?us-ascii?Q?LKt9lGsNiAX9+qNHeKW9DDAo4uphXp0Gsgu3D7694Ma0hzAla42AyfeWsvTb?= =?us-ascii?Q?lbOFnB2thEMeLmpGOYdCu7i9DxJgm3ix4j3vuvk7+d/MJjK3RO3k6onZJuUk?= =?us-ascii?Q?QTwJ0n79hKrPdEL/EuEQeVom6J6m+GfOHcp/97UU4B9BTFRCUzxKTkErkWI7?= =?us-ascii?Q?V2eMcLE1g2UZ8zf8NHRXzWMZf8oM5rhmqHX95D6a0t9nLehOJ763hKJ+WN2p?= =?us-ascii?Q?cid5NnqiS8I8LnqlH5hQAaHPPiXcempNNOkMo6ZqpXfzP1Gj7emwrkSzo9t0?= =?us-ascii?Q?uxe6Lk0Ikrpl4+YBPkt+881f8M7xBqXUd/asPQIjCx7yzGIl0LNpLaAw=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 5:WQai/pLIFgwa19X7JMEWWhySGwLvE6rsR2GGHmX0JmMZCYyDWaWt9qSOBn+jnjPItn0ur2sf45JBZ+F7KWeoNXW/EFW+e5ZKfoQK4gKb3UmJoBwyAY/GTN150vs6qGzCXhqOWGvt3GIULG9PmzBFRDA0rMVuBhFMnLmrGirPRfc=; 24:trQji+wz/jYPZCM8D9lazjaPMgeXHjCkmg7i3AIvRgjnSqn6ejibGTNKMXxn3Glk3sVYMQ9wtogLDYoraIK9ZxLKed9AdhQFMMg/L443wvg=; 7:5VBjlqF9INI+CNwDfBE3vCg4/QJg2Qks/UILu/vF1Vgt1rCekka2mvEiWmT+/3jjoUWSXQPOBjpPrryKBxXxJmov0bObwAOmz1E7CW87U7eoH8H+N6DUhaPtQpv/eRXfUJ4+j0mQMB8lbDr2nMaHe3BDqrzd7r6nlEnCSJdVklvbxgI/Vdk/QsnSK2b2af6Q SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2016 10:11:40.7799 (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.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB476 Cc: Russell King 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 To support generic atomic page flip, this patch customizes ->atomic_commit for async commits. Signed-off-by: Liu Ying --- drivers/gpu/drm/imx/imx-drm-core.c | 137 +++++++++++++++++++++++++++++++- drivers/gpu/drm/imx/ipuv3-crtc.c | 156 ++----------------------------------- 2 files changed, 144 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 2fa04a0..cb521cb 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 @@ -48,6 +52,14 @@ struct imx_drm_device { struct imx_drm_crtc { struct drm_crtc *crtc; struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs; + wait_queue_head_t commit_wait; + bool commit_pending; +}; + +struct imx_drm_commit { + struct work_struct work; + struct drm_device *dev; + struct drm_atomic_state *state; }; #if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) @@ -168,11 +180,132 @@ static void imx_drm_output_poll_changed(struct drm_device *drm) drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); } +static void imx_drm_atomic_complete(struct imx_drm_commit *commit, bool async) +{ + struct drm_device *dev = commit->dev; + struct imx_drm_device *imxdrm = dev->dev_private; + struct imx_drm_crtc *imx_crtc; + struct drm_atomic_state *old_state = commit->state; + struct drm_crtc *crtc; + struct drm_crtc_state *old_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(old_state, crtc, old_crtc_state, i) { + if (crtc->state->event) { + plane_state = crtc->primary->state; + 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]); + } + } + } + } + + /* Apply the atomic update. */ + drm_atomic_helper_commit_modeset_disables(dev, old_state); + drm_atomic_helper_commit_modeset_enables(dev, old_state); + drm_atomic_helper_commit_planes(dev, old_state, false); + drm_atomic_helper_wait_for_vblanks(dev, old_state); + drm_atomic_helper_cleanup_planes(dev, old_state); + + if (async) + for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { + imx_crtc = imxdrm->crtc[i]; + + /* Complete the commit, wake up any waiter. */ + spin_lock(&imx_crtc->commit_wait.lock); + imx_crtc->commit_pending = false; + wake_up_all_locked(&imx_crtc->commit_wait); + spin_unlock(&imx_crtc->commit_wait.lock); + } + + drm_atomic_state_free(old_state); + + kfree(commit); +} + +static void imx_drm_atomic_work(struct work_struct *work) +{ + struct imx_drm_commit *commit = + container_of(work, struct imx_drm_commit, work); + + imx_drm_atomic_complete(commit, true); +} + +static int imx_drm_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, bool async) +{ + struct imx_drm_device *imxdrm = dev->dev_private; + struct imx_drm_crtc *imx_crtc; + struct imx_drm_commit *commit; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + unsigned int i; + int ret; + + commit = kzalloc(sizeof(*commit), GFP_KERNEL); + if (commit == NULL) + return -ENOMEM; + + commit->dev = dev; + commit->state = state; + + if (async) { + for_each_crtc_in_state(state, crtc, crtc_state, i) { + imx_crtc = imxdrm->crtc[i]; + + spin_lock(&imx_crtc->commit_wait.lock); + ret = wait_event_interruptible_locked( + imx_crtc->commit_wait, + !imx_crtc->commit_pending); + if (ret == 0) + imx_crtc->commit_pending = true; + spin_unlock(&imx_crtc->commit_wait.lock); + + if (ret) { + kfree(commit); + return ret; + } + } + + INIT_WORK(&commit->work, imx_drm_atomic_work); + } + + drm_atomic_helper_swap_state(dev, state); + + if (async) + schedule_work(&commit->work); + else + imx_drm_atomic_complete(commit, async); + + return 0; +} + 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, + .atomic_commit = imx_drm_atomic_commit, }; /* @@ -315,6 +448,8 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; imx_drm_crtc->crtc = crtc; + init_waitqueue_head(&imx_drm_crtc->commit_wait); + crtc->port = port; imxdrm->crtc[imxdrm->pipes++] = imx_drm_crtc; diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 4d1b911..dcbeb56 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,9 +43,6 @@ struct ipu_crtc { struct ipu_dc *dc; struct ipu_di *di; - enum ipu_flip_status flip_state; - struct workqueue_struct *flip_queue; - struct ipu_flip_work *flip_work; int irq; }; @@ -94,150 +72,35 @@ static void ipu_crtc_disable(struct drm_crtc *crtc) drm_crtc_vblank_off(&ipu_crtc->base); } -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_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) +static void ipu_crtc_handle_pageflip(struct drm_crtc *crtc) { + struct drm_device *drm = crtc->dev; 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); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; 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; + struct drm_crtc *crtc = &ipu_crtc->base; 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; - } + if (crtc->state->event) + ipu_crtc_handle_pageflip(crtc); return IRQ_HANDLED; } @@ -452,8 +315,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, ipu_plane_put_resources(ipu_crtc->plane[0]); - ipu_crtc->flip_queue = create_singlethread_workqueue("ipu-crtc-flip"); - return 0; err_put_plane_res: @@ -495,7 +356,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); }