mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
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> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
parent
025398e912
commit
73702f45db
16 changed files with 1087 additions and 4 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "iris_buffer.h"
|
#include "iris_buffer.h"
|
||||||
#include "iris_instance.h"
|
#include "iris_instance.h"
|
||||||
|
#include "iris_vpu_buffer.h"
|
||||||
|
|
||||||
#define PIXELS_4K 4096
|
#define PIXELS_4K 4096
|
||||||
#define MAX_WIDTH 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)
|
void iris_vb2_queue_error(struct iris_inst *inst)
|
||||||
{
|
{
|
||||||
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
|
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
|
||||||
|
|
|
@ -102,6 +102,13 @@ struct iris_buffers {
|
||||||
};
|
};
|
||||||
|
|
||||||
int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
|
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);
|
void iris_vb2_queue_error(struct iris_inst *inst);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
|
|
||||||
|
#include "iris_buffer.h"
|
||||||
|
|
||||||
struct iris_inst;
|
struct iris_inst;
|
||||||
struct iris_core;
|
struct iris_core;
|
||||||
|
|
||||||
|
@ -114,6 +116,8 @@ struct iris_hfi_command_ops {
|
||||||
void *payload, u32 payload_size);
|
void *payload, u32 payload_size);
|
||||||
int (*session_open)(struct iris_inst *inst);
|
int (*session_open)(struct iris_inst *inst);
|
||||||
int (*session_start)(struct iris_inst *inst, u32 plane);
|
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_stop)(struct iris_inst *inst, u32 plane);
|
||||||
int (*session_close)(struct iris_inst *inst);
|
int (*session_close)(struct iris_inst *inst);
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,24 @@
|
||||||
#include "iris_instance.h"
|
#include "iris_instance.h"
|
||||||
#include "iris_vpu_buffer.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)
|
static int iris_hfi_gen1_sys_init(struct iris_core *core)
|
||||||
{
|
{
|
||||||
struct hfi_sys_init_pkt sys_init_pkt;
|
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;
|
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
|
static int
|
||||||
iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet,
|
iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet,
|
||||||
struct iris_inst *inst, u32 ptype, void *pdata)
|
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)) {
|
if (iris_split_mode_enabled(inst)) {
|
||||||
bufsz.type = HFI_BUFFER_OUTPUT;
|
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));
|
ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
|
||||||
if (ret)
|
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_config_params = iris_hfi_gen1_session_set_config_params,
|
||||||
.session_set_property = iris_hfi_gen1_session_set_property,
|
.session_set_property = iris_hfi_gen1_session_set_property,
|
||||||
.session_start = iris_hfi_gen1_session_start,
|
.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_stop = iris_hfi_gen1_session_stop,
|
||||||
.session_close = iris_hfi_gen1_session_close,
|
.session_close = iris_hfi_gen1_session_close,
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,11 +24,13 @@
|
||||||
#define HFI_CMD_SYS_SESSION_END 0x10008
|
#define HFI_CMD_SYS_SESSION_END 0x10008
|
||||||
|
|
||||||
#define HFI_CMD_SESSION_SET_PROPERTY 0x11001
|
#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_LOAD_RESOURCES 0x211001
|
||||||
#define HFI_CMD_SESSION_START 0x211002
|
#define HFI_CMD_SESSION_START 0x211002
|
||||||
#define HFI_CMD_SESSION_STOP 0x211003
|
#define HFI_CMD_SESSION_STOP 0x211003
|
||||||
#define HFI_CMD_SESSION_FLUSH 0x211008
|
#define HFI_CMD_SESSION_FLUSH 0x211008
|
||||||
|
#define HFI_CMD_SESSION_RELEASE_BUFFERS 0x21100b
|
||||||
#define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c
|
#define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c
|
||||||
|
|
||||||
#define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008
|
#define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008
|
||||||
|
@ -53,6 +55,9 @@
|
||||||
#define HFI_BUFFER_INPUT 0x1
|
#define HFI_BUFFER_INPUT 0x1
|
||||||
#define HFI_BUFFER_OUTPUT 0x2
|
#define HFI_BUFFER_OUTPUT 0x2
|
||||||
#define HFI_BUFFER_OUTPUT2 0x3
|
#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_CODEC_POWER_PLANE_CTRL 0x5
|
||||||
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
|
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
|
||||||
|
@ -80,6 +85,7 @@
|
||||||
#define HFI_MSG_SESSION_STOP 0x221003
|
#define HFI_MSG_SESSION_STOP 0x221003
|
||||||
#define HFI_MSG_SESSION_FLUSH 0x221006
|
#define HFI_MSG_SESSION_FLUSH 0x221006
|
||||||
#define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a
|
#define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a
|
||||||
|
#define HFI_MSG_SESSION_RELEASE_BUFFERS 0x22100c
|
||||||
|
|
||||||
struct hfi_pkt_hdr {
|
struct hfi_pkt_hdr {
|
||||||
u32 size;
|
u32 size;
|
||||||
|
@ -128,11 +134,36 @@ struct hfi_sys_pc_prep_pkt {
|
||||||
struct hfi_pkt_hdr hdr;
|
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_flush_pkt {
|
||||||
struct hfi_session_hdr_pkt shdr;
|
struct hfi_session_hdr_pkt shdr;
|
||||||
u32 flush_type;
|
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_msg_event_notify_pkt {
|
||||||
struct hfi_session_hdr_pkt shdr;
|
struct hfi_session_hdr_pkt shdr;
|
||||||
u32 event_id;
|
u32 event_id;
|
||||||
|
@ -227,6 +258,12 @@ struct hfi_multi_stream {
|
||||||
u32 enable;
|
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_msg_sys_debug_pkt {
|
||||||
struct hfi_pkt_hdr hdr;
|
struct hfi_pkt_hdr hdr;
|
||||||
u32 msg_type;
|
u32 msg_type;
|
||||||
|
|
|
@ -176,6 +176,10 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
|
||||||
.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
|
.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
|
||||||
.pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
|
.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)
|
static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response)
|
||||||
|
|
|
@ -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,
|
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 plane, u32 payload_type, void *payload,
|
||||||
u32 payload_size)
|
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);
|
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 = {
|
static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
|
||||||
.sys_init = iris_hfi_gen2_sys_init,
|
.sys_init = iris_hfi_gen2_sys_init,
|
||||||
.sys_image_version = iris_hfi_gen2_sys_image_version,
|
.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_config_params = iris_hfi_gen2_session_set_config_params,
|
||||||
.session_set_property = iris_hfi_gen2_session_set_property,
|
.session_set_property = iris_hfi_gen2_session_set_property,
|
||||||
.session_start = iris_hfi_gen2_session_start,
|
.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_stop = iris_hfi_gen2_session_stop,
|
||||||
.session_close = iris_hfi_gen2_session_close,
|
.session_close = iris_hfi_gen2_session_close,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define HFI_CMD_CLOSE 0x01000004
|
#define HFI_CMD_CLOSE 0x01000004
|
||||||
#define HFI_CMD_START 0x01000005
|
#define HFI_CMD_START 0x01000005
|
||||||
#define HFI_CMD_STOP 0x01000006
|
#define HFI_CMD_STOP 0x01000006
|
||||||
|
#define HFI_CMD_BUFFER 0x01000009
|
||||||
#define HFI_CMD_SUBSCRIBE_MODE 0x0100000B
|
#define HFI_CMD_SUBSCRIBE_MODE 0x0100000B
|
||||||
#define HFI_CMD_END 0x01FFFFFF
|
#define HFI_CMD_END 0x01FFFFFF
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
|
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
|
||||||
#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169
|
#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169
|
||||||
#define HFI_PROP_NO_OUTPUT 0x0300016a
|
#define HFI_PROP_NO_OUTPUT 0x0300016a
|
||||||
|
#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193
|
||||||
#define HFI_PROP_END 0x03FFFFFF
|
#define HFI_PROP_END 0x03FFFFFF
|
||||||
|
|
||||||
#define HFI_SESSION_ERROR_BEGIN 0x04000000
|
#define HFI_SESSION_ERROR_BEGIN 0x04000000
|
||||||
|
@ -106,6 +108,13 @@ enum hfi_buffer_type {
|
||||||
HFI_BUFFER_VPSS = 0x0000000D,
|
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 {
|
enum hfi_packet_firmware_flags {
|
||||||
HFI_FW_FLAGS_SUCCESS = 0x00000001,
|
HFI_FW_FLAGS_SUCCESS = 0x00000001,
|
||||||
HFI_FW_FLAGS_INFORMATION = 0x00000002,
|
HFI_FW_FLAGS_INFORMATION = 0x00000002,
|
||||||
|
|
|
@ -61,6 +61,47 @@ struct iris_hfi_packet {
|
||||||
u32 payload[];
|
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_color_primaries(u32 primaries);
|
||||||
u32 iris_hfi_gen2_get_transfer_char(u32 characterstics);
|
u32 iris_hfi_gen2_get_transfer_char(u32 characterstics);
|
||||||
u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients);
|
u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients);
|
||||||
|
|
|
@ -25,6 +25,94 @@ struct iris_hfi_gen2_packet_handle {
|
||||||
int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
|
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)
|
static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt)
|
||||||
{
|
{
|
||||||
u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE;
|
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);
|
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,
|
static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
|
||||||
struct iris_hfi_packet *pkt)
|
struct iris_hfi_packet *pkt)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
switch (pkt->type) {
|
switch (pkt->type) {
|
||||||
case HFI_CMD_CLOSE:
|
case HFI_CMD_CLOSE:
|
||||||
iris_hfi_gen2_handle_session_close(inst, pkt);
|
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:
|
case HFI_CMD_STOP:
|
||||||
complete(&inst->completion);
|
complete(&inst->completion);
|
||||||
break;
|
break;
|
||||||
|
case HFI_CMD_BUFFER:
|
||||||
|
ret = iris_hfi_gen2_handle_session_buffer(inst, pkt);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
|
static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct platform_inst_caps {
|
||||||
u32 min_frame_height;
|
u32 min_frame_height;
|
||||||
u32 max_frame_height;
|
u32 max_frame_height;
|
||||||
u32 max_mbpf;
|
u32 max_mbpf;
|
||||||
|
u32 num_comv;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum platform_inst_fw_cap_type {
|
enum platform_inst_fw_cap_type {
|
||||||
|
@ -151,6 +152,10 @@ struct iris_platform_data {
|
||||||
unsigned int dec_input_prop_size;
|
unsigned int dec_input_prop_size;
|
||||||
const u32 *dec_output_prop;
|
const u32 *dec_output_prop;
|
||||||
unsigned int dec_output_prop_size;
|
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
|
#endif
|
||||||
|
|
|
@ -126,6 +126,7 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = {
|
||||||
.min_frame_height = 96,
|
.min_frame_height = 96,
|
||||||
.max_frame_height = 8192,
|
.max_frame_height = 8192,
|
||||||
.max_mbpf = (8192 * 4352) / 256,
|
.max_mbpf = (8192 * 4352) / 256,
|
||||||
|
.num_comv = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void iris_set_sm8550_preset_registers(struct iris_core *core)
|
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,
|
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 = {
|
struct iris_platform_data sm8550_data = {
|
||||||
.get_instance = iris_hfi_gen2_get_instance,
|
.get_instance = iris_hfi_gen2_get_instance,
|
||||||
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
|
.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_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
|
||||||
.dec_output_prop = sm8550_vdec_subscribe_output_properties,
|
.dec_output_prop = sm8550_vdec_subscribe_output_properties,
|
||||||
.dec_output_prop_size = ARRAY_SIZE(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),
|
||||||
};
|
};
|
||||||
|
|
|
@ -273,6 +273,24 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
return iris_vdec_process_streamon_input(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,10 +315,24 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = iris_vdec_process_streamon_output(inst);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||||||
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -149,6 +149,15 @@ int iris_open(struct file *filp)
|
||||||
|
|
||||||
mutex_init(&inst->lock);
|
mutex_init(&inst->lock);
|
||||||
mutex_init(&inst->ctx_q_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->completion);
|
||||||
init_completion(&inst->flush_completion);
|
init_completion(&inst->flush_completion);
|
||||||
|
|
||||||
|
@ -221,6 +230,8 @@ int iris_close(struct file *filp)
|
||||||
iris_session_close(inst);
|
iris_session_close(inst);
|
||||||
iris_inst_change_state(inst, IRIS_INST_DEINIT);
|
iris_inst_change_state(inst, IRIS_INST_DEINIT);
|
||||||
iris_v4l2_fh_deinit(inst);
|
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);
|
iris_remove_session(inst);
|
||||||
mutex_unlock(&inst->lock);
|
mutex_unlock(&inst->lock);
|
||||||
mutex_destroy(&inst->ctx_q_lock);
|
mutex_destroy(&inst->ctx_q_lock);
|
||||||
|
|
|
@ -6,7 +6,167 @@
|
||||||
#include "iris_instance.h"
|
#include "iris_instance.h"
|
||||||
#include "iris_vpu_buffer.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))
|
if (iris_split_mode_enabled(inst))
|
||||||
return iris_get_buffer_size(inst, BUF_DPB);
|
return iris_get_buffer_size(inst, BUF_DPB);
|
||||||
|
@ -14,6 +174,70 @@ u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
|
||||||
return 0;
|
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)
|
static inline int iris_vpu_dpb_count(struct iris_inst *inst)
|
||||||
{
|
{
|
||||||
if (iris_split_mode_enabled(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;
|
return MIN_BUFFERS;
|
||||||
case BUF_OUTPUT:
|
case BUF_OUTPUT:
|
||||||
return inst->fw_min_count;
|
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:
|
case BUF_DPB:
|
||||||
return iris_vpu_dpb_count(inst);
|
return iris_vpu_dpb_count(inst);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -10,7 +10,82 @@ struct iris_inst;
|
||||||
|
|
||||||
#define MIN_BUFFERS 4
|
#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);
|
int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue