[PATCH v2 1/4] media: qcom: camss: Use contiguous DMA buffers
From: Allan Siriani
Date: Mon Nov 09 2026 - 06:31:08 EST
From: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
The VFE write masters are programmed with a single base address per
plane and then write the whole plane from there. video_buf_init() took
that address from sg_dma_address() of the first scatterlist entry of a
vb2_dma_sg buffer, which is only correct when the whole plane is mapped
as one contiguous range in the device address space.
Neither the driver nor the hardware can handle a plane split across
several DMA segments, so scatter-gather buffers were never really
supported here. The issue stayed dormant because vb2_dma_sg gives no
IOVA contiguity guarantee but still tries hard to keep the number of
segments low, and with an IOMMU dma_map_sgtable() usually maps the
whole table into a single IOVA range. The mapping therefore almost
always came back contiguous in the device address space, so reading
only the first entry happened to work.
Where that does not hold, the write master runs past the first segment
and writes the rest of the frame into memory belonging to someone else.
This recently surfaced as patch proposals enforcing contiguity in
camss itself, walking the scatterlist to verify that the DMA segments
follow each other, which amounts to re-implementing what the dma-contig
framework already provides.
Use vb2_dma_contig instead. It guarantees that each plane is mapped as
a single contiguous range in the device address space, one IOVA range
when an IOMMU is present, physically contiguous memory when there is
none.
Fixes: 0ac2586c410f ("media: camss: Add files which handle the video device nodes")
Reported-by: Allan Siriani <allan@xxxxxxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/all/20261104202313.72494-2-allan@xxxxxxxxxxxxxxxxxxx/
Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx>
Tested-by: Allan Siriani <allan@xxxxxxxxxxxxxxxxxxx> # MSM8226 (no IOMMU), both sensors
Signed-off-by: Allan Siriani <allan@xxxxxxxxxxxxxxxxxxx>
---
drivers/media/platform/qcom/camss/Kconfig | 2 +-
drivers/media/platform/qcom/camss/camss-video.c | 14 ++++----------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/platform/qcom/camss/Kconfig
index b51745c94..e1967bc20 100644
--- a/drivers/media/platform/qcom/camss/Kconfig
+++ b/drivers/media/platform/qcom/camss/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_QCOM_CAMSS
depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
- select VIDEOBUF2_DMA_SG
+ select VIDEOBUF2_DMA_CONTIG
select V4L2_FWNODE
select GENERIC_PHY
imply PHY_QCOM_MIPI_CSI2
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 0852eb6f1..5de6ff5ec 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -13,7 +13,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
-#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-dma-contig.h>
#include "camss-video.h"
#include "camss.h"
@@ -154,16 +154,10 @@ static int video_buf_init(struct vb2_buffer *vb)
vb);
const struct v4l2_pix_format_mplane *format =
&video->active_fmt.fmt.pix_mp;
- struct sg_table *sgt;
unsigned int i;
- for (i = 0; i < format->num_planes; i++) {
- sgt = vb2_dma_sg_plane_desc(vb, i);
- if (!sgt)
- return -EFAULT;
-
- buffer->addr[i] = sg_dma_address(sgt->sgl);
- }
+ for (i = 0; i < format->num_planes; i++)
+ buffer->addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
if (format->pixelformat == V4L2_PIX_FMT_NV12 ||
format->pixelformat == V4L2_PIX_FMT_NV21 ||
@@ -699,7 +693,7 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
q = &video->vb2_q;
q->drv_priv = video;
- q->mem_ops = &vb2_dma_sg_memops;
+ q->mem_ops = &vb2_dma_contig_memops;
q->ops = &msm_video_vb2_q_ops;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
--
2.43.0