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 = {