[PATCH v5 06/13] media: iris: Route buffers to the matching context bank device
COOLING4d
REVIEWED: 1 (0M)
From: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Date: 2026-09-26 06:35:17
Also in:
linux-arm-msm, linux-iommu, linux-media, lkml
Subsystem:
arm/qualcomm mailing list, media input infrastructure (v4l/dvb), qualcomm iris video accelerator driver, the rest · Maintainers:
Mauro Carvalho Chehab, Vikash Garodia, Dikshita Agarwal, Linus Torvalds
1 review trailer.
The VPU issues DMA through several SMMU streams, and the hardware does not give every stream the same addressable range. The non-pixel stream cannot address the low 600MB of IOVA space, while the pixel stream can address the full range. Add iris_get_cb_dev(), which maps a buffer type to the owning context bank device. Bitstream and internal buffers (BIN, ARP, COMV, LINE, NON_COMV, PERSIST) belong to the non-pixel device, and uncompressed buffers (DPB, PARTIAL, SCRATCH_1, SCRATCH_2, VPSS) to the pixel device. BUF_INPUT and BUF_OUTPUT depend on direction and are resolved from inst->domain: for a decoder the input is non-pixel and the output pixel, and the other way round for an encoder. Fall back to core->dev whenever the relevant context bank device is absent, so platforms still describing "iommus" on the parent iris node behave exactly as before to maintain backward compatibility. Reviewed-by: Dmitry Baryshkov <redacted> Co-developed-by: Vishnu Reddy <redacted> Signed-off-by: Vishnu Reddy <redacted> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com> --- drivers/media/platform/qcom/iris/iris_buffer.c | 8 ++--- drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++++---- drivers/media/platform/qcom/iris/iris_resources.c | 41 +++++++++++++++++++++++ drivers/media/platform/qcom/iris/iris_resources.h | 1 + drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-- 5 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index eb8de60c1177f5e1ab83b90a3c8c80e0b4d1f02e..6e03d13ac1a792c539bf8fe6d26354aa29d7b3a2 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c@@ -531,7 +531,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, enum iris_buffer_type buffer_type, u32 index) { struct iris_buffers *buffers = &inst->buffers[buffer_type]; - struct iris_core *core = inst->core; + struct device *dev = iris_get_cb_dev(inst, buffer_type); struct iris_buffer *buffer; if (!buffers->size)
@@ -547,7 +547,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, buffer->buffer_size = buffers->size; buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING; - buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size, + buffer->kvaddr = dma_alloc_attrs(dev, buffer->buffer_size, &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs); if (!buffer->kvaddr) { kfree(buffer);
@@ -650,10 +650,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) void iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer) { - struct iris_core *core = inst->core; + struct device *dev = iris_get_cb_dev(inst, buffer->type); list_del(&buffer->list); - dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr, + dma_free_attrs(dev, buffer->buffer_size, buffer->kvaddr, buffer->device_addr, buffer->dma_attrs); kfree(buffer); }
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
index bf6db23b53e2106c08f2139b643f8626af8bc40a..ce6a682b0f9ada79f9fae26289db298855d777c2 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c@@ -245,25 +245,26 @@ static void iris_hfi_queue_deinit(struct iris_iface_q_info *iface_q) int iris_hfi_queues_init(struct iris_core *core) { + struct device *dev = core->np_dev ? core->np_dev : core->dev; struct iris_hfi_queue_table_header *q_tbl_hdr; u32 queue_size; /* Iris hardware requires 4K queue alignment */ queue_size = ALIGN((sizeof(*q_tbl_hdr) + (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ)), SZ_4K); - core->iface_q_table_vaddr = dma_alloc_attrs(core->dev, queue_size, + core->iface_q_table_vaddr = dma_alloc_attrs(dev, queue_size, &core->iface_q_table_daddr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!core->iface_q_table_vaddr) { - dev_err(core->dev, "queues alloc and map failed\n"); + dev_err(dev, "queues alloc and map failed\n"); return -ENOMEM; } - core->sfr_vaddr = dma_alloc_attrs(core->dev, SFR_SIZE, + core->sfr_vaddr = dma_alloc_attrs(dev, SFR_SIZE, &core->sfr_daddr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!core->sfr_vaddr) { - dev_err(core->dev, "sfr alloc and map failed\n"); - dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr, + dev_err(dev, "sfr alloc and map failed\n"); + dma_free_attrs(dev, queue_size, core->iface_q_table_vaddr, core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); return -ENOMEM; }
@@ -291,6 +292,7 @@ int iris_hfi_queues_init(struct iris_core *core) void iris_hfi_queues_deinit(struct iris_core *core) { + struct device *dev = core->np_dev ? core->np_dev : core->dev; u32 queue_size; if (!core->iface_q_table_vaddr)
@@ -300,7 +302,7 @@ void iris_hfi_queues_deinit(struct iris_core *core) iris_hfi_queue_deinit(&core->message_queue); iris_hfi_queue_deinit(&core->command_queue); - dma_free_attrs(core->dev, SFR_SIZE, core->sfr_vaddr, + dma_free_attrs(dev, SFR_SIZE, core->sfr_vaddr, core->sfr_daddr, DMA_ATTR_WRITE_COMBINE); core->sfr_vaddr = NULL;
@@ -309,7 +311,7 @@ void iris_hfi_queues_deinit(struct iris_core *core) queue_size = ALIGN(sizeof(struct iris_hfi_queue_table_header) + (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K); - dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr, + dma_free_attrs(dev, queue_size, core->iface_q_table_vaddr, core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); core->iface_q_table_vaddr = NULL;
diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c
index 2c4d34c7bd77d1f78d3572f659da656eb3b12113..a6c3df892ca9888d82414ca6b48c80efbf7b06d0 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.c
+++ b/drivers/media/platform/qcom/iris/iris_resources.c@@ -12,6 +12,7 @@ #include <linux/reset.h> #include "iris_core.h" +#include "iris_instance.h" #include "iris_resources.h" #define BW_THRESHOLD 50000
@@ -138,3 +139,43 @@ int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type return 0; } + +struct device *iris_get_cb_dev(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + struct iris_core *core = inst->core; + struct device *dev = NULL; + + switch (buffer_type) { + case BUF_INPUT: + if (inst->domain == DECODER) + dev = core->np_dev; + else + dev = core->p_dev; + break; + case BUF_OUTPUT: + if (inst->domain == DECODER) + dev = core->p_dev; + else + dev = core->np_dev; + break; + case BUF_DPB: + case BUF_PARTIAL: + case BUF_SCRATCH_1: + case BUF_SCRATCH_2: + case BUF_VPSS: + dev = core->p_dev; + break; + case BUF_BIN: + case BUF_ARP: + case BUF_COMV: + case BUF_LINE: + case BUF_NON_COMV: + case BUF_PERSIST: + dev = core->np_dev; + break; + default: + dev_err(core->dev, "invalid buffer type: %d\n", buffer_type); + } + + return dev ? dev : core->dev; +}
diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
index 6bfbd2dc6db095ec05e53c894e048285f82446c6..a9a5bddb19c24917de4c5dba52567934b77e5c59 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.h
+++ b/drivers/media/platform/qcom/iris/iris_resources.h@@ -15,5 +15,6 @@ int iris_unset_icc_bw(struct iris_core *core); int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw); int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type); int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type); +struct device *iris_get_cb_dev(struct iris_inst *inst, enum iris_buffer_type buffer_type); #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c
index fcbc60016beec693f2ce27927a09a2d51494bc38..064cf0a80748dab1be0515c4c2b6688aeb2b7022 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c@@ -108,7 +108,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ src_vq->drv_priv = inst; src_vq->buf_struct_size = sizeof(struct iris_buffer); src_vq->min_reqbufs_allocation = MIN_BUFFERS; - src_vq->dev = inst->core->dev; + src_vq->dev = iris_get_cb_dev(inst, BUF_INPUT); src_vq->lock = &inst->ctx_q_lock; ret = vb2_queue_init(src_vq); if (ret)
@@ -122,7 +122,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ dst_vq->drv_priv = inst; dst_vq->buf_struct_size = sizeof(struct iris_buffer); dst_vq->min_reqbufs_allocation = MIN_BUFFERS; - dst_vq->dev = inst->core->dev; + dst_vq->dev = iris_get_cb_dev(inst, BUF_OUTPUT); dst_vq->lock = &inst->ctx_q_lock; return vb2_queue_init(dst_vq);
--
2.34.1