From patchwork Fri Jun 29 11:17:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 10496233 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 D8B856022E for ; Fri, 29 Jun 2018 11:17:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CAA35298A6 for ; Fri, 29 Jun 2018 11:17:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF32E298A8; Fri, 29 Jun 2018 11:17:31 +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 5825A298A6 for ; Fri, 29 Jun 2018 11:17:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0A5256EE04; Fri, 29 Jun 2018 11:17:28 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by gabe.freedesktop.org (Postfix) with ESMTP id 026EC6EE04 for ; Fri, 29 Jun 2018 11:17:27 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 6831720DB4; Fri, 29 Jun 2018 13:17:25 +0200 (CEST) Received: from localhost.localdomain (AAubervilliers-681-1-87-188.w90-88.abo.wanadoo.fr [90.88.29.188]) by mail.bootlin.com (Postfix) with ESMTPSA id 27E202082B; Fri, 29 Jun 2018 13:17:25 +0200 (CEST) From: Boris Brezillon To: David Airlie , Daniel Vetter , dri-devel@lists.freedesktop.org Subject: [PATCH v2 4/8] drm/crtc: Add a generic infrastructure to fake VBLANK events Date: Fri, 29 Jun 2018 13:17:17 +0200 Message-Id: <20180629111722.20299-5-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180629111722.20299-1-boris.brezillon@bootlin.com> References: <20180629111722.20299-1-boris.brezillon@bootlin.com> 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: Liviu Dudau , Boris Brezillon MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP In some cases CRTCs are active but are not able to generating events, at least not at every frame at it's expected to. This is typically the case when the CRTC is feeding a writeback connector that has no job queued. In this situation the CRTC is usually stopped until a new job is queued, and this can lead to timeouts when part of the pipeline is updated but no new jobs are queued to the active writeback connector. In order to solve that, we add a ->no_vblank flag to drm_crtc_state and ask the CRTC drivers to set it to true when they know they're not able to generate VBLANK events. The core drm_atomic_helper_fake_vblank() helper can then be used to fake VBLANKs at commit time. Signed-off-by: Boris Brezillon Reviewed-by: Liviu Dudau Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 40 +++++++++++++++++++++++++++++++++++++ include/drm/drm_atomic_helper.h | 1 + include/drm/drm_crtc.h | 15 ++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 69063bcf2334..ca586993c2a2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2051,6 +2051,46 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) } EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); +/** + * drm_atomic_helper_fake_vblank - fake VBLANK events if needed + * @old_state: atomic state object with old state structures + * + * This function walks all CRTCs and fake VBLANK events on those with + * &drm_crtc_state.no_vblank set to true and &drm_crtc_state.event != NULL. + * The primary use of this function is writeback connectors working in oneshot + * mode and faking VBLANK events. In this case they only fake the VBLANK event + * when a job is queued, and any change to the pipeline that does not touch the + * connector is leading to timeouts when calling + * drm_atomic_helper_wait_for_vblanks() or + * drm_atomic_helper_wait_for_flip_done(). + * + * This is part of the atomic helper support for nonblocking commits, see + * drm_atomic_helper_setup_commit() for an overview. + */ +void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state) +{ + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + struct drm_crtc *crtc; + int i; + + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, + new_crtc_state, i) { + unsigned long flags; + + if (!new_crtc_state->no_vblank && !old_crtc_state->no_vblank) + continue; + + spin_lock_irqsave(&old_state->dev->event_lock, flags); + if (new_crtc_state->event) { + drm_crtc_send_vblank_event(crtc, + new_crtc_state->event); + new_crtc_state->event = NULL; + } + spin_unlock_irqrestore(&old_state->dev->event_lock, flags); + } +} +EXPORT_SYMBOL(drm_atomic_helper_fake_vblank); + /** * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit * @old_state: atomic state object with old state structures diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 26aaba58d6ce..99e2a5297c69 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -100,6 +100,7 @@ int __must_check drm_atomic_helper_swap_state(struct drm_atomic_state *state, int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, bool nonblock); void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state); +void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state); void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state); void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 23eddbccab10..7435dc66c08a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -87,6 +87,20 @@ struct drm_plane_helper_funcs; * @zpos_changed: zpos values of planes on this crtc have been updated * @color_mgmt_changed: color management properties have changed (degamma or * gamma LUT or CSC matrix) + * @no_vblank: reflects the ability of a CRTC to send VBLANK events. This state + * usually depends on the pipeline configuration, and the main usuage is + * CRTCs feeding a writeback connector operating in oneshot mode. In this + * case the VBLANK event is only generated when a job is queued to the + * writeback connector, and we want the core to fake VBLANK events when + * this part of the pipeline hasn't changed but others had or when the + * CRTC and connectors are disabled. + * __drm_atomic_helper_crtc_duplicate_state() will the value from the + * current state, the CRTC driver is then responsible for updating this + * field when needed. + * Note that, even when no_blank is set to true, the CRTC driver can still + * steal the &drm_crtc_state.event object and send the event on its own. + * That's usually what happens when a job is queued to the writeback + * connector. * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders @@ -118,6 +132,7 @@ struct drm_crtc_state { bool connectors_changed : 1; bool zpos_changed : 1; bool color_mgmt_changed : 1; + bool no_vblank : 1; /* attached planes bitmask: * WARNING: transitional helpers do not maintain plane_mask so