From patchwork Sun May 5 17:37:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10930647 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 BB83D1395 for ; Mon, 6 May 2019 07:28:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A397827E01 for ; Mon, 6 May 2019 07:28:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 97EA728632; Mon, 6 May 2019 07:28:43 +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 5889227E01 for ; Mon, 6 May 2019 07:28:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8387B8935A; Mon, 6 May 2019 07:28:07 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x143.google.com (mail-lf1-x143.google.com [IPv6:2a00:1450:4864:20::143]) by gabe.freedesktop.org (Postfix) with ESMTPS id AC536892CB for ; Sun, 5 May 2019 17:39:49 +0000 (UTC) Received: by mail-lf1-x143.google.com with SMTP id v1so7555524lfg.5 for ; Sun, 05 May 2019 10:39:49 -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:mime-version:content-transfer-encoding; bh=XT2iXDlEU6v0lNteGjb1DNAvzBwb+KsZ+Jk4cl51M84=; b=m83i9bSH4zZ2M7+EP24fXxyLAk1YAf1ooxJfHaqqAsv4vvt7NSxVjuSHOqqH239igc Wj8YX6AtDypBR76nM2LJmszyuwsoWPGz4P5qq7cZ82853Gfndm/86V/3YcvDoQnxcXoO f7YlNcvFNISI/e8ZNyk3Kl88ieTbiMcLfkxyxeGTUFL0BY4rzOhu+9JCOMUo2irQ3p4V 0Bi+zY3su2wjqfoqHyeQ15dttln+49LBXpSq1rKpu3gWMhCSjvwmgrIQTwIX06p1HYZU 4hUpr2Y3w8jNhljj0YrfTE96lfF0I5MFWW7Rp3Nj8Oyb/mZq5G+UQWu6YZsGdUodyC85 3IKg== X-Gm-Message-State: APjAAAXJ5nMzTW2OuzWyQ9qDnDr1hmBE/PGbjN+qdg1lu+8ETC7oFeka Ebl6zvKyxin4q3172MDA8ZQ= X-Google-Smtp-Source: APXvYqyZocWedZVqGZOQeo8alH8Z9CYdqk1a+SwfInq6p9vkKQaTkWK0V8kDAlOnjWuK9P1JbC4MxQ== X-Received: by 2002:ac2:5446:: with SMTP id d6mr217591lfn.47.1557077988165; Sun, 05 May 2019 10:39:48 -0700 (PDT) Received: from localhost.localdomain (ppp94-29-35-107.pppoe.spdop.ru. [94.29.35.107]) by smtp.gmail.com with ESMTPSA id z17sm1626938lja.26.2019.05.05.10.39.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 May 2019 10:39:47 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding Subject: [PATCH v1 1/3] drm/tegra: dc: Tune up high priority request controls on Tegra20 Date: Sun, 5 May 2019 20:37:05 +0300 Message-Id: <20190505173707.29282-2-digetx@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190505173707.29282-1-digetx@gmail.com> References: <20190505173707.29282-1-digetx@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 06 May 2019 07:27:59 +0000 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 :mime-version:content-transfer-encoding; bh=XT2iXDlEU6v0lNteGjb1DNAvzBwb+KsZ+Jk4cl51M84=; b=K8fENxB2VacBBLP3NUMvI7fVRVLSi7lZ3CIlki2EKyKs1L4awSmyH2lUMDfqO2WJTK KGTLrCsVUD1m4ISqtQFbZDWv94ylMr2qHtVRW6WgXPpHpZ2W0kD6KIalKko5l0SO5nxx sJVjYzaCnZ0gnkAglz0ScVSz44aS2srC28DXpiXQ1Z0v9u40wH6nE833LzDapt/BKQcP IEP1iCnG5l7ARQqiwXlN5sOTNDhRMDW0CHq6JHjQC90MmEaIvXiZxS3aqdNWGK89SbnB hZyRONX5NPvXm5SCCYmWdjySuBn7lAlIaKZ4IONG3fbr6k2VgE+rM6UZSgniHvGdLI0n 0BxQ== 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: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Tegra20 has a high priority request control that allow to configure when display's memory client should perform read requests with a higher priority (Tegra30+ uses other means). Set up the controls for a more aggressive prefetching to reliably avoid FIFO underflow on a lower memory frequency, this allow to safely drop the memory bandwidth requirement by about two times in a most popular cases (only one display active, video overlay inactive, no scaling is done). Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/dc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 607a6ea17ecc..cf622a07e9b6 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1833,12 +1833,12 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); /* initialize timer */ - value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | - WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); + value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x70) | + WINDOW_B_THRESHOLD(0x30) | WINDOW_C_THRESHOLD(0x70); tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); - value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) | - WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1); + value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0) | + WINDOW_B_THRESHOLD(0) | WINDOW_C_THRESHOLD(0); tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | From patchwork Sun May 5 17:37:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10930641 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 86A0215A6 for ; Mon, 6 May 2019 07:28:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7018827E01 for ; Mon, 6 May 2019 07:28:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 646AF28632; Mon, 6 May 2019 07:28: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 16CB727E01 for ; Mon, 6 May 2019 07:28:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A61B589362; Mon, 6 May 2019 07:28:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x242.google.com (mail-lj1-x242.google.com [IPv6:2a00:1450:4864:20::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9B6A2892CB for ; Sun, 5 May 2019 17:39:50 +0000 (UTC) Received: by mail-lj1-x242.google.com with SMTP id y10so2644141lji.9 for ; Sun, 05 May 2019 10:39:50 -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:mime-version:content-transfer-encoding; bh=d3SE5g/jmgV5mNASQhzXKhHYJPe76OILIthVB+qsohQ=; b=ifB0ubvu/S7k4nnSQULJfqsE38TUejxR3zXN669CscgwKDXkZcyFeth8YwpXaTgq+E QS2lDT5YZiUponqlemzvzkDg3JHVmfIOaZbhh8EMEAUKtja4wLvElQUamn+PfJemOSo4 JHUVDiaw5f0O+/NaIz+Ka0n94U3STVFtED99T2fnRJRiwyNWwuI+yz4UVTs4BZ8s+Yq5 gDJI7iuyhleFGbO0vanPrnHK0F0GBK/VFGD6wSCSskrR07emW2XFOl38Rgpg39tBq3+i 9+nRk1fat4Ce6Y+ODUx4Ag6obL/9n9PcgTSCGeZnilfytMncxie6dn68rOhAU7zulfil SIjA== X-Gm-Message-State: APjAAAW0jyaLY0mu4hbddaAjMrgQK0SfQ2DDrNrmQxy67ecEwD+DmI3o kef5CbW3NmRVR6wpVlkcW1A= X-Google-Smtp-Source: APXvYqwhSikFAq0dClUlxDG5krmxsB5eIzTUe9DMnqQJTN/73P5v5zF61OIjS8NyBZbhVlbGpRSHhw== X-Received: by 2002:a2e:1508:: with SMTP id s8mr10931682ljd.87.1557077989134; Sun, 05 May 2019 10:39:49 -0700 (PDT) Received: from localhost.localdomain (ppp94-29-35-107.pppoe.spdop.ru. [94.29.35.107]) by smtp.gmail.com with ESMTPSA id z17sm1626938lja.26.2019.05.05.10.39.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 May 2019 10:39:48 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding Subject: [PATCH v1 2/3] drm/tegra: dc: Extend debug stats with total number of events Date: Sun, 5 May 2019 20:37:06 +0300 Message-Id: <20190505173707.29282-3-digetx@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190505173707.29282-1-digetx@gmail.com> References: <20190505173707.29282-1-digetx@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 06 May 2019 07:27:59 +0000 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 :mime-version:content-transfer-encoding; bh=d3SE5g/jmgV5mNASQhzXKhHYJPe76OILIthVB+qsohQ=; b=i48kTU5OFPZStOA2TWKl13rQC4YdClnfX7TBrdw23LNxhtlh5lQ4RbXm9d4MiWQeXb /utUJpAGFUvzbNDne6BaaGxk49WL1TfDmKvruhQeoJ7EMLOK1kdH2MNTTJ7dBdT5Jec7 UWe4jyCZLUkPYXochN2wFbsoVnUItB+0l/DrqMUg2xdjRT1rpko3lzGY5NeGVnXGNyU+ yfXOa8uI2drOPSgaLNDh2T1W+jRWsVUFtbkxvfuIXpDs3GVOF7vJyTLlItrr0izM81V1 xoXlpj25GwOXqSe9arRSGtzLQg3GkZyA2rFfZ+CO+B4zBbvFhm/iwf8Yh5GT7dWU2MMA YGlg== 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: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP I found useful to know the total number of underflow events while was working on adding support for memory bandwidth management. Currently the debug stats are getting reset after disabling CRTC, let's account the overall number of events that doesn't get reset. Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/dc.c | 10 ++++++++++ drivers/gpu/drm/tegra/dc.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index cf622a07e9b6..41cb67db6dbc 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1482,6 +1482,11 @@ static int tegra_dc_show_stats(struct seq_file *s, void *data) seq_printf(s, "underflow: %lu\n", dc->stats.underflow); seq_printf(s, "overflow: %lu\n", dc->stats.overflow); + seq_printf(s, "frames total: %lu\n", dc->stats.frames_total); + seq_printf(s, "vblank total: %lu\n", dc->stats.vblank_total); + seq_printf(s, "underflow total: %lu\n", dc->stats.underflow_total); + seq_printf(s, "overflow total: %lu\n", dc->stats.overflow_total); + return 0; } @@ -1945,6 +1950,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): frame end\n", __func__); */ + dc->stats.frames_total++; dc->stats.frames++; } @@ -1953,6 +1959,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); */ drm_crtc_handle_vblank(&dc->base); + dc->stats.vblank_total++; dc->stats.vblank++; } @@ -1960,6 +1967,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): underflow\n", __func__); */ + dc->stats.underflow_total++; dc->stats.underflow++; } @@ -1967,11 +1975,13 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) /* dev_dbg(dc->dev, "%s(): overflow\n", __func__); */ + dc->stats.overflow_total++; dc->stats.overflow++; } if (status & HEAD_UF_INT) { dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__); + dc->stats.underflow_total++; dc->stats.underflow++; } diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 1256dfb6b2f5..ab25157c948e 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -41,6 +41,11 @@ struct tegra_dc_stats { unsigned long vblank; unsigned long underflow; unsigned long overflow; + + unsigned long frames_total; + unsigned long vblank_total; + unsigned long underflow_total; + unsigned long overflow_total; }; struct tegra_windowgroup_soc { From patchwork Sun May 5 17:37:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 10930631 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 B0C53933 for ; Mon, 6 May 2019 07:28:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 981A027E01 for ; Mon, 6 May 2019 07:28:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C6AC28632; Mon, 6 May 2019 07:28:24 +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 A705027E01 for ; Mon, 6 May 2019 07:28:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5F85F892A0; Mon, 6 May 2019 07:28:02 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x144.google.com (mail-lf1-x144.google.com [IPv6:2a00:1450:4864:20::144]) by gabe.freedesktop.org (Postfix) with ESMTPS id D65E3892D6 for ; Sun, 5 May 2019 17:39:51 +0000 (UTC) Received: by mail-lf1-x144.google.com with SMTP id y10so868685lfl.3 for ; Sun, 05 May 2019 10:39:51 -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:mime-version:content-transfer-encoding; bh=CWUTPMHiOcRTWhYgTe83q9DaoJF+NVqYi7Gez6hex8k=; b=DPExBAwAV6xFsptfcr0dKuhcZlNn1rEY6FzNADNM85rSB8bJ6s4fbBx6rRRHizkc1N dAJ6CvnvS7ACDbRqc8k5OFT1zTyY8Na0AVMPXKEJhU9MpMNVpRMNat9qtWvzJU4VrK5E A2+T1GbYAPgXGAkdP4FydkDTawMdMLJ1e15Rj7R2WjVK/h7ezHnsIQwPdV2mrZLqnqHq P3vZR4efc+PTbKiF+Pc0lSeUKxd4hffRYs/owGBTHM7AA1ElMTqez9mbnu7wYr+Li5ju ivNueuyTuq/7hxncTXA8y23dzzevSWmC1WYuPI8AqxzHEHa8LKZz/JfLguphH2Ms/EuQ 2BeA== X-Gm-Message-State: APjAAAXz8WVYsEBr1CgnMp4Zewf0BITOZTdrn9V845HDdQ1tQAThWmNq MRujEo9Uqe5RLncqlECthTk= X-Google-Smtp-Source: APXvYqzvQUDAfwQV+p7f+7tedRSN0dxpfYw4wclWHrIIQMfBIfLRbya4q4ThvWuZgEgSrpAN/as0tA== X-Received: by 2002:a19:189:: with SMTP id 131mr8939344lfb.74.1557077990138; Sun, 05 May 2019 10:39:50 -0700 (PDT) Received: from localhost.localdomain (ppp94-29-35-107.pppoe.spdop.ru. [94.29.35.107]) by smtp.gmail.com with ESMTPSA id z17sm1626938lja.26.2019.05.05.10.39.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 May 2019 10:39:49 -0700 (PDT) From: Dmitry Osipenko To: Thierry Reding Subject: [PATCH v1 3/3] drm/tegra: Support PM QoS memory bandwidth management Date: Sun, 5 May 2019 20:37:07 +0300 Message-Id: <20190505173707.29282-4-digetx@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190505173707.29282-1-digetx@gmail.com> References: <20190505173707.29282-1-digetx@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 06 May 2019 07:27:59 +0000 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 :mime-version:content-transfer-encoding; bh=CWUTPMHiOcRTWhYgTe83q9DaoJF+NVqYi7Gez6hex8k=; b=XNmrl4RfFZmfqO9Q4qSI9nNINGxU5k7Ar9p6YeP01+s7Twia5QTAsqkkXD8yJxK0KI ksWftW5RoBnzSwyqs0YvWUQOEXI5kK1RhgiEKzz/a6FsSkuqMwe4zIUuLB9+Jtxf3AS6 PTzn4rGW8ytu9Ad2T8pyRsOazQDG+I1SRynnKzAVoNMEdv6E+IjtWVo/4pi6p/4LqFD5 6hU0xo567XESQ9iZWLeXzAaq0SJXTUaeN35x9IH/mOz4DDtwqQFPbrWTG74N3nHIt6N5 dORZD0vAoc8tyGJzHPm6do6Guv9hyG2NefaH0WLDQtdlMqKj7ka13+CWg9V28NypYtP+ it/w== 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: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Display controller (DC) performs isochronous memory transfers and thus has a requirement for a minimum memory bandwidth that shall be fulfilled, otherwise framebuffer data can't be fetched fast enough and this results in a DC's data-FIFO underflow that follows by a visual corruption. The External Memory Controller drivers will provide memory bandwidth management facility via the generic Power Management QoS API soonish. This patch wires up the PM QoS API support for the display driver beforehand. Display won't have visual corruption on coming up from suspend state when devfreq driver is active once all prerequisite bits will get upstreamed. The devfreq reaction has a quite significant latency and it also doesn't take into account the ISO transfers which may result in assumption about lower memory bandwidth requirement than actually needed. Signed-off-by: Dmitry Osipenko --- drivers/gpu/drm/tegra/dc.c | 216 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/tegra/dc.h | 8 ++ drivers/gpu/drm/tegra/drm.c | 18 +++ drivers/gpu/drm/tegra/plane.c | 1 + drivers/gpu/drm/tegra/plane.h | 4 +- 5 files changed, 245 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 41cb67db6dbc..8c5b9e71ca6f 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -514,6 +514,107 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, tegra_plane_setup_blending(plane, window); } +static unsigned long +tegra_plane_memory_bandwidth(struct drm_plane_state *state, + struct tegra_dc_window *window) +{ + struct tegra_plane_state *tegra_state; + struct drm_crtc_state *crtc_state; + struct tegra_dc_window win; + unsigned int mul; + unsigned int bpp; + bool planar; + bool yuv; + + if (!state->fb || !state->visible) + return 0; + + crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); + tegra_state = to_tegra_plane_state(state); + + if (!window) + window = &win; + + window->src.w = drm_rect_width(&state->src) >> 16; + window->src.h = drm_rect_height(&state->src) >> 16; + window->dst.w = drm_rect_width(&state->dst); + window->dst.h = drm_rect_height(&state->dst); + window->format = tegra_state->format; + window->tiling = tegra_state->tiling; + + yuv = tegra_plane_format_is_yuv(window->format, &planar); + if (!yuv || !planar) + bpp = state->fb->format->cpp[0] * 8; + else + bpp = 16; + + /* + * Horizontal downscale takes extra bandwidth which roughly depends + * on the scaled width. + */ + if (window->src.w > window->dst.w) + mul = (window->src.w - window->dst.w) * bpp / 2048 + 1; + else + mul = 1; + + /* + * Ignore window if its width is small enough such that data-prefetch + * FIFO will easily help to overcome temporal memory pressure. This is + * a typical case for the cursor's plane. + */ + if (mul == 1 && window->src.w * bpp <= 2048) + return 0; + + /* mode.clock in kHz, bandwidth in Mbit/s */ + return crtc_state->mode.clock / 1000 * bpp * mul; +} + +static unsigned long +tegra20_plane_memory_bandwidth(struct drm_plane_state *state) +{ + /* x2: ~50% efficiency */ + return tegra_plane_memory_bandwidth(state, NULL) * 2; +} + +static unsigned long +tegra30_plane_memory_bandwidth(struct drm_plane_state *state) +{ + struct tegra_dc_window window; + unsigned long bandwidth; + + bandwidth = tegra_plane_memory_bandwidth(state, &window); + + /* x2 memory overfetch for tiled framebuffer and DDR3 */ + if (window.tiling.mode == TEGRA_BO_TILING_MODE_TILED) + bandwidth *= 2; + + /* x2: ~50% efficiency */ + return bandwidth * 2; +} + +static unsigned long +tegra114_plane_memory_bandwidth(struct drm_plane_state *state) +{ + struct tegra_dc_window window; + unsigned long bandwidth; + + bandwidth = tegra_plane_memory_bandwidth(state, &window); + + /* x2 memory overfetch for tiled framebuffer and DDR3 */ + if (window.tiling.mode == TEGRA_BO_TILING_MODE_TILED) + bandwidth *= 2; + + /* 2-channel memory */ + return bandwidth; +} + +static unsigned long +tegra124_plane_memory_bandwidth(struct drm_plane_state *state) +{ + /* 64bit memory bus */ + return tegra_plane_memory_bandwidth(state, NULL); +} + static const u32 tegra20_primary_formats[] = { DRM_FORMAT_ARGB4444, DRM_FORMAT_ARGB1555, @@ -603,8 +704,10 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, int err; /* no need for further checks if the plane is being disabled */ - if (!state->crtc) + if (!state->crtc) { + plane_state->memory_bandwidth = 0; return 0; + } err = tegra_plane_format(state->fb->format->format, &plane_state->format, @@ -657,6 +760,8 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, if (err < 0) return err; + plane_state->memory_bandwidth = dc->soc->plane_memory_bandwidth(state); + return 0; } @@ -1187,6 +1292,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) copy->pclk = state->pclk; copy->div = state->div; copy->planes = state->planes; + copy->memory_bandwidth = state->memory_bandwidth; return ©->base; } @@ -1780,6 +1886,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc, spin_unlock_irq(&crtc->dev->event_lock); pm_runtime_put_sync(dc->dev); + + pm_qos_update_request(&dc->pm_qos_req, + PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE); } static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, @@ -1790,6 +1899,8 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, struct tegra_dc *dc = to_tegra_dc(crtc); u32 value; + pm_qos_update_request(&dc->pm_qos_req, state->memory_bandwidth); + pm_runtime_get_sync(dc->dev); /* initialize display controller */ @@ -1899,6 +2010,9 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, static void tegra_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { + struct tegra_dc_state *dc_old_state = to_dc_state(old_crtc_state); + struct tegra_dc_state *dc_state = to_dc_state(crtc->state); + struct tegra_dc *dc = to_tegra_dc(crtc); unsigned long flags; if (crtc->state->event) { @@ -1913,6 +2027,23 @@ static void tegra_crtc_atomic_begin(struct drm_crtc *crtc, crtc->state->event = NULL; } + + if (old_crtc_state && old_crtc_state->active) { + /* + * Raise memory bandwidth before changes take effect if it + * goes from low to high. + */ + if (dc_old_state->memory_bandwidth < dc_state->memory_bandwidth) + pm_qos_update_request(&dc->pm_qos_req, + dc_state->memory_bandwidth); + } else { + /* + * Raise memory bandwidth before changes take effect if + * CRTC is turning on. + */ + pm_qos_update_request(&dc->pm_qos_req, + dc_state->memory_bandwidth); + } } static void tegra_crtc_atomic_flush(struct drm_crtc *crtc, @@ -1931,7 +2062,78 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc, value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); } +static bool +tegra_plane_intersects_with_other_plane(struct drm_crtc_state *state, + const struct drm_plane_state *plane_state) +{ + const struct drm_plane_state *other_state; + struct drm_plane *plane; + struct drm_rect rect; + + drm_atomic_crtc_state_for_each_plane_state(plane, other_state, state) { + rect = plane_state->dst; + + if (other_state == plane_state) + continue; + + if (!other_state->visible || !other_state->fb) + continue; + + if (drm_rect_intersect(&rect, &other_state->dst)) + return true; + } + + return false; +} + +static int tegra_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct tegra_dc_state *dc_state = to_dc_state(state); + const struct drm_plane_state *plane_state; + const struct tegra_plane_state *tegra; + unsigned long bandwidth = 0; + struct drm_plane *plane; + + /* + * For overlapping planes pixel's data is fetched for each plane at + * the same time, hence bandwidth is accumulated in this case. + */ + drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) { + tegra = to_tegra_plane_state(plane_state); + + if (tegra_plane_intersects_with_other_plane(state, plane_state)) + bandwidth += tegra->memory_bandwidth; + else + bandwidth = max(bandwidth, tegra->memory_bandwidth); + } + + dc_state->memory_bandwidth = bandwidth; + + return 0; +} + +void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state) +{ + struct tegra_dc_state *dc_old_state = to_dc_state(old_crtc_state); + struct tegra_dc_state *dc_state = to_dc_state(crtc->state); + struct tegra_dc *dc = to_tegra_dc(crtc); + + if (!dc_old_state) + return; + + /* + * Drop memory bandwidth after changes take effect if it goes from + * high to low. + */ + if (dc_old_state->memory_bandwidth > dc_state->memory_bandwidth) + pm_qos_update_request(&dc->pm_qos_req, + dc_state->memory_bandwidth); +} + static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = { + .atomic_check = tegra_crtc_atomic_check, .atomic_begin = tegra_crtc_atomic_begin, .atomic_flush = tegra_crtc_atomic_flush, .atomic_enable = tegra_crtc_atomic_enable, @@ -2087,6 +2289,9 @@ static int tegra_dc_init(struct host1x_client *client) goto cleanup; } + pm_qos_add_request(&dc->pm_qos_req, PM_QOS_MEMORY_BANDWIDTH, + PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE); + return 0; cleanup: @@ -2107,6 +2312,8 @@ static int tegra_dc_exit(struct host1x_client *client) struct tegra_dc *dc = host1x_client_to_dc(client); int err; + pm_qos_remove_request(&dc->pm_qos_req); + if (!tegra_dc_has_window_groups(dc)) return 0; @@ -2146,6 +2353,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = { .modifiers = tegra20_modifiers, .has_win_a_without_filters = true, .has_win_c_without_vert_filter = true, + .plane_memory_bandwidth = tegra20_plane_memory_bandwidth, }; static const struct tegra_dc_soc_info tegra30_dc_soc_info = { @@ -2165,6 +2373,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = { .modifiers = tegra20_modifiers, .has_win_a_without_filters = false, .has_win_c_without_vert_filter = false, + .plane_memory_bandwidth = tegra30_plane_memory_bandwidth, }; static const struct tegra_dc_soc_info tegra114_dc_soc_info = { @@ -2184,6 +2393,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = { .modifiers = tegra20_modifiers, .has_win_a_without_filters = false, .has_win_c_without_vert_filter = false, + .plane_memory_bandwidth = tegra114_plane_memory_bandwidth, }; static const struct tegra_dc_soc_info tegra124_dc_soc_info = { @@ -2203,6 +2413,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = { .modifiers = tegra124_modifiers, .has_win_a_without_filters = false, .has_win_c_without_vert_filter = false, + .plane_memory_bandwidth = tegra124_plane_memory_bandwidth, }; static const struct tegra_dc_soc_info tegra210_dc_soc_info = { @@ -2222,6 +2433,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = { .modifiers = tegra124_modifiers, .has_win_a_without_filters = false, .has_win_c_without_vert_filter = false, + .plane_memory_bandwidth = tegra124_plane_memory_bandwidth, }; static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = { @@ -2270,6 +2482,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = { .has_nvdisplay = true, .wgrps = tegra186_dc_wgrps, .num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps), + .plane_memory_bandwidth = tegra124_plane_memory_bandwidth, }; static const struct tegra_windowgroup_soc tegra194_dc_wgrps[] = { @@ -2318,6 +2531,7 @@ static const struct tegra_dc_soc_info tegra194_dc_soc_info = { .has_nvdisplay = true, .wgrps = tegra194_dc_wgrps, .num_wgrps = ARRAY_SIZE(tegra194_dc_wgrps), + .plane_memory_bandwidth = tegra124_plane_memory_bandwidth, }; static const struct of_device_id tegra_dc_of_match[] = { diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index ab25157c948e..e224fb9dd187 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -11,6 +11,7 @@ #define TEGRA_DC_H 1 #include +#include #include @@ -26,6 +27,8 @@ struct tegra_dc_state { unsigned int div; u32 planes; + + unsigned long memory_bandwidth; }; static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state) @@ -74,6 +77,7 @@ struct tegra_dc_soc_info { const u64 *modifiers; bool has_win_a_without_filters; bool has_win_c_without_vert_filter; + unsigned long (*plane_memory_bandwidth)(struct drm_plane_state *state); }; struct tegra_dc { @@ -100,6 +104,8 @@ struct tegra_dc { const struct tegra_dc_soc_info *soc; struct iommu_group *group; + + struct pm_qos_request pm_qos_req; }; static inline struct tegra_dc * @@ -160,6 +166,8 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc, struct drm_crtc_state *crtc_state, struct clk *clk, unsigned long pclk, unsigned int div); +void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state); /* from rgb.c */ int tegra_dc_rgb_probe(struct tegra_dc *dc); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 0c5f1e6a0446..d2080bd7d392 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -19,6 +19,7 @@ #include #endif +#include "dc.h" #include "drm.h" #include "gem.h" @@ -58,6 +59,21 @@ static const struct drm_mode_config_funcs tegra_drm_mode_config_funcs = { .atomic_commit = drm_atomic_helper_commit, }; +static void tegra_atomic_post_commit(struct drm_device *drm, + 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) { + if (!new_crtc_state->active) + continue; + + tegra_crtc_atomic_post_commit(crtc, old_crtc_state); + } +} + static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *drm = old_state->dev; @@ -74,6 +90,8 @@ static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state) } else { drm_atomic_helper_commit_tail_rpm(old_state); } + + tegra_atomic_post_commit(drm, old_state); } static const struct drm_mode_config_helper_funcs diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 5a8a3387f5ee..e7cd21a0d7d9 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -58,6 +58,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane) copy->swap = state->swap; copy->bottom_up = state->bottom_up; copy->opaque = state->opaque; + copy->memory_bandwidth = state->memory_bandwidth; for (i = 0; i < 2; i++) copy->blending[i] = state->blending[i]; diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h index e79e6b4a8e0a..357174bff2fd 100644 --- a/drivers/gpu/drm/tegra/plane.h +++ b/drivers/gpu/drm/tegra/plane.h @@ -51,10 +51,12 @@ struct tegra_plane_state { /* used for legacy blending support only */ struct tegra_plane_legacy_blending_state blending[2]; bool opaque; + + unsigned long memory_bandwidth; }; static inline struct tegra_plane_state * -to_tegra_plane_state(struct drm_plane_state *state) +to_tegra_plane_state(const struct drm_plane_state *state) { if (state) return container_of(state, struct tegra_plane_state, base);