From patchwork Wed Apr 3 20:13:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 10885135 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC45F17EE for ; Thu, 4 Apr 2019 07:18:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 908E528901 for ; Thu, 4 Apr 2019 07:18:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 84DA228992; Thu, 4 Apr 2019 07:18:57 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3F58028901 for ; Thu, 4 Apr 2019 07:18:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9C55E6E9D9; Thu, 4 Apr 2019 07:18:28 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id 376BF6E4ED for ; Wed, 3 Apr 2019 20:13:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id ED3132827FB From: Sebastian Reichel To: Sebastian Reichel , Tomi Valkeinen , Tony Lindgren , Pavel Machek , Laurent Pinchart Subject: [PATCHv6 1/4] drm/omap: use DRM_DEBUG_DRIVER instead of CORE Date: Wed, 3 Apr 2019 22:13:23 +0200 Message-Id: <20190403201326.3127-2-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403201326.3127-1-sebastian.reichel@collabora.com> References: <20190403195413.djfrgzuj7povdksi@earth.universe> <20190403201326.3127-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 04 Apr 2019 07:17:55 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, "H. Nikolaus Schaller" , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Sebastian Reichel , linux-omap@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This macro is only used by omapdrm, which should print debug messages using the DRIVER category instead of the default CORE category. Acked-by: Pavel Machek Tested-by: Tony Lindgren Tested-by: Pavel Machek Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 3cca45cb25f3..896aa12f09b2 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -37,8 +37,8 @@ #include "omap_irq.h" #include "omap_plane.h" -#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) -#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */ +#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__) +#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) /* verbose debug */ #define MODULE_NAME "omapdrm" From patchwork Wed Apr 3 20:13:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 10885087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D1F3C18E8 for ; Thu, 4 Apr 2019 07:18:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B435028901 for ; Thu, 4 Apr 2019 07:18:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A7C53289B4; Thu, 4 Apr 2019 07:18:10 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2D150289BF for ; Thu, 4 Apr 2019 07:18:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2EA5C6E56A; Thu, 4 Apr 2019 07:17:57 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1932B6E4F4 for ; Wed, 3 Apr 2019 20:13:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id E46BC2827FC From: Sebastian Reichel To: Sebastian Reichel , Tomi Valkeinen , Tony Lindgren , Pavel Machek , Laurent Pinchart Subject: [PATCHv6 2/4] drm/omap: don't check dispc timings for DSI Date: Wed, 3 Apr 2019 22:13:24 +0200 Message-Id: <20190403201326.3127-3-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403201326.3127-1-sebastian.reichel@collabora.com> References: <20190403195413.djfrgzuj7povdksi@earth.universe> <20190403201326.3127-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 04 Apr 2019 07:17:55 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, "H. Nikolaus Schaller" , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Sebastian Reichel , linux-omap@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP While most display types only forward their VM to the DISPC, this is not true for DSI. DSI calculates the VM for DISPC based on its own, but it's not identical. Actually the DSI VM is not even a valid DISPC VM making this check fail. Let's restore the old behaviour and avoid checking the DISPC VM for DSI here. Fixes: 7c27fa57ef31 ("drm/omap: Call dispc timings check operation directly") Acked-by: Pavel Machek Tested-by: Tony Lindgren Tested-by: Pavel Machek Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_crtc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 5a29bf01c0e8..86827a061b0b 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -395,10 +395,20 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, int r; drm_display_mode_to_videomode(mode, &vm); - r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel, - &vm); - if (r) - return r; + + /* + * DSI might not call this, since the supplied mode is not a + * valid DISPC mode. DSI will calculate and configure the + * proper DISPC mode later. + */ + if (omap_crtc->pipe->output->next == NULL || + omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) { + r = priv->dispc_ops->mgr_check_timings(priv->dispc, + omap_crtc->channel, + &vm); + if (r) + return r; + } /* Check for bandwidth limit */ if (priv->max_bandwidth) { From patchwork Wed Apr 3 20:13:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 10885097 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9C43C1669 for ; Thu, 4 Apr 2019 07:18:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7E7D128901 for ; Thu, 4 Apr 2019 07:18:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7280928992; Thu, 4 Apr 2019 07:18:21 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CEDAB28901 for ; Thu, 4 Apr 2019 07:18:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C72EF6E571; Thu, 4 Apr 2019 07:17:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by gabe.freedesktop.org (Postfix) with ESMTPS id 13E5A6E4F7 for ; Wed, 3 Apr 2019 20:13:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id E6CB22827FE From: Sebastian Reichel To: Sebastian Reichel , Tomi Valkeinen , Tony Lindgren , Pavel Machek , Laurent Pinchart Subject: [PATCHv6 3/4] drm/omap: add framedone interrupt support Date: Wed, 3 Apr 2019 22:13:25 +0200 Message-Id: <20190403201326.3127-4-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403201326.3127-1-sebastian.reichel@collabora.com> References: <20190403195413.djfrgzuj7povdksi@earth.universe> <20190403201326.3127-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 04 Apr 2019 07:17:55 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, "H. Nikolaus Schaller" , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Sebastian Reichel , linux-omap@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This prepares framedone interrupt handling for manual display update support. Acked-by: Pavel Machek Tested-by: Tony Lindgren Tested-by: Pavel Machek Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_crtc.c | 50 +++++++++++++++++++++++++++++ drivers/gpu/drm/omapdrm/omap_crtc.h | 1 + drivers/gpu/drm/omapdrm/omap_irq.c | 25 +++++++++++++++ drivers/gpu/drm/omapdrm/omap_irq.h | 1 + 4 files changed, 77 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 86827a061b0b..68697820d189 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -51,6 +51,9 @@ struct omap_crtc { bool pending; wait_queue_head_t pending_wait; struct drm_pending_vblank_event *event; + + void (*framedone_handler)(void *); + void *framedone_handler_data; }; /* ----------------------------------------------------------------------------- @@ -230,6 +233,18 @@ static int omap_crtc_dss_register_framedone( struct omap_drm_private *priv, enum omap_channel channel, void (*handler)(void *), void *data) { + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_device *dev = omap_crtc->base.dev; + + if (omap_crtc->framedone_handler) + return -EBUSY; + + dev_dbg(dev->dev, "register framedone %s", omap_crtc->name); + + omap_crtc->framedone_handler = handler; + omap_crtc->framedone_handler_data = data; + return 0; } @@ -237,6 +252,17 @@ static void omap_crtc_dss_unregister_framedone( struct omap_drm_private *priv, enum omap_channel channel, void (*handler)(void *), void *data) { + struct drm_crtc *crtc = priv->channels[channel]->crtc; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_device *dev = omap_crtc->base.dev; + + dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name); + + WARN_ON(omap_crtc->framedone_handler != handler); + WARN_ON(omap_crtc->framedone_handler_data != data); + + omap_crtc->framedone_handler = NULL; + omap_crtc->framedone_handler_data = NULL; } static const struct dss_mgr_ops mgr_ops = { @@ -302,6 +328,30 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc) DBG("%s: apply done", omap_crtc->name); } +void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus) +{ + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + + if (!omap_crtc->framedone_handler) { + dev_warn(omap_crtc->base.dev->dev, "no framedone handler?"); + return; + } + + omap_crtc->framedone_handler(omap_crtc->framedone_handler_data); + + spin_lock(&crtc->dev->event_lock); + /* Send the vblank event if one has been requested. */ + if (omap_crtc->event) { + drm_crtc_send_vblank_event(crtc, omap_crtc->event); + omap_crtc->event = NULL; + } + omap_crtc->pending = false; + spin_unlock(&crtc->dev->event_lock); + + /* Wake up omap_atomic_complete. */ + wake_up(&omap_crtc->pending_wait); +} + static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) { struct omap_drm_private *priv = crtc->dev->dev_private; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h index d9de437ba9dd..d33bbb7a4f90 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.h +++ b/drivers/gpu/drm/omapdrm/omap_crtc.h @@ -41,5 +41,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, int omap_crtc_wait_pending(struct drm_crtc *crtc); void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus); void omap_crtc_vblank_irq(struct drm_crtc *crtc); +void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus); #endif /* __OMAPDRM_CRTC_H__ */ diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c index 329ad26d6d50..01dda84ca2ee 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c @@ -85,6 +85,28 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, return ret == 0 ? -1 : 0; } +int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable) +{ + struct drm_device *dev = crtc->dev; + struct omap_drm_private *priv = dev->dev_private; + unsigned long flags; + enum omap_channel channel = omap_crtc_channel(crtc); + int framedone_irq = + priv->dispc_ops->mgr_get_framedone_irq(priv->dispc, channel); + + DBG("dev=%p, crtc=%u, enable=%d", dev, channel, enable); + + spin_lock_irqsave(&priv->wait_lock, flags); + if (enable) + priv->irq_mask |= framedone_irq; + else + priv->irq_mask &= ~framedone_irq; + omap_irq_update(dev); + spin_unlock_irqrestore(&priv->wait_lock, flags); + + return 0; +} + /** * enable_vblank - enable vblank interrupt events * @dev: DRM device @@ -217,6 +239,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg) if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel)) omap_crtc_error_irq(crtc, irqstatus); + + if (irqstatus & priv->dispc_ops->mgr_get_framedone_irq(priv->dispc, channel)) + omap_crtc_framedone_irq(crtc, irqstatus); } omap_irq_ocp_error_handler(dev, irqstatus); diff --git a/drivers/gpu/drm/omapdrm/omap_irq.h b/drivers/gpu/drm/omapdrm/omap_irq.h index 9d5441468eca..02abb4ed9813 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.h +++ b/drivers/gpu/drm/omapdrm/omap_irq.h @@ -27,6 +27,7 @@ struct drm_device; struct omap_irq_wait; int omap_irq_enable_vblank(struct drm_crtc *crtc); +int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable); void omap_irq_disable_vblank(struct drm_crtc *crtc); void omap_drm_irq_uninstall(struct drm_device *dev); int omap_drm_irq_install(struct drm_device *dev); From patchwork Wed Apr 3 20:13:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 10885123 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1EC5F139A for ; Thu, 4 Apr 2019 07:18:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F170628901 for ; Thu, 4 Apr 2019 07:18:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5C9328992; Thu, 4 Apr 2019 07:18:49 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D9B5B28901 for ; Thu, 4 Apr 2019 07:18:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 860B66E9CC; Thu, 4 Apr 2019 07:18:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id BA7206E4F7 for ; Wed, 3 Apr 2019 20:13:44 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id 94CF82827FB From: Sebastian Reichel To: Sebastian Reichel , Tomi Valkeinen , Tony Lindgren , Pavel Machek , Laurent Pinchart Subject: [PATCHv6 4/4] drm/omap: add support for manually updated displays Date: Wed, 3 Apr 2019 22:13:26 +0200 Message-Id: <20190403201326.3127-5-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403201326.3127-1-sebastian.reichel@collabora.com> References: <20190403195413.djfrgzuj7povdksi@earth.universe> <20190403201326.3127-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 04 Apr 2019 07:17:55 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, "H. Nikolaus Schaller" , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Sebastian Reichel , linux-omap@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds the required infrastructure for manually updated displays, such as DSI command mode panels. While those panels often support partial updates we currently always do a full refresh. The display will be refreshed when something calls the dirty callback, such as libdrm's drmModeDirtyFB(). This is currently being done at least by the kernel console and Xorg (with modesetting driver) in their default configuration. Weston does not implement this and the fbdev backend does not work (display will not update). Weston's DRM backend uses double buffering and the page flip will also trigger a display refresh. Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_crtc.c | 114 ++++++++++++++++++++++++++-- drivers/gpu/drm/omapdrm/omap_crtc.h | 1 + drivers/gpu/drm/omapdrm/omap_fb.c | 19 +++++ 3 files changed, 129 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 68697820d189..b59065365c9e 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -32,6 +32,7 @@ struct omap_crtc_state { /* Shadow values for legacy userspace support. */ unsigned int rotation; unsigned int zpos; + bool manually_updated; }; #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) @@ -51,6 +52,7 @@ struct omap_crtc { bool pending; wait_queue_head_t pending_wait; struct drm_pending_vblank_event *event; + struct delayed_work update_work; void (*framedone_handler)(void *); void *framedone_handler_data; @@ -105,21 +107,18 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc) /* * Manager-ops, callbacks from output when they need to configure * the upstream part of the video pipe. - * - * Most of these we can ignore until we add support for command-mode - * panels.. for video-mode the crtc-helpers already do an adequate - * job of sequencing the setup of the video pipe in the proper order */ -/* we can probably ignore these until we support command-mode panels: */ static void omap_crtc_dss_start_update(struct omap_drm_private *priv, enum omap_channel channel) { + priv->dispc_ops->mgr_enable(priv->dispc, channel, true); } /* Called only from the encoder enable/disable and suspend/resume handlers. */ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) { + struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state); struct drm_device *dev = crtc->dev; struct omap_drm_private *priv = dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); @@ -131,6 +130,12 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) if (WARN_ON(omap_crtc->enabled == enable)) return; + if (omap_state->manually_updated) { + omap_irq_enable_framedone(crtc, enable); + omap_crtc->enabled = enable; + return; + } + if (omap_crtc->pipe->output->type == OMAP_DISPLAY_TYPE_HDMI) { priv->dispc_ops->mgr_enable(priv->dispc, channel, enable); omap_crtc->enabled = enable; @@ -352,6 +357,51 @@ void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus) wake_up(&omap_crtc->pending_wait); } +void omap_crtc_flush(struct drm_crtc *crtc) +{ + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state); + + if (!omap_state->manually_updated) + return; + + if (!delayed_work_pending(&omap_crtc->update_work)) + schedule_delayed_work(&omap_crtc->update_work, 0); +} + +static void omap_crtc_manual_display_update(struct work_struct *data) +{ + struct omap_crtc *omap_crtc = + container_of(data, struct omap_crtc, update_work.work); + struct drm_display_mode *mode = &omap_crtc->pipe->crtc->mode; + struct omap_dss_device *dssdev = omap_crtc->pipe->output->next; + struct drm_device *dev = omap_crtc->base.dev; + const struct omap_dss_driver *dssdrv; + int ret; + + if (!dssdev) { + dev_err_once(dev->dev, "missing display dssdev!"); + return; + } + + dssdrv = dssdev->driver; + if (!dssdrv || !dssdrv->update) { + dev_err_once(dev->dev, "missing or incorrect dssdrv!"); + return; + } + + if (dssdrv->sync) + dssdrv->sync(dssdev); + + ret = dssdrv->update(dssdev, 0, 0, mode->hdisplay, mode->vdisplay); + if (ret < 0) { + spin_lock_irq(&dev->event_lock); + omap_crtc->pending = false; + spin_unlock_irq(&dev->event_lock); + wake_up(&omap_crtc->pending_wait); + } +} + static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) { struct omap_drm_private *priv = crtc->dev->dev_private; @@ -401,12 +451,17 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc, { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state); int ret; DBG("%s", omap_crtc->name); priv->dispc_ops->runtime_get(priv->dispc); + /* manual updated display will not trigger vsync irq */ + if (omap_state->manually_updated) + return; + spin_lock_irq(&crtc->dev->event_lock); drm_crtc_vblank_on(crtc); ret = drm_crtc_vblank_get(crtc); @@ -421,6 +476,7 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc, { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct drm_device *dev = crtc->dev; DBG("%s", omap_crtc->name); @@ -431,6 +487,11 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc, } spin_unlock_irq(&crtc->dev->event_lock); + cancel_delayed_work(&omap_crtc->update_work); + + if (!omap_crtc_wait_pending(crtc)) + dev_warn(dev->dev, "manual display update did not finish!"); + drm_crtc_vblank_off(crtc); priv->dispc_ops->runtime_put(priv->dispc); @@ -501,6 +562,22 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) drm_display_mode_to_videomode(mode, &omap_crtc->vm); } +static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc) +{ + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_dss_device *display = omap_crtc->pipe->output->next; + + if (!display) + return false; + + if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { + DBG("detected manually updated display!"); + return true; + } + + return false; +} + static int omap_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -522,6 +599,9 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, /* Mirror new values for zpos and rotation in omap_crtc_state */ omap_crtc_state->zpos = pri_state->zpos; omap_crtc_state->rotation = pri_state->rotation; + + /* Check if this CRTC is for a manually updated display */ + omap_crtc_state->manually_updated = omap_crtc_is_manually_updated(crtc); } return 0; @@ -537,6 +617,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + struct omap_crtc_state *omap_crtc_state = to_omap_crtc_state(crtc->state); int ret; if (crtc->state->color_mgmt_changed) { @@ -561,6 +642,15 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, DBG("%s: GO", omap_crtc->name); + if (omap_crtc_state->manually_updated) { + /* send new image for page flips and modeset changes */ + spin_lock_irq(&crtc->dev->event_lock); + omap_crtc_flush(crtc); + omap_crtc_arm_event(crtc); + spin_unlock_irq(&crtc->dev->event_lock); + return; + } + ret = drm_crtc_vblank_get(crtc); WARN_ON(ret != 0); @@ -646,6 +736,7 @@ omap_crtc_duplicate_state(struct drm_crtc *crtc) state->zpos = current_state->zpos; state->rotation = current_state->rotation; + state->manually_updated = current_state->manually_updated; return &state->base; } @@ -722,6 +813,19 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->channel = channel; omap_crtc->name = channel_names[channel]; + /* + * We want to refresh manually updated displays from dirty callback, + * which is called quite often (e.g. for each drawn line). This will + * be used to do the display update asynchronously to avoid blocking + * the rendering process and merges multiple dirty calls into one + * update if they arrive very fast. We also call this function for + * atomic display updates (e.g. for page flips), which means we do + * not need extra locking. Atomic updates should be synchronous, but + * need to wait for the framedone interrupt anyways. + */ + INIT_DELAYED_WORK(&omap_crtc->update_work, + omap_crtc_manual_display_update); + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, &omap_crtc_funcs, NULL); if (ret < 0) { diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h index d33bbb7a4f90..2b518c74203e 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.h +++ b/drivers/gpu/drm/omapdrm/omap_crtc.h @@ -42,5 +42,6 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc); void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus); void omap_crtc_vblank_irq(struct drm_crtc *crtc); void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus); +void omap_crtc_flush(struct drm_crtc *crtc); #endif /* __OMAPDRM_CRTC_H__ */ diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 4f8eb9d08f99..b6f052f2a7e1 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -66,8 +66,27 @@ struct omap_framebuffer { struct mutex lock; }; +static int omap_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct drm_crtc *crtc; + + drm_modeset_lock_all(fb->dev); + + drm_for_each_crtc(crtc, fb->dev) + omap_crtc_flush(crtc); + + drm_modeset_unlock_all(fb->dev); + + return 0; +} + static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { .create_handle = drm_gem_fb_create_handle, + .dirty = omap_framebuffer_dirty, .destroy = drm_gem_fb_destroy, };