From patchwork Sat Sep 17 12:25:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 9337079 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 5E5AC6077F for ; Sat, 17 Sep 2016 12:26:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4ECD1297A5 for ; Sat, 17 Sep 2016 12:26:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 426D6297B8; Sat, 17 Sep 2016 12:26:30 +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=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID 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 ED2EE297A5 for ; Sat, 17 Sep 2016 12:26:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2095089B97; Sat, 17 Sep 2016 12:26:26 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x241.google.com (mail-wm0-x241.google.com [IPv6:2a00:1450:400c:c09::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7ADF46E386 for ; Sat, 17 Sep 2016 12:26:17 +0000 (UTC) Received: by mail-wm0-x241.google.com with SMTP id w84so387182wmg.0 for ; Sat, 17 Sep 2016 05:26:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lh30dQ2FAJS1PlFR2iItuv0q2aXogrIiqA9zgzRGlTs=; b=Xwz1d1EbPRKRoiplFuz9TqKyv5gNas6VvqKq5Luo9EzRSWbwyUcK8YuKj3nIUJK2xo 0Wdvtc3Pf6PDFo0rEJeeMzBN84MaXHdNrW7Exv0U/N4mNunv4Y03U3dRljnyM82G2rmP N6tMes35ZsRzeFJybQ+QXXTKMjiyxlR+7hA5Ocdr7AHlgkgemWCcLeMfp3h+tF+Wr3rC OKiMmgxJlv7G0veldDpwkXDkBJZNsnIjZ27yeM9IBREsJVM/Ewcs3tleHy1hnL85DlKU aiWqFRtWNBIQjZwcp29ODqGa5527YsUekWjjtdafbKNNlQ8OzQXysKHeWfWWafKlxoqQ ARXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lh30dQ2FAJS1PlFR2iItuv0q2aXogrIiqA9zgzRGlTs=; b=SRDn6n2gR5xsg1ibWB4S2GQJf9IsXZi5FeW1yTQgwrls5ZwFJdd9lvYICNzxNtxKip U5qgl2jcXkmD0hUCHP53gBS+gECajRbinhu6BHvEeXDsy+vKjb29GG/3Mz4wpHll7E0Q yDfLjTrLkxeKLYNTt4g3ctZobuXe8UYIWv0bFsz3cmnk4OndPG6BNOtwRSDxysGHXb+6 5HCcimlGhaTUDVMWuL4HSGzLxa2lVCNIC0v7WClK7YhAySBXBpvjugGPW0xtkgKk1QTJ tOuvoyIEVA34Ymp5mhKKwvULd+q3RjzFfUkVGfwhhkghOG4PnN/+aGQ8ff1wNuPPTaUJ 0o+g== X-Gm-Message-State: AE9vXwOPa6BTtbpPJBAvooRKWKRNqZaO7XqUBRRWmYx2G3DI8hQbPZnkzuqsH5j+Ft8tQQ== X-Received: by 10.28.24.129 with SMTP id 123mr1948965wmy.52.1474115175186; Sat, 17 Sep 2016 05:26:15 -0700 (PDT) Received: from twisty.fritz.box (x5f703dd8.dyn.telefonica.de. [95.112.61.216]) by smtp.gmail.com with ESMTPSA id bw9sm12964797wjc.33.2016.09.17.05.26.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 17 Sep 2016 05:26:14 -0700 (PDT) From: Mario Kleiner To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/2] drm/radeon: Prevent races on pre DCE4 between flip submission and completion. Date: Sat, 17 Sep 2016 14:25:39 +0200 Message-Id: <1474115139-25201-3-git-send-email-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1474115139-25201-1-git-send-email-mario.kleiner.de@gmail.com> References: <1474115139-25201-1-git-send-email-mario.kleiner.de@gmail.com> Cc: alexander.deucher@amd.com, michel.daenzer@amd.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Pre DCE4 hw doesn't have reliable pageflip completion interrupts, so instead polling for flip completion is used from within the vblank irq handler to complete page flips. This causes a race if pageflip ioctl is called close to vblank: 1. pageflip ioctl queues execution of radeon_flip_work_func. 2. vblank irq fires, radeon_crtc_handle_vblank checks for flip_status == FLIP_SUBMITTED finds none, no-ops. 3. radeon_flip_work_func runs inside vblank, decides to set flip_status == FLIP_SUBMITTED and programs the flip into hw. 4. hw executes flip immediately (because in vblank), but as 2 already happened, the flip completion routine only emits the flip completion event one refresh later -> wrong vblank count/timestamp for completion and no performance gain, as instead of delaying the flip until next vblank, we now delay the next flip by 1 refresh while waiting for the delayed flip completion event. Given we often don't gain anything due to this race, but lose precision, prevent the programmed flip from executing in vblank on pre DCE4 asics to avoid this race. On pre-AVIVO hw we can't program the hw for edge-triggered flips, they always execute anywhere in vblank. Therefore delay the actual flip programming until after vblank on pre-AVIVO. Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- drivers/gpu/drm/radeon/atombios_crtc.c | 4 ++-- drivers/gpu/drm/radeon/radeon_display.c | 17 ++++++++++------- drivers/gpu/drm/radeon/rv515.c | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a4e9f35..74f99ba 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1638,8 +1638,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (viewport_w << 16) | viewport_h); - /* set pageflip to happen anywhere in vblank interval */ - WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + /* set pageflip to happen only at start of vblank interval (front porch) */ + WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3); if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5070646..b8ab30a 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -452,16 +452,19 @@ static void radeon_flip_work_func(struct work_struct *__work) } /* Wait until we're out of the vertical blank period before the one - * targeted by the flip + * targeted by the flip. Always wait on pre DCE4 to avoid races with + * flip completion handling from vblank irq, as these old asics don't + * have reliable pageflip completion interrupts. */ while (radeon_crtc->enabled && - (radeon_get_crtc_scanoutpos(dev, work->crtc_id, 0, - &vpos, &hpos, NULL, NULL, - &crtc->hwmode) + (radeon_get_crtc_scanoutpos(dev, work->crtc_id, 0, + &vpos, &hpos, NULL, NULL, + &crtc->hwmode) & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) == - (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) && - (int)(work->target_vblank - - dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0) + (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) && + (!ASIC_IS_AVIVO(rdev) || + ((int) (work->target_vblank - + dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0))) usleep_range(1000, 2000); /* We borrow the event spin lock for protecting flip_status */ diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 76c55c5..c55d653 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -406,8 +406,9 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) for (i = 0; i < rdev->num_crtc; i++) { if (save->crtc_enabled[i]) { tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]); - if ((tmp & 0x7) != 0) { + if ((tmp & 0x7) != 3) { tmp &= ~0x7; + tmp |= 0x3; WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); } tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);