From patchwork Tue Jul 10 10:41:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Russell King (Oracle)" X-Patchwork-Id: 10518943 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 029F46032A for ; Wed, 11 Jul 2018 07:21:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DEB7C2621E for ; Wed, 11 Jul 2018 07:21:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D2F4228E6F; Wed, 11 Jul 2018 07:21:44 +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 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 D694428B1B for ; Wed, 11 Jul 2018 07:21:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 526236EBE7; Wed, 11 Jul 2018 07:17:25 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:3201:214:fdff:fe10:1be6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5B7A06E90D for ; Tue, 10 Jul 2018 10:42:01 +0000 (UTC) Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:48162 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.90_1) (envelope-from ) id 1fcq5h-0002qD-0n; Tue, 10 Jul 2018 11:41:53 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1fcq5g-0004Hn-8j; Tue, 10 Jul 2018 11:41:52 +0100 In-Reply-To: <20180710104027.GJ17271@n2100.armlinux.org.uk> References: <20180710104027.GJ17271@n2100.armlinux.org.uk> From: Russell King To: dri-devel@lists.freedesktop.org Subject: [PATCH 08/20] drm/armada: handle atomic modeset crtc events MIME-Version: 1.0 Content-Disposition: inline Message-Id: Date: Tue, 10 Jul 2018 11:41:52 +0100 X-Mailman-Approved-At: Wed, 11 Jul 2018 07:16:21 +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: David Airlie Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Prepare handling for atomic modeset CRTC events. Currently, using the transition helpers, CRTC events do not exist, but once we switch to proper atomic modeset, they have to be handled. We queue an event for the next vblank in two places: - armada_drm_crtc_atomic_flush() provided we aren't doing an atomic modeset. - armada_drm_crtc_commit() if we are committing a modeset. This ensures that the event is sent at the correct time (after all updates have been written to the hardware and after the following vblank.) Signed-off-by: Russell King --- drivers/gpu/drm/armada/armada_crtc.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/armada/armada_crtc.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 80d34a4b7d41..a0c67ec892cf 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -232,6 +232,19 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc) armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); } +static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc) +{ + struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); + struct drm_pending_vblank_event *event; + + /* If we have an event, we need vblank events enabled */ + event = xchg(&crtc->state->event, NULL); + if (event) { + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + dcrtc->event = event; + } +} + /* The mode_config.mutex will be held for this call */ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms) { @@ -294,6 +307,8 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc) dcrtc->dpms = DRM_MODE_DPMS_ON; armada_drm_crtc_update(dcrtc); drm_crtc_vblank_on(crtc); + + armada_drm_crtc_queue_state_event(crtc); } /* The mode_config.mutex will be held for this call */ @@ -337,6 +352,7 @@ static void armada_drm_crtc_enable_irq(struct armada_crtc *dcrtc, u32 mask) static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) { + struct drm_pending_vblank_event *event; void __iomem *base = dcrtc->base; struct drm_plane *ovl_plane; @@ -383,6 +399,16 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) if (stat & GRA_FRAME_IRQ) armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); + + if (stat & VSYNC_IRQ) { + event = xchg(&dcrtc->event, NULL); + if (event) { + spin_lock(&dcrtc->crtc.dev->event_lock); + drm_crtc_send_vblank_event(&dcrtc->crtc, event); + spin_unlock(&dcrtc->crtc.dev->event_lock); + drm_crtc_vblank_put(&dcrtc->crtc); + } + } } static irqreturn_t armada_drm_irq(int irq, void *arg) @@ -554,6 +580,13 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc, spin_lock_irqsave(&dcrtc->irq_lock, flags); armada_drm_crtc_update_regs(dcrtc, dcrtc->regs); spin_unlock_irqrestore(&dcrtc->irq_lock, flags); + + /* + * If we aren't doing a full modeset, then we need to queue + * the event here. + */ + if (!drm_atomic_crtc_needs_modeset(crtc->state)) + armada_drm_crtc_queue_state_event(crtc); } static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index 775c01c52982..8b1de877cb02 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -90,6 +90,7 @@ struct armada_crtc { spinlock_t irq_lock; uint32_t irq_ena; + struct drm_pending_vblank_event *event; struct armada_regs atomic_regs[32]; struct armada_regs *regs; unsigned int regs_idx;