summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panfrost/panfrost_mmu.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2022-09-11 21:46:57 +1000
committerDave Airlie <airlied@redhat.com>2022-09-11 22:03:07 +1000
commitfb34d8a04e5876552cd0d4f9e14400ee13f116fb (patch)
tree4bdd1c43f67c6c013d2b08b11cecfd576fa1fa4b /drivers/gpu/drm/panfrost/panfrost_mmu.c
parent8284bae723f025cb6a8431566757a3854a3c53eb (diff)
parent5d832b6694e094b176627ed9918a1b21c56fb742 (diff)
Merge tag 'drm-misc-next-2022-09-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.1-rc1: [airlied - fix sun4i_tv build] UAPI Changes: - Hide unregistered connectors from GETCONNECTOR ioctl. - drm/virtio no longer advertises LINEAR modifier, as it doesn't work. - Cross-subsystem Changes: - Fix GPF in udmabuf failure path. Core Changes: - Rework TTM placement to use intersect/compatible functions. - Drop legacy DP-MST support. - More DP-MST related fixes, and move all state into atomic. - Make DRM_MIPI_DBI select DRM_KMS_HELPER. - Add audio_infoframe packing for DP. - Add logging when some atomic check functions fail. - Assorted documentation updates and fixes. Driver Changes: - Assorted cleanups and fixes in msm, lcdif, nouveau, virtio, panel/ilitek, bridge/icn6211, tve200, gma500, bridge/*, panfrost, via, bochs, qxl, sun4i. - Add add AUO B133UAN02.1, IVO M133NW4J-R3, Innolux N120ACA-EA1 eDP panels. - Improve DP-MST modeset state handling in amdgpu, nouveau, i915. - Drop DP-MST from radeon driver, it was broken and only user of legacy DP-MST. - Handle unplugging better in vc4. - Simplify drm cmdparser tests. - Add DP support to ti-sn65dsi86. - Add MT8195 DP support to mediatek. - Support RGB565, XRGB64, and ARGB64 formats in vkms. - Convert sun4i tv support to atomic. - Refactor vc4/vec TV Modesetting, and fix timings. - Use atomic helpers instead of simple display helpers in ssd130x. Maintainer changes: - Add Douglas Anderson as reviewer for panel-edp. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/a489485b-3ebc-c734-0f80-aed963d89efe@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/panfrost/panfrost_mmu.c')
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_mmu.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index b285a8001b1d..e246d914e7f6 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -248,11 +248,15 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev)
mmu_write(pfdev, MMU_INT_MASK, ~0);
}
-static size_t get_pgsize(u64 addr, size_t size)
+static size_t get_pgsize(u64 addr, size_t size, size_t *count)
{
- if (addr & (SZ_2M - 1) || size < SZ_2M)
- return SZ_4K;
+ size_t blk_offset = -addr % SZ_2M;
+ if (blk_offset || size < SZ_2M) {
+ *count = min_not_zero(blk_offset, size) / SZ_4K;
+ return SZ_4K;
+ }
+ *count = size / SZ_2M;
return SZ_2M;
}
@@ -287,12 +291,16 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx, len=%zx", mmu->as, iova, paddr, len);
while (len) {
- size_t pgsize = get_pgsize(iova | paddr, len);
-
- ops->map(ops, iova, paddr, pgsize, prot, GFP_KERNEL);
- iova += pgsize;
- paddr += pgsize;
- len -= pgsize;
+ size_t pgcount, mapped = 0;
+ size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
+
+ ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
+ GFP_KERNEL, &mapped);
+ /* Don't get stuck if things have gone wrong */
+ mapped = max(mapped, pgsize);
+ iova += mapped;
+ paddr += mapped;
+ len -= mapped;
}
}
@@ -344,15 +352,17 @@ void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping)
mapping->mmu->as, iova, len);
while (unmapped_len < len) {
- size_t unmapped_page;
- size_t pgsize = get_pgsize(iova, len - unmapped_len);
-
- if (ops->iova_to_phys(ops, iova)) {
- unmapped_page = ops->unmap(ops, iova, pgsize, NULL);
- WARN_ON(unmapped_page != pgsize);
+ size_t unmapped_page, pgcount;
+ size_t pgsize = get_pgsize(iova, len - unmapped_len, &pgcount);
+
+ if (bo->is_heap)
+ pgcount = 1;
+ if (!bo->is_heap || ops->iova_to_phys(ops, iova)) {
+ unmapped_page = ops->unmap_pages(ops, iova, pgsize, pgcount, NULL);
+ WARN_ON(unmapped_page != pgsize * pgcount);
}
- iova += pgsize;
- unmapped_len += pgsize;
+ iova += pgsize * pgcount;
+ unmapped_len += pgsize * pgcount;
}
panfrost_mmu_flush_range(pfdev, mapping->mmu,