From patchwork Mon Mar 18 17:19:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 10858251 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 E7E5A1669 for ; Mon, 18 Mar 2019 17:20:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C44E922F3E for ; Mon, 18 Mar 2019 17:20:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B8C2B2911B; Mon, 18 Mar 2019 17:20:32 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 BA4CD22F3E for ; Mon, 18 Mar 2019 17:20:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 07C2F897B5; Mon, 18 Mar 2019 17:20:23 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by gabe.freedesktop.org (Postfix) with ESMTPS id 46D80897E0; Mon, 18 Mar 2019 17:20:21 +0000 (UTC) Received: by mail-wr1-x442.google.com with SMTP id w1so12040787wrp.2; Mon, 18 Mar 2019 10:20:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=x1/x3PsnMz6jhQyO2Pf/6Z4TFD/ROn+kUAhhs1PouPE=; b=r3GrviRaVa704rgfvwo7iSGb2uHMCjvCfv5iUaOHUL6p14aJzhtAldmunlXVKmDqvo QLuN0QWvOz+/dP8xpAhCk0TKHJqc0QBToddvwXguIoPgsSywCAgoV2F+GPwjSmOHNI9a +ukR/uuZCex9c5tS+AQ2R8lttyvfBg42tQS4feQ6A5rheI5ycugT5d+csnxWedHCyjnk NFWsrnbKnN9VhnucA4fLq0+Ff/rJZlxhAjKG5e9yspMfwmldlr14Ufpit71bRfHpRVig bfPynLYmj6sc3nYzq6E5x6ILSdnlU+8znYlcNhaszHCdS8HrP/PvDbU1mbhPpUsMGdbM pt/Q== X-Gm-Message-State: APjAAAWNcJkjtj/wLo10pvKeD2BMnsAhWKxq6u4vKoot9NUBnoUKkocL 7SVsltzKWAI6P6yJWzk7z+vmNLBE X-Google-Smtp-Source: APXvYqwL4YvYF4RuOgc+0x7YDJiaAaz7ixlvgwP++nV/6Tmg9j17kEFOwxCZs0a2gjsisvmtUL5RgQ== X-Received: by 2002:adf:f147:: with SMTP id y7mr5726288wro.102.1552929619727; Mon, 18 Mar 2019 10:20:19 -0700 (PDT) Received: from twisty.cin.medizin.uni-tuebingen.de ([2a01:c22:d43c:e500:e9fd:d3f1:412c:598a]) by smtp.gmail.com with ESMTPSA id d9sm21415814wrn.72.2019.03.18.10.20.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Mar 2019 10:20:18 -0700 (PDT) From: Mario Kleiner To: amd-gfx@lists.freedesktop.org Subject: [PATCH 1/4] drm/amd/display: Prevent vblank irq disable while VRR is active. Date: Mon, 18 Mar 2019 18:19:49 +0100 Message-Id: <20190318171952.24302-2-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190318171952.24302-1-mario.kleiner.de@gmail.com> References: <20190318171952.24302-1-mario.kleiner.de@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=x1/x3PsnMz6jhQyO2Pf/6Z4TFD/ROn+kUAhhs1PouPE=; b=AXYISfwG7wxTL6uIMRUgJgcEZKR4vTfxd4BpNKXthxXXnBc8ulPoc09+RaLlMTh9kC HF+6gawulXVfAJdM5I6e8XG7Ws1QItNWIiXrQXid+7PGvQ83sdMLOEVSu75eiPLJN6eM KizX0Lvs2WOY0VDkRYAKOZjJEV1BfEnYheC674xBhLiX4LDjusjCWVGPCvXuuwm3AhBy sc+wgbUkmLqZIVZEj4LQ573HIrYEIY0mXEaoEBXHZmRlwZz1TFcdRjdqDrgzTbo9UqT2 GIGdMOziwxQza1x0bvLpPXlQqC4tWb7CMLEVt8yGi1ryRzF47ZxPA25zGpfG9ygolrlu hgYQ== 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: nicholas.kazlauskas@amd.com, dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP During VRR mode we can not allow vblank irq dis-/enable transitions, as an enable after a disable can happen at an arbitrary time during the video refresh cycle, e.g., with a high likelyhood inside vblank front-porch. An enable during front-porch would cause vblank timestamp updates/calculations which are completely bogus, given the code can't know when the vblank will end as long as we are in front-porch with no page flip completed. Hold a permanent vblank reference on the crtc while in active VRR mode to prevent a vblank disable, and drop the reference again when switching back to fixed refresh rate non-VRR mode. Signed-off-by: Mario Kleiner --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a718ac2..c1c3815 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -251,6 +251,12 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, return NULL; } +static inline bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) +{ + return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || + dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; +} + static void dm_pflip_high_irq(void *interrupt_params) { struct amdgpu_crtc *amdgpu_crtc; @@ -4716,6 +4722,32 @@ static void update_freesync_state_on_stream( (int)vrr_params.state); } +static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, + struct dm_crtc_state *new_state) +{ + bool old_vrr_active = amdgpu_dm_vrr_active(old_state); + bool new_vrr_active = amdgpu_dm_vrr_active(new_state); + + if (!old_vrr_active && new_vrr_active) { + /* Transition VRR inactive -> active: + * While VRR is active, we must not disable vblank irq, as a + * reenable after disable would compute bogus vblank/pflip + * timestamps if it likely happened inside display front-porch. + */ + drm_crtc_vblank_get(new_state->base.crtc); + DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", + __func__, new_state->base.crtc->base.id); + } + else if (old_vrr_active && !new_vrr_active) { + /* Transition VRR active -> inactive: + * Allow vblank irq disable again for fixed refresh rate. + */ + drm_crtc_vblank_put(new_state->base.crtc); + DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", + __func__, new_state->base.crtc->base.id); + } +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_state *dc_state, struct drm_device *dev, @@ -4757,6 +4789,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, goto cleanup; } + /* Take care to hold extra vblank ref for a crtc in VRR mode */ + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, acrtc_state); + /* update planes when needed */ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { struct drm_crtc *crtc = new_plane_state->crtc; From patchwork Mon Mar 18 17:19:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 10858247 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 4BDB717EF for ; Mon, 18 Mar 2019 17:20:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2665D2939F for ; Mon, 18 Mar 2019 17:20:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A1C929065; Mon, 18 Mar 2019 17:20: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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 AD05928066 for ; Mon, 18 Mar 2019 17:20:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A7EBE897E0; Mon, 18 Mar 2019 17:20:29 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by gabe.freedesktop.org (Postfix) with ESMTPS id CB7B6897E7; Mon, 18 Mar 2019 17:20:27 +0000 (UTC) Received: by mail-wm1-x343.google.com with SMTP id t124so13645214wma.4; Mon, 18 Mar 2019 10:20:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GlX8dmNdsMj4BRk1A8r8WPXIkP0KMHtBn3L0X3o7PhM=; b=s2TXXa3/hUpm7MSGrS6thMwfWSrQa1jxDPpHaALH3nVjog3mlGKmwnYFz3dWlYsK7L 15MI/LaOndhlUTA1PtLXDSslxHqKJs7kwFPNwfT9zf6zyxkHKtSPJayVXO8JkMRk9uMo Si9T+i/0MIGM8MOYPrrtS2d9kMyQYt2Q+dCXSyCQet3tzJuQcxbzH+WfDSiseS+gHXNU JNRrBVzrQNXtCx96p9s0EegYy8fTPUd3bR1yzKwCwGGD9j0XVxgZ8SUbgonHnVrmxY8Z JbbyI57vrAyMrWIcebRhWtZe1SZA4bZmJtJfUxs98tldjxWGBvlk65MC3wIwtSL4vyQx 9AFw== X-Gm-Message-State: APjAAAXcHM5CYOoVrXQ89PFPVX5AMaA1GygOf3dtki4EzfFCqToPJbyV 16N2rbOZ8OdMlRnFu1ZjjGlgHHUU X-Google-Smtp-Source: APXvYqy/Pn5sfedjMQL7n4wE1cblMIc0yYpOfKi2f+puOPWVajle3mICzdTOr+6kpHbvASE9s2zpLA== X-Received: by 2002:a1c:f510:: with SMTP id t16mr11625438wmh.105.1552929626239; Mon, 18 Mar 2019 10:20:26 -0700 (PDT) Received: from twisty.cin.medizin.uni-tuebingen.de ([2a01:c22:d43c:e500:e9fd:d3f1:412c:598a]) by smtp.gmail.com with ESMTPSA id d9sm21415814wrn.72.2019.03.18.10.20.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Mar 2019 10:20:25 -0700 (PDT) From: Mario Kleiner To: amd-gfx@lists.freedesktop.org Subject: [PATCH 2/4] drm/amd/display: Rework vrr flip throttling for late vblank irq. Date: Mon, 18 Mar 2019 18:19:50 +0100 Message-Id: <20190318171952.24302-3-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190318171952.24302-1-mario.kleiner.de@gmail.com> References: <20190318171952.24302-1-mario.kleiner.de@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GlX8dmNdsMj4BRk1A8r8WPXIkP0KMHtBn3L0X3o7PhM=; b=nGVbPBGVc9m5qhWOkrcWQSjpPUk9EuVDUMRsW4FZQ12AwC73tcEWIFXvIiwvW++x4k Og76V4M8b/9TM0D/SFroP4xlOMcZHvhtU30fAMKlvBGbvihA5N5TQ6cjuvbGJddsRID6 eZyUNK7d/ZOJhQDPNePYBLb5AwIx2wylGLsL5O/24wZBCHzYSC3Hgz6kN6lPcv5bLTGg fDorRX9zP32b86WpkmTTnDMSr/jJ7kXY3aZ+9hBb14OPsCQY/4nZ2jSuE7P2nrmuIWCm cT7oP1yAgMoH4cVOnig/ihWOY0tsO5z2XUZwuoKUvnr0w9IvGCgWJ4rIHfWjPa+Irq4B AQ2g== 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: nicholas.kazlauskas@amd.com, dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP For throttling to work correctly, we always need a baseline vblank count last_flip_vblank that increments at start of front-porch. This is the case for drm_crtc_vblank_count() in non-VRR mode, where the vblank irq fires at start of front-porch and triggers DRM core vblank handling, but it is no longer the case in VRR mode, where core vblank handling is done later, after end of front-porch. Therefore drm_crtc_vblank_count() is no longer useful for this. We also can't use drm_crtc_accurate_vblank_count(), as that would screw up vblank timestamps in VRR mode when called in front-porch. To solve this, use the cooked hardware vblank counter returned by amdgpu_get_vblank_counter_kms() instead, as that one is cooked to always increment at start of front-porch, independent of when vblank related irq's fire. This patch allows vblank irq handling to happen anywhere within vblank of even after it, without a negative impact on flip throttling, so followup patches can shift the vblank core handling trigger point wherever they need it. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 889e443..add238f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -406,7 +406,7 @@ struct amdgpu_crtc { struct amdgpu_flip_work *pflip_works; enum amdgpu_flip_status pflip_status; int deferred_flip_completion; - u64 last_flip_vblank; + u32 last_flip_vblank; /* pll sharing */ struct amdgpu_atom_ss ss; bool ss_enabled; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c1c3815..85e4f87 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -286,7 +286,7 @@ static void dm_pflip_high_irq(void *interrupt_params) } /* Update to correct count(s) if racing with vblank irq */ - amdgpu_crtc->last_flip_vblank = drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); + drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); /* wake up userspace */ if (amdgpu_crtc->event) { @@ -298,6 +298,14 @@ static void dm_pflip_high_irq(void *interrupt_params) } else WARN_ON(1); + /* Keep track of vblank of this flip for flip throttling. We use the + * cooked hw counter, as that one incremented at start of this vblank + * of pageflip completion, so last_flip_vblank is the forbidden count + * for queueing new pageflips if vsync + VRR is enabled. + */ + amdgpu_crtc->last_flip_vblank = amdgpu_get_vblank_counter_kms(adev->ddev, + amdgpu_crtc->crtc_id); + amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; spin_unlock_irqrestore(&adev->ddev->event_lock, flags); @@ -4769,9 +4777,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, unsigned long flags; struct amdgpu_bo *abo; uint64_t tiling_flags; - uint32_t target, target_vblank; - uint64_t last_flip_vblank; - bool vrr_active = acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE; + uint32_t target_vblank, last_flip_vblank; + bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); bool pflip_present = false; struct { @@ -4918,7 +4925,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * clients using the GLX_OML_sync_control extension or * DRI3/Present extension with defined target_msc. */ - last_flip_vblank = drm_crtc_vblank_count(pcrtc); + last_flip_vblank = amdgpu_get_vblank_counter_kms(dm->ddev, acrtc_attach->crtc_id); } else { /* For variable refresh rate mode only: @@ -4934,11 +4941,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); } - target = (uint32_t)last_flip_vblank + wait_for_vblank; - - /* Prepare wait for target vblank early - before the fence-waits */ - target_vblank = target - (uint32_t)drm_crtc_vblank_count(pcrtc) + - amdgpu_get_vblank_counter_kms(pcrtc->dev, acrtc_attach->crtc_id); + target_vblank = last_flip_vblank + wait_for_vblank; /* * Wait until we're out of the vertical blank period before the one From patchwork Mon Mar 18 17:19:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 10858253 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 DD29F139A for ; Mon, 18 Mar 2019 17:20:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B987928066 for ; Mon, 18 Mar 2019 17:20:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD52A2900B; Mon, 18 Mar 2019 17:20:35 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 BD3B52907B for ; Mon, 18 Mar 2019 17:20:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 26F6A8984D; Mon, 18 Mar 2019 17:20:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by gabe.freedesktop.org (Postfix) with ESMTPS id 684E589803; Mon, 18 Mar 2019 17:20:31 +0000 (UTC) Received: by mail-wm1-x342.google.com with SMTP id a188so13643666wmf.3; Mon, 18 Mar 2019 10:20:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8a0qxznz3dXZT6YME9RGUMaIcxHYQ32ORD9TMZ+R4II=; b=ZNZguUVgmQeETsQFSDi7NRKa3ydvXFFaet8x6IDT14GW+Xe6zD7oU1ooADSOSZ/A1+ uWxl6bsV7iqT3iVSnx0PJpWoSPNvl2AyZwiWUO/t7ftqK7CMAVKMtNM7lGIcHJo1njmB iuSAssZ27I3tBBD6i7fohu0GCTRR1p1CyActXc3pSVEPazolZb7A8R6yTexiWB143vWT 2b/8J407HzDhGjYcQGLjh4+OWyWVBYl5BftUIRfxmjmHS0yjuAd+aLb/mk9xdVYZXYbY 0ixY8bE5QEscM1Dkj6jf1a05uKzOnktNdpuTxqxBK6jQLjS2kQxBtHxh6k7ciayPGY8A ElqA== X-Gm-Message-State: APjAAAUWO1nnFtUc11glel/AE37dImE/xn2Px+SueVFeShG63AD5yRl7 hhDbYmiF3M+Bb7+79zpIdD3B8p46 X-Google-Smtp-Source: APXvYqw1pohJforKvAJTIbbynwAxhd5bDhH1clarXfhvBV2Cg+ZXYOuDrMAwWcbZJuPOZoG5AsEXpQ== X-Received: by 2002:a7b:cc19:: with SMTP id f25mr3523wmh.8.1552929629274; Mon, 18 Mar 2019 10:20:29 -0700 (PDT) Received: from twisty.cin.medizin.uni-tuebingen.de ([2a01:c22:d43c:e500:e9fd:d3f1:412c:598a]) by smtp.gmail.com with ESMTPSA id d9sm21415814wrn.72.2019.03.18.10.20.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Mar 2019 10:20:28 -0700 (PDT) From: Mario Kleiner To: amd-gfx@lists.freedesktop.org Subject: [PATCH 3/4] drm/amd/display: In VRR mode, do DRM core vblank handling at end of vblank. Date: Mon, 18 Mar 2019 18:19:51 +0100 Message-Id: <20190318171952.24302-4-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190318171952.24302-1-mario.kleiner.de@gmail.com> References: <20190318171952.24302-1-mario.kleiner.de@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8a0qxznz3dXZT6YME9RGUMaIcxHYQ32ORD9TMZ+R4II=; b=OLSST661lxWloM+SLBu3xvAQncLgbPy9SNu35ufHoTgeMGrW5H79vsEVIGzvnSj9sl xpg7YjsGjQa15kPTuIyB8OWxwDhQc9KoheGs+eYJxhdBzFH/A9OxNzw3rpDr6RwEi2BF aDXSAn4s4HiFTFU0pBGtk9wC2/K87PN7i9idMtl6ycFgtIQIdndK9kdfHXYssXoerYec IDluRzc/KmprmNEkEHs9YQPRq/ElIs8dwTMWGLy41bvE279DbjxEHW62XXyO8UZjckGN g4mETbiSKMuhOtcckbPmgssOwM2BUT2Nl88SMwSQg2VDdNYREPJX9qq3eQC++lzi9vPV XdEg== 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: nicholas.kazlauskas@amd.com, dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP In VRR mode, proper vblank/pageflip timestamps can only be computed after the display scanout position has left front-porch. Therefore delay calls to drm_crtc_handle_vblank(), and thereby calls to drm_update_vblank_count() and pageflip event delivery, to after the end of front-porch when in VRR mode. We add a new vupdate irq, which triggers at the end of the vupdate interval, ie. at the end of vblank, and calls the core vblank handler function. The new irq handler is not executed in standard non-VRR mode, so vblank handling for fixed refresh rate mode is identical to the past implementation. Signed-off-by: Mario Kleiner Acked-by: Harry Wentland --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 129 ++++++++++++++++++++- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 ++++ .../amd/display/dc/irq/dce110/irq_service_dce110.c | 7 +- .../amd/display/dc/irq/dce120/irq_service_dce120.c | 7 +- .../amd/display/dc/irq/dce80/irq_service_dce80.c | 6 +- .../amd/display/dc/irq/dcn10/irq_service_dcn10.c | 40 +++++-- 8 files changed, 205 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index f88761a..64167dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -827,6 +827,7 @@ struct amdgpu_device { /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ struct work_struct hotplug_work; struct amdgpu_irq_src crtc_irq; + struct amdgpu_irq_src vupdate_irq; struct amdgpu_irq_src pageflip_irq; struct amdgpu_irq_src hpd_irq; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 85e4f87..555d9e9f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -315,6 +315,32 @@ static void dm_pflip_high_irq(void *interrupt_params) drm_crtc_vblank_put(&amdgpu_crtc->base); } +static void dm_vupdate_high_irq(void *interrupt_params) +{ + struct common_irq_params *irq_params = interrupt_params; + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_crtc *acrtc; + struct dm_crtc_state *acrtc_state; + + acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); + + if (acrtc) { + acrtc_state = to_dm_crtc_state(acrtc->base.state); + + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, + amdgpu_dm_vrr_active(acrtc_state)); + + /* Core vblank handling is done here after end of front-porch in + * vrr mode, as vblank timestamping will give valid results + * while now done after front-porch. This will also deliver + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ + if (amdgpu_dm_vrr_active(acrtc_state)) + drm_crtc_handle_vblank(&acrtc->base); + } +} + static void dm_crtc_high_irq(void *interrupt_params) { struct common_irq_params *irq_params = interrupt_params; @@ -325,11 +351,24 @@ static void dm_crtc_high_irq(void *interrupt_params) acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); if (acrtc) { - drm_crtc_handle_vblank(&acrtc->base); - amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); - acrtc_state = to_dm_crtc_state(acrtc->base.state); + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, + amdgpu_dm_vrr_active(acrtc_state)); + + /* Core vblank handling at start of front-porch is only possible + * in non-vrr mode, as only there vblank timestamping will give + * valid results while done in front-porch. Otherwise defer it + * to dm_vupdate_high_irq after end of front-porch. + */ + if (!amdgpu_dm_vrr_active(acrtc_state)) + drm_crtc_handle_vblank(&acrtc->base); + + /* Following stuff must happen at start of vblank, for crc + * computation and below-the-range btr support in vrr mode. + */ + amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); + if (acrtc_state->stream && acrtc_state->vrr_params.supported && acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { @@ -1447,6 +1486,27 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) dm_crtc_high_irq, c_irq_params); } + /* Use VUPDATE interrupt */ + for (i = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT; i <= VISLANDS30_IV_SRCID_D6_V_UPDATE_INT; i+=2) { + r = amdgpu_irq_add_id(adev, client_id, i, &adev->vupdate_irq); + if (r) { + DRM_ERROR("Failed to add vupdate irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params); + } + /* Use GRPH_PFLIP interrupt */ for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i <= VISLANDS30_IV_SRCID_D6_GRPH_PFLIP; i += 2) { @@ -1532,6 +1592,34 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) dm_crtc_high_irq, c_irq_params); } + /* Use VUPDATE_NO_LOCK interrupt on DCN, which seems to correspond to + * the regular VUPDATE interrupt on DCE. We want DC_IRQ_SOURCE_VUPDATEx + * to trigger at end of each vblank, regardless of state of the lock, + * matching DCE behaviour. + */ + for (i = DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT; + i <= DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT + adev->mode_info.num_crtc - 1; + i++) { + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->vupdate_irq); + + if (r) { + DRM_ERROR("Failed to add vupdate irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params); + } + /* Use GRPH_PFLIP interrupt */ for (i = DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT; i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + adev->mode_info.num_crtc - 1; @@ -3226,12 +3314,42 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) return &state->base; } +static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) +{ + enum dc_irq_source irq_source; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + struct amdgpu_device *adev = crtc->dev->dev_private; + int rc; + + irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst; + + rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; + + DRM_DEBUG_DRIVER("%s: crtc %d - vupdate irq %sabling: r=%d\n", + __func__, acrtc->crtc_id, enable ? "en" : "dis", rc); + return rc; +} static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) { enum dc_irq_source irq_source; struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_device *adev = crtc->dev->dev_private; + struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); + int rc = 0; + + if (enable) { + /* vblank irq on -> Only need vupdate irq in vrr mode */ + if (amdgpu_dm_vrr_active(acrtc_state)) + rc = dm_set_vupdate_irq(crtc, true); + } + else { + /* vblank irq off -> vupdate irq off */ + rc = dm_set_vupdate_irq(crtc, false); + } + + if (rc) + return rc; irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; @@ -4741,7 +4859,11 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, * While VRR is active, we must not disable vblank irq, as a * reenable after disable would compute bogus vblank/pflip * timestamps if it likely happened inside display front-porch. + * + * We also need vupdate irq for the actual core vblank handling + * at end of vblank. */ + dm_set_vupdate_irq(new_state->base.crtc, true); drm_crtc_vblank_get(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", __func__, new_state->base.crtc->base.id); @@ -4750,6 +4872,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, /* Transition VRR active -> inactive: * Allow vblank irq disable again for fixed refresh rate. */ + dm_set_vupdate_irq(new_state->base.crtc, false); drm_crtc_vblank_put(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", __func__, new_state->base.crtc->base.id); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index f741ea3..0b35f84 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -182,6 +182,15 @@ struct amdgpu_display_manager { struct common_irq_params vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1]; + /** + * @vupdate_params: + * + * Vertical update IRQ parameters, passed to registered handlers when + * triggered. + */ + struct common_irq_params + vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1]; + spinlock_t irq_handler_list_table_lock; struct backlight_device *backlight_dev; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index cd10f77..fee7837 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -674,11 +674,30 @@ static int amdgpu_dm_set_crtc_irq_state(struct amdgpu_device *adev, __func__); } +static int amdgpu_dm_set_vupdate_irq_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned crtc_id, + enum amdgpu_interrupt_state state) +{ + return dm_irq_state( + adev, + source, + crtc_id, + state, + IRQ_TYPE_VUPDATE, + __func__); +} + static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = { .set = amdgpu_dm_set_crtc_irq_state, .process = amdgpu_dm_irq_handler, }; +static const struct amdgpu_irq_src_funcs dm_vupdate_irq_funcs = { + .set = amdgpu_dm_set_vupdate_irq_state, + .process = amdgpu_dm_irq_handler, +}; + static const struct amdgpu_irq_src_funcs dm_pageflip_irq_funcs = { .set = amdgpu_dm_set_pflip_irq_state, .process = amdgpu_dm_irq_handler, @@ -695,6 +714,9 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) adev->crtc_irq.num_types = adev->mode_info.num_crtc; adev->crtc_irq.funcs = &dm_crtc_irq_funcs; + adev->vupdate_irq.num_types = adev->mode_info.num_crtc; + adev->vupdate_irq.funcs = &dm_vupdate_irq_funcs; + adev->pageflip_irq.num_types = adev->mode_info.num_crtc; adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index afe0876..86987f5 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -81,6 +81,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ @@ -137,7 +142,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ .ack_value =\ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c index 1ea7256..750ba0a 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c @@ -84,6 +84,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define BASE_INNER(seg) \ DCE_BASE__INST0_SEG ## seg @@ -140,7 +145,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { IRQ_REG_ENTRY(CRTC, reg_num,\ CRTC_INTERRUPT_CONTROL, CRTC_V_UPDATE_INT_MSK,\ CRTC_V_UPDATE_INT_STATUS, CRTC_V_UPDATE_INT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c index 8a2066c..de218fe 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c @@ -84,6 +84,10 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_INVALID + reg_num] = {\ @@ -142,7 +146,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ .ack_value =\ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index e04ae49..10ac6de 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -56,6 +56,18 @@ enum dc_irq_source to_dal_irq_source_dcn10( return DC_IRQ_SOURCE_VBLANK5; case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE1; + case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE2; + case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE3; + case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE4; + case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE5; + case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE6; case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT: return DC_IRQ_SOURCE_PFLIP1; case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT: @@ -153,6 +165,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define BASE_INNER(seg) \ DCE_BASE__INST0_SEG ## seg @@ -203,12 +220,15 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .funcs = &pflip_irq_info_funcs\ } -#define vupdate_int_entry(reg_num)\ +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ IRQ_REG_ENTRY(OTG, reg_num,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ + .funcs = &vupdate_no_lock_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ @@ -315,12 +335,12 @@ irq_source_info_dcn10[DAL_IRQ_SOURCES_NUMBER] = { dc_underflow_int_entry(6), [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), - vupdate_int_entry(0), - vupdate_int_entry(1), - vupdate_int_entry(2), - vupdate_int_entry(3), - vupdate_int_entry(4), - vupdate_int_entry(5), + vupdate_no_lock_int_entry(0), + vupdate_no_lock_int_entry(1), + vupdate_no_lock_int_entry(2), + vupdate_no_lock_int_entry(3), + vupdate_no_lock_int_entry(4), + vupdate_no_lock_int_entry(5), vblank_int_entry(0), vblank_int_entry(1), vblank_int_entry(2), From patchwork Mon Mar 18 17:19:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 10858255 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 C968014DE for ; Mon, 18 Mar 2019 17:20:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A73A829010 for ; Mon, 18 Mar 2019 17:20:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B6F4291F8; Mon, 18 Mar 2019 17:20:38 +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,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 2B1A729010 for ; Mon, 18 Mar 2019 17:20:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8C589898ED; Mon, 18 Mar 2019 17:20:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by gabe.freedesktop.org (Postfix) with ESMTPS id CB04389803; Mon, 18 Mar 2019 17:20:32 +0000 (UTC) Received: by mail-wm1-x32e.google.com with SMTP id z11so5369114wmi.0; Mon, 18 Mar 2019 10:20:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=v6nByaDUJ8aiiAPVC/Biy+92/0ZMD41E362Ae4SxFxs=; b=sOgmdEPhhlFAd8Txog6EdVqgEx+nm2XU3VoxUZsbPbxZWSg1OyruSjzUKM3MnzMXib CDKUV1iSy6itZrmmb2IXlxLUipE16ocxdWjYwvwont4DHqI3AhmmHrJpn7t4CMfQyOtn ZP8NmdcQPrYH3HxwKf2+OHyjVIwBZN3BkQ32aplpP5VBW8FfEWnAMgTSNLEz5r38gtYj H0vn1RnwvkB5KCz5BsMYxURnM/AwSMK+XOLtF6EWgdRX13BKZD4FTnmLY0S+ZsfQptOu 8DBlmoTGXbcEhQiAzv/27QgMhiF2oAUZHxA3RaeygE9HhUVgbuv+02r1M9C4grb1gzLx wUjA== X-Gm-Message-State: APjAAAWep7GzzRC7EpjcZVx3E1yVqvthe9UXvkJ7YmplHGBt1dnHFjyT aSSbXwmHpgpUl3oPRniK/ITyVsf0 X-Google-Smtp-Source: APXvYqy/VxVuRiIpByvoy+5Mjfi3juNjv0+Puty+rHtfOEjXCun593HHJdg1nC4vspuHRAZRcW4gqw== X-Received: by 2002:a7b:cb45:: with SMTP id v5mr11372896wmj.61.1552929631270; Mon, 18 Mar 2019 10:20:31 -0700 (PDT) Received: from twisty.cin.medizin.uni-tuebingen.de ([2a01:c22:d43c:e500:e9fd:d3f1:412c:598a]) by smtp.gmail.com with ESMTPSA id d9sm21415814wrn.72.2019.03.18.10.20.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Mar 2019 10:20:30 -0700 (PDT) From: Mario Kleiner To: amd-gfx@lists.freedesktop.org Subject: [PATCH 4/4] drm/amd/display: Make pageflip event delivery compatible with VRR. Date: Mon, 18 Mar 2019 18:19:52 +0100 Message-Id: <20190318171952.24302-5-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190318171952.24302-1-mario.kleiner.de@gmail.com> References: <20190318171952.24302-1-mario.kleiner.de@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=v6nByaDUJ8aiiAPVC/Biy+92/0ZMD41E362Ae4SxFxs=; b=MuWks0ayGCuY3yyWd2BHAyzA0o5WswYgcBORiDP9YQMXWE0n7iAJuLuCb22dVM6yqF aZyIOF8B/pKJL+bjAcMhDXUVGDKyb9bZOQy9tdNSldVxzyrPVSCH8/MxDg0HHALQDczp FDoJEOhOuus2prghRnVZ8+NherqFWWx9yupBHwCsK3AyzcZqERurMlHs1uKHCu56obIa GIJisawUL/61YtTRF0L0VgmjdjrEUYRzlN7Q2USKoAr7xc10RhZNiVMz3O8X/1mTagN9 qnRy8M1Cr/lSAEZPUZIEye31FBmUXKiPig/vCjgdr4kMYZPa/KervUJyHF6sWouoBwPX 4nPA== 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: nicholas.kazlauskas@amd.com, dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP We want vblank counts and timestamps of flip completion as sent in pageflip completion events to be consistent with the vblank count and timestamp of the vblank of flip completion, like in non VRR mode. In VRR mode, drm_update_vblank_count() - and thereby vblank count and timestamp updates - must be delayed until after the end of front-porch of each vblank, as it is only safe to calculate vblank timestamps outside of the front-porch, when we actually know when the vblank will end or has ended. The function drm_update_vblank_count() which updates timestamps and counts gets called by drm_crtc_accurate_vblank_count() or by drm_crtc_handle_vblank(). Therefore we must make sure that pageflip events for a completed flip are only sent out after drm_crtc_accurate_vblank_count() or drm_crtc_handle_vblank() is executed, after end of front-porch for the vblank of flip completion. Two cases: a) Pageflip irq handler executes inside front-porch: In this case we must defer sending pageflip events until drm_crtc_handle_vblank() executes after end of front-porch, and thereby calculates proper vblank count and timestamp. Iow. the pflip irq handler must just arm a pageflip event to be sent out by drm_crtc_handle_vblank() later on. b) Pageflip irq handler executes after end of front-porch, e.g., after flip completion in back-porch or due to a massively delayed handler invocation into the active scanout of the new frame. In this case we can call drm_crtc_accurate_vblank_count() to safely force calculation of a proper vblank count and timestamp, and must send the pageflip completion event ourselves from the pageflip irq handler. This is the same behaviour as needed for standard fixed refresh rate mode. To decide from within pageflip handler if we are in case a) or b), we check the current scanout position against the boundary of front-porch. In non-VRR mode we just do what we did in the past. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 68 ++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 555d9e9f..499284d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -263,6 +263,10 @@ static void dm_pflip_high_irq(void *interrupt_params) struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; unsigned long flags; + struct drm_pending_vblank_event *e; + struct dm_crtc_state *acrtc_state; + uint32_t vpos, hpos, v_blank_start, v_blank_end; + bool vrr_active; amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP); @@ -285,18 +289,57 @@ static void dm_pflip_high_irq(void *interrupt_params) return; } - /* Update to correct count(s) if racing with vblank irq */ - drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); + /* page flip completed. */ + e = amdgpu_crtc->event; + amdgpu_crtc->event = NULL; - /* wake up userspace */ - if (amdgpu_crtc->event) { - drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event); + if (!e) + WARN_ON(1); - /* page flip completed. clean up */ - amdgpu_crtc->event = NULL; + acrtc_state = to_dm_crtc_state(amdgpu_crtc->base.state); + vrr_active = amdgpu_dm_vrr_active(acrtc_state); + + /* Fixed refresh rate, or VRR scanout position outside front-porch? */ + if (!vrr_active || + !dc_stream_get_scanoutpos(acrtc_state->stream, &v_blank_start, + &v_blank_end, &hpos, &vpos) || + (vpos < v_blank_start)) { + /* Update to correct count and vblank timestamp if racing with + * vblank irq. This also updates to the correct vblank timestamp + * even in VRR mode, as scanout is past the front-porch atm. + */ + drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); - } else - WARN_ON(1); + /* Wake up userspace by sending the pageflip event with proper + * count and timestamp of vblank of flip completion. + */ + if (e) { + drm_crtc_send_vblank_event(&amdgpu_crtc->base, e); + + /* Event sent, so done with vblank for this flip */ + drm_crtc_vblank_put(&amdgpu_crtc->base); + } + } else if (e) { + /* VRR active and inside front-porch: vblank count and + * timestamp for pageflip event will only be up to date after + * drm_crtc_handle_vblank() has been executed from late vblank + * irq handler after start of back-porch (vline 0). We queue the + * pageflip event for send-out by drm_crtc_handle_vblank() with + * updated timestamp and count, once it runs after us. + * + * We need to open-code this instead of using the helper + * drm_crtc_arm_vblank_event(), as that helper would + * call drm_crtc_accurate_vblank_count(), which we must + * not call in VRR mode while we are in front-porch! + */ + + /* sequence will be replaced by real count during send-out. */ + e->sequence = drm_crtc_vblank_count(&amdgpu_crtc->base); + e->pipe = amdgpu_crtc->crtc_id; + + list_add_tail(&e->base.link, &adev->ddev->vblank_event_list); + e = NULL; + } /* Keep track of vblank of this flip for flip throttling. We use the * cooked hw counter, as that one incremented at start of this vblank @@ -309,10 +352,9 @@ static void dm_pflip_high_irq(void *interrupt_params) amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; spin_unlock_irqrestore(&adev->ddev->event_lock, flags); - DRM_DEBUG_DRIVER("%s - crtc :%d[%p], pflip_stat:AMDGPU_FLIP_NONE\n", - __func__, amdgpu_crtc->crtc_id, amdgpu_crtc); - - drm_crtc_vblank_put(&amdgpu_crtc->base); + DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_NONE, vrr[%d]-fp %d\n", + amdgpu_crtc->crtc_id, amdgpu_crtc, + vrr_active, (int) !e); } static void dm_vupdate_high_irq(void *interrupt_params)