mirror of
https://github.com/armbian/build.git
synced 2025-08-15 15:46:58 +02:00
1478 lines
46 KiB
Diff
1478 lines
46 KiB
Diff
From 1d0c9406d6b3174c928b1bd745912e63dfa4106e Mon Sep 17 00:00:00 2001
|
|
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
|
Date: Fri, 7 Feb 2025 13:24:59 +0530
|
|
Subject: [PATCH] media: iris: allocate, initialize and queue internal buffers
|
|
|
|
Implement the functions for creating, queueing, releasing and destroying
|
|
the buffers for internal usage.
|
|
|
|
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS 13 9345)
|
|
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
|
|
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
|
|
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
|
|
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-19-ab66eeffbd20@quicinc.com
|
|
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
|
|
---
|
|
.../media/platform/qcom/iris/iris_buffer.c | 206 ++++++++++++++++
|
|
.../media/platform/qcom/iris/iris_buffer.h | 7 +
|
|
.../platform/qcom/iris/iris_hfi_common.h | 4 +
|
|
.../qcom/iris/iris_hfi_gen1_command.c | 127 +++++++++-
|
|
.../qcom/iris/iris_hfi_gen1_defines.h | 37 +++
|
|
.../qcom/iris/iris_hfi_gen1_response.c | 4 +
|
|
.../qcom/iris/iris_hfi_gen2_command.c | 132 ++++++++++
|
|
.../qcom/iris/iris_hfi_gen2_defines.h | 9 +
|
|
.../platform/qcom/iris/iris_hfi_gen2_packet.h | 41 +++
|
|
.../qcom/iris/iris_hfi_gen2_response.c | 149 ++++++++++-
|
|
.../platform/qcom/iris/iris_platform_common.h | 5 +
|
|
.../platform/qcom/iris/iris_platform_sm8550.c | 17 ++
|
|
drivers/media/platform/qcom/iris/iris_vdec.c | 32 +++
|
|
drivers/media/platform/qcom/iris/iris_vidc.c | 11 +
|
|
.../platform/qcom/iris/iris_vpu_buffer.c | 233 +++++++++++++++++-
|
|
.../platform/qcom/iris/iris_vpu_buffer.h | 77 +++++-
|
|
16 files changed, 1087 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
|
|
index 58d45d23393b..e9d372580b5f 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
|
|
@@ -7,6 +7,7 @@
|
|
|
|
#include "iris_buffer.h"
|
|
#include "iris_instance.h"
|
|
+#include "iris_vpu_buffer.h"
|
|
|
|
#define PIXELS_4K 4096
|
|
#define MAX_WIDTH 4096
|
|
@@ -228,6 +229,211 @@ int iris_get_buffer_size(struct iris_inst *inst,
|
|
}
|
|
}
|
|
|
|
+static void iris_fill_internal_buf_info(struct iris_inst *inst,
|
|
+ enum iris_buffer_type buffer_type)
|
|
+{
|
|
+ struct iris_buffers *buffers = &inst->buffers[buffer_type];
|
|
+
|
|
+ buffers->size = iris_vpu_buf_size(inst, buffer_type);
|
|
+ buffers->min_count = iris_vpu_buf_count(inst, buffer_type);
|
|
+}
|
|
+
|
|
+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
|
|
+{
|
|
+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
|
|
+ const u32 *internal_buf_type;
|
|
+ u32 internal_buffer_count, i;
|
|
+
|
|
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
|
|
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
|
|
+ for (i = 0; i < internal_buffer_count; i++)
|
|
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
|
|
+ } else {
|
|
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
|
|
+ for (i = 0; i < internal_buffer_count; i++)
|
|
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
|
|
+ }
|
|
+}
|
|
+
|
|
+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 iris_buffer *buffer;
|
|
+
|
|
+ if (!buffers->size)
|
|
+ return 0;
|
|
+
|
|
+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
|
|
+ if (!buffer)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ INIT_LIST_HEAD(&buffer->list);
|
|
+ buffer->type = buffer_type;
|
|
+ buffer->index = index;
|
|
+ buffer->buffer_size = buffers->size;
|
|
+ buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING;
|
|
+ list_add_tail(&buffer->list, &buffers->list);
|
|
+
|
|
+ buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size,
|
|
+ &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs);
|
|
+ if (!buffer->kvaddr)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane)
|
|
+{
|
|
+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
|
|
+ u32 internal_buffer_count, i, j;
|
|
+ struct iris_buffers *buffers;
|
|
+ const u32 *internal_buf_type;
|
|
+ int ret;
|
|
+
|
|
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
|
|
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
|
|
+ } else {
|
|
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < internal_buffer_count; i++) {
|
|
+ buffers = &inst->buffers[internal_buf_type[i]];
|
|
+ for (j = 0; j < buffers->min_count; j++) {
|
|
+ ret = iris_create_internal_buffer(inst, internal_buf_type[i], j);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
|
|
+{
|
|
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
|
|
+ int ret;
|
|
+
|
|
+ ret = hfi_ops->session_queue_buf(inst, buf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ buf->attr &= ~BUF_ATTR_DEFERRED;
|
|
+ buf->attr |= BUF_ATTR_QUEUED;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
|
|
+{
|
|
+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
|
|
+ struct iris_buffer *buffer, *next;
|
|
+ struct iris_buffers *buffers;
|
|
+ const u32 *internal_buf_type;
|
|
+ u32 internal_buffer_count, i;
|
|
+ int ret;
|
|
+
|
|
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
|
|
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
|
|
+ } else {
|
|
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
|
|
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < internal_buffer_count; i++) {
|
|
+ buffers = &inst->buffers[internal_buf_type[i]];
|
|
+ list_for_each_entry_safe(buffer, next, &buffers->list, list) {
|
|
+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
|
|
+ continue;
|
|
+ if (buffer->attr & BUF_ATTR_QUEUED)
|
|
+ continue;
|
|
+ ret = iris_queue_buffer(inst, buffer);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
|
|
+{
|
|
+ struct iris_core *core = inst->core;
|
|
+
|
|
+ list_del(&buffer->list);
|
|
+ dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr,
|
|
+ buffer->device_addr, buffer->dma_attrs);
|
|
+ kfree(buffer);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane)
|
|
+{
|
|
+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
|
|
+ struct iris_buffer *buf, *next;
|
|
+ struct iris_buffers *buffers;
|
|
+ const u32 *internal_buf_type;
|
|
+ u32 i, len;
|
|
+ int ret;
|
|
+
|
|
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
|
|
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
|
|
+ len = platform_data->dec_ip_int_buf_tbl_size;
|
|
+ } else {
|
|
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
|
|
+ len = platform_data->dec_op_int_buf_tbl_size;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < len; i++) {
|
|
+ buffers = &inst->buffers[internal_buf_type[i]];
|
|
+ list_for_each_entry_safe(buf, next, &buffers->list, list) {
|
|
+ ret = iris_destroy_internal_buffer(inst, buf);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
|
|
+{
|
|
+ struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST];
|
|
+ struct iris_buffer *buffer, *next;
|
|
+ int ret;
|
|
+ u32 i;
|
|
+
|
|
+ if (!list_empty(&buffers->list))
|
|
+ return 0;
|
|
+
|
|
+ iris_fill_internal_buf_info(inst, BUF_PERSIST);
|
|
+
|
|
+ for (i = 0; i < buffers->min_count; i++) {
|
|
+ ret = iris_create_internal_buffer(inst, BUF_PERSIST, i);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ list_for_each_entry_safe(buffer, next, &buffers->list, list) {
|
|
+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
|
|
+ continue;
|
|
+ if (buffer->attr & BUF_ATTR_QUEUED)
|
|
+ continue;
|
|
+ ret = iris_queue_buffer(inst, buffer);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void iris_vb2_queue_error(struct iris_inst *inst)
|
|
{
|
|
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h
|
|
index ae2ec5637108..73f3a16ff7a2 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
|
|
@@ -102,6 +102,13 @@ struct iris_buffers {
|
|
};
|
|
|
|
int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
|
|
+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane);
|
|
+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);
|
|
+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
|
|
+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);
|
|
+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
|
|
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
|
|
+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
|
|
void iris_vb2_queue_error(struct iris_inst *inst);
|
|
|
|
#endif
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h
|
|
index 1fba5a9292af..c54c88658633 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
|
|
@@ -9,6 +9,8 @@
|
|
#include <linux/types.h>
|
|
#include <media/v4l2-device.h>
|
|
|
|
+#include "iris_buffer.h"
|
|
+
|
|
struct iris_inst;
|
|
struct iris_core;
|
|
|
|
@@ -114,6 +116,8 @@ struct iris_hfi_command_ops {
|
|
void *payload, u32 payload_size);
|
|
int (*session_open)(struct iris_inst *inst);
|
|
int (*session_start)(struct iris_inst *inst, u32 plane);
|
|
+ int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buffer);
|
|
+ int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *buffer);
|
|
int (*session_stop)(struct iris_inst *inst, u32 plane);
|
|
int (*session_close)(struct iris_inst *inst);
|
|
};
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
|
|
index 26fe65ddba8a..603ca485992d 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
|
|
@@ -8,6 +8,24 @@
|
|
#include "iris_instance.h"
|
|
#include "iris_vpu_buffer.h"
|
|
|
|
+static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type)
|
|
+{
|
|
+ switch (buffer_type) {
|
|
+ case BUF_INPUT:
|
|
+ return HFI_BUFFER_INPUT;
|
|
+ case BUF_OUTPUT:
|
|
+ return HFI_BUFFER_OUTPUT;
|
|
+ case BUF_PERSIST:
|
|
+ return HFI_BUFFER_INTERNAL_PERSIST_1;
|
|
+ case BUF_BIN:
|
|
+ return HFI_BUFFER_INTERNAL_SCRATCH;
|
|
+ case BUF_SCRATCH_1:
|
|
+ return HFI_BUFFER_INTERNAL_SCRATCH_1;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
static int iris_hfi_gen1_sys_init(struct iris_core *core)
|
|
{
|
|
struct hfi_sys_init_pkt sys_init_pkt;
|
|
@@ -183,6 +201,111 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
|
|
return ret;
|
|
}
|
|
|
|
+static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf)
|
|
+{
|
|
+ struct hfi_session_set_buffers_pkt *int_pkt;
|
|
+ u32 buffer_type, i;
|
|
+ u32 packet_size;
|
|
+ int ret;
|
|
+
|
|
+ packet_size = struct_size(int_pkt, buffer_info, 1);
|
|
+ int_pkt = kzalloc(packet_size, GFP_KERNEL);
|
|
+ if (!int_pkt)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ int_pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS;
|
|
+ int_pkt->shdr.session_id = inst->session_id;
|
|
+ int_pkt->buffer_size = buf->buffer_size;
|
|
+ int_pkt->min_buffer_size = buf->buffer_size;
|
|
+ int_pkt->num_buffers = 1;
|
|
+ int_pkt->extradata_size = 0;
|
|
+ int_pkt->shdr.hdr.size = packet_size;
|
|
+ for (i = 0; i < int_pkt->num_buffers; i++)
|
|
+ int_pkt->buffer_info[i] = buf->device_addr;
|
|
+ buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type);
|
|
+ if (buffer_type == -EINVAL) {
|
|
+ ret = -EINVAL;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ int_pkt->buffer_type = buffer_type;
|
|
+ ret = iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.size);
|
|
+
|
|
+exit:
|
|
+ kfree(int_pkt);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
|
|
+{
|
|
+ switch (buf->type) {
|
|
+ case BUF_PERSIST:
|
|
+ case BUF_BIN:
|
|
+ case BUF_SCRATCH_1:
|
|
+ return iris_hfi_gen1_queue_internal_buffer(inst, buf);
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct iris_buffer *buf)
|
|
+{
|
|
+ struct hfi_session_release_buffer_pkt *pkt;
|
|
+ u32 packet_size, buffer_type, i;
|
|
+ int ret;
|
|
+
|
|
+ buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type);
|
|
+ if (buffer_type == -EINVAL)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (buffer_type == HFI_BUFFER_INPUT)
|
|
+ return 0;
|
|
+
|
|
+ packet_size = sizeof(*pkt) + sizeof(struct hfi_buffer_info);
|
|
+ pkt = kzalloc(packet_size, GFP_KERNEL);
|
|
+ if (!pkt)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS;
|
|
+ pkt->shdr.session_id = inst->session_id;
|
|
+ pkt->buffer_size = buf->buffer_size;
|
|
+ pkt->num_buffers = 1;
|
|
+
|
|
+ if (buffer_type == HFI_BUFFER_OUTPUT ||
|
|
+ buffer_type == HFI_BUFFER_OUTPUT2) {
|
|
+ struct hfi_buffer_info *bi;
|
|
+
|
|
+ bi = (struct hfi_buffer_info *)pkt->buffer_info;
|
|
+ for (i = 0; i < pkt->num_buffers; i++) {
|
|
+ bi->buffer_addr = buf->device_addr;
|
|
+ bi->extradata_addr = 0;
|
|
+ }
|
|
+ pkt->shdr.hdr.size = packet_size;
|
|
+ } else {
|
|
+ for (i = 0; i < pkt->num_buffers; i++)
|
|
+ pkt->buffer_info[i] = buf->device_addr;
|
|
+ pkt->extradata_size = 0;
|
|
+ pkt->shdr.hdr.size =
|
|
+ sizeof(struct hfi_session_set_buffers_pkt) +
|
|
+ ((pkt->num_buffers) * sizeof(u32));
|
|
+ }
|
|
+
|
|
+ pkt->response_req = true;
|
|
+ pkt->buffer_type = buffer_type;
|
|
+
|
|
+ ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size);
|
|
+ if (ret)
|
|
+ goto exit;
|
|
+
|
|
+ ret = iris_wait_for_session_response(inst, false);
|
|
+
|
|
+exit:
|
|
+ kfree(pkt);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int
|
|
iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet,
|
|
struct iris_inst *inst, u32 ptype, void *pdata)
|
|
@@ -495,7 +618,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
|
|
|
|
if (iris_split_mode_enabled(inst)) {
|
|
bufsz.type = HFI_BUFFER_OUTPUT;
|
|
- bufsz.size = iris_vpu_dec_dpb_size(inst);
|
|
+ bufsz.size = iris_vpu_buf_size(inst, BUF_DPB);
|
|
|
|
ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
|
|
if (ret)
|
|
@@ -600,6 +723,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = {
|
|
.session_set_config_params = iris_hfi_gen1_session_set_config_params,
|
|
.session_set_property = iris_hfi_gen1_session_set_property,
|
|
.session_start = iris_hfi_gen1_session_start,
|
|
+ .session_queue_buf = iris_hfi_gen1_session_queue_buffer,
|
|
+ .session_release_buf = iris_hfi_gen1_session_unset_buffers,
|
|
.session_stop = iris_hfi_gen1_session_stop,
|
|
.session_close = iris_hfi_gen1_session_close,
|
|
};
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
|
|
index 67e7575351d4..cabd91eafc92 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
|
|
@@ -24,11 +24,13 @@
|
|
#define HFI_CMD_SYS_SESSION_END 0x10008
|
|
|
|
#define HFI_CMD_SESSION_SET_PROPERTY 0x11001
|
|
+#define HFI_CMD_SESSION_SET_BUFFERS 0x11002
|
|
|
|
#define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001
|
|
#define HFI_CMD_SESSION_START 0x211002
|
|
#define HFI_CMD_SESSION_STOP 0x211003
|
|
#define HFI_CMD_SESSION_FLUSH 0x211008
|
|
+#define HFI_CMD_SESSION_RELEASE_BUFFERS 0x21100b
|
|
#define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c
|
|
|
|
#define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008
|
|
@@ -53,6 +55,9 @@
|
|
#define HFI_BUFFER_INPUT 0x1
|
|
#define HFI_BUFFER_OUTPUT 0x2
|
|
#define HFI_BUFFER_OUTPUT2 0x3
|
|
+#define HFI_BUFFER_INTERNAL_PERSIST_1 0x5
|
|
+#define HFI_BUFFER_INTERNAL_SCRATCH 0x6
|
|
+#define HFI_BUFFER_INTERNAL_SCRATCH_1 0x7
|
|
|
|
#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5
|
|
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
|
|
@@ -80,6 +85,7 @@
|
|
#define HFI_MSG_SESSION_STOP 0x221003
|
|
#define HFI_MSG_SESSION_FLUSH 0x221006
|
|
#define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a
|
|
+#define HFI_MSG_SESSION_RELEASE_BUFFERS 0x22100c
|
|
|
|
struct hfi_pkt_hdr {
|
|
u32 size;
|
|
@@ -128,11 +134,36 @@ struct hfi_sys_pc_prep_pkt {
|
|
struct hfi_pkt_hdr hdr;
|
|
};
|
|
|
|
+struct hfi_session_set_buffers_pkt {
|
|
+ struct hfi_session_hdr_pkt shdr;
|
|
+ u32 buffer_type;
|
|
+ u32 buffer_size;
|
|
+ u32 extradata_size;
|
|
+ u32 min_buffer_size;
|
|
+ u32 num_buffers;
|
|
+ u32 buffer_info[];
|
|
+};
|
|
+
|
|
struct hfi_session_flush_pkt {
|
|
struct hfi_session_hdr_pkt shdr;
|
|
u32 flush_type;
|
|
};
|
|
|
|
+struct hfi_session_release_buffer_pkt {
|
|
+ struct hfi_session_hdr_pkt shdr;
|
|
+ u32 buffer_type;
|
|
+ u32 buffer_size;
|
|
+ u32 extradata_size;
|
|
+ u32 response_req;
|
|
+ u32 num_buffers;
|
|
+ u32 buffer_info[];
|
|
+};
|
|
+
|
|
+struct hfi_buffer_info {
|
|
+ u32 buffer_addr;
|
|
+ u32 extradata_addr;
|
|
+};
|
|
+
|
|
struct hfi_msg_event_notify_pkt {
|
|
struct hfi_session_hdr_pkt shdr;
|
|
u32 event_id;
|
|
@@ -227,6 +258,12 @@ struct hfi_multi_stream {
|
|
u32 enable;
|
|
};
|
|
|
|
+struct hfi_msg_session_release_buffers_done_pkt {
|
|
+ struct hfi_msg_session_hdr_pkt shdr;
|
|
+ u32 num_buffers;
|
|
+ u32 buffer_info[];
|
|
+};
|
|
+
|
|
struct hfi_msg_sys_debug_pkt {
|
|
struct hfi_pkt_hdr hdr;
|
|
u32 msg_type;
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
|
|
index db5858ec04ea..a84bb00388d9 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
|
|
@@ -176,6 +176,10 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
|
|
.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
|
|
.pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
|
|
},
|
|
+ {
|
|
+ .pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
|
|
+ .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
|
|
+ },
|
|
};
|
|
|
|
static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response)
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
|
|
index dddaa074cae1..cc75231f07f1 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
|
|
@@ -100,6 +100,24 @@ static u32 iris_hfi_gen2_get_port(u32 plane)
|
|
}
|
|
}
|
|
|
|
+static u32 iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buffer_type)
|
|
+{
|
|
+ switch (buffer_type) {
|
|
+ case BUF_INPUT:
|
|
+ case BUF_BIN:
|
|
+ case BUF_COMV:
|
|
+ case BUF_NON_COMV:
|
|
+ case BUF_LINE:
|
|
+ return HFI_PORT_BITSTREAM;
|
|
+ case BUF_OUTPUT:
|
|
+ case BUF_DPB:
|
|
+ return HFI_PORT_RAW;
|
|
+ case BUF_PERSIST:
|
|
+ default:
|
|
+ return HFI_PORT_NONE;
|
|
+ }
|
|
+}
|
|
+
|
|
static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
|
|
u32 plane, u32 payload_type, void *payload,
|
|
u32 payload_size)
|
|
@@ -719,6 +737,118 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
|
|
return iris_wait_for_session_response(inst, false);
|
|
}
|
|
|
|
+static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
|
|
+{
|
|
+ switch (buffer_type) {
|
|
+ case BUF_INPUT:
|
|
+ return HFI_BUFFER_BITSTREAM;
|
|
+ case BUF_OUTPUT:
|
|
+ return HFI_BUFFER_RAW;
|
|
+ case BUF_BIN:
|
|
+ return HFI_BUFFER_BIN;
|
|
+ case BUF_COMV:
|
|
+ return HFI_BUFFER_COMV;
|
|
+ case BUF_NON_COMV:
|
|
+ return HFI_BUFFER_NON_COMV;
|
|
+ case BUF_LINE:
|
|
+ return HFI_BUFFER_LINE;
|
|
+ case BUF_DPB:
|
|
+ return HFI_BUFFER_DPB;
|
|
+ case BUF_PERSIST:
|
|
+ return HFI_BUFFER_PERSIST;
|
|
+ default:
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int iris_set_num_comv(struct iris_inst *inst)
|
|
+{
|
|
+ struct platform_inst_caps *caps;
|
|
+ struct iris_core *core = inst->core;
|
|
+ u32 num_comv;
|
|
+
|
|
+ caps = core->iris_platform_data->inst_caps;
|
|
+ num_comv = caps->num_comv;
|
|
+
|
|
+ return core->hfi_ops->session_set_property(inst,
|
|
+ HFI_PROP_COMV_BUFFER_COUNT,
|
|
+ HFI_HOST_FLAGS_NONE,
|
|
+ HFI_PORT_BITSTREAM,
|
|
+ HFI_PAYLOAD_U32,
|
|
+ &num_comv, sizeof(u32));
|
|
+}
|
|
+
|
|
+static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf)
|
|
+{
|
|
+ memset(buf, 0, sizeof(*buf));
|
|
+ buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type);
|
|
+ buf->index = buffer->index;
|
|
+ buf->base_address = buffer->device_addr;
|
|
+ buf->addr_offset = 0;
|
|
+ buf->buffer_size = buffer->buffer_size;
|
|
+
|
|
+ if (buffer->type == BUF_INPUT)
|
|
+ buf->buffer_size = ALIGN(buffer->buffer_size, 256);
|
|
+ buf->data_offset = buffer->data_offset;
|
|
+ buf->data_size = buffer->data_size;
|
|
+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
|
|
+ buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
|
|
+ buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
|
|
+ buf->timestamp = buffer->timestamp;
|
|
+}
|
|
+
|
|
+static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
|
|
+{
|
|
+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
|
|
+ struct iris_hfi_buffer hfi_buffer;
|
|
+ u32 port;
|
|
+ int ret;
|
|
+
|
|
+ iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
|
|
+ if (buffer->type == BUF_COMV) {
|
|
+ ret = iris_set_num_comv(inst);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
|
|
+ iris_hfi_gen2_packet_session_command(inst,
|
|
+ HFI_CMD_BUFFER,
|
|
+ HFI_HOST_FLAGS_INTR_REQUIRED,
|
|
+ port,
|
|
+ inst->session_id,
|
|
+ HFI_PAYLOAD_STRUCTURE,
|
|
+ &hfi_buffer,
|
|
+ sizeof(hfi_buffer));
|
|
+
|
|
+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
|
|
+ inst_hfi_gen2->packet->size);
|
|
+}
|
|
+
|
|
+static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
|
|
+{
|
|
+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
|
|
+ struct iris_hfi_buffer hfi_buffer;
|
|
+ u32 port;
|
|
+
|
|
+ iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
|
|
+ hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
|
|
+ port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
|
|
+
|
|
+ iris_hfi_gen2_packet_session_command(inst,
|
|
+ HFI_CMD_BUFFER,
|
|
+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
|
|
+ HFI_HOST_FLAGS_INTR_REQUIRED),
|
|
+ port,
|
|
+ inst->session_id,
|
|
+ HFI_PAYLOAD_STRUCTURE,
|
|
+ &hfi_buffer,
|
|
+ sizeof(hfi_buffer));
|
|
+
|
|
+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
|
|
+ inst_hfi_gen2->packet->size);
|
|
+}
|
|
+
|
|
static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
|
|
.sys_init = iris_hfi_gen2_sys_init,
|
|
.sys_image_version = iris_hfi_gen2_sys_image_version,
|
|
@@ -728,6 +858,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
|
|
.session_set_config_params = iris_hfi_gen2_session_set_config_params,
|
|
.session_set_property = iris_hfi_gen2_session_set_property,
|
|
.session_start = iris_hfi_gen2_session_start,
|
|
+ .session_queue_buf = iris_hfi_gen2_session_queue_buffer,
|
|
+ .session_release_buf = iris_hfi_gen2_session_release_buffer,
|
|
.session_stop = iris_hfi_gen2_session_stop,
|
|
.session_close = iris_hfi_gen2_session_close,
|
|
};
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
|
|
index 4fb7a4e4604d..afbdf1f1e68a 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
|
|
@@ -17,6 +17,7 @@
|
|
#define HFI_CMD_CLOSE 0x01000004
|
|
#define HFI_CMD_START 0x01000005
|
|
#define HFI_CMD_STOP 0x01000006
|
|
+#define HFI_CMD_BUFFER 0x01000009
|
|
#define HFI_CMD_SUBSCRIBE_MODE 0x0100000B
|
|
#define HFI_CMD_END 0x01FFFFFF
|
|
|
|
@@ -53,6 +54,7 @@
|
|
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
|
|
#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169
|
|
#define HFI_PROP_NO_OUTPUT 0x0300016a
|
|
+#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193
|
|
#define HFI_PROP_END 0x03FFFFFF
|
|
|
|
#define HFI_SESSION_ERROR_BEGIN 0x04000000
|
|
@@ -106,6 +108,13 @@ enum hfi_buffer_type {
|
|
HFI_BUFFER_VPSS = 0x0000000D,
|
|
};
|
|
|
|
+enum hfi_buffer_host_flags {
|
|
+ HFI_BUF_HOST_FLAG_RELEASE = 0x00000001,
|
|
+ HFI_BUF_HOST_FLAG_READONLY = 0x00000010,
|
|
+ HFI_BUF_HOST_FLAG_CODEC_CONFIG = 0x00000100,
|
|
+ HFI_BUF_HOST_FLAGS_CB_NON_SECURE = 0x00000200,
|
|
+};
|
|
+
|
|
enum hfi_packet_firmware_flags {
|
|
HFI_FW_FLAGS_SUCCESS = 0x00000001,
|
|
HFI_FW_FLAGS_INFORMATION = 0x00000002,
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
|
|
index 0333e37572f6..25b9582349ca 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
|
|
@@ -61,6 +61,47 @@ struct iris_hfi_packet {
|
|
u32 payload[];
|
|
};
|
|
|
|
+/**
|
|
+ * struct iris_hfi_buffer
|
|
+ *
|
|
+ * @type: buffer type indicated by "enum hfi_buffer_type"
|
|
+ * FW needs to return proper type for any buffer command.
|
|
+ * @index: index of the buffer
|
|
+ * @base_address: base address of the buffer.
|
|
+ * This buffer address is always 4KBytes aligned.
|
|
+ * @addr_offset: accessible buffer offset from base address
|
|
+ * Decoder bitstream buffer: 256 Bytes aligned
|
|
+ * Firmware can uniquely identify a buffer based on
|
|
+ * base_address & addr_offset.
|
|
+ * HW can read memory only from base_address+addr_offset.
|
|
+ * @buffer_size: accessible buffer size in bytes starting from addr_offset
|
|
+ * @data_offset: data starts from "base_address + addr_offset + data_offset"
|
|
+ * RAW buffer: data_offset is 0. Restriction: 4KBytes aligned
|
|
+ * decoder bitstream buffer: no restriction (can be any value)
|
|
+ * @data_size: data size in bytes
|
|
+ * @flags: buffer flags. It is represented as bit masks.
|
|
+ * host buffer flags are "enum hfi_buffer_host_flags"
|
|
+ * firmware buffer flags are "enum hfi_buffer_firmware_flags"
|
|
+ * @timestamp: timestamp of the buffer in nano seconds (ns)
|
|
+ * It is Presentation timestamp (PTS) for encoder & decoder.
|
|
+ * Decoder: it is pass through from bitstream to raw buffer.
|
|
+ * firmware does not need to return as part of input buffer done.
|
|
+ * For any internal buffers: there is no timestamp. Host sets as 0.
|
|
+ * @reserved: reserved for future use
|
|
+ */
|
|
+struct iris_hfi_buffer {
|
|
+ u32 type;
|
|
+ u32 index;
|
|
+ u64 base_address;
|
|
+ u32 addr_offset;
|
|
+ u32 buffer_size;
|
|
+ u32 data_offset;
|
|
+ u32 data_size;
|
|
+ u64 timestamp;
|
|
+ u32 flags;
|
|
+ u32 reserved[5];
|
|
+};
|
|
+
|
|
u32 iris_hfi_gen2_get_color_primaries(u32 primaries);
|
|
u32 iris_hfi_gen2_get_transfer_char(u32 characterstics);
|
|
u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients);
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
|
|
index 336b43740b72..9f3764f1903b 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
|
|
@@ -25,6 +25,94 @@ struct iris_hfi_gen2_packet_handle {
|
|
int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
|
|
};
|
|
|
|
+static u32 iris_hfi_gen2_buf_type_to_driver(enum hfi_buffer_type buf_type)
|
|
+{
|
|
+ switch (buf_type) {
|
|
+ case HFI_BUFFER_BITSTREAM:
|
|
+ return BUF_INPUT;
|
|
+ case HFI_BUFFER_RAW:
|
|
+ return BUF_OUTPUT;
|
|
+ case HFI_BUFFER_BIN:
|
|
+ return BUF_BIN;
|
|
+ case HFI_BUFFER_ARP:
|
|
+ return BUF_ARP;
|
|
+ case HFI_BUFFER_COMV:
|
|
+ return BUF_COMV;
|
|
+ case HFI_BUFFER_NON_COMV:
|
|
+ return BUF_NON_COMV;
|
|
+ case HFI_BUFFER_LINE:
|
|
+ return BUF_LINE;
|
|
+ case HFI_BUFFER_DPB:
|
|
+ return BUF_DPB;
|
|
+ case HFI_BUFFER_PERSIST:
|
|
+ return BUF_PERSIST;
|
|
+ default:
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type)
|
|
+{
|
|
+ switch (buffer_type) {
|
|
+ case HFI_BUFFER_BITSTREAM:
|
|
+ case HFI_BUFFER_RAW:
|
|
+ case HFI_BUFFER_BIN:
|
|
+ case HFI_BUFFER_ARP:
|
|
+ case HFI_BUFFER_COMV:
|
|
+ case HFI_BUFFER_NON_COMV:
|
|
+ case HFI_BUFFER_LINE:
|
|
+ case HFI_BUFFER_DPB:
|
|
+ case HFI_BUFFER_PERSIST:
|
|
+ case HFI_BUFFER_VPSS:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
+static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type)
|
|
+{
|
|
+ if (port == HFI_PORT_NONE && buffer_type != HFI_BUFFER_PERSIST)
|
|
+ return false;
|
|
+
|
|
+ if (port != HFI_PORT_BITSTREAM && port != HFI_PORT_RAW)
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *pkt)
|
|
+{
|
|
+ u32 payload_size = 0;
|
|
+
|
|
+ switch (pkt->payload_info) {
|
|
+ case HFI_PAYLOAD_U32:
|
|
+ case HFI_PAYLOAD_S32:
|
|
+ case HFI_PAYLOAD_Q16:
|
|
+ case HFI_PAYLOAD_U32_ENUM:
|
|
+ case HFI_PAYLOAD_32_PACKED:
|
|
+ payload_size = 4;
|
|
+ break;
|
|
+ case HFI_PAYLOAD_U64:
|
|
+ case HFI_PAYLOAD_S64:
|
|
+ case HFI_PAYLOAD_64_PACKED:
|
|
+ payload_size = 8;
|
|
+ break;
|
|
+ case HFI_PAYLOAD_STRUCTURE:
|
|
+ if (pkt->type == HFI_CMD_BUFFER)
|
|
+ payload_size = sizeof(struct iris_hfi_buffer);
|
|
+ break;
|
|
+ default:
|
|
+ payload_size = 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (pkt->size < sizeof(struct iris_hfi_packet) + payload_size)
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt)
|
|
{
|
|
u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE;
|
|
@@ -149,9 +237,65 @@ static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst,
|
|
complete(&inst->completion);
|
|
}
|
|
|
|
+static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst,
|
|
+ struct iris_hfi_buffer *buffer)
|
|
+{
|
|
+ struct iris_buffer *buf, *iter;
|
|
+ struct iris_buffers *buffers;
|
|
+ u32 buf_type;
|
|
+ int ret = 0;
|
|
+ bool found;
|
|
+
|
|
+ buf_type = iris_hfi_gen2_buf_type_to_driver(buffer->type);
|
|
+ buffers = &inst->buffers[buf_type];
|
|
+
|
|
+ found = false;
|
|
+ list_for_each_entry(iter, &buffers->list, list) {
|
|
+ if (iter->device_addr == buffer->base_address) {
|
|
+ found = true;
|
|
+ buf = iter;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!found)
|
|
+ return -EINVAL;
|
|
+
|
|
+ buf->attr &= ~BUF_ATTR_QUEUED;
|
|
+
|
|
+ if (buf->attr & BUF_ATTR_PENDING_RELEASE)
|
|
+ ret = iris_destroy_internal_buffer(inst, buf);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst,
|
|
+ struct iris_hfi_packet *pkt)
|
|
+{
|
|
+ struct iris_hfi_buffer *buffer;
|
|
+
|
|
+ if (pkt->payload_info == HFI_PAYLOAD_NONE)
|
|
+ return 0;
|
|
+
|
|
+ if (!iris_hfi_gen2_validate_packet_payload(pkt)) {
|
|
+ iris_inst_change_state(inst, IRIS_INST_ERROR);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ buffer = (struct iris_hfi_buffer *)((u8 *)pkt + sizeof(*pkt));
|
|
+ if (!iris_hfi_gen2_is_valid_hfi_buffer_type(buffer->type))
|
|
+ return 0;
|
|
+
|
|
+ if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type))
|
|
+ return 0;
|
|
+
|
|
+ return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
|
|
+}
|
|
+
|
|
static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
|
|
struct iris_hfi_packet *pkt)
|
|
{
|
|
+ int ret = 0;
|
|
+
|
|
switch (pkt->type) {
|
|
case HFI_CMD_CLOSE:
|
|
iris_hfi_gen2_handle_session_close(inst, pkt);
|
|
@@ -159,11 +303,14 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
|
|
case HFI_CMD_STOP:
|
|
complete(&inst->completion);
|
|
break;
|
|
+ case HFI_CMD_BUFFER:
|
|
+ ret = iris_hfi_gen2_handle_session_buffer(inst, pkt);
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
- return 0;
|
|
+ return ret;
|
|
}
|
|
|
|
static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
|
|
index 50965450cbb9..de0388a100c3 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
|
|
@@ -67,6 +67,7 @@ struct platform_inst_caps {
|
|
u32 min_frame_height;
|
|
u32 max_frame_height;
|
|
u32 max_mbpf;
|
|
+ u32 num_comv;
|
|
};
|
|
|
|
enum platform_inst_fw_cap_type {
|
|
@@ -151,6 +152,10 @@ struct iris_platform_data {
|
|
unsigned int dec_input_prop_size;
|
|
const u32 *dec_output_prop;
|
|
unsigned int dec_output_prop_size;
|
|
+ const u32 *dec_ip_int_buf_tbl;
|
|
+ unsigned int dec_ip_int_buf_tbl_size;
|
|
+ const u32 *dec_op_int_buf_tbl;
|
|
+ unsigned int dec_op_int_buf_tbl_size;
|
|
};
|
|
|
|
#endif
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
|
|
index 703e48802795..dc51df71c377 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
|
|
@@ -126,6 +126,7 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = {
|
|
.min_frame_height = 96,
|
|
.max_frame_height = 8192,
|
|
.max_mbpf = (8192 * 4352) / 256,
|
|
+ .num_comv = 0,
|
|
};
|
|
|
|
static void iris_set_sm8550_preset_registers(struct iris_core *core)
|
|
@@ -192,6 +193,17 @@ static const u32 sm8550_vdec_subscribe_output_properties[] = {
|
|
HFI_PROP_CABAC_SESSION,
|
|
};
|
|
|
|
+static const u32 sm8550_dec_ip_int_buf_tbl[] = {
|
|
+ BUF_BIN,
|
|
+ BUF_COMV,
|
|
+ BUF_NON_COMV,
|
|
+ BUF_LINE,
|
|
+};
|
|
+
|
|
+static const u32 sm8550_dec_op_int_buf_tbl[] = {
|
|
+ BUF_DPB,
|
|
+};
|
|
+
|
|
struct iris_platform_data sm8550_data = {
|
|
.get_instance = iris_hfi_gen2_get_instance,
|
|
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
|
|
@@ -233,4 +245,9 @@ struct iris_platform_data sm8550_data = {
|
|
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
|
|
.dec_output_prop = sm8550_vdec_subscribe_output_properties,
|
|
.dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
|
|
+
|
|
+ .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
|
|
+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
|
|
+ .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
|
|
+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
|
|
};
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
|
|
index 13902f4e9724..8d489530da31 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
|
|
@@ -273,6 +273,24 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ ret = iris_alloc_and_queue_persist_bufs(inst);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
|
+
|
|
+ ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
return iris_vdec_process_streamon_input(inst);
|
|
}
|
|
|
|
@@ -297,10 +315,24 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
+
|
|
+ ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
ret = iris_vdec_process_streamon_output(inst);
|
|
if (ret)
|
|
goto error;
|
|
|
|
+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
+ if (ret)
|
|
+ goto error;
|
|
+
|
|
return ret;
|
|
|
|
error:
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c
|
|
index 1d10c430c795..ec5694c1c8de 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
|
|
@@ -149,6 +149,15 @@ int iris_open(struct file *filp)
|
|
|
|
mutex_init(&inst->lock);
|
|
mutex_init(&inst->ctx_q_lock);
|
|
+
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_BIN].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_ARP].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_COMV].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_NON_COMV].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_LINE].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list);
|
|
+ INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list);
|
|
init_completion(&inst->completion);
|
|
init_completion(&inst->flush_completion);
|
|
|
|
@@ -221,6 +230,8 @@ int iris_close(struct file *filp)
|
|
iris_session_close(inst);
|
|
iris_inst_change_state(inst, IRIS_INST_DEINIT);
|
|
iris_v4l2_fh_deinit(inst);
|
|
+ iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
|
+ iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
iris_remove_session(inst);
|
|
mutex_unlock(&inst->lock);
|
|
mutex_destroy(&inst->ctx_q_lock);
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
|
|
index 0a65a17f13d2..dce25e410d80 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
|
|
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
|
|
@@ -6,7 +6,167 @@
|
|
#include "iris_instance.h"
|
|
#include "iris_vpu_buffer.h"
|
|
|
|
-u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
|
|
+static u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
|
|
+{
|
|
+ u32 size_yuv, size_bin_hdr, size_bin_res;
|
|
+
|
|
+ size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ?
|
|
+ ((BIN_BUFFER_THRESHOLD * 3) >> 1) :
|
|
+ ((frame_width * frame_height * 3) >> 1);
|
|
+ size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT;
|
|
+ size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT;
|
|
+ size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes,
|
|
+ DMA_ALIGNMENT) * num_vpp_pipes;
|
|
+ size_bin_res = ALIGN(size_bin_res / num_vpp_pipes,
|
|
+ DMA_ALIGNMENT) * num_vpp_pipes;
|
|
+
|
|
+ return size_bin_hdr + size_bin_res;
|
|
+}
|
|
+
|
|
+static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
|
|
+{
|
|
+ u32 n_aligned_h = ALIGN(frame_height, 16);
|
|
+ u32 n_aligned_w = ALIGN(frame_width, 16);
|
|
+
|
|
+ return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);
|
|
+}
|
|
+
|
|
+static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount)
|
|
+{
|
|
+ u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16);
|
|
+ u32 frame_width_in_mbs = DIV_ROUND_UP(frame_width, 16);
|
|
+ u32 col_zero_aligned_width = (frame_width_in_mbs << 2);
|
|
+ u32 col_mv_aligned_width = (frame_width_in_mbs << 7);
|
|
+ u32 col_zero_size, size_colloc;
|
|
+
|
|
+ col_mv_aligned_width = ALIGN(col_mv_aligned_width, 16);
|
|
+ col_zero_aligned_width = ALIGN(col_zero_aligned_width, 16);
|
|
+ col_zero_size = col_zero_aligned_width *
|
|
+ ((frame_height_in_mbs + 1) >> 1);
|
|
+ col_zero_size = ALIGN(col_zero_size, 64);
|
|
+ col_zero_size <<= 1;
|
|
+ col_zero_size = ALIGN(col_zero_size, 512);
|
|
+ size_colloc = col_mv_aligned_width * ((frame_height_in_mbs + 1) >> 1);
|
|
+ size_colloc = ALIGN(size_colloc, 64);
|
|
+ size_colloc <<= 1;
|
|
+ size_colloc = ALIGN(size_colloc, 512);
|
|
+ size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2);
|
|
+
|
|
+ return (size_colloc * (_comv_bufcount)) + 512;
|
|
+}
|
|
+
|
|
+static u32 size_h264d_bse_cmd_buf(u32 frame_height)
|
|
+{
|
|
+ u32 height = ALIGN(frame_height, 32);
|
|
+
|
|
+ return min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) *
|
|
+ SIZE_H264D_BSE_CMD_PER_BUF;
|
|
+}
|
|
+
|
|
+static u32 size_h264d_vpp_cmd_buf(u32 frame_height)
|
|
+{
|
|
+ u32 size, height = ALIGN(frame_height, 32);
|
|
+
|
|
+ size = min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) *
|
|
+ SIZE_H264D_VPP_CMD_PER_BUF;
|
|
+
|
|
+ return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size;
|
|
+}
|
|
+
|
|
+static u32 hfi_buffer_persist_h264d(void)
|
|
+{
|
|
+ return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 +
|
|
+ H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO +
|
|
+ NUM_HW_PIC_BUF * SIZE_SEI_USERDATA,
|
|
+ DMA_ALIGNMENT);
|
|
+}
|
|
+
|
|
+static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
|
|
+{
|
|
+ u32 size_bse, size_vpp, size;
|
|
+
|
|
+ size_bse = size_h264d_bse_cmd_buf(frame_height);
|
|
+ size_vpp = size_h264d_vpp_cmd_buf(frame_height);
|
|
+ size = ALIGN(size_bse, DMA_ALIGNMENT) +
|
|
+ ALIGN(size_vpp, DMA_ALIGNMENT) +
|
|
+ ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
|
|
+
|
|
+ return ALIGN(size, DMA_ALIGNMENT);
|
|
+}
|
|
+
|
|
+static u32 size_vpss_lb(u32 frame_width, u32 frame_height)
|
|
+{
|
|
+ u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;
|
|
+ u32 opb_wr_top_line_chroma_buffer_size;
|
|
+ u32 opb_wr_top_line_luma_buffer_size;
|
|
+ u32 macrotiling_size = 32;
|
|
+
|
|
+ opb_wr_top_line_luma_buffer_size =
|
|
+ ALIGN(frame_width, macrotiling_size) / macrotiling_size * 256;
|
|
+ opb_wr_top_line_luma_buffer_size =
|
|
+ ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) +
|
|
+ (MAX_TILE_COLUMNS - 1) * 256;
|
|
+ opb_wr_top_line_luma_buffer_size =
|
|
+ max_t(u32, opb_wr_top_line_luma_buffer_size, (32 * ALIGN(frame_height, 8)));
|
|
+ opb_wr_top_line_chroma_buffer_size = opb_wr_top_line_luma_buffer_size;
|
|
+ opb_lb_wr_llb_uv_buffer_size =
|
|
+ ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32);
|
|
+ opb_lb_wr_llb_y_buffer_size =
|
|
+ ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32);
|
|
+ return opb_wr_top_line_luma_buffer_size +
|
|
+ opb_wr_top_line_chroma_buffer_size +
|
|
+ opb_lb_wr_llb_uv_buffer_size +
|
|
+ opb_lb_wr_llb_y_buffer_size;
|
|
+}
|
|
+
|
|
+static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
|
|
+ bool is_opb, u32 num_vpp_pipes)
|
|
+{
|
|
+ u32 vpss_lb_size = 0;
|
|
+ u32 size;
|
|
+
|
|
+ size = ALIGN(size_h264d_lb_fe_top_data(frame_width), DMA_ALIGNMENT) +
|
|
+ ALIGN(size_h264d_lb_fe_top_ctrl(frame_width), DMA_ALIGNMENT) +
|
|
+ ALIGN(size_h264d_lb_fe_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
|
|
+ ALIGN(size_h264d_lb_se_top_ctrl(frame_width), DMA_ALIGNMENT) +
|
|
+ ALIGN(size_h264d_lb_se_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes +
|
|
+ ALIGN(size_h264d_lb_pe_top_data(frame_width), DMA_ALIGNMENT) +
|
|
+ ALIGN(size_h264d_lb_vsp_top(frame_width), DMA_ALIGNMENT) +
|
|
+ ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_height), DMA_ALIGNMENT) * 2 +
|
|
+ ALIGN(size_h264d_qp(frame_width, frame_height), DMA_ALIGNMENT);
|
|
+ size = ALIGN(size, DMA_ALIGNMENT);
|
|
+ if (is_opb)
|
|
+ vpss_lb_size = size_vpss_lb(frame_width, frame_height);
|
|
+
|
|
+ return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT);
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_bin_size(struct iris_inst *inst)
|
|
+{
|
|
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
|
+ struct v4l2_format *f = inst->fmt_src;
|
|
+ u32 height = f->fmt.pix_mp.height;
|
|
+ u32 width = f->fmt.pix_mp.width;
|
|
+
|
|
+ return hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)
|
|
+{
|
|
+ u32 num_comv = VIDEO_MAX_FRAME;
|
|
+ struct v4l2_format *f = inst->fmt_src;
|
|
+ u32 height = f->fmt.pix_mp.height;
|
|
+ u32 width = f->fmt.pix_mp.width;
|
|
+
|
|
+ return hfi_buffer_comv_h264d(width, height, num_comv);
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
|
|
+{
|
|
+ return hfi_buffer_persist_h264d();
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
|
|
{
|
|
if (iris_split_mode_enabled(inst))
|
|
return iris_get_buffer_size(inst, BUF_DPB);
|
|
@@ -14,6 +174,70 @@ u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
|
|
return 0;
|
|
}
|
|
|
|
+static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst)
|
|
+{
|
|
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
|
+ struct v4l2_format *f = inst->fmt_src;
|
|
+ u32 height = f->fmt.pix_mp.height;
|
|
+ u32 width = f->fmt.pix_mp.width;
|
|
+
|
|
+ return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
|
|
+{
|
|
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
|
|
+ struct v4l2_format *f = inst->fmt_src;
|
|
+ u32 height = f->fmt.pix_mp.height;
|
|
+ u32 width = f->fmt.pix_mp.width;
|
|
+ bool is_opb = false;
|
|
+
|
|
+ if (iris_split_mode_enabled(inst))
|
|
+ is_opb = true;
|
|
+
|
|
+ return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes);
|
|
+}
|
|
+
|
|
+static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)
|
|
+{
|
|
+ return iris_vpu_dec_comv_size(inst) +
|
|
+ iris_vpu_dec_non_comv_size(inst) +
|
|
+ iris_vpu_dec_line_size(inst);
|
|
+}
|
|
+
|
|
+struct iris_vpu_buf_type_handle {
|
|
+ enum iris_buffer_type type;
|
|
+ u32 (*handle)(struct iris_inst *inst);
|
|
+};
|
|
+
|
|
+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
|
|
+{
|
|
+ const struct iris_vpu_buf_type_handle *buf_type_handle_arr;
|
|
+ u32 size = 0, buf_type_handle_size, i;
|
|
+
|
|
+ static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = {
|
|
+ {BUF_BIN, iris_vpu_dec_bin_size },
|
|
+ {BUF_COMV, iris_vpu_dec_comv_size },
|
|
+ {BUF_NON_COMV, iris_vpu_dec_non_comv_size },
|
|
+ {BUF_LINE, iris_vpu_dec_line_size },
|
|
+ {BUF_PERSIST, iris_vpu_dec_persist_size },
|
|
+ {BUF_DPB, iris_vpu_dec_dpb_size },
|
|
+ {BUF_SCRATCH_1, iris_vpu_dec_scratch1_size },
|
|
+ };
|
|
+
|
|
+ buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle);
|
|
+ buf_type_handle_arr = dec_internal_buf_type_handle;
|
|
+
|
|
+ for (i = 0; i < buf_type_handle_size; i++) {
|
|
+ if (buf_type_handle_arr[i].type == buffer_type) {
|
|
+ size = buf_type_handle_arr[i].handle(inst);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return size;
|
|
+}
|
|
+
|
|
static inline int iris_vpu_dpb_count(struct iris_inst *inst)
|
|
{
|
|
if (iris_split_mode_enabled(inst)) {
|
|
@@ -31,6 +255,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type
|
|
return MIN_BUFFERS;
|
|
case BUF_OUTPUT:
|
|
return inst->fw_min_count;
|
|
+ case BUF_BIN:
|
|
+ case BUF_COMV:
|
|
+ case BUF_NON_COMV:
|
|
+ case BUF_LINE:
|
|
+ case BUF_PERSIST:
|
|
+ case BUF_SCRATCH_1:
|
|
+ return 1; /* internal buffer count needed by firmware is 1 */
|
|
case BUF_DPB:
|
|
return iris_vpu_dpb_count(inst);
|
|
default:
|
|
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
|
|
index 865539d626b7..62af6ea6ba1f 100644
|
|
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
|
|
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
|
|
@@ -10,7 +10,82 @@ struct iris_inst;
|
|
|
|
#define MIN_BUFFERS 4
|
|
|
|
-u32 iris_vpu_dec_dpb_size(struct iris_inst *inst);
|
|
+#define DMA_ALIGNMENT 256
|
|
+
|
|
+#define NUM_HW_PIC_BUF 32
|
|
+#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))
|
|
+
|
|
+#define MAX_TILE_COLUMNS 32
|
|
+#define BIN_BUFFER_THRESHOLD (1280 * 736)
|
|
+#define VPP_CMD_MAX_SIZE (BIT(20))
|
|
+#define H264D_MAX_SLICE 1800
|
|
+
|
|
+#define SIZE_H264D_BUFTAB_T 256
|
|
+#define SIZE_H264D_BSE_CMD_PER_BUF (32 * 4)
|
|
+#define SIZE_H264D_VPP_CMD_PER_BUF 512
|
|
+
|
|
+#define NUM_SLIST_BUF_H264 (256 + 32)
|
|
+#define SIZE_SLIST_BUF_H264 512
|
|
+#define H264_DISPLAY_BUF_SIZE 3328
|
|
+#define H264_NUM_FRM_INFO 66
|
|
+
|
|
+#define SIZE_SEI_USERDATA 4096
|
|
+
|
|
+#define H264_CABAC_HDR_RATIO_HD_TOT 1
|
|
+#define H264_CABAC_RES_RATIO_HD_TOT 3
|
|
+#define SIZE_H264D_HW_PIC_T (BIT(11))
|
|
+
|
|
+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64
|
|
+#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 16
|
|
+#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384
|
|
+#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640
|
|
+
|
|
+static inline u32 size_h264d_lb_fe_top_data(u32 frame_width)
|
|
+{
|
|
+ return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3;
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width)
|
|
+{
|
|
+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_height)
|
|
+{
|
|
+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width)
|
|
+{
|
|
+ return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_height)
|
|
+{
|
|
+ return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_pe_top_data(u32 frame_width)
|
|
+{
|
|
+ return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_vsp_top(u32 frame_width)
|
|
+{
|
|
+ return (DIV_ROUND_UP(frame_width, 16) << 7);
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_lb_recon_dma_metadata_wr(u32 frame_height)
|
|
+{
|
|
+ return ALIGN(frame_height, 16) * 32;
|
|
+}
|
|
+
|
|
+static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
|
|
+{
|
|
+ return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128;
|
|
+}
|
|
+
|
|
+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
|
|
int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type);
|
|
|
|
#endif
|
|
--
|
|
2.34.1
|
|
|