Depending on the buffer type (input, output, internal and interface
queues), associated context bank is selected, if available. Fallback to
parent device for backward compatibility.
Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_resources.h | 2 +
drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
6 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index 9151f43bc6b9c2c34c803de4231d1e6de0bec6c4..95962c19c334f08a74c5b7e8ba978ab631a65e9c 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -335,8 +335,8 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
static int iris_create_internal_buffer(struct iris_inst *inst,
enum iris_buffer_type buffer_type, u32 index)
{
+ struct device *dev = iris_get_cb_dev(inst->core, inst, buffer_type);
struct iris_buffers *buffers = &inst->buffers[buffer_type];
- struct iris_core *core = inst->core;
struct iris_buffer *buffer;
if (!buffers->size)
@@ -352,7 +352,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);
@@ -490,9 +490,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
int 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(core, 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_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h
index 75bb767761824c4c02e0df9b765896cc093be333..9520aa290b44f06ed2004ad89940c19d1c08a3d2 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -28,6 +28,7 @@ struct iris_inst;
* @BUF_SCRATCH_2: buffer to store encoding context data for HW
* @BUF_VPSS: buffer to store VPSS context data for HW
* @BUF_PARTIAL: buffer for AV1 IBC data
+ * @BUF_HFI_QUEUE: buffer for hardware firmware interface queue
* @BUF_TYPE_MAX: max buffer types
*/
enum iris_buffer_type {
@@ -44,6 +45,7 @@ enum iris_buffer_type {
BUF_SCRATCH_2,
BUF_VPSS,
BUF_PARTIAL,
+ BUF_HFI_QUEUE,
BUF_TYPE_MAX,
};
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
index b3ed06297953b902d5ea6c452385a88d5431ac66..c1241fb8dc6519020a063cbba87aed665701d7ae 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
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, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr,
+ dev_err(dev, "sfr alloc and map failed\n");
+ dma_free_attrs(dev, sizeof(*q_tbl_hdr), 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
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 be58e8620086d0f82c2c2bda29247483f5c56d79..65544cb0fa8fc4b250b0a0be1bb900d74b999d35 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.c
+++ b/drivers/media/platform/qcom/iris/iris_resources.c
@@ -13,6 +13,7 @@
#include <linux/reset.h>
#include "iris_core.h"
+#include "iris_instance.h"
#include "iris_resources.h"
#define BW_THRESHOLD 50000
@@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
return 0;
}
+
+static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
+ enum iris_buffer_type buffer_type)
+{
+ switch (buffer_type) {
+ case BUF_INPUT:
+ if (inst && inst->domain == ENCODER)
+ return IRIS_PIXEL_REGION;
+ else if (inst && inst->domain == DECODER)
+ return IRIS_BITSTREAM_REGION;
+ break;
+ case BUF_OUTPUT:
+ if (inst && inst->domain == ENCODER)
+ return IRIS_BITSTREAM_REGION;
+ else if (inst && inst->domain == DECODER)
+ return IRIS_PIXEL_REGION;
+ break;
+ case BUF_BIN:
+ return IRIS_BITSTREAM_REGION;
+ case BUF_DPB:
+ case BUF_PARTIAL:
+ case BUF_SCRATCH_2:
+ case BUF_VPSS:
+ return IRIS_PIXEL_REGION;
+ case BUF_ARP:
+ case BUF_COMV:
+ case BUF_HFI_QUEUE:
+ case BUF_LINE:
+ case BUF_NON_COMV:
+ case BUF_PERSIST:
+ return IRIS_NON_PIXEL_REGION;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
+ enum iris_buffer_type buffer_type)
+{
+ enum iris_buffer_region region;
+ struct device *dev = NULL;
+ int i;
+
+ region = iris_get_region(inst, buffer_type);
+
+ for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
+ if (core->iris_platform_data->cb_data[i].region & region) {
+ dev = core->iris_platform_data->cb_data[i].dev;
+ break;
+ }
+ }
+
+ if (!dev)
+ dev = core->dev;
+
+ return dev;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
index b7efe15facb203eea9ae13d5f0abdcc2ea718b4d..ea31726f1789130fccf6b24540a62b86cb3c36ac 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.h
+++ b/drivers/media/platform/qcom/iris/iris_resources.h
@@ -16,5 +16,7 @@ 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);
int iris_create_child_device_and_map(struct iris_core *core, struct iris_context_bank *cb);
+struct device *iris_get_cb_dev(struct iris_core *core, 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 bd38d84c9cc79d15585ed5dd5f905a37521cb6dc..b61d7941d88662f34a9d2ab3b6c5bd9acf4b5df5 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -107,7 +107,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->core, inst, BUF_INPUT);
src_vq->lock = &inst->ctx_q_lock;
ret = vb2_queue_init(src_vq);
if (ret)
@@ -121,7 +121,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->core, inst, BUF_OUTPUT);
dst_vq->lock = &inst->ctx_q_lock;
return vb2_queue_init(dst_vq);
--
2.34.1
On Fri, Feb 27, 2026 at 07:41:21PM +0530, Vikash Garodia wrote:
> Depending on the buffer type (input, output, internal and interface
> queues), associated context bank is selected, if available. Fallback to
> parent device for backward compatibility.
>
> Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
> drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
> drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
> drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_resources.h | 2 +
> drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
> 6 files changed, 79 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
> index 9151f43bc6b9c2c34c803de4231d1e6de0bec6c4..95962c19c334f08a74c5b7e8ba978ab631a65e9c 100644
> --- a/drivers/media/platform/qcom/iris/iris_buffer.c
> +++ b/drivers/media/platform/qcom/iris/iris_buffer.c
> @@ -335,8 +335,8 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
> static int iris_create_internal_buffer(struct iris_inst *inst,
> enum iris_buffer_type buffer_type, u32 index)
> {
> + struct device *dev = iris_get_cb_dev(inst->core, inst, buffer_type);
> struct iris_buffers *buffers = &inst->buffers[buffer_type];
> - struct iris_core *core = inst->core;
> struct iris_buffer *buffer;
>
> if (!buffers->size)
> @@ -352,7 +352,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);
> @@ -490,9 +490,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
> int 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(core, 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_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h
> index 75bb767761824c4c02e0df9b765896cc093be333..9520aa290b44f06ed2004ad89940c19d1c08a3d2 100644
> --- a/drivers/media/platform/qcom/iris/iris_buffer.h
> +++ b/drivers/media/platform/qcom/iris/iris_buffer.h
> @@ -28,6 +28,7 @@ struct iris_inst;
> * @BUF_SCRATCH_2: buffer to store encoding context data for HW
> * @BUF_VPSS: buffer to store VPSS context data for HW
> * @BUF_PARTIAL: buffer for AV1 IBC data
> + * @BUF_HFI_QUEUE: buffer for hardware firmware interface queue
Separate commit?
> * @BUF_TYPE_MAX: max buffer types
> */
> enum iris_buffer_type {
> @@ -44,6 +45,7 @@ enum iris_buffer_type {
> BUF_SCRATCH_2,
> BUF_VPSS,
> BUF_PARTIAL,
> + BUF_HFI_QUEUE,
> BUF_TYPE_MAX,
> };
>
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
> index b3ed06297953b902d5ea6c452385a88d5431ac66..c1241fb8dc6519020a063cbba87aed665701d7ae 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
> 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, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr,
> + dev_err(dev, "sfr alloc and map failed\n");
> + dma_free_attrs(dev, sizeof(*q_tbl_hdr), 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
> 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 be58e8620086d0f82c2c2bda29247483f5c56d79..65544cb0fa8fc4b250b0a0be1bb900d74b999d35 100644
> --- a/drivers/media/platform/qcom/iris/iris_resources.c
> +++ b/drivers/media/platform/qcom/iris/iris_resources.c
> @@ -13,6 +13,7 @@
> #include <linux/reset.h>
>
> #include "iris_core.h"
> +#include "iris_instance.h"
> #include "iris_resources.h"
>
> #define BW_THRESHOLD 50000
> @@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
>
> return 0;
> }
> +
> +static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
> + enum iris_buffer_type buffer_type)
> +{
> + switch (buffer_type) {
> + case BUF_INPUT:
> + if (inst && inst->domain == ENCODER)
Can inst be NULL here?
> + return IRIS_PIXEL_REGION;
> + else if (inst && inst->domain == DECODER)
> + return IRIS_BITSTREAM_REGION;
Are there any other possibilities than encoder and decoder?
> + break;
> + case BUF_OUTPUT:
> + if (inst && inst->domain == ENCODER)
> + return IRIS_BITSTREAM_REGION;
> + else if (inst && inst->domain == DECODER)
> + return IRIS_PIXEL_REGION;
> + break;
> + case BUF_BIN:
> + return IRIS_BITSTREAM_REGION;
> + case BUF_DPB:
> + case BUF_PARTIAL:
> + case BUF_SCRATCH_2:
> + case BUF_VPSS:
> + return IRIS_PIXEL_REGION;
> + case BUF_ARP:
> + case BUF_COMV:
> + case BUF_HFI_QUEUE:
> + case BUF_LINE:
> + case BUF_NON_COMV:
> + case BUF_PERSIST:
> + return IRIS_NON_PIXEL_REGION;
> + default:
> + return 0;
dev_err(dev, "unsupported buffer type %x\n", buffer_type)
return -EINVAL;
> + }
> +
> + return 0;
Drop
> +}
> +
> +struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
> + enum iris_buffer_type buffer_type)
> +{
> + enum iris_buffer_region region;
> + struct device *dev = NULL;
> + int i;
> +
> + region = iris_get_region(inst, buffer_type);
> +
> + for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
> + if (core->iris_platform_data->cb_data[i].region & region) {
> + dev = core->iris_platform_data->cb_data[i].dev;
> + break;
> + }
You really seem to overcomplicate things. Replace array search with the
indexed array access. Much easier and much better.
enum iris_buffer_region {
IRIS_PIXEL_REGION,
IRIS_BITSTREAM_REGION,
IRIS_NON_PIXEL_REGION,
// add more when necessary
IRIS_NUM_REGIONS,
};
struct iris_core {
struct iris_cb_device cb_devices[IRIS_NUM_REGIONS];
};
region = iris_get_region(inst, buffer_type);
dev = core->cb_devices[region];
if (!dev)
dev = core->dev;
> + }
> +
> + if (!dev)
> + dev = core->dev;
> +
> + return dev;
> +}
> diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
> index b7efe15facb203eea9ae13d5f0abdcc2ea718b4d..ea31726f1789130fccf6b24540a62b86cb3c36ac 100644
> --- a/drivers/media/platform/qcom/iris/iris_resources.h
> +++ b/drivers/media/platform/qcom/iris/iris_resources.h
> @@ -16,5 +16,7 @@ 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);
> int iris_create_child_device_and_map(struct iris_core *core, struct iris_context_bank *cb);
> +struct device *iris_get_cb_dev(struct iris_core *core, 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 bd38d84c9cc79d15585ed5dd5f905a37521cb6dc..b61d7941d88662f34a9d2ab3b6c5bd9acf4b5df5 100644
> --- a/drivers/media/platform/qcom/iris/iris_vidc.c
> +++ b/drivers/media/platform/qcom/iris/iris_vidc.c
> @@ -107,7 +107,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->core, inst, BUF_INPUT);
> src_vq->lock = &inst->ctx_q_lock;
> ret = vb2_queue_init(src_vq);
> if (ret)
> @@ -121,7 +121,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->core, inst, BUF_OUTPUT);
> dst_vq->lock = &inst->ctx_q_lock;
>
> return vb2_queue_init(dst_vq);
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
On 2/28/2026 1:57 AM, Dmitry Baryshkov wrote:
> On Fri, Feb 27, 2026 at 07:41:21PM +0530, Vikash Garodia wrote:
>> Depending on the buffer type (input, output, internal and interface
>> queues), associated context bank is selected, if available. Fallback to
>> parent device for backward compatibility.
>>
>> Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
>> ---
>> drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
>> drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
>> drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
>> drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_resources.h | 2 +
>> drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
>> 6 files changed, 79 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
>> index 9151f43bc6b9c2c34c803de4231d1e6de0bec6c4..95962c19c334f08a74c5b7e8ba978ab631a65e9c 100644
>> --- a/drivers/media/platform/qcom/iris/iris_buffer.c
>> +++ b/drivers/media/platform/qcom/iris/iris_buffer.c
>> @@ -335,8 +335,8 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
>> static int iris_create_internal_buffer(struct iris_inst *inst,
>> enum iris_buffer_type buffer_type, u32 index)
>> {
>> + struct device *dev = iris_get_cb_dev(inst->core, inst, buffer_type);
>> struct iris_buffers *buffers = &inst->buffers[buffer_type];
>> - struct iris_core *core = inst->core;
>> struct iris_buffer *buffer;
>>
>> if (!buffers->size)
>> @@ -352,7 +352,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);
>> @@ -490,9 +490,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
>> int 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(core, 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_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h
>> index 75bb767761824c4c02e0df9b765896cc093be333..9520aa290b44f06ed2004ad89940c19d1c08a3d2 100644
>> --- a/drivers/media/platform/qcom/iris/iris_buffer.h
>> +++ b/drivers/media/platform/qcom/iris/iris_buffer.h
>> @@ -28,6 +28,7 @@ struct iris_inst;
>> * @BUF_SCRATCH_2: buffer to store encoding context data for HW
>> * @BUF_VPSS: buffer to store VPSS context data for HW
>> * @BUF_PARTIAL: buffer for AV1 IBC data
>> + * @BUF_HFI_QUEUE: buffer for hardware firmware interface queue
>
> Separate commit?
sure, introducing the HFI_QUEUE buffer type can be made into a separate
patch.
>
>> * @BUF_TYPE_MAX: max buffer types
>> */
>> enum iris_buffer_type {
>> @@ -44,6 +45,7 @@ enum iris_buffer_type {
>> BUF_SCRATCH_2,
>> BUF_VPSS,
>> BUF_PARTIAL,
>> + BUF_HFI_QUEUE,
>> BUF_TYPE_MAX,
>> };
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
>> index b3ed06297953b902d5ea6c452385a88d5431ac66..c1241fb8dc6519020a063cbba87aed665701d7ae 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
>> 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, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr,
>> + dev_err(dev, "sfr alloc and map failed\n");
>> + dma_free_attrs(dev, sizeof(*q_tbl_hdr), 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 = iris_get_cb_dev(core, NULL, BUF_HFI_QUEUE);
>> 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 be58e8620086d0f82c2c2bda29247483f5c56d79..65544cb0fa8fc4b250b0a0be1bb900d74b999d35 100644
>> --- a/drivers/media/platform/qcom/iris/iris_resources.c
>> +++ b/drivers/media/platform/qcom/iris/iris_resources.c
>> @@ -13,6 +13,7 @@
>> #include <linux/reset.h>
>>
>> #include "iris_core.h"
>> +#include "iris_instance.h"
>> #include "iris_resources.h"
>>
>> #define BW_THRESHOLD 50000
>> @@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
>>
>> return 0;
>> }
>> +
>> +static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
>> + enum iris_buffer_type buffer_type)
>> +{
>> + switch (buffer_type) {
>> + case BUF_INPUT:
>> + if (inst && inst->domain == ENCODER)
>
> Can inst be NULL here?
during queues init/deinit, instances are not created.
>
>> + return IRIS_PIXEL_REGION;
>> + else if (inst && inst->domain == DECODER)
>> + return IRIS_BITSTREAM_REGION;
>
> Are there any other possibilities than encoder and decoder?
will simplify it as
if (inst) {
if (inst->domain == ENCODER)
return IRIS_PIXEL_REGION;
else
return IRIS_BITSTREAM_REGION;
}
>
>> + break;
>> + case BUF_OUTPUT:
>> + if (inst && inst->domain == ENCODER)
>> + return IRIS_BITSTREAM_REGION;
>> + else if (inst && inst->domain == DECODER)
>> + return IRIS_PIXEL_REGION;
>> + break;
>> + case BUF_BIN:
>> + return IRIS_BITSTREAM_REGION;
>> + case BUF_DPB:
>> + case BUF_PARTIAL:
>> + case BUF_SCRATCH_2:
>> + case BUF_VPSS:
>> + return IRIS_PIXEL_REGION;
>> + case BUF_ARP:
>> + case BUF_COMV:
>> + case BUF_HFI_QUEUE:
>> + case BUF_LINE:
>> + case BUF_NON_COMV:
>> + case BUF_PERSIST:
>> + return IRIS_NON_PIXEL_REGION;
>> + default:
>> + return 0;
>
> dev_err(dev, "unsupported buffer type %x\n", buffer_type)
> return -EINVAL;
these are bit fields, returning -EINVAL would still match some bits and
can make the logic as true. 0 can be defined as IRIS_UNKNOWN_REGION
>
>> + }
>> +
>> + return 0;
>
> Drop
>
Ack
>> +}
>> +
>> +struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
>> + enum iris_buffer_type buffer_type)
>> +{
>> + enum iris_buffer_region region;
>> + struct device *dev = NULL;
>> + int i;
>> +
>> + region = iris_get_region(inst, buffer_type);
>> +
>> + for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
>> + if (core->iris_platform_data->cb_data[i].region & region) {
>> + dev = core->iris_platform_data->cb_data[i].dev;
>> + break;
>> + }
>
> You really seem to overcomplicate things. Replace array search with the
> indexed array access. Much easier and much better.
>
> enum iris_buffer_region {
> IRIS_PIXEL_REGION,
> IRIS_BITSTREAM_REGION,
> IRIS_NON_PIXEL_REGION,
> // add more when necessary
> IRIS_NUM_REGIONS,
> };
>
> struct iris_core {
> struct iris_cb_device cb_devices[IRIS_NUM_REGIONS];
> };
>
> region = iris_get_region(inst, buffer_type);
> dev = core->cb_devices[region];
all the regions may/may not be present in all SOC
> if (!dev)
> dev = core->dev;
>
>
>> + }
>> +
>> + if (!dev)
>> + dev = core->dev;
>> +
>> + return dev;
>> +}
>> diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
>> index b7efe15facb203eea9ae13d5f0abdcc2ea718b4d..ea31726f1789130fccf6b24540a62b86cb3c36ac 100644
>> --- a/drivers/media/platform/qcom/iris/iris_resources.h
>> +++ b/drivers/media/platform/qcom/iris/iris_resources.h
>> @@ -16,5 +16,7 @@ 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);
>> int iris_create_child_device_and_map(struct iris_core *core, struct iris_context_bank *cb);
>> +struct device *iris_get_cb_dev(struct iris_core *core, 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 bd38d84c9cc79d15585ed5dd5f905a37521cb6dc..b61d7941d88662f34a9d2ab3b6c5bd9acf4b5df5 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vidc.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vidc.c
>> @@ -107,7 +107,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->core, inst, BUF_INPUT);
>> src_vq->lock = &inst->ctx_q_lock;
>> ret = vb2_queue_init(src_vq);
>> if (ret)
>> @@ -121,7 +121,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->core, inst, BUF_OUTPUT);
>> dst_vq->lock = &inst->ctx_q_lock;
>>
>> return vb2_queue_init(dst_vq);
>>
>> --
>> 2.34.1
>>
>
On Wed, Mar 04, 2026 at 12:46:27AM +0530, Vikash Garodia wrote:
>
>
> On 2/28/2026 1:57 AM, Dmitry Baryshkov wrote:
> > On Fri, Feb 27, 2026 at 07:41:21PM +0530, Vikash Garodia wrote:
> > > Depending on the buffer type (input, output, internal and interface
> > > queues), associated context bank is selected, if available. Fallback to
> > > parent device for backward compatibility.
> > >
> > > Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > > Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > > Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > > ---
> > > drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
> > > drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
> > > drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
> > > drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
> > > drivers/media/platform/qcom/iris/iris_resources.h | 2 +
> > > drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
> > > 6 files changed, 79 insertions(+), 12 deletions(-)
> > >
> > > @@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
> > > return 0;
> > > }
> > > +
> > > +static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
> > > + enum iris_buffer_type buffer_type)
> > > +{
> > > + switch (buffer_type) {
> > > + case BUF_INPUT:
> > > + if (inst && inst->domain == ENCODER)
> >
> > Can inst be NULL here?
>
> during queues init/deinit, instances are not created.
Is this function being called during queues init?
>
> >
> > > + return IRIS_PIXEL_REGION;
> > > + else if (inst && inst->domain == DECODER)
> > > + return IRIS_BITSTREAM_REGION;
> >
> > Are there any other possibilities than encoder and decoder?
>
> will simplify it as
>
> if (inst) {
> if (inst->domain == ENCODER)
> return IRIS_PIXEL_REGION;
> else
> return IRIS_BITSTREAM_REGION;
> }
> >
> > > + break;
> > > + case BUF_OUTPUT:
> > > + if (inst && inst->domain == ENCODER)
> > > + return IRIS_BITSTREAM_REGION;
> > > + else if (inst && inst->domain == DECODER)
> > > + return IRIS_PIXEL_REGION;
> > > + break;
> > > + case BUF_BIN:
> > > + return IRIS_BITSTREAM_REGION;
> > > + case BUF_DPB:
> > > + case BUF_PARTIAL:
> > > + case BUF_SCRATCH_2:
> > > + case BUF_VPSS:
> > > + return IRIS_PIXEL_REGION;
> > > + case BUF_ARP:
> > > + case BUF_COMV:
> > > + case BUF_HFI_QUEUE:
> > > + case BUF_LINE:
> > > + case BUF_NON_COMV:
> > > + case BUF_PERSIST:
> > > + return IRIS_NON_PIXEL_REGION;
> > > + default:
> > > + return 0;
> >
> > dev_err(dev, "unsupported buffer type %x\n", buffer_type)
> > return -EINVAL;
>
> these are bit fields, returning -EINVAL would still match some bits and can
> make the logic as true. 0 can be defined as IRIS_UNKNOWN_REGION
Yes, sounds good.
>
> >
> > > + }
> > > +
> > > + return 0;
> >
> > Drop
> >
>
> Ack
>
> > > +}
> > > +
> > > +struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
> > > + enum iris_buffer_type buffer_type)
> > > +{
> > > + enum iris_buffer_region region;
> > > + struct device *dev = NULL;
> > > + int i;
> > > +
> > > + region = iris_get_region(inst, buffer_type);
> > > +
> > > + for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
> > > + if (core->iris_platform_data->cb_data[i].region & region) {
> > > + dev = core->iris_platform_data->cb_data[i].dev;
> > > + break;
> > > + }
> >
> > You really seem to overcomplicate things. Replace array search with the
> > indexed array access. Much easier and much better.
> >
> > enum iris_buffer_region {
> > IRIS_PIXEL_REGION,
> > IRIS_BITSTREAM_REGION,
> > IRIS_NON_PIXEL_REGION,
> > // add more when necessary
> > IRIS_NUM_REGIONS,
> > };
> >
> > struct iris_core {
> > struct iris_cb_device cb_devices[IRIS_NUM_REGIONS];
> > };
> >
> > region = iris_get_region(inst, buffer_type);
> > dev = core->cb_devices[region];
>
> all the regions may/may not be present in all SOC
You can check for dev != NULL afterwards.
--
With best wishes
Dmitry
On 3/4/2026 3:57 AM, Dmitry Baryshkov wrote:
> On Wed, Mar 04, 2026 at 12:46:27AM +0530, Vikash Garodia wrote:
>>
>>
>> On 2/28/2026 1:57 AM, Dmitry Baryshkov wrote:
>>> On Fri, Feb 27, 2026 at 07:41:21PM +0530, Vikash Garodia wrote:
>>>> Depending on the buffer type (input, output, internal and interface
>>>> queues), associated context bank is selected, if available. Fallback to
>>>> parent device for backward compatibility.
>>>>
>>>> Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>>>> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>>>> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
>>>> ---
>>>> drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
>>>> drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
>>>> drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
>>>> drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
>>>> drivers/media/platform/qcom/iris/iris_resources.h | 2 +
>>>> drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
>>>> 6 files changed, 79 insertions(+), 12 deletions(-)
>>>>
>>>> @@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
>>>> return 0;
>>>> }
>>>> +
>>>> +static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
>>>> + enum iris_buffer_type buffer_type)
>>>> +{
>>>> + switch (buffer_type) {
>>>> + case BUF_INPUT:
>>>> + if (inst && inst->domain == ENCODER)
>>>
>>> Can inst be NULL here?
>>
>> during queues init/deinit, instances are not created.
>
> Is this function being called during queues init?
yes, via iris_get_cb_dev()
>
>>
>>>
>>>> + return IRIS_PIXEL_REGION;
>>>> + else if (inst && inst->domain == DECODER)
>>>> + return IRIS_BITSTREAM_REGION;
>>>
>>> Are there any other possibilities than encoder and decoder?
>>
>> will simplify it as
>>
>> if (inst) {
>> if (inst->domain == ENCODER)
>> return IRIS_PIXEL_REGION;
>> else
>> return IRIS_BITSTREAM_REGION;
>> }
>>>
>>>> + break;
>>>> + case BUF_OUTPUT:
>>>> + if (inst && inst->domain == ENCODER)
>>>> + return IRIS_BITSTREAM_REGION;
>>>> + else if (inst && inst->domain == DECODER)
>>>> + return IRIS_PIXEL_REGION;
>>>> + break;
>>>> + case BUF_BIN:
>>>> + return IRIS_BITSTREAM_REGION;
>>>> + case BUF_DPB:
>>>> + case BUF_PARTIAL:
>>>> + case BUF_SCRATCH_2:
>>>> + case BUF_VPSS:
>>>> + return IRIS_PIXEL_REGION;
>>>> + case BUF_ARP:
>>>> + case BUF_COMV:
>>>> + case BUF_HFI_QUEUE:
>>>> + case BUF_LINE:
>>>> + case BUF_NON_COMV:
>>>> + case BUF_PERSIST:
>>>> + return IRIS_NON_PIXEL_REGION;
>>>> + default:
>>>> + return 0;
>>>
>>> dev_err(dev, "unsupported buffer type %x\n", buffer_type)
>>> return -EINVAL;
>>
>> these are bit fields, returning -EINVAL would still match some bits and can
>> make the logic as true. 0 can be defined as IRIS_UNKNOWN_REGION
>
> Yes, sounds good.
>
>>
>>>
>>>> + }
>>>> +
>>>> + return 0;
>>>
>>> Drop
>>>
>>
>> Ack
>>
>>>> +}
>>>> +
>>>> +struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
>>>> + enum iris_buffer_type buffer_type)
>>>> +{
>>>> + enum iris_buffer_region region;
>>>> + struct device *dev = NULL;
>>>> + int i;
>>>> +
>>>> + region = iris_get_region(inst, buffer_type);
>>>> +
>>>> + for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
>>>> + if (core->iris_platform_data->cb_data[i].region & region) {
>>>> + dev = core->iris_platform_data->cb_data[i].dev;
>>>> + break;
>>>> + }
>>>
>>> You really seem to overcomplicate things. Replace array search with the
>>> indexed array access. Much easier and much better.
>>>
>>> enum iris_buffer_region {
>>> IRIS_PIXEL_REGION,
>>> IRIS_BITSTREAM_REGION,
>>> IRIS_NON_PIXEL_REGION,
>>> // add more when necessary
>>> IRIS_NUM_REGIONS,
>>> };
>>>
>>> struct iris_core {
>>> struct iris_cb_device cb_devices[IRIS_NUM_REGIONS];
>>> };
>>>
>>> region = iris_get_region(inst, buffer_type);
>>> dev = core->cb_devices[region];
>>
>> all the regions may/may not be present in all SOC
>
> You can check for dev != NULL afterwards.
with one CB to multiple region mapping, this logic would not work.
Regards,
Vikash
>
>
On Wed, Mar 04, 2026 at 08:59:24PM +0530, Vikash Garodia wrote:
>
> On 3/4/2026 3:57 AM, Dmitry Baryshkov wrote:
> > On Wed, Mar 04, 2026 at 12:46:27AM +0530, Vikash Garodia wrote:
> > >
> > >
> > > On 2/28/2026 1:57 AM, Dmitry Baryshkov wrote:
> > > > On Fri, Feb 27, 2026 at 07:41:21PM +0530, Vikash Garodia wrote:
> > > > > Depending on the buffer type (input, output, internal and interface
> > > > > queues), associated context bank is selected, if available. Fallback to
> > > > > parent device for backward compatibility.
> > > > >
> > > > > Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > > > > Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > > > > Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > > > > ---
> > > > > drivers/media/platform/qcom/iris/iris_buffer.c | 7 +--
> > > > > drivers/media/platform/qcom/iris/iris_buffer.h | 2 +
> > > > > drivers/media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---
> > > > > drivers/media/platform/qcom/iris/iris_resources.c | 60 +++++++++++++++++++++++
> > > > > drivers/media/platform/qcom/iris/iris_resources.h | 2 +
> > > > > drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
> > > > > 6 files changed, 79 insertions(+), 12 deletions(-)
> > > > >
> > > > > @@ -177,3 +178,62 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
> > > > > return 0;
> > > > > }
> > > > > +
> > > > > +static enum iris_buffer_region iris_get_region(struct iris_inst *inst,
> > > > > + enum iris_buffer_type buffer_type)
> > > > > +{
> > > > > + switch (buffer_type) {
> > > > > + case BUF_INPUT:
> > > > > + if (inst && inst->domain == ENCODER)
> > > >
> > > > Can inst be NULL here?
> > >
> > > during queues init/deinit, instances are not created.
> >
> > Is this function being called during queues init?
>
> yes, via iris_get_cb_dev()
I think this is a part of overcomplication. queue init uses
BUF_HFI_QUEUE, which always maps to NON_PIXEL. If you remove all
indirection and device lists, you can access necessary device directly.
BUF_HFI_QUEUE looks like an extra entity created just to get the device.
>
> >
> > >
> > > >
> > > > > +}
> > > > > +
> > > > > +struct device *iris_get_cb_dev(struct iris_core *core, struct iris_inst *inst,
> > > > > + enum iris_buffer_type buffer_type)
> > > > > +{
> > > > > + enum iris_buffer_region region;
> > > > > + struct device *dev = NULL;
> > > > > + int i;
> > > > > +
> > > > > + region = iris_get_region(inst, buffer_type);
> > > > > +
> > > > > + for (i = 0; i < core->iris_platform_data->cb_data_size; i++) {
> > > > > + if (core->iris_platform_data->cb_data[i].region & region) {
> > > > > + dev = core->iris_platform_data->cb_data[i].dev;
> > > > > + break;
> > > > > + }
> > > >
> > > > You really seem to overcomplicate things. Replace array search with the
> > > > indexed array access. Much easier and much better.
> > > >
> > > > enum iris_buffer_region {
> > > > IRIS_PIXEL_REGION,
> > > > IRIS_BITSTREAM_REGION,
> > > > IRIS_NON_PIXEL_REGION,
> > > > // add more when necessary
> > > > IRIS_NUM_REGIONS,
> > > > };
> > > >
> > > > struct iris_core {
> > > > struct iris_cb_device cb_devices[IRIS_NUM_REGIONS];
> > > > };
> > > >
> > > > region = iris_get_region(inst, buffer_type);
> > > > dev = core->cb_devices[region];
> > >
> > > all the regions may/may not be present in all SOC
> >
> > You can check for dev != NULL afterwards.
>
> with one CB to multiple region mapping, this logic would not work.
I'm not sure I follow. We always need only one CB device and we can
always access it (or check that it's NULL).
--
With best wishes
Dmitry
© 2016 - 2026 Red Hat, Inc.