From patchwork Mon Aug 20 12:50:29 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: 10570325 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 A8AE01575 for ; Mon, 20 Aug 2018 12:51:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9448129384 for ; Mon, 20 Aug 2018 12:51:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87CCB29375; Mon, 20 Aug 2018 12:51:18 +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 9F2DC29384 for ; Mon, 20 Aug 2018 12:51:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8F8646E095; Mon, 20 Aug 2018 12:51:14 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00079.outbound.protection.outlook.com [40.107.0.79]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4AA086E095 for ; Mon, 20 Aug 2018 12:51:13 +0000 (UTC) Received: from e114479-lin.cambridge.arm.com (217.140.106.52) by AM5PR0802MB2547.eurprd08.prod.outlook.com (2603:10a6:203:a0::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1059.21; Mon, 20 Aug 2018 12:51:07 +0000 From: Alexandru Gheorghe To: seanpaul@chromium.org, liviu.dudau@arm.com, brian.starkey@arm.com, malidp@foss.arm.com, airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH] drm/malidp: Enable MMU prefetch on Mali-DP650 Date: Mon, 20 Aug 2018 13:50:29 +0100 Message-Id: <20180820125029.5366-1-alexandru-cosmin.gheorghe@arm.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-Originating-IP: [217.140.106.52] X-ClientProxiedBy: CY4PR06CA0054.namprd06.prod.outlook.com (2603:10b6:903:13d::16) To AM5PR0802MB2547.eurprd08.prod.outlook.com (2603:10a6:203:a0::23) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0e4704ed-cb24-4f15-6f99-08d6069b9a67 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989137)(5600074)(711020)(4618075)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(2017052603328)(7153060)(7193020); SRVR:AM5PR0802MB2547; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 3:8UuXnSnRtwQsl5pnfZCVIioRDHF2CeWaKLAJexyve0IWLdrZIgbqawb+Sit61/WkNoZLJEEg/wkumZkD4vSWXwfQ19waNOdPdwMopsyz/tNJDfy4fkAOGVLBrrBA7xSjN8554vKQcpythbG9Lcmy8GkqvzgBJ9+sNotCgyyQHpo178PN+DJAKJgDCVtI2Lrk38sKLKjgy8xdoc4ScMv8Z4Gq6obnfaZR8p57gqJ/fO+wLcnRenSo1AunMX9dAW9J; 25:urGqbauJxcdYDJlYlwmX1panffhrm39Scxx10U/DRTaChxMTT1dKmxnbDLOTj25E+HPd0SqVLrlgttTpVDRf6nGlI+GalvXh3r0p0Uyk6OCd3HG2hCELZY5pIzKlPd/UWQ6WGRHCxbAEQWl0UPNZATLanRQj8+9yXoq/cKC1ibGf/Gt87+zDDtqbWwzviWYc22cmyVh+kMDnVYmBnM3LVq905d7OUMuA1fSwzQoU9O9UZvycdewueisY5lQnBXanzxYcJUsM467EY6uM+O0O0AgJgMFm4JdZ2FzaheqGbuDttz94RLCxWkyk8uNhKm+wTTiJcEpwHwMF84B5RbqjuA==; 31:+7TD5Pvib7JxPY+XVWkkJ+54c11jtRiu6Qky2YTOSke2t8uwKTfnJd+ogJdEkvyz18aj5NzFNX+b9RJ0vembTFnfERanUB/WRw0UMxZHJHHx/EaPD1R3lVKCjnpzMS0h4ayzoJrlqimbcQOlJgoSgQx3T2+JJtk9GclZhFbPxOu+sRjLvkO0wf3elEZtxslWb50EpPSNuruFPpqUY3+wrJwvAO+EWUJisEaeVxlXh/8= X-MS-TrafficTypeDiagnostic: AM5PR0802MB2547: NoDisclaimer: True X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 20:oWNO6BJWpbut09er7i/zYDBeX0s4GP+H2GmGEsAh+T5IlZ7+/LDGNKf/26cv30NvWcbHthIVQxn4syxl2X/74EpHD+J4k0nlJ2WKeYZeFNekS6h4uX2ygTckgZd1AZPqcQ8pyC8hstPqAyooC7/maidq4qZrMK3JfWMOqXNE9H067NYnDogR5jxIt1cYU2omXx852HowvxbQtCz+/JHwpvkMSOwcyH02LOixBOFi46w2avexxzH2J2GLvvNARbRoT299n0JG1a+FLMj/j76ZrymVirHg4hVZQHaR671ixCv8xReeL8JHS1VujqAMSHq+VzXMDyocLRoHynxD3pIIrg==; 4:KI34O3EpiCWex8MWaDPr3Tiw8n/SVyYJWbQyt8hI8FT2wa61+d1LR10K502cpAZTEtVn7ZZGTD/GqkguLLrbl40KtXabbeAb7TfowFaSA/sxFnLCCAyZg4o+ZxYauNICy/WycjjINAzAUKuEumXojr7kEZxVCkbNLC5WB+y6+n8FjrqTH9YU8dn1veYOEQXBezr8K4a4R7cp6IpGnwuYPASwyMWm8Inj/oUmDgQC5p0GtJE+3mIiKPI9NpxoDm4UIVFHmlAAb9rOyZKG9V7H1y/8jZHgaD+hkvIZEnd2XNM8hsWz94wvWc4ASpWWeMFj 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)(5005006)(8121501046)(823301075)(93006095)(93001095)(3231311)(944501410)(52105095)(10201501046)(3002001)(6055026)(149027)(150027)(6041310)(20161123560045)(20161123564045)(20161123562045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699016); SRVR:AM5PR0802MB2547; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0802MB2547; X-Forefront-PRVS: 0770F75EA9 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(366004)(39860400002)(346002)(376002)(136003)(396003)(189003)(199004)(575784001)(7696005)(14444005)(36756003)(48376002)(86362001)(26005)(6116002)(8676002)(53936002)(1857600001)(16526019)(956004)(186003)(45080400002)(1076002)(2616005)(81156014)(81166006)(66066001)(72206003)(386003)(478600001)(50466002)(316002)(486006)(476003)(5660300001)(3846002)(25786009)(4326008)(105586002)(50226002)(6486002)(16586007)(68736007)(2906002)(8936002)(305945005)(97736004)(7736002)(106356001)(47776003)(54906003)(6666003)(51416003)(52116002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0802MB2547; H:e114479-lin.cambridge.arm.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0802MB2547; 23:+aKHO6n7dfPQb43Apax2pCJwPP+FWmhiimpxgpj?= LjSreOWx1XP1Zjpj6cyle6pEi+LmRUw79OdLYnl5kAG4clpkkPQ40MD7G4lCU0TOCIVny82VBa92zDXEjwJ33Me/5Axc43n0CYVO97YEa/LrQ6BL4+yyBYLIWC2vK3Xxhk0R119VqP7yotWHuFdkwHVDKDtH15eFSvHNOJdsuDta/M+FvkuqODw5ioPAd124GiuLkdKgIfwbkLTAQk6RJSNSNL+dWfN6hw4WyPzUgLCTOYdLlVS327kd1N3cogoB0j2OhA3vaOEtu/vp/fBxRM3GJ9/1II/SdE2LjVub3wO0HUVxcLcmO+SWyMJg9hMn047OEFBo30azhmr+Oo2kklk6t/juiS13NTpS9542V0NWAa2GS4256LSVSp44SRQmyhp9Ed4ATttfderpNcH9ywHqnnlud8MJ4X3MK9LtosVGXkYfmOWUDNXVHuvC3wq/EfDRha+iRUkMSriQFUVxV6WmU+NAcGlhT3MK1PZ+sdyX0v/VrgMJKzVxQ3WmzevtuzmHvdeMCIGvhPnh7VZBeWykR9OnRjqBpbhNaP608dsAw70SFYKFnHnCyo8fZD7Qfohchvb+thUfWR6S5Rk8hY2HyT1ZMCECDg5hvZ7eLWfQquB/9vGofYZxzfQE3BmS/xGRubd5PLThww7C7rKuSLXE4Z7rkom6rf5X0L8/Occq4WHW3i6qId0nKORsIUpLHqBDT5BHZLd/MVHX15Ku9wYcJ/zdJjWuAnvJ9NRmSFH0zcKfE1S1kk20p2IDR64OwdO7tYUDXmSLJFxhANXpRTBp6xa62aOPHMn1GDhiyVPwrYjApxo1j9VVzTDZpZMStaMXyBvwrdi3JMDomK+5OeNnuqtt2quyQfCb7Hs4Xk0WFSRuUCIbRhhshAfn/3Q9bsXRZWmlYmJ/2Uk4csX7XlgpRZMLP0DROm60XnkzQ6485HZK2nBlLLfWzTzqEK69i83DDBjJOBEF2MZQNjUy/B2rdsFj6UTc/2GCAWVHpyrvDp136HyGaEhzuXmJvldgEKhur7QtjSOFCwtudOOwPySJbrfLtqa08QhnZecKVJDMbwVBYpeLgRMKnnOf4Ahy0mbUMQ1AwAZYUxfl7qG+chcw3n0b0McDsFT8JABKO7tmAHroRiIchBhKRGr4n+CqmD1NtKhglKb4ykZASipGOdp/tv6SxNNZ8fuPFx2DT90KzyQ== X-Microsoft-Antispam-Message-Info: SlVUV06v5SLOWOc+6u+uoAx8u632KGOEHQdct2l5JAo4QYUjF1pGNvUc3LqXrZkEGAkGFNLvSv1NP6RsbFvAcERb8Vxx9wf0sAT39WOI4dfGiJCUZ5hzhC0tJjfdntd36FmyVHHuOBnwTnAT5gCGK6x8utZ30/qlgbDoFqy+ZBsbBpou7NXlRaLEb0xuIZEdK1PArLsEVbHj1DOwd/TMbn3qogFW8gJh3lniNNpBqQD66JRQ4KAI272lT59UT0ePM3ok+a5O1biTWNBD9FosLcXncw8VGt6spF66cintQnLWyzYTz15C/jh59XltRC6DRgvjIpEo2RPSQri7ef4sCrPynS0xDaeZ594G6gJbPtg= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 6:JZUgxDLgG6Wyn0bM1Dc53UdmozavdocD3jjfXECAYkOMSpf+rCbwheVFV0ZwEpIaaHHUcKeHlavLVtmdQQ1uBlWGDySpjMqoD6ynPQJTT0ALJlO4yepU92Ep/4VU+tmpAp5dbCC3+ucpFiiQH08MNHoiiIET82l47u8MedMZlR/5HNTBWrxNptYt/NYQTaEueTISCSlfHFioFtL5vGlsNQg54URvWiXdJ3XQfiWF1c5Hk3mn40G8Sk9SaecD95lgUH+28Zhrto8lYxEuSfMwAXZK+20ffGVzZDTUkVA00OZIEiQwxvUYp3l63+c1GanL6w1aL3q6Lzd1iEE63V0RnGJhFgtCbR2HnkN/0hqEPHF/+FO3G3OTHhONgGJxSAIAWfDGRAm9DB4V5iwLu2V7yJEUWF+fLZAJxWkCpvgmBZD7r9SK36znpiYsHrstq/3ExkpexKBuerijtyeh1DdGzA==; 5:uQ9u3bdvJ3Z47EJ4oC3arHAb6NoeMAseEzLFAr7m1cwPjdlZ7+Ec2coJZmkobV1TC6q1uQ/YlEKxPHZ4uz7CoSL+O0+1pVCkpjPI0Fn5+Svm0fJ1b4B2KpgVEgEUdS8vhAN4XRCSQiSkbWUbfNZ0XWyU5U/z3XPir+dwpX7wYwI=; 7:qzgL1n8cbTcM2rofPLfp1xY2GB+JUayUIappZTEgm+UlncCSGAjjeeowK/dzT4i13UjutfG4RtRt3bI4BxonkFNJB5fw+evEvufN+coX5ALQaeFp4lk08uUuCYMO21I6NZYy1ooFZ9bmR4QZ5njQ1QiXCSWk8VRjV/WE8j7oT8NXpuxmqWDFAM9xR4RX/RAAs+8A3YOatGRMB+hHgRUvZ7FAuFM2tWKuccXrrdyD2/6yqnuCwEa9gGOv2BX9mdzd SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Aug 2018 12:51:07.1898 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0e4704ed-cb24-4f15-6f99-08d6069b9a67 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0802MB2547 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. Signed-off-by: Jamie Fox Signed-off-by: Alexandru Gheorghe Acked-by: Liviu Dudau --- drivers/gpu/drm/arm/malidp_drv.h | 9 ++ drivers/gpu/drm/arm/malidp_hw.c | 17 +- drivers/gpu/drm/arm/malidp_hw.h | 1 + drivers/gpu/drm/arm/malidp_planes.c | 233 ++++++++++++++++++++++++++++ drivers/gpu/drm/arm/malidp_regs.h | 11 ++ 5 files changed, 269 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h index e3eb0cb1f385..2d824558216f 100644 --- a/drivers/gpu/drm/arm/malidp_drv.h +++ b/drivers/gpu/drm/arm/malidp_drv.h @@ -53,6 +53,13 @@ struct malidp_plane { struct drm_plane base; struct malidp_hw_device *hwdev; 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 { @@ -63,6 +70,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 c94a4422e0e9..4233be1c5709 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -96,6 +96,19 @@ static const struct malidp_layer malidp550_layers[] = { { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 }, }; +static const struct malidp_layer malidp650_layers[] = { + { 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 static const u16 dp500_se_scaling_coeffs[][SE_N_SCALING_COEFFS] = { [MALIDP_UPSCALING_COEFFS - 1] = { @@ -832,8 +845,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 ad2e96915d44..39b92a9fb810 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 29409a65d864..99c487be9a1d 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 @@ -56,6 +59,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); @@ -103,6 +113,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; } @@ -115,6 +128,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) { @@ -123,6 +142,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 = { @@ -176,6 +198,9 @@ static int malidp_se_check_scaling(struct malidp_plane *mp, return 0; } +static void malidp_de_prefetch_settings(struct malidp_plane *mp, + struct malidp_plane_state *ms); + static int malidp_de_plane_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -245,6 +270,7 @@ static int malidp_de_plane_check(struct drm_plane *plane, ms->rotmem_size = val; } + malidp_de_prefetch_settings(mp, ms); return 0; } @@ -321,6 +347,210 @@ static void malidp_de_set_color_encoding(struct malidp_plane *plane, } } +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 sg_table *sgt; + struct scatterlist *sgl; + + obj = drm_gem_fb_get_obj(ms->base.fb, i); + sgt = obj->dev->driver->gem_prime_get_sg_table(obj); + + if (!sgt) + return false; + + sgl = sgt->sgl; + + while (sgl) { + if (sgl->length < pgsize) { + kfree(sgt); + return false; + } + + sgl = sg_next(sgl); + } + + 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 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) { @@ -351,6 +581,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, plane->state->fb->pitches); diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h index 3579d36b2a71..c60fff4b2aaf 100644 --- a/drivers/gpu/drm/arm/malidp_regs.h +++ b/drivers/gpu/drm/arm/malidp_regs.h @@ -245,6 +245,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: