From patchwork Mon Oct 1 13:39:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru-Cosmin Gheorghe X-Patchwork-Id: 10622137 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 96616175A for ; Mon, 1 Oct 2018 13:40:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 845712940A for ; Mon, 1 Oct 2018 13:40:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7692629431; Mon, 1 Oct 2018 13:40:01 +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=BAD_ENC_HEADER,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8DAEC2940A for ; Mon, 1 Oct 2018 13:40:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0C2B089BA5; Mon, 1 Oct 2018 13:39:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on0057.outbound.protection.outlook.com [104.47.1.57]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5A5C889BA5 for ; Mon, 1 Oct 2018 13:39:55 +0000 (UTC) Received: from e114479-lin.cambridge.arm.com (217.140.106.51) by DB6PR0802MB2551.eurprd08.prod.outlook.com (2603:10a6:4:a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1185.20; Mon, 1 Oct 2018 13:39:51 +0000 From: Alexandru Gheorghe To: liviu.dudau@arm.com, brian.starkey@arm.com, malidp@foss.arm.com, airlied@linux.ie, dri-devel@lists.freedesktop.org, ayan.halder@arm.com Subject: [PATCH v2] drm/malidp: Enable MMU prefetch on Mali-DP650 Date: Mon, 1 Oct 2018 14:39:07 +0100 Message-Id: <20181001133907.19915-1-alexandru-cosmin.gheorghe@arm.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-Originating-IP: [217.140.106.51] X-ClientProxiedBy: AM0PR07CA0009.eurprd07.prod.outlook.com (2603:10a6:208:ac::22) To DB6PR0802MB2551.eurprd08.prod.outlook.com (2603:10a6:4:a1::21) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6c628882-c6c3-4e8f-af55-08d627a35d82 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB6PR0802MB2551; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 3:yPhYlMFYVy4sN7bh07GMBOB/a7X17A8TwUmkvEHMXc4tHDHh5cEOROtpoIHgsmLohPHl0HaWJecT1NZ5Z1J1efhU1vqWwgYK98y+ZrAhi/na0REeOng6JNEXHDnxnlFSg2tap90BVnjjWee8llrnM2zbE4r5L0VuMYsPaBD14Ex+imiAB9X/YSGstDf7+CqG87ZF5GRcIYVAVZQaKa3hKilnvwHSLzkQzAI7f0mnyRj37bK9+KwvL3CVz9Kte4c3; 25:D54Jc9rztMOPH9+jBvPRHFdt8pL6+ALFpcN84vlGHmyga4vXsYZrFzu/ujEKwN2nk/KbVMc1Iw8YXI7o94Yk8muMkou0KmnjBr3wk2QKgqk7E/JAeJ07nLHVUpCMGRwsz1TQkH8ngFA9yVLUHPKXFs5tAQscwYxZIKMxHPVOtR0ZGW9xOV3W/tnq8RtHdaaT+lXF53zYkN6QyxEUv4oCsoZnV0fL58RWUnLRw84lXSPl065lRJxEaFcgk5H8KhpQRMJBkyM+Htzie7yeDbv4JfezO+c4I9V5JOIE18F8dAlZ7oev7Xh9QnA3RKqyh5PalfiaN+HiBSV7JbayHCJoaw==; 31:8isFMHYJeUXP0eVUXY84vvC5/xO9i4GC8ZSuv7kqVe+05nS8MtJrRnOx7I1JCrRnGyjkeO3/rVTYD/n5RdYQERWbdz+DoNXAFDAfzaoUeYJCnefdz9lSaLTyq9NVF5f1CLujGNZwjwNmtpjNlDGiZklGzIv8jfWw/zOLVyXut+xdkd9Gsz6RySwqMuZRv4nHQIBjWUlEJiU/Z8CMU0ezMhJDN634SBKuxtT/op2gXKM= X-MS-TrafficTypeDiagnostic: DB6PR0802MB2551: NoDisclaimer: True X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 20:Up+Vksgt02ZiPTpHvNDHbZla23YWxqf0T8r6xTj0FELTXkd/7h7GypRfsXk5APRkIzFBsf8cDeXUtYsCBOGrCCCDx876O6VCFaEPC79nmXvHJYhOriLGznjb9bR5zClauEloW9Dzc73e5dzCWTBi1WNQ5s5whwOkOxL/SAsy1mUPVB0k/GMl4OVmZP9sYa7FVSNPcPCcew92VNUQB54yFju2csxDbB4+gMeD1xTclSgDcxezjOrb3zUHBMmPwfjkM1mhVaOA7C8cpH24GU6DSjM81i6gfhWSk80PqUrqHmRwgmYQONHkhXOtBpVZRURGivlNmdVPxDerLWe3f/4Ixyj2EwK5euyRj9Zbh7mxiaIiSEeyJ/Daf8kVXI5Xuugn+1m2LrCKkBYCV3LgAd9lEYKIrQZDefYA4Xl3M1Tgu9k=; 4:9LRwHrzPKKvK2bmXkmeMq+p2CLxWrG9kTezovVYbxGnypFvAa8LSFkOm89FjumCxB4yHmGVo5M8jCNzgi+PtYFZCq8X7SwTUaD+PK9+ipnfxY4ElJNDw18EUZMPLoHZwpKzoRCQBG/0jCV4m9EnMbXN9UvT+PfGjLqtRjJinwRVGsU/JaVgy6NGwyWn0hdfCr0Hi59QjxNgmf83To8+6NfjW5YdVl9tkmC9sfFPqtm0VibUSoRULQxnYQfoq0+DyGoTR2qrMoNS4peZFb9QGNKeKJ9GCLSk50Ry/tiInyHC2NoXfBXBU63CMHNh6IoJ4 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(10201501046)(3231355)(944501410)(52105095)(3002001)(6055026)(149066)(150057)(6041310)(20161123560045)(20161123558120)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(201708071742011)(7699051); SRVR:DB6PR0802MB2551; BCL:0; PCL:0; RULEID:; SRVR:DB6PR0802MB2551; X-Forefront-PRVS: 0812095267 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(396003)(366004)(376002)(136003)(199004)(189003)(26005)(6116002)(3846002)(386003)(316002)(7736002)(7696005)(1076002)(51416003)(52116002)(50466002)(2906002)(6486002)(106356001)(105586002)(53936002)(47776003)(14444005)(956004)(4326008)(6636002)(2616005)(476003)(6666003)(16586007)(486006)(97736004)(478600001)(45080400002)(5660300001)(68736007)(72206003)(66066001)(34290500001)(25786009)(81156014)(305945005)(50226002)(86362001)(81166006)(48376002)(36756003)(16526019)(8676002)(575784001)(54906003)(8936002); DIR:OUT; SFP:1101; SCL:1; SRVR:DB6PR0802MB2551; H:e114479-lin.cambridge.arm.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB6PR0802MB2551; 23:CZdtZu+bYJTZ6a48AdbeAFirPAKHAO9YNxP1Vfz?= cqUa9e7gnUFv1v+aSqNmFmVcBuXW/LjWt9OSV0i84WgLp6rr+D50I/URRLJhu8GhVDeQeBEeg82EJlPo2/vQb9RvDwes4YoIKe9d4yEn+BS9GwElReYLIvL3GundX3z9tBh5k0JiMWlbdgseMuHyc8xg1S4Kc/zrP9Yu7admLoPUimgaH0F1YKP2k8QP+6Z7QYKgzzsShYTQW612zkvxxRN4MdTetfyy1/XT8x7kCJhY+P3NCmGCZE4h/YgGIOT7b9LSDvIWg0JJ3i24MLkDsX4NwsfesTdTvHS0YJnplXsYL4pQ/TlAd7sptVRSvDCBtNQpJL1a7AXb+KWXSvXv3jDy6KxIMtVPFuXTs0DgjWvJ4Xk0oZpOH9+RQwRMR5I5VEkakwgndbFyRnXA7u5KHkKETonx20L7L8dRCMywuzhj8F+lypLyMp9RK651pTj0NV2q274AV57EZSYSCDkwUO1KCxNsYVM1v0gVjEhTq0UOdX+PnzP9JdnVr5U/89hUAWCtprPIRzXJ+CajHZ5AdJCmiW+ojPNuQtBvZx3SndlMDEbHy9ASa19EdSrXbcrfGy0g0eq+adpP+DIkYrKjdglpnk+qeOTlc8Ysa9mr7tmUxUSIgtFl66MGOWf8F9WoHwxEgWwNVdEGZOofC3p0+i51+w6oHy3riF+a+6fLQwwXeNOuUw6H9ZKpG61RUd1zuhVMEa5W23YjCtuxi2RIkt5JNIMWuln359zkl+8QEhCQzd4yKJpeAlDTljYZnThT5Tb2VpKFIfvvQjDfmfSzGVRxJ/K2BF9thtFfwCLn0XTHyqxR4xPzAHZnRorM2x3kINx83RCF1MQ8xPmTMI/X+A0/lyxMNMRW1KqEaMAkqeJCuYjrOyn9xIEi9XcShnBzU6GvxGtH/Pl5vGow6c37iM1mTY6KTjUjibvo9tmtY1M5aihhqn1lImyY2wkdlvl8yIs3NHCdZ+wbFfPix48BkgGhXePBjNkA834XBWADKjgPIcDu45ruZ2qV++WDz4VtBSY2Od41u+9vYlACRAGtUWej+w5mpQN4/FNu5biqLu9lLkGI78n5FcdqDeeEvqfGBFLKtB2unefdHTAsiSoI7JKkXvnwYVKPLd+I41HIywlXDvfCIMjfBcdfVCnKmp95ZZfbI+BAg/BZx08jm91yB3Hx+brrBjrtZvo+K7RtBIWvA9g== X-Microsoft-Antispam-Message-Info: h9RtzQhvGMYvggimJwhfg6q0TkOgcygdczyL/MrkCk62Smj668nl2z3jtBF/wIBjv/65okpuwDCELPfDLGZN1BzSgwSDMfKZhMDor+6Uakoe4bbK7hruRW0oJ4ZHR3nS2RKs3IMuLpaYwXHJ1GWOy0t2Ksyt/ipv4JdnEO7ZFNb6MVAdJLDVuwQwcckvSwD0Zpa3A6BSukSHiLXLderDQzlaXA4Z1K45VvYI2a0DO7aum5hH1AFMZKXIoPZXO1zlumggF7LNgLDGwDKml6oavXjpIz2I7avDf1HzpQjZT8XNHATJuxUEzmWePK8PHEkMoL5wdWThhlKGXi2adNtDbyK2/o1OzGlIe0agrHXI4CM= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 6:Voe/OKudUGoW/Ggg0YsLo/jd35BnGlQcFkh6RnQcSyqlT2F+j0l1EeeouLj7tegEGbzjKzUtirAuw7Zt7BaOrGpSju35fH6DLErvPDPdRYNTGSnresE0ZVhRee6gQrdp2PmkxvhyxlyrpJY5F0V30i1NT5RPKITBR1+FzQ92yWCILWyuWwdDDxnjkmfOo48zMOdYK3w7AsgbzJTOWdgIPntPDokEd7F/h99y8Ju0h4KUnXxNWdGgIUtnZ/rKEMT2l8j3bjQc7Jjio5hKWon1Ak9Sad528HmyuHZ0PpGUFiRU9xF6JaHVPvkD8svTwkicb+IcDig+MgVdt1HrERW7MFFEF3bfC4lIdy7lhBoh7e5GCiUrs1QiBt8/n454a5+igZdguM0sMNDwKSQdYU6jaE0IoQyjLXaE8LrTNC5belJ6O+UJK9GTJH4tdi0eBAbsjnA4d9/Epji3Z73M657/AA==; 5:ySyFAOAnpXFl97qBlBAOWCjIgaHkTkb+q0JUMGFcAmX7+MQi05J21qc99IWoyICU32ettRzhCW13C3j9dp/HFCPaw0tYsKh8O3BF5Ajuh/Ku7JEQ8B2lHQW4h0lfDRRvTuVXr1jQbDXsKqqm3grvLotAZUgyo+DkfQ6p+00U8DU=; 7:sTUvrP2PfWGPXDump9rh9cjZa63+w97ijNmqjJB0HxXDyV62VAXt+K88Rp+xIU1rNJdaicfWhNanQnxtKR1/wjGk+GoxsuJEOB/qzB6poS+RdTmYwNEKOLO2gWc5KlqH5koypB9DxAN6xIJLeZHeMvcZgJ+ff+Z0Og7TCWm/MHKXU3RGMX00XYcHFfeT8nmFbF2OFS2jBc9m5iL3nslAz4cSh8m1uZiRV1+FXhX+E73lMoTc7bO4sQG06V/5DGnb SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Oct 2018 13:39:51.8377 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6c628882-c6c3-4e8f-af55-08d627a35d82 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2551 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: nd@arm.com, Alexandru Gheorghe , Jamie Fox Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Jamie Fox Mali-DP650 supports warming up the SMMU translations, by sending requsts to the SMMU before a buffer is read. There are two modes supported: - PARTIAL: could be enabled when the buffer is composed of 4K or 64K pages, the display hardware will send a configurable number of requests before the actual reading. - FULL: could be enabled when the buffer is composed of 1M or 2M pages, the display hardware will send requests before reading for all pages composing the buffer. This patch adds a mechanism for detecting the page size and set the MMU prefetch mode if possible. Changes since v1: - For imported buffers use the already populated drm_gem_cma_object.sgt instead of calling driver.gem_prime_get_sg_table, which works just for buffers allocated through the gem_cma API. Signed-off-by: Jamie Fox Signed-off-by: Alexandru Gheorghe [rebased and re-ordered functions] Signed-off-by: Liviu Dudau Acked-by: Liviu Dudau --- drivers/gpu/drm/arm/malidp_drv.h | 8 + drivers/gpu/drm/arm/malidp_hw.c | 47 ++++-- drivers/gpu/drm/arm/malidp_hw.h | 1 + drivers/gpu/drm/arm/malidp_planes.c | 238 ++++++++++++++++++++++++++++ drivers/gpu/drm/arm/malidp_regs.h | 11 ++ 5 files changed, 296 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h index e3eb0cb1f385..b76c86f18a56 100644 --- a/drivers/gpu/drm/arm/malidp_drv.h +++ b/drivers/gpu/drm/arm/malidp_drv.h @@ -55,6 +55,12 @@ struct malidp_plane { const struct malidp_layer *layer; }; +enum mmu_prefetch_mode { + MALIDP_PREFETCH_MODE_NONE, + MALIDP_PREFETCH_MODE_PARTIAL, + MALIDP_PREFETCH_MODE_FULL, +}; + struct malidp_plane_state { struct drm_plane_state base; @@ -63,6 +69,8 @@ struct malidp_plane_state { /* internal format ID */ u8 format; u8 n_planes; + enum mmu_prefetch_mode mmu_prefetch_mode; + u32 mmu_prefetch_pgsize; }; #define to_malidp_plane(x) container_of(x, struct malidp_plane, base) diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index 2781e462c1ed..c874ef4ac005 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -84,16 +84,45 @@ static const struct malidp_format_id malidp550_de_formats[] = { }; static const struct malidp_layer malidp500_layers[] = { - { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB }, - { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, - { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, + /* id, base address, fb pointer address base, stride offset, + * yuv2rgb matrix offset, mmu control register offset + */ + { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0 }, + { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, 0 }, + { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, 0 }, }; static const struct malidp_layer malidp550_layers[] = { - { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, - { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, - { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, - { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 }, + /* id, base address, fb pointer address base, stride offset, + * yuv2rgb matrix offset, mmu control register offset + */ + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 }, + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, 0 }, + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 }, + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, + MALIDP550_DE_LS_R1_STRIDE, 0, 0 }, +}; + +static const struct malidp_layer malidp650_layers[] = { + /* id, base address, fb pointer address base, stride offset, + * yuv2rgb matrix offset, mmu control register offset + */ + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, + MALIDP650_DE_LV_MMU_CTRL }, + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL }, + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, + MALIDP650_DE_LV_MMU_CTRL }, + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, + MALIDP550_DE_LS_R1_STRIDE, 0, MALIDP650_DE_LS_MMU_CTRL }, }; #define SE_N_SCALING_COEFFS 96 @@ -853,8 +882,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = { .dc_base = MALIDP550_DC_BASE, .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH, .features = MALIDP_REGMAP_HAS_CLEARIRQ, - .n_layers = ARRAY_SIZE(malidp550_layers), - .layers = malidp550_layers, + .n_layers = ARRAY_SIZE(malidp650_layers), + .layers = malidp650_layers, .de_irq_map = { .irq_mask = MALIDP_DE_IRQ_UNDERRUN | MALIDP650_DE_IRQ_DRIFT | diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h index 9fc94c08190f..0d7f9ea0ade8 100644 --- a/drivers/gpu/drm/arm/malidp_hw.h +++ b/drivers/gpu/drm/arm/malidp_hw.h @@ -62,6 +62,7 @@ struct malidp_layer { u16 ptr; /* address offset for the pointer register */ u16 stride_offset; /* offset to the first stride register. */ s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */ + u16 mmu_ctrl_offset; /* offset to the MMU control register */ }; enum malidp_scaling_coeff_set { diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 39416bcd880e..76aafc296e1b 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -10,11 +10,14 @@ * ARM Mali DP plane manipulation routines. */ +#include + #include #include #include #include #include +#include #include #include @@ -57,6 +60,13 @@ */ #define MALIDP_ALPHA_LUT 0xffaa5500 +/* page sizes the MMU prefetcher can support */ +#define MALIDP_MMU_PREFETCH_PARTIAL_PGSIZES (SZ_4K | SZ_64K) +#define MALIDP_MMU_PREFETCH_FULL_PGSIZES (SZ_1M | SZ_2M) + +/* readahead for partial-frame prefetch */ +#define MALIDP_MMU_PREFETCH_READAHEAD 8 + static void malidp_de_plane_destroy(struct drm_plane *plane) { struct malidp_plane *mp = to_malidp_plane(plane); @@ -101,6 +111,9 @@ drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) state->format = m_state->format; state->n_planes = m_state->n_planes; + state->mmu_prefetch_mode = m_state->mmu_prefetch_mode; + state->mmu_prefetch_pgsize = m_state->mmu_prefetch_pgsize; + return &state->base; } @@ -113,6 +126,12 @@ static void malidp_destroy_plane_state(struct drm_plane *plane, kfree(m_state); } +static const char * const prefetch_mode_names[] = { + [MALIDP_PREFETCH_MODE_NONE] = "MMU_PREFETCH_NONE", + [MALIDP_PREFETCH_MODE_PARTIAL] = "MMU_PREFETCH_PARTIAL", + [MALIDP_PREFETCH_MODE_FULL] = "MMU_PREFETCH_FULL", +}; + static void malidp_plane_atomic_print_state(struct drm_printer *p, const struct drm_plane_state *state) { @@ -121,6 +140,9 @@ static void malidp_plane_atomic_print_state(struct drm_printer *p, drm_printf(p, "\trotmem_size=%u\n", ms->rotmem_size); drm_printf(p, "\tformat_id=%u\n", ms->format); drm_printf(p, "\tn_planes=%u\n", ms->n_planes); + drm_printf(p, "\tmmu_prefetch_mode=%s\n", + prefetch_mode_names[ms->mmu_prefetch_mode]); + drm_printf(p, "\tmmu_prefetch_pgsize=%d\n", ms->mmu_prefetch_pgsize); } static const struct drm_plane_funcs malidp_de_plane_funcs = { @@ -174,6 +196,199 @@ static int malidp_se_check_scaling(struct malidp_plane *mp, return 0; } +static u32 malidp_get_pgsize_bitmap(struct malidp_plane *mp) +{ + u32 pgsize_bitmap = 0; + + if (iommu_present(&platform_bus_type)) { + struct iommu_domain *mmu_dom = + iommu_get_domain_for_dev(mp->base.dev->dev); + + if (mmu_dom) + pgsize_bitmap = mmu_dom->pgsize_bitmap; + } + + return pgsize_bitmap; +} + +/* + * Check if the framebuffer is entirely made up of pages at least pgsize in + * size. Only a heuristic: assumes that each scatterlist entry has been aligned + * to the largest page size smaller than its length and that the MMU maps to + * the largest page size possible. + */ +static bool malidp_check_pages_threshold(struct malidp_plane_state *ms, + u32 pgsize) +{ + int i; + + for (i = 0; i < ms->n_planes; i++) { + struct drm_gem_object *obj; + struct drm_gem_cma_object *cma_obj; + struct sg_table *sgt; + struct scatterlist *sgl; + + obj = drm_gem_fb_get_obj(ms->base.fb, i); + cma_obj = to_drm_gem_cma_obj(obj); + + if (cma_obj->sgt) + sgt = cma_obj->sgt; + else + sgt = obj->dev->driver->gem_prime_get_sg_table(obj); + + if (!sgt) + return false; + + sgl = sgt->sgl; + + while (sgl) { + if (sgl->length < pgsize) { + if (!cma_obj->sgt) + kfree(sgt); + return false; + } + + sgl = sg_next(sgl); + } + if (!cma_obj->sgt) + kfree(sgt); + } + + return true; +} + +/* + * Check if it is possible to enable partial-frame MMU prefetch given the + * current format, AFBC state and rotation. + */ +static bool malidp_partial_prefetch_supported(u32 format, u64 modifier, + unsigned int rotation) +{ + bool afbc, sparse; + + /* rotation and horizontal flip not supported for partial prefetch */ + if (rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | + DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X)) + return false; + + afbc = modifier & DRM_FORMAT_MOD_ARM_AFBC(0); + sparse = modifier & AFBC_FORMAT_MOD_SPARSE; + + switch (format) { + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRA8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_BGRX8888: + case DRM_FORMAT_RGB888: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_RGB565: + /* always supported */ + return true; + + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_BGR565: + /* supported, but if AFBC then must be sparse mode */ + return (!afbc) || (afbc && sparse); + + case DRM_FORMAT_BGR888: + /* supported, but not for AFBC */ + return !afbc; + + case DRM_FORMAT_YUYV: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_NV12: + case DRM_FORMAT_YUV420: + /* not supported */ + return false; + + default: + return false; + } +} + +/* + * Select the preferred MMU prefetch mode. Full-frame prefetch is preferred as + * long as the framebuffer is all large pages. Otherwise partial-frame prefetch + * is selected as long as it is supported for the current format. The selected + * page size for prefetch is returned in pgsize_bitmap. + */ +static enum mmu_prefetch_mode malidp_mmu_prefetch_select_mode + (struct malidp_plane_state *ms, u32 *pgsize_bitmap) +{ + u32 pgsizes; + + /* get the full-frame prefetch page size(s) supported by the MMU */ + pgsizes = *pgsize_bitmap & MALIDP_MMU_PREFETCH_FULL_PGSIZES; + + while (pgsizes) { + u32 largest_pgsize = 1 << __fls(pgsizes); + + if (malidp_check_pages_threshold(ms, largest_pgsize)) { + *pgsize_bitmap = largest_pgsize; + return MALIDP_PREFETCH_MODE_FULL; + } + + pgsizes -= largest_pgsize; + } + + /* get the partial-frame prefetch page size(s) supported by the MMU */ + pgsizes = *pgsize_bitmap & MALIDP_MMU_PREFETCH_PARTIAL_PGSIZES; + + if (malidp_partial_prefetch_supported(ms->base.fb->format->format, + ms->base.fb->modifier, + ms->base.rotation)) { + /* partial prefetch using the smallest page size */ + *pgsize_bitmap = 1 << __ffs(pgsizes); + return MALIDP_PREFETCH_MODE_PARTIAL; + } + *pgsize_bitmap = 0; + return MALIDP_PREFETCH_MODE_NONE; +} + +static u32 malidp_calc_mmu_control_value(enum mmu_prefetch_mode mode, + u8 readahead, u8 n_planes, u32 pgsize) +{ + u32 mmu_ctrl = 0; + + if (mode != MALIDP_PREFETCH_MODE_NONE) { + mmu_ctrl |= MALIDP_MMU_CTRL_EN; + + if (mode == MALIDP_PREFETCH_MODE_PARTIAL) { + mmu_ctrl |= MALIDP_MMU_CTRL_MODE; + mmu_ctrl |= MALIDP_MMU_CTRL_PP_NUM_REQ(readahead); + } + + if (pgsize == SZ_64K || pgsize == SZ_2M) { + int i; + + for (i = 0; i < n_planes; i++) + mmu_ctrl |= MALIDP_MMU_CTRL_PX_PS(i); + } + } + + return mmu_ctrl; +} + +static void malidp_de_prefetch_settings(struct malidp_plane *mp, + struct malidp_plane_state *ms) +{ + if (!mp->layer->mmu_ctrl_offset) + return; + + /* get the page sizes supported by the MMU */ + ms->mmu_prefetch_pgsize = malidp_get_pgsize_bitmap(mp); + ms->mmu_prefetch_mode = + malidp_mmu_prefetch_select_mode(ms, &ms->mmu_prefetch_pgsize); +} + static int malidp_de_plane_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -250,6 +465,8 @@ static int malidp_de_plane_check(struct drm_plane *plane, fb->format->has_alpha) return -EINVAL; + malidp_de_prefetch_settings(mp, ms); + return 0; } @@ -326,6 +543,24 @@ static void malidp_de_set_color_encoding(struct malidp_plane *plane, } } +static void malidp_de_set_mmu_control(struct malidp_plane *mp, + struct malidp_plane_state *ms) +{ + u32 mmu_ctrl; + + /* check hardware supports MMU prefetch */ + if (!mp->layer->mmu_ctrl_offset) + return; + + mmu_ctrl = malidp_calc_mmu_control_value(ms->mmu_prefetch_mode, + MALIDP_MMU_PREFETCH_READAHEAD, + ms->n_planes, + ms->mmu_prefetch_pgsize); + + malidp_hw_write(mp->hwdev, mmu_ctrl, + mp->layer->base + mp->layer->mmu_ctrl_offset); +} + static void malidp_de_plane_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -358,6 +593,9 @@ static void malidp_de_plane_update(struct drm_plane *plane, malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr); malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4); } + + malidp_de_set_mmu_control(mp, ms); + malidp_de_set_plane_pitches(mp, ms->n_planes, state->fb->pitches); diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h index 6ffe849774f2..7ce3e141464d 100644 --- a/drivers/gpu/drm/arm/malidp_regs.h +++ b/drivers/gpu/drm/arm/malidp_regs.h @@ -247,6 +247,17 @@ #define MALIDP550_CONFIG_VALID 0x0c014 #define MALIDP550_CONFIG_ID 0x0ffd4 +/* register offsets specific to DP650 */ +#define MALIDP650_DE_LV_MMU_CTRL 0x000D0 +#define MALIDP650_DE_LG_MMU_CTRL 0x00048 +#define MALIDP650_DE_LS_MMU_CTRL 0x00078 + +/* bit masks to set the MMU control register */ +#define MALIDP_MMU_CTRL_EN (1 << 0) +#define MALIDP_MMU_CTRL_MODE (1 << 4) +#define MALIDP_MMU_CTRL_PX_PS(x) (1 << (8 + (x))) +#define MALIDP_MMU_CTRL_PP_NUM_REQ(x) (((x) & 0x7f) << 12) + /* * Starting with DP550 the register map blocks has been standardised to the * following layout: