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 | 58 +++++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_resources.h | 2 +
drivers/media/platform/qcom/iris/iris_vidc.c | 4 +-
6 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index f1f003a787bf22db6f048c9e682ba8ed2f39bc21..060b12525a63b9dbffa19f23c63f1dc50429069b 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 647f6760f2b7a6bab8a585a13eb03cf60a9c047e..dd3577cf485ac238015f919f663198a575e78dde 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
@@ -176,3 +177,60 @@ int iris_create_child_device_and_map(struct iris_core *core, struct iris_context
return ret;
}
+
+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_NON_SECURE_PIXEL;
+ else if (inst && inst->domain == DECODER)
+ return IRIS_NON_SECURE_BITSTREAM;
+ break;
+ case BUF_OUTPUT:
+ if (inst && inst->domain == ENCODER)
+ return IRIS_NON_SECURE_BITSTREAM;
+ else if (inst && inst->domain == DECODER)
+ return IRIS_NON_SECURE_PIXEL;
+ break;
+ case BUF_DPB:
+ case BUF_VPSS:
+ case BUF_SCRATCH_2:
+ return IRIS_NON_SECURE_PIXEL;
+ case BUF_BIN:
+ case BUF_COMV:
+ case BUF_NON_COMV:
+ case BUF_LINE:
+ case BUF_PERSIST:
+ case BUF_ARP:
+ case BUF_HFI_QUEUE:
+ return IRIS_NON_SECURE_NON_PIXEL;
+ 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
© 2016 - 2026 Red Hat, Inc.