From patchwork Mon Nov 30 21:07:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philipp Zabel X-Patchwork-Id: 7729861 Return-Path: X-Original-To: patchwork-linux-mediatek@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9FD21BEEE5 for ; Mon, 30 Nov 2015 21:09:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9559C205DF for ; Mon, 30 Nov 2015 21:09:10 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6960620600 for ; Mon, 30 Nov 2015 21:09:09 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a3Vh6-0001yH-V7; Mon, 30 Nov 2015 21:09:08 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a3Vgy-0001c3-Tb for linux-mediatek@lists.infradead.org; Mon, 30 Nov 2015 21:09:03 +0000 Received: from paszta.hi.4.pengutronix.de ([10.1.0.120] helo=paszta.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1a3VgJ-0003vh-E8; Mon, 30 Nov 2015 22:08:19 +0100 From: Philipp Zabel To: dri-devel@lists.freedesktop.org Subject: [PATCH v7 14/14] drm/mediatek: Add fence control, wait on GPU fence Date: Mon, 30 Nov 2015 22:07:56 +0100 Message-Id: <1448917676-25584-15-git-send-email-p.zabel@pengutronix.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1448917676-25584-1-git-send-email-p.zabel@pengutronix.de> References: <1448917676-25584-1-git-send-email-p.zabel@pengutronix.de> X-SA-Exim-Connect-IP: 10.1.0.120 X-SA-Exim-Mail-From: p.zabel@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-mediatek@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151130_130901_268330_7118D22C X-CRM114-Status: GOOD ( 15.32 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, Paul Bolle , YT Shen , Jitao Shi , Jie Qiu , Pawel Moll , Ian Campbell , Cawa Cheng , Daniel Stone , Tomasz Figa , CK Hu , Rob Herring , linux-mediatek@lists.infradead.org, Daniel Vetter , Kumar Gala , Matthias Brugger , Philipp Zabel , Dave Airlie , kernel@pengutronix.de MIME-Version: 1.0 Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Wait on the exclusive fence for the incoming framebuffer, using "wait_for_fences" from drm_atomic_helper.c, which needs to be exported first. Signed-off-by: CK Hu Signed-off-by: YT Shen Signed-off-by: Daniel Kurtz Signed-off-by: Philipp Zabel --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 36 ++++++++++++++++++++++++++++++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ drivers/gpu/drm/mediatek/mtk_drm_plane.c | 22 ++++++++++++++++--- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index ec0540f..69e8fe5 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -65,6 +65,8 @@ struct mtk_crtc_state { struct drm_crtc_state base; struct drm_pending_vblank_event *event; + bool pending_needs_vblank; + bool pending_config; unsigned int pending_width; unsigned int pending_height; @@ -100,10 +102,24 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) { struct drm_crtc *crtc = &mtk_crtc->base; struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state); + unsigned long flags; + spin_lock_irqsave(&crtc->dev->event_lock, flags); drm_send_vblank_event(crtc->dev, state->event->pipe, state->event); drm_crtc_vblank_put(crtc); state->event = NULL; + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); +} + +static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) +{ + struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); + + drm_handle_vblank(mtk_crtc->base.dev, mtk_crtc->pipe); + if (state->pending_needs_vblank) { + mtk_drm_crtc_finish_page_flip(mtk_crtc); + state->pending_needs_vblank = false; + } } static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) @@ -391,10 +407,26 @@ void mtk_drm_crtc_commit(struct drm_crtc *crtc) } } +void mtk_drm_crtc_check_flush(struct drm_crtc *crtc) +{ + struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state); + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + + if (mtk_crtc->do_flush) { + if (state->event) + state->pending_needs_vblank = true; + mtk_drm_crtc_commit(crtc); + mtk_crtc->do_flush = false; + } +} + static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { - mtk_drm_crtc_commit(crtc); + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + + mtk_crtc->do_flush = true; + mtk_drm_crtc_check_flush(crtc); } static const struct drm_crtc_funcs mtk_crtc_funcs = { @@ -482,7 +514,7 @@ void mtk_crtc_ddp_irq(struct drm_device *drm_dev, struct mtk_ddp_comp *ovl) } } - drm_handle_vblank(mtk_crtc->base.dev, mtk_crtc->pipe); + mtk_drm_finish_page_flip(mtk_crtc); } int mtk_drm_crtc_create(struct drm_device *drm_dev, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h index f04854f..94eba3c 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h @@ -22,6 +22,7 @@ int mtk_drm_crtc_enable_vblank(struct drm_device *drm, unsigned int pipe); void mtk_drm_crtc_disable_vblank(struct drm_device *drm, unsigned int pipe); +void mtk_drm_crtc_check_flush(struct drm_crtc *crtc); void mtk_drm_crtc_commit(struct drm_crtc *crtc); void mtk_crtc_ddp_irq(struct drm_device *drm_dev, struct mtk_ddp_comp *ovl); int mtk_drm_crtc_create(struct drm_device *drm_dev, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 2d5bd16..e6d8adf 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -49,6 +49,8 @@ static void mtk_atomic_complete(struct mtk_drm_private *private, { struct drm_device *drm = private->drm; + drm_atomic_helper_wait_for_fences(drm, state); + drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_planes(drm, state, false); drm_atomic_helper_commit_modeset_enables(drm, state); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index c0b62d1..343c060 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -123,6 +123,8 @@ static int mtk_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_framebuffer *fb = state->fb; + struct drm_gem_object *gem; + struct reservation_object *resv; struct drm_crtc_state *crtc_state; bool visible; int ret; @@ -167,6 +169,16 @@ static int mtk_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; + /* Find pending fence from incoming FB, if any, and stash in state */ + gem = mtk_fb_get_gem_obj(fb); + if (!gem->dma_buf || !gem->dma_buf->resv) + return 0; + + resv = gem->dma_buf->resv; + ww_mutex_lock(&resv->lock, NULL); + state->fence = fence_get(reservation_object_get_excl(resv)); + ww_mutex_unlock(&resv->lock); + return 0; } @@ -176,6 +188,7 @@ static void mtk_plane_atomic_update(struct drm_plane *plane, struct mtk_plane_state *state = to_mtk_plane_state(plane->state); struct drm_crtc *crtc = state->base.crtc; struct drm_gem_object *gem; + struct mtk_drm_gem_obj *mtk_gem; struct mtk_drm_plane *mtk_plane = to_mtk_plane(plane); struct drm_rect dest = { .x1 = state->base.crtc_x, @@ -193,9 +206,10 @@ static void mtk_plane_atomic_update(struct drm_plane *plane, drm_rect_intersect(&dest, &clip); gem = mtk_fb_get_gem_obj(state->base.fb); - if (gem) - mtk_plane_config(mtk_plane, true, to_mtk_gem_obj(gem)->dma_addr, - &dest); + mtk_gem = to_mtk_gem_obj(gem); + mtk_plane_config(mtk_plane, true, mtk_gem->dma_addr, &dest); + + mtk_drm_crtc_check_flush(crtc); } static void mtk_plane_atomic_disable(struct drm_plane *plane, @@ -209,6 +223,8 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane, return; mtk_plane_config(mtk_plane, false, 0, &dest); + + mtk_drm_crtc_check_flush(crtc); } static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {