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: 8+ 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]
[not found] ` <20261006131920.6870D1F000FF@smtp.kernel.org>
2026-10-07 5:19 ` [RFT 3/5] drm/msm: Extract out map/unmap helpers Karl Mehltretter
2026-10-06 13:09 ` [RFT 4/5] drm/msm: Convert iommu map/unmap to helpers Rob Clark
[not found] ` <20261006132545.8BFD51F000FF@smtp.kernel.org>
2026-10-07 5:23 ` Karl Mehltretter
2026-10-06 13:09 ` [RFT 5/5] drm/msm: Convert map helper to use dma-address 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®