From patchwork Wed Nov 19 18:04:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 5340151 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CA8F69F2ED for ; Wed, 19 Nov 2014 18:05:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E88D82020E for ; Wed, 19 Nov 2014 18:05:40 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id F069C201FB for ; Wed, 19 Nov 2014 18:05:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6D4666EF53; Wed, 19 Nov 2014 10:05:39 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qg0-f51.google.com (mail-qg0-f51.google.com [209.85.192.51]) by gabe.freedesktop.org (Postfix) with ESMTP id 25FD46EF55 for ; Wed, 19 Nov 2014 10:05:37 -0800 (PST) Received: by mail-qg0-f51.google.com with SMTP id l89so817178qgf.24 for ; Wed, 19 Nov 2014 10:05:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=6KksPdBNODmYzeRYlJ/V0x0IfkJ7XjuX2zR5kQlsjmM=; b=DZy3wXsEh2pBwH67yLUl4lAYP5/jOo1jdphgJE+39Cl9hueuDlYp7OiCs3Razerwr7 Pq5dXH24QqMcBFMzwrnk9DV8Uf3LvkHT1Iw/hUEtbh7677TVlLO0CojSnpPNCPWPquFh UMwMkhq/ZRCAFC+T9K2Whc6tWWl40lpgKkGg0= 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; bh=6KksPdBNODmYzeRYlJ/V0x0IfkJ7XjuX2zR5kQlsjmM=; b=b54oF1VJc7kgqGY9LQuOw5Wey4RtgUNLleh2AHGpVhw5TqIXdRJsAImGlIU3nFiTXg OaAQPRqYe5Pi4aSxfHsRRsdADsuKyjn2jynIppi3DD4miAC94eIFu6o+dMivZgftMpdv ECgSEuBjKiaexxPmmgwB1UYdvRD/UeIskl6H8rc00D0cScbzbjG8vTnFHrZ5te+TvFc0 O80zS0a6AIPHkiNsSvdpzbKvqopeqD4V5EMqGrKarePihNcZqQg130j2jHr0vBYEccZi uAZMHc/ePSuQZwrflKNXCVnStCN6L90E8HLMMRBABySvKc4GDBDTTZ7gqvvsDyKqlD23 VSaQ== X-Gm-Message-State: ALoCoQmoMoNwTZYw7mCH41nfIhQrifJrszt7osigwBle2yy2rAGXr57IpNdQHoAo4K8/WMk5Vf2p X-Received: by 10.140.51.99 with SMTP id t90mr53317137qga.72.1416420336642; Wed, 19 Nov 2014 10:05:36 -0800 (PST) Received: from philcollins.nc.rr.com (cpe-173-095-180-236.nc.res.rr.com. [173.95.180.236]) by mx.google.com with ESMTPSA id k4sm1987263qaf.0.2014.11.19.10.05.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Nov 2014 10:05:36 -0800 (PST) From: Sean Paul To: thierry.reding@gmail.com, dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org Subject: [PATCH] drm/tegra: Select root window for event dispatch Date: Wed, 19 Nov 2014 13:04:49 -0500 Message-Id: <1416420289-4112-1-git-send-email-seanpaul@chromium.org> X-Mailer: git-send-email 2.1.1 Cc: marcheu@chromium.org 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-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In finish pageflip, the driver was not selecting the root window when dispatching events. This exposed a race where a plane update would change the window selection and cause tegra_dc_finish_page_flip to check the wrong base address. This patch also protects access to the window selection register as well as the registers affected by it. Signed-off-by: Sean Paul --- drivers/gpu/drm/tegra/dc.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index b957908..a3b41ea 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -168,7 +168,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, const struct tegra_dc_window *window) { unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; - unsigned long value; + unsigned long value, flags; bool yuv, planar; /* @@ -181,6 +181,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, else bpp = planar ? 1 : 2; + spin_lock_irqsave(&dc->lock, flags); + value = WINDOW_A_SELECT << index; tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); @@ -273,6 +275,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, case TEGRA_BO_TILING_MODE_BLOCK: DRM_ERROR("hardware doesn't support block linear mode\n"); + spin_unlock_irqrestore(&dc->lock, flags); return -EINVAL; } @@ -330,6 +333,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, } tegra_dc_window_commit(dc, index); + spin_unlock_irqrestore(&dc->lock, flags); return 0; } @@ -339,10 +343,12 @@ static int tegra_window_plane_disable(struct drm_plane *plane) struct tegra_dc *dc = to_tegra_dc(plane->crtc); struct tegra_plane *p = to_tegra_plane(plane); u32 value; + unsigned long flags; if (!plane->crtc) return 0; + spin_lock_irqsave(&dc->lock, flags); value = WINDOW_A_SELECT << p->index; tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); @@ -351,6 +357,7 @@ static int tegra_window_plane_disable(struct drm_plane *plane) tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); tegra_dc_window_commit(dc, p->index); + spin_unlock_irqrestore(&dc->lock, flags); return 0; } @@ -700,13 +707,14 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, unsigned int h_offset = 0, v_offset = 0; struct tegra_bo_tiling tiling; unsigned int format, swap; - unsigned long value; + unsigned long value, flags; int err; err = tegra_fb_get_tiling(fb, &tiling); if (err < 0) return err; + spin_lock_irqsave(&dc->lock, flags); tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); value = fb->offsets[0] + y * fb->pitches[0] + @@ -752,6 +760,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, case TEGRA_BO_TILING_MODE_BLOCK: DRM_ERROR("hardware doesn't support block linear mode\n"); + spin_unlock_irqrestore(&dc->lock, flags); return -EINVAL; } @@ -777,6 +786,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); + spin_unlock_irqrestore(&dc->lock, flags); return 0; } @@ -790,7 +800,6 @@ void tegra_dc_enable_vblank(struct tegra_dc *dc) value = tegra_dc_readl(dc, DC_CMD_INT_MASK); value |= VBLANK_INT; tegra_dc_writel(dc, value, DC_CMD_INT_MASK); - spin_unlock_irqrestore(&dc->lock, flags); } @@ -819,11 +828,16 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) bo = tegra_fb_get_plane(crtc->primary->fb, 0); + spin_lock_irqsave(&dc->lock, flags); + /* check if new start address has been latched */ + tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); + spin_unlock_irqrestore(&dc->lock, flags); + if (base == bo->paddr + crtc->primary->fb->offsets[0]) { spin_lock_irqsave(&drm->event_lock, flags); drm_send_vblank_event(drm, dc->pipe, dc->event);