From: Rob Clark <robin.clark@oss.qualcomm.com>
To: dri-devel@lists.freedesktop.org
Cc: linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
"Jianfeng Liu" <liujianfeng1994@gmail.com>,
"Christian König" <christian.koenig@amd.com>,
"Rob Clark" <robin.clark@oss.qualcomm.com>,
"Dmitry Baryshkov" <lumag@kernel.org>,
"Abhinav Kumar" <abhinav.kumar@linux.dev>,
"Jessica Zhang" <jesszhan0024@gmail.com>,
"Sean Paul" <sean@poorly.run>,
"Marijn Suijten" <marijn.suijten@somainline.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
linux-kernel@vger.kernel.org (open list)
Subject: [RFT 3/5] drm/msm: Extract out map/unmap helpers
Date: Tue, 6 Oct 2026 06:09:54 -0700 [thread overview]
Message-ID: <20261006131000.81501-4-robin.clark@oss.qualcomm.com> (raw)
In-Reply-To: <20261006131000.81501-1-robin.clark@oss.qualcomm.com>
We're going to re-use these in the next commit. No functional changes,
just some ugly callbacks.
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
---
drivers/gpu/drm/msm/msm_iommu.c | 150 ++++++++++++++++++++------------
1 file changed, 93 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index da6782fca6bd..a658493f8007 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -52,9 +52,8 @@ static struct msm_iommu_pagetable *to_pagetable(struct msm_mmu *mmu)
}
/* based on iommu_pgsize() in iommu.c: */
-static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
- unsigned long iova, phys_addr_t paddr,
- size_t size, size_t *count)
+static size_t calc_pgsize(unsigned long pgsize_bitmap, unsigned long iova,
+ phys_addr_t paddr, size_t size, size_t *count)
{
unsigned int pgsize_idx, pgsize_idx_next;
unsigned long pgsizes;
@@ -62,7 +61,7 @@ static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
unsigned long addr_merge = paddr | iova;
/* Page sizes supported by the hardware and small enough for @size */
- pgsizes = pagetable->pgsize_bitmap & GENMASK(__fls(size), 0);
+ pgsizes = pgsize_bitmap & GENMASK(__fls(size), 0);
/* Constrain the page sizes further based on the maximum alignment */
if (likely(addr_merge))
@@ -78,7 +77,7 @@ static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
return pgsize;
/* Find the next biggest support page size, if it exists */
- pgsizes = pagetable->pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
+ pgsizes = pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
if (!pgsizes)
goto out_set_count;
@@ -107,24 +106,27 @@ static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
return pgsize;
}
-static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
- size_t size)
+typedef size_t (*unmap_fn)(void *arg, u64 iova, size_t pgsize, size_t count);
+typedef int (*map_fn)(void *arg, phys_addr_t paddr, u64 iova, size_t pgsize,
+ size_t pgcount, int prot, size_t *mapped);
+
+static inline int
+__do_unmap(unsigned long pgsize_bitmap, u64 iova, size_t size,
+ void *arg, unmap_fn unmap)
{
- struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
- struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
int ret = 0;
while (size) {
size_t pgsize, count;
ssize_t unmapped;
- pgsize = calc_pgsize(pagetable, iova, iova, size, &count);
+ pgsize = calc_pgsize(pgsize_bitmap, iova, iova, size, &count);
- unmapped = ops->unmap_pages(ops, iova, pgsize, count, NULL);
+ unmapped = unmap(arg, iova, pgsize, count);
if (unmapped <= 0) {
ret = -EINVAL;
/*
- * Continue attempting to unamp the remained of the
+ * Continue attempting to unmap the remained of the
* range, so we don't end up with some dangling
* mapped pages
*/
@@ -135,55 +137,18 @@ static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
size -= unmapped;
}
- iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain);
-
return ret;
}
-static int msm_iommu_pagetable_map_prr(struct msm_mmu *mmu, u64 iova, size_t len, int prot)
-{
- struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
- struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
- struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
- phys_addr_t phys = page_to_phys(iommu->prr_page);
- u64 addr = iova;
-
- while (len) {
- size_t mapped = 0;
- size_t size = PAGE_SIZE;
- int ret;
-
- ret = ops->map_pages(ops, addr, phys, size, 1, prot, GFP_KERNEL, &mapped);
-
- /* map_pages could fail after mapping some of the pages,
- * so update the counters before error handling.
- */
- addr += mapped;
- len -= mapped;
-
- if (ret) {
- msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
- struct sg_table *sgt, size_t off, size_t len,
- int prot)
+static inline int
+__do_map(unsigned long pgsize_bitmap, u64 iova, struct sg_table *sgt, size_t off,
+ size_t len, int prot, void *arg, map_fn map, unmap_fn unmap)
{
- struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
- struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
struct scatterlist *sg;
u64 addr = iova;
unsigned int i;
- if (!sgt)
- return msm_iommu_pagetable_map_prr(mmu, iova, len, prot);
-
- for_each_sgtable_sg(sgt, sg, i) {
+ for_each_sgtable_sg (sgt, sg, i) {
size_t size = sg->length;
phys_addr_t phys = sg_phys(sg);
@@ -204,10 +169,9 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
size_t pgsize, count, mapped = 0;
int ret;
- pgsize = calc_pgsize(pagetable, addr, phys, size, &count);
+ pgsize = calc_pgsize(pgsize_bitmap, addr, phys, size, &count);
- ret = ops->map_pages(ops, addr, phys, pgsize, count,
- prot, GFP_KERNEL, &mapped);
+ ret = map(arg, phys, addr, pgsize, count, prot, &mapped);
/* map_pages could fail after mapping some of the pages,
* so update the counters before error handling.
@@ -218,7 +182,7 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
len -= mapped;
if (ret) {
- msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
+ __do_unmap(pgsize_bitmap, iova, addr - iova, arg, unmap);
return -EINVAL;
}
}
@@ -227,6 +191,78 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
return 0;
}
+static size_t
+__unmap_pgtable(void *arg, u64 iova, size_t pgsize, size_t pgcount)
+{
+ struct io_pgtable_ops *ops = arg;
+ return ops->unmap_pages(ops, iova, pgsize, pgcount, NULL);
+}
+
+static int
+__map_pgtable(void *arg, phys_addr_t paddr, u64 iova, size_t pgsize,
+ size_t pgcount, int prot, size_t *mapped)
+{
+ struct io_pgtable_ops *ops = arg;
+ return ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, GFP_KERNEL, mapped);
+}
+
+static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova, size_t size)
+{
+ struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+ struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+ int ret = 0;
+
+ ret = __do_unmap(pagetable->pgsize_bitmap, iova, size, ops, __unmap_pgtable);
+
+ iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain);
+
+ return ret;
+}
+
+static int msm_iommu_pagetable_map_prr(struct msm_mmu *mmu, u64 iova, size_t len, int prot)
+{
+ struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+ struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+ struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
+ phys_addr_t phys = page_to_phys(iommu->prr_page);
+ u64 addr = iova;
+
+ while (len) {
+ size_t mapped = 0;
+ size_t size = PAGE_SIZE;
+ int ret;
+
+ ret = ops->map_pages(ops, addr, phys, size, 1, prot, GFP_KERNEL, &mapped);
+
+ /* map_pages could fail after mapping some of the pages,
+ * so update the counters before error handling.
+ */
+ addr += mapped;
+ len -= mapped;
+
+ if (ret) {
+ msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
+ struct sg_table *sgt, size_t off, size_t len,
+ int prot)
+{
+ struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+ struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+
+ if (!sgt)
+ return msm_iommu_pagetable_map_prr(mmu, iova, len, prot);
+
+ return __do_map(pagetable->pgsize_bitmap, iova, sgt, off, len, prot,
+ ops, __map_pgtable, __unmap_pgtable);
+}
+
static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
{
struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
--
2.55.0
next prev parent reply other threads:[~2026-10-06 13:10 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 13:09 [RFT 0/5] drm/msm: DMABUF_DEBUG fixes Rob Clark
2026-10-06 13:09 ` [RFT 1/5] drm/msm: Cleanup if pages_to_sg() fails Rob Clark
2026-10-06 13:09 ` [RFT 2/5] drm/msm/gem: dma_map/unmap_sgtable() Rob Clark
2026-10-06 13:09 ` Rob Clark [this message]
2026-10-06 13:19 ` [RFT 3/5] drm/msm: Extract out map/unmap helpers sashiko-bot
2026-10-07 5:19 ` Karl Mehltretter
2026-10-07 15:13 ` Rob Clark
2026-10-06 13:09 ` [RFT 4/5] drm/msm: Convert iommu map/unmap to helpers Rob Clark
2026-10-06 13:25 ` sashiko-bot
2026-10-07 5:23 ` Karl Mehltretter
2026-10-07 15:14 ` Rob Clark
2026-10-06 13:09 ` [RFT 5/5] drm/msm: Convert map helper to use dma-address Rob Clark
2026-10-07 13:15 ` [RFT 0/5] drm/msm: DMABUF_DEBUG fixes Jianfeng Liu
2026-10-07 15:54 ` Rob Clark
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261006131000.81501-4-robin.clark@oss.qualcomm.com \
--to=robin.clark@oss.qualcomm.com \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jesszhan0024@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liujianfeng1994@gmail.com \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.