These patches were generated from: https://github.com/raspberrypi/linux/commits/rpi-6.12.y With the following command: git format-patch -N v6.12.27..HEAD (HEAD -> 8d3206ee456a5ecdf9ddbfd8e5e231e4f0cd716e) Exceptions: - (def)configs patches - github workflows patches - applied & reverted patches - readme patches - wireless patches Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
110 lines
3.7 KiB
Diff
110 lines
3.7 KiB
Diff
From 709ff25f55abbcdd75ba89fce824f929dac3a761 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
|
|
Date: Mon, 23 Sep 2024 10:55:12 -0300
|
|
Subject: [PATCH] drm/v3d: Support Big/Super Pages when writing out PTEs
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Commit e4c17720262f394f6320a2b6e17a128bfdabb37c upstream
|
|
|
|
The V3D MMU also supports 64KB and 1MB pages, called big and super pages,
|
|
respectively. In order to set a 64KB page or 1MB page in the MMU, we need
|
|
to make sure that page table entries for all 4KB pages within a big/super
|
|
page must be correctly configured.
|
|
|
|
In order to create a big/super page, we need a contiguous memory region.
|
|
That's why we use a separate mountpoint with THP enabled. In order to
|
|
place the page table entries in the MMU, we iterate over the 16 4KB pages
|
|
(for big pages) or 256 4KB pages (for super pages) and insert the PTE.
|
|
|
|
Signed-off-by: Maíra Canal <mcanal@igalia.com>
|
|
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
|
|
Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-9-mcanal@igalia.com
|
|
---
|
|
drivers/gpu/drm/v3d/v3d_drv.h | 1 +
|
|
drivers/gpu/drm/v3d/v3d_mmu.c | 54 ++++++++++++++++++++++++++---------
|
|
2 files changed, 42 insertions(+), 13 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/v3d/v3d_drv.h
|
|
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
|
|
@@ -20,6 +20,7 @@ struct platform_device;
|
|
struct reset_control;
|
|
|
|
#define V3D_MMU_PAGE_SHIFT 12
|
|
+#define V3D_PAGE_FACTOR (PAGE_SIZE >> V3D_MMU_PAGE_SHIFT)
|
|
|
|
#define V3D_MAX_QUEUES (V3D_CPU + 1)
|
|
|
|
--- a/drivers/gpu/drm/v3d/v3d_mmu.c
|
|
+++ b/drivers/gpu/drm/v3d/v3d_mmu.c
|
|
@@ -25,9 +25,16 @@
|
|
* superpage bit set.
|
|
*/
|
|
#define V3D_PTE_SUPERPAGE BIT(31)
|
|
+#define V3D_PTE_BIGPAGE BIT(30)
|
|
#define V3D_PTE_WRITEABLE BIT(29)
|
|
#define V3D_PTE_VALID BIT(28)
|
|
|
|
+static bool v3d_mmu_is_aligned(u32 page, u32 page_address, size_t alignment)
|
|
+{
|
|
+ return IS_ALIGNED(page, alignment >> V3D_MMU_PAGE_SHIFT) &&
|
|
+ IS_ALIGNED(page_address, alignment >> V3D_MMU_PAGE_SHIFT);
|
|
+}
|
|
+
|
|
int v3d_mmu_flush_all(struct v3d_dev *v3d)
|
|
{
|
|
int ret;
|
|
@@ -78,19 +85,40 @@ void v3d_mmu_insert_ptes(struct v3d_bo *
|
|
struct drm_gem_shmem_object *shmem_obj = &bo->base;
|
|
struct v3d_dev *v3d = to_v3d_dev(shmem_obj->base.dev);
|
|
u32 page = bo->node.start;
|
|
- u32 page_prot = V3D_PTE_WRITEABLE | V3D_PTE_VALID;
|
|
- struct sg_dma_page_iter dma_iter;
|
|
+ struct scatterlist *sgl;
|
|
+ unsigned int count;
|
|
+
|
|
+ for_each_sgtable_dma_sg(shmem_obj->sgt, sgl, count) {
|
|
+ dma_addr_t dma_addr = sg_dma_address(sgl);
|
|
+ u32 pfn = dma_addr >> V3D_MMU_PAGE_SHIFT;
|
|
+ unsigned int len = sg_dma_len(sgl);
|
|
+
|
|
+ while (len > 0) {
|
|
+ u32 page_prot = V3D_PTE_WRITEABLE | V3D_PTE_VALID;
|
|
+ u32 page_address = page_prot | pfn;
|
|
+ unsigned int i, page_size;
|
|
+
|
|
+ BUG_ON(pfn + V3D_PAGE_FACTOR >= BIT(24));
|
|
+
|
|
+ if (len >= SZ_1M &&
|
|
+ v3d_mmu_is_aligned(page, page_address, SZ_1M)) {
|
|
+ page_size = SZ_1M;
|
|
+ page_address |= V3D_PTE_SUPERPAGE;
|
|
+ } else if (len >= SZ_64K &&
|
|
+ v3d_mmu_is_aligned(page, page_address, SZ_64K)) {
|
|
+ page_size = SZ_64K;
|
|
+ page_address |= V3D_PTE_BIGPAGE;
|
|
+ } else {
|
|
+ page_size = SZ_4K;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < page_size >> V3D_MMU_PAGE_SHIFT; i++) {
|
|
+ v3d->pt[page++] = page_address + i;
|
|
+ pfn++;
|
|
+ }
|
|
|
|
- for_each_sgtable_dma_page(shmem_obj->sgt, &dma_iter, 0) {
|
|
- dma_addr_t dma_addr = sg_page_iter_dma_address(&dma_iter);
|
|
- u32 page_address = dma_addr >> V3D_MMU_PAGE_SHIFT;
|
|
- u32 pte = page_prot | page_address;
|
|
- u32 i;
|
|
-
|
|
- BUG_ON(page_address + (PAGE_SIZE >> V3D_MMU_PAGE_SHIFT) >=
|
|
- BIT(24));
|
|
- for (i = 0; i < PAGE_SIZE >> V3D_MMU_PAGE_SHIFT; i++)
|
|
- v3d->pt[page++] = pte + i;
|
|
+ len -= page_size;
|
|
+ }
|
|
}
|
|
|
|
WARN_ON_ONCE(page - bo->node.start !=
|