summaryrefslogtreecommitdiff
path: root/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/chips-media/wave5/wave5-vpuapi.c')
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpuapi.c442
1 files changed, 178 insertions, 264 deletions
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
index 5a0078a0d174..1a3efb638dde 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c
@@ -2,7 +2,7 @@
/*
* Wave5 series multi-standard codec IP - helper functions
*
- * Copyright (C) 2021 CHIPS&MEDIA INC
+ * Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#include <linux/bug.h>
@@ -13,11 +13,6 @@
#define DECODE_ALL_TEMPORAL_LAYERS 0
#define DECODE_ALL_SPATIAL_LAYERS 0
-void wave5_vpu_clear_interrupt_ex(struct vpu_instance *inst, u32 intr_flag)
-{
- wave5_vpu_clear_interrupt(inst, intr_flag);
-}
-
static int wave5_initialize_vpu(struct device *dev, u8 *code, size_t size)
{
int ret;
@@ -52,6 +47,39 @@ int wave5_vpu_init_with_bitcode(struct device *dev, u8 *bitcode, size_t size)
return wave5_initialize_vpu(dev, bitcode, size);
}
+int wave5_vpu_flush_instance(struct vpu_instance *inst)
+{
+ int ret = 0;
+ int retry = 0;
+
+ ret = mutex_lock_interruptible(&inst->dev->hw_lock);
+ if (ret)
+ return ret;
+ do {
+ /*
+ * Repeat the FLUSH command until the firmware reports that the
+ * VPU isn't running anymore
+ */
+ ret = wave5_vpu_hw_flush_instance(inst);
+ if (ret < 0 && ret != -EBUSY) {
+ dev_warn(inst->dev->dev, "Flush of %s instance with id: %d fail: %d\n",
+ inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id,
+ ret);
+ mutex_unlock(&inst->dev->hw_lock);
+ return ret;
+ }
+ if (ret == -EBUSY && retry++ >= MAX_FIRMWARE_CALL_RETRY) {
+ dev_warn(inst->dev->dev, "Flush of %s instance with id: %d timed out!\n",
+ inst->type == VPU_INST_TYPE_DEC ? "DECODER" : "ENCODER", inst->id);
+ mutex_unlock(&inst->dev->hw_lock);
+ return -ETIMEDOUT;
+ }
+ } while (ret != 0);
+ mutex_unlock(&inst->dev->hw_lock);
+
+ return ret;
+}
+
int wave5_vpu_get_version_info(struct device *dev, u32 *revision, unsigned int *product_id)
{
int ret;
@@ -77,8 +105,6 @@ err_out:
static int wave5_check_dec_open_param(struct vpu_instance *inst, struct dec_open_param *param)
{
- struct vpu_attr *p_attr = &inst->dev->attr;
-
if (inst->id >= MAX_NUM_INSTANCE) {
dev_err(inst->dev->dev, "Too many simultaneous instances: %d (max: %u)\n",
inst->id, MAX_NUM_INSTANCE);
@@ -91,33 +117,14 @@ static int wave5_check_dec_open_param(struct vpu_instance *inst, struct dec_open
return -EINVAL;
}
- if (param->bitstream_mode == BS_MODE_INTERRUPT &&
- (param->bitstream_buffer_size % 1024 ||
- param->bitstream_buffer_size < MIN_BITSTREAM_BUFFER_SIZE)) {
+ if (param->bitstream_buffer_size % 1024 ||
+ param->bitstream_buffer_size < MIN_BITSTREAM_BUFFER_SIZE) {
dev_err(inst->dev->dev,
"Bitstream buffer size must be aligned to a multiple of 1024 and have a minimum size of %d\n",
MIN_BITSTREAM_BUFFER_SIZE);
return -EINVAL;
}
- if (!(BIT(param->bitstream_mode) && p_attr->support_bitstream_mode)) {
- dev_err(inst->dev->dev,
- "Bitstream mode only configurable with the 'support_bitstream_mode' flag");
- return -EINVAL;
- }
-
- if (!(BIT(param->frame_endian) && p_attr->support_endian_mask)) {
- dev_err(inst->dev->dev,
- "Frame endianness only configurable with the 'support_endian_mask' flag");
- return -EINVAL;
- }
-
- if (!(BIT(param->stream_endian) && p_attr->support_endian_mask)) {
- dev_err(inst->dev->dev,
- "Stream endianness only configurable with the 'support_endian_mask' flag");
- return -EINVAL;
- }
-
return 0;
}
@@ -142,12 +149,6 @@ int wave5_vpu_dec_open(struct vpu_instance *inst, struct dec_open_param *open_pa
return -ENODEV;
}
- inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL);
- if (!inst->codec_info) {
- mutex_unlock(&vpu_dev->hw_lock);
- return -ENOMEM;
- }
-
p_dec_info = &inst->codec_info->dec_info;
memcpy(&p_dec_info->open_param, open_param, sizeof(struct dec_open_param));
@@ -159,30 +160,39 @@ int wave5_vpu_dec_open(struct vpu_instance *inst, struct dec_open_param *open_pa
p_dec_info->stream_buf_size = buffer_size;
p_dec_info->stream_buf_end_addr = buffer_addr + buffer_size;
p_dec_info->reorder_enable = TRUE;
- p_dec_info->mirror_direction = MIRDIR_NONE;
p_dec_info->temp_id_select_mode = TEMPORAL_ID_MODE_ABSOLUTE;
p_dec_info->target_temp_id = DECODE_ALL_TEMPORAL_LAYERS;
p_dec_info->target_spatial_id = DECODE_ALL_SPATIAL_LAYERS;
ret = wave5_vpu_build_up_dec_param(inst, open_param);
- if (ret)
- goto free_codec_info;
-
mutex_unlock(&vpu_dev->hw_lock);
- return 0;
+ return ret;
+}
-free_codec_info:
- kfree(inst->codec_info);
- mutex_unlock(&vpu_dev->hw_lock);
+static int reset_auxiliary_buffers(struct vpu_instance *inst, unsigned int index)
+{
+ struct dec_info *p_dec_info = &inst->codec_info->dec_info;
- return ret;
+ if (index >= MAX_REG_FRAME)
+ return 1;
+
+ if (p_dec_info->vb_mv[index].size == 0 && p_dec_info->vb_fbc_y_tbl[index].size == 0 &&
+ p_dec_info->vb_fbc_c_tbl[index].size == 0)
+ return 1;
+
+ wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_mv[index]);
+ wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_fbc_y_tbl[index]);
+ wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_fbc_c_tbl[index]);
+
+ return 0;
}
int wave5_vpu_dec_close(struct vpu_instance *inst, u32 *fail_res)
{
struct dec_info *p_dec_info = &inst->codec_info->dec_info;
int ret;
+ int retry = 0;
struct vpu_device *vpu_dev = inst->dev;
int i;
@@ -194,38 +204,38 @@ int wave5_vpu_dec_close(struct vpu_instance *inst, u32 *fail_res)
if (ret)
return ret;
- ret = wave5_vpu_dec_finish_seq(inst, fail_res);
- if (ret) {
- dev_warn(inst->dev->dev, "dec_finish_seq timed out\n");
+ do {
+ ret = wave5_vpu_dec_finish_seq(inst, fail_res);
+ if (ret < 0 && *fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) {
+ dev_warn(inst->dev->dev, "dec_finish_seq timed out\n");
+ goto unlock_and_return;
+ }
- if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING) {
- mutex_unlock(&vpu_dev->hw_lock);
- return ret;
+ if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING &&
+ retry++ >= MAX_FIRMWARE_CALL_RETRY) {
+ ret = -ETIMEDOUT;
+ goto unlock_and_return;
}
- }
+ } while (ret != 0);
dev_dbg(inst->dev->dev, "%s: dec_finish_seq complete\n", __func__);
- if (p_dec_info->vb_work.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_work);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_work);
for (i = 0 ; i < MAX_REG_FRAME; i++) {
- if (p_dec_info->vb_mv[i].size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_mv[i]);
- if (p_dec_info->vb_fbc_y_tbl[i].size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_fbc_y_tbl[i]);
- if (p_dec_info->vb_fbc_c_tbl[i].size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_fbc_c_tbl[i]);
+ ret = reset_auxiliary_buffers(inst, i);
+ if (ret) {
+ ret = 0;
+ break;
+ }
}
- if (p_dec_info->vb_task.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_task);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_dec_info->vb_task);
+unlock_and_return:
mutex_unlock(&vpu_dev->hw_lock);
- kfree(inst->codec_info);
-
- return 0;
+ return ret;
}
int wave5_vpu_dec_issue_seq_init(struct vpu_instance *inst)
@@ -258,7 +268,7 @@ int wave5_vpu_dec_complete_seq_init(struct vpu_instance *inst, struct dec_initia
if (!ret)
p_dec_info->initial_info_obtained = true;
- info->rd_ptr = wave5_vpu_dec_get_rd_ptr(inst);
+ info->rd_ptr = wave5_dec_get_rd_ptr(inst);
info->wr_ptr = p_dec_info->stream_wr_ptr;
p_dec_info->initial_info = *info;
@@ -269,8 +279,7 @@ int wave5_vpu_dec_complete_seq_init(struct vpu_instance *inst, struct dec_initia
}
int wave5_vpu_dec_register_frame_buffer_ex(struct vpu_instance *inst, int num_of_decoding_fbs,
- int num_of_display_fbs, int stride, int height,
- int map_type)
+ int num_of_display_fbs, int stride, int height)
{
struct dec_info *p_dec_info;
int ret;
@@ -326,21 +335,17 @@ int wave5_vpu_dec_get_bitstream_buffer(struct vpu_instance *inst, dma_addr_t *pr
ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
if (ret)
return ret;
- rd_ptr = wave5_vpu_dec_get_rd_ptr(inst);
+ rd_ptr = wave5_dec_get_rd_ptr(inst);
mutex_unlock(&vpu_dev->hw_lock);
wr_ptr = p_dec_info->stream_wr_ptr;
- if (p_dec_info->open_param.bitstream_mode != BS_MODE_PIC_END) {
- if (wr_ptr < rd_ptr)
- room = rd_ptr - wr_ptr;
- else
- room = (p_dec_info->stream_buf_end_addr - wr_ptr) +
- (rd_ptr - p_dec_info->stream_buf_start_addr);
- room--;
- } else {
- room = (p_dec_info->stream_buf_end_addr - wr_ptr);
- }
+ if (wr_ptr < rd_ptr)
+ room = rd_ptr - wr_ptr;
+ else
+ room = (p_dec_info->stream_buf_end_addr - wr_ptr) +
+ (rd_ptr - p_dec_info->stream_buf_start_addr);
+ room--;
if (prd_ptr)
*prd_ptr = rd_ptr;
@@ -373,15 +378,13 @@ int wave5_vpu_dec_update_bitstream_buffer(struct vpu_instance *inst, size_t size
wr_ptr += size;
- if (p_dec_info->open_param.bitstream_mode != BS_MODE_PIC_END) {
- if (wr_ptr > p_dec_info->stream_buf_end_addr) {
- u32 room = wr_ptr - p_dec_info->stream_buf_end_addr;
+ if (wr_ptr > p_dec_info->stream_buf_end_addr) {
+ u32 room = wr_ptr - p_dec_info->stream_buf_end_addr;
- wr_ptr = p_dec_info->stream_buf_start_addr;
- wr_ptr += room;
- } else if (wr_ptr == p_dec_info->stream_buf_end_addr) {
- wr_ptr = p_dec_info->stream_buf_start_addr;
- }
+ wr_ptr = p_dec_info->stream_buf_start_addr;
+ wr_ptr += room;
+ } else if (wr_ptr == p_dec_info->stream_buf_end_addr) {
+ wr_ptr = p_dec_info->stream_buf_start_addr;
}
p_dec_info->stream_wr_ptr = wr_ptr;
@@ -397,20 +400,20 @@ int wave5_vpu_dec_update_bitstream_buffer(struct vpu_instance *inst, size_t size
return ret;
}
-int wave5_vpu_dec_start_one_frame(struct vpu_instance *inst, struct dec_param *param, u32 *res_fail)
+int wave5_vpu_dec_start_one_frame(struct vpu_instance *inst, u32 *res_fail)
{
struct dec_info *p_dec_info = &inst->codec_info->dec_info;
int ret;
struct vpu_device *vpu_dev = inst->dev;
- if (p_dec_info->stride == 0) // this means frame buffers have not been registered.
+ if (p_dec_info->stride == 0) /* this means frame buffers have not been registered. */
return -EINVAL;
ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
if (ret)
return ret;
- ret = wave5_vpu_decode(inst, param, res_fail);
+ ret = wave5_vpu_decode(inst, res_fail);
mutex_unlock(&vpu_dev->hw_lock);
@@ -438,6 +441,22 @@ int wave5_vpu_dec_set_rd_ptr(struct vpu_instance *inst, dma_addr_t addr, int upd
return ret;
}
+dma_addr_t wave5_vpu_dec_get_rd_ptr(struct vpu_instance *inst)
+{
+ int ret;
+ dma_addr_t rd_ptr;
+
+ ret = mutex_lock_interruptible(&inst->dev->hw_lock);
+ if (ret)
+ return ret;
+
+ rd_ptr = wave5_dec_get_rd_ptr(inst);
+
+ mutex_unlock(&inst->dev->hw_lock);
+
+ return rd_ptr;
+}
+
int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_info *info)
{
struct dec_info *p_dec_info;
@@ -470,13 +489,13 @@ int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_i
decoded_index = info->index_frame_decoded;
- // calculate display frame region
+ /* calculate display frame region */
val = 0;
- //default value
rect_info.left = 0;
rect_info.right = 0;
rect_info.top = 0;
rect_info.bottom = 0;
+
if (decoded_index < WAVE5_MAX_FBS) {
if (inst->std == W_HEVC_DEC || inst->std == W_AVC_DEC)
rect_info = p_dec_info->initial_info.pic_crop_rect;
@@ -484,120 +503,48 @@ int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_i
if (inst->std == W_HEVC_DEC)
p_dec_info->dec_out_info[decoded_index].decoded_poc = info->decoded_poc;
- if (inst->std == W_AVS2_DEC)
- p_dec_info->dec_out_info[decoded_index].avs2_info.decoded_poi =
- info->avs2_info.decoded_poi;
-
p_dec_info->dec_out_info[decoded_index].rc_decoded = rect_info;
}
info->rc_decoded = rect_info;
- dev_dbg(inst->dev->dev, "%s %d %u %u %u %u\n", __func__, __LINE__,
- rect_info.left, rect_info.right, rect_info.top, rect_info.bottom);
disp_idx = info->index_frame_display;
- disp_info = &p_dec_info->dec_out_info[disp_idx];
if (info->index_frame_display >= 0 && info->index_frame_display < WAVE5_MAX_FBS) {
- u32 width = info->dec_pic_width;
- u32 height = info->dec_pic_height;
- dev_dbg(inst->dev->dev, "%s %d dec_pic_width %u dec_pic_height %u\n",
- __func__, __LINE__, info->dec_pic_width, info->dec_pic_height);
-
+ disp_info = &p_dec_info->dec_out_info[disp_idx];
if (info->index_frame_display != info->index_frame_decoded) {
/*
* when index_frame_decoded < 0, and index_frame_display >= 0
* info->dec_pic_width and info->dec_pic_height are still valid
* but those of p_dec_info->dec_out_info[disp_idx] are invalid in VP9
*/
- width = disp_info->dec_pic_width;
- height = disp_info->dec_pic_height;
- }
- // TODO no rotation/mirror v4l2 cmd implemented for the decoder
- if (p_dec_info->rotation_enable || p_dec_info->mirror_enable)
- if (p_dec_info->rotation_angle == 90 || p_dec_info->rotation_angle == 270)
- swap(width, height);
-
- if (p_dec_info->rotation_enable) {
- switch (p_dec_info->rotation_angle) {
- case 90:
- info->rc_display.left = disp_info->rc_decoded.top;
- info->rc_display.right = disp_info->rc_decoded.bottom;
- info->rc_display.top = disp_info->rc_decoded.right;
- info->rc_display.bottom = disp_info->rc_decoded.left;
- break;
- case 270:
- info->rc_display.left = disp_info->rc_decoded.bottom;
- info->rc_display.right = disp_info->rc_decoded.top;
- info->rc_display.top = disp_info->rc_decoded.left;
- info->rc_display.bottom = disp_info->rc_decoded.right;
- break;
- case 180:
- info->rc_display.left = disp_info->rc_decoded.right;
- info->rc_display.right = disp_info->rc_decoded.left;
- info->rc_display.top = disp_info->rc_decoded.bottom;
- info->rc_display.bottom = disp_info->rc_decoded.top;
- break;
- default:
- info->rc_display = disp_info->rc_decoded;
- break;
- }
+ info->disp_pic_width = disp_info->dec_pic_width;
+ info->disp_pic_height = disp_info->dec_pic_height;
} else {
- info->rc_display = disp_info->rc_decoded;
- }
-
- if (p_dec_info->mirror_enable) {
- if (p_dec_info->mirror_direction & MIRDIR_VER)
- swap(info->rc_display.top, info->rc_display.bottom);
- if (p_dec_info->mirror_direction & MIRDIR_HOR)
- swap(info->rc_display.left, info->rc_display.right);
+ info->disp_pic_width = info->dec_pic_width;
+ info->disp_pic_height = info->dec_pic_height;
}
- switch (inst->std) {
- case W_AVS2_DEC:
- info->avs2_info.display_poi =
- disp_info->avs2_info.decoded_poi;
- break;
- default:
- break;
- }
+ info->rc_display = disp_info->rc_decoded;
- info->disp_pic_width = width;
- info->disp_pic_height = height;
} else {
info->rc_display.left = 0;
info->rc_display.right = 0;
info->rc_display.top = 0;
info->rc_display.bottom = 0;
-
- if (p_dec_info->rotation_enable || p_dec_info->mirror_enable ||
- p_dec_info->dering_enable) {
- info->disp_pic_width = info->dec_pic_width;
- info->disp_pic_height = info->dec_pic_height;
- } else {
- info->disp_pic_width = 0;
- info->disp_pic_height = 0;
- }
+ info->disp_pic_width = 0;
+ info->disp_pic_height = 0;
}
- dev_dbg(inst->dev->dev, "%s %d disp_pic_width %u disp_pic_height %u\n",
- __func__, __LINE__, info->disp_pic_width, info->disp_pic_height);
- p_dec_info->stream_rd_ptr = wave5_vpu_dec_get_rd_ptr(inst);
+ p_dec_info->stream_rd_ptr = wave5_dec_get_rd_ptr(inst);
p_dec_info->frame_display_flag = vpu_read_reg(vpu_dev, W5_RET_DEC_DISP_IDC);
- if (inst->std == W_VP9_DEC)
- p_dec_info->frame_display_flag &= 0xFFFF;
- if (p_dec_info->dering_enable || p_dec_info->mirror_enable || p_dec_info->rotation_enable) {
- info->disp_frame = p_dec_info->rotator_output;
- info->disp_frame.stride = p_dec_info->rotator_stride;
- } else {
- val = p_dec_info->num_of_decoding_fbs; //fb_offset
+ val = p_dec_info->num_of_decoding_fbs; //fb_offset
- max_dec_index = (p_dec_info->num_of_decoding_fbs > p_dec_info->num_of_display_fbs) ?
- p_dec_info->num_of_decoding_fbs : p_dec_info->num_of_display_fbs;
+ max_dec_index = (p_dec_info->num_of_decoding_fbs > p_dec_info->num_of_display_fbs) ?
+ p_dec_info->num_of_decoding_fbs : p_dec_info->num_of_display_fbs;
- if (info->index_frame_display >= 0 &&
- info->index_frame_display < (int)max_dec_index)
- info->disp_frame = inst->frame_buf[val + info->index_frame_display];
- }
+ if (info->index_frame_display >= 0 &&
+ info->index_frame_display < (int)max_dec_index)
+ info->disp_frame = inst->frame_buf[val + info->index_frame_display];
info->rd_ptr = p_dec_info->stream_rd_ptr;
info->wr_ptr = p_dec_info->stream_wr_ptr;
@@ -610,8 +557,7 @@ int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_i
if (disp_idx < WAVE5_MAX_FBS)
info->disp_frame.sequence_no = info->sequence_no;
- if (info->sequence_changed &&
- !(info->sequence_changed & SEQ_CHANGE_INTER_RES_CHANGE)) {
+ if (info->sequence_changed) {
memcpy((void *)&p_dec_info->initial_info, (void *)&p_dec_info->new_seq_info,
sizeof(struct dec_initial_info));
p_dec_info->initial_info.sequence_no++;
@@ -626,7 +572,7 @@ err_out:
int wave5_vpu_dec_clr_disp_flag(struct vpu_instance *inst, int index)
{
struct dec_info *p_dec_info = &inst->codec_info->dec_info;
- int ret = 0;
+ int ret;
struct vpu_device *vpu_dev = inst->dev;
if (index >= p_dec_info->num_of_display_fbs)
@@ -659,9 +605,23 @@ int wave5_vpu_dec_set_disp_flag(struct vpu_instance *inst, int index)
return ret;
}
+int wave5_vpu_dec_reset_framebuffer(struct vpu_instance *inst, unsigned int index)
+{
+ if (index >= MAX_REG_FRAME)
+ return -EINVAL;
+
+ if (inst->frame_vbuf[index].size == 0)
+ return -EINVAL;
+
+ wave5_vdi_free_dma_memory(inst->dev, &inst->frame_vbuf[index]);
+
+ return 0;
+}
+
int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter)
{
struct dec_info *p_dec_info = &inst->codec_info->dec_info;
+ int ret = 0;
switch (cmd) {
case DEC_GET_QUEUE_STATUS: {
@@ -671,17 +631,19 @@ int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd
queue_info->report_queue_count = p_dec_info->report_queue_count;
break;
}
- case ENABLE_DEC_THUMBNAIL_MODE:
- p_dec_info->thumbnail_mode = true;
- break;
case DEC_RESET_FRAMEBUF_INFO: {
int i;
- for (i = 0; i < inst->dst_buf_count; i++) {
- wave5_vdi_free_dma_memory(inst->dev, &inst->frame_vbuf[i]);
- wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_mv[i]);
- wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_fbc_y_tbl[i]);
- wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_fbc_c_tbl[i]);
+ for (i = 0; i < MAX_REG_FRAME; i++) {
+ ret = wave5_vpu_dec_reset_framebuffer(inst, i);
+ if (ret)
+ break;
+ }
+
+ for (i = 0; i < MAX_REG_FRAME; i++) {
+ ret = reset_auxiliary_buffers(inst, i);
+ if (ret)
+ break;
}
wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_task);
@@ -698,7 +660,7 @@ int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd
return -EINVAL;
}
- return 0;
+ return ret;
}
int wave5_vpu_enc_open(struct vpu_instance *inst, struct enc_open_param *open_param)
@@ -720,24 +682,10 @@ int wave5_vpu_enc_open(struct vpu_instance *inst, struct enc_open_param *open_pa
return -ENODEV;
}
- inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL);
- if (!inst->codec_info) {
- mutex_unlock(&vpu_dev->hw_lock);
- return -ENOMEM;
- }
-
p_enc_info = &inst->codec_info->enc_info;
p_enc_info->open_param = *open_param;
ret = wave5_vpu_build_up_enc_param(vpu_dev->dev, inst, open_param);
- if (ret)
- goto free_codec_info;
- mutex_unlock(&vpu_dev->hw_lock);
-
- return 0;
-
-free_codec_info:
- kfree(inst->codec_info);
mutex_unlock(&vpu_dev->hw_lock);
return ret;
@@ -745,55 +693,49 @@ free_codec_info:
int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res)
{
- struct enc_info *p_enc_info;
+ struct enc_info *p_enc_info = &inst->codec_info->enc_info;
int ret;
+ int retry = 0;
struct vpu_device *vpu_dev = inst->dev;
- *fail_res = 0;
+ *fail_res = 0;
if (!inst->codec_info)
return -EINVAL;
- p_enc_info = &inst->codec_info->enc_info;
ret = mutex_lock_interruptible(&vpu_dev->hw_lock);
if (ret)
return ret;
- ret = wave5_vpu_enc_finish_seq(inst, fail_res);
- if (ret) {
- dev_warn(inst->dev->dev, "enc seq end timed out\n");
-
- if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING) {
+ do {
+ ret = wave5_vpu_enc_finish_seq(inst, fail_res);
+ if (ret < 0 && *fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) {
+ dev_warn(inst->dev->dev, "enc_finish_seq timed out\n");
mutex_unlock(&vpu_dev->hw_lock);
return ret;
}
- }
-
- dev_dbg(inst->dev->dev, "%s: enc seq end timed out\n", __func__);
- if (p_enc_info->vb_work.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_work);
-
- if (inst->std == W_HEVC_ENC || inst->std == W_AVC_ENC) {
- if (p_enc_info->vb_sub_sam_buf.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_sub_sam_buf);
+ if (*fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING &&
+ retry++ >= MAX_FIRMWARE_CALL_RETRY) {
+ mutex_unlock(&vpu_dev->hw_lock);
+ return -ETIMEDOUT;
+ }
+ } while (ret != 0);
- if (p_enc_info->vb_mv.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_mv);
+ dev_dbg(inst->dev->dev, "%s: enc_finish_seq complete\n", __func__);
- if (p_enc_info->vb_fbc_y_tbl.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_fbc_y_tbl);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_work);
- if (p_enc_info->vb_fbc_c_tbl.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_fbc_c_tbl);
+ if (inst->std == W_HEVC_ENC || inst->std == W_AVC_ENC) {
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_sub_sam_buf);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_mv);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_fbc_y_tbl);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_fbc_c_tbl);
}
- if (p_enc_info->vb_task.size)
- wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_task);
+ wave5_vdi_free_dma_memory(vpu_dev, &p_enc_info->vb_task);
mutex_unlock(&vpu_dev->hw_lock);
- kfree(inst->codec_info);
-
return 0;
}
@@ -840,7 +782,6 @@ int wave5_vpu_enc_register_frame_buffer(struct vpu_instance *inst, unsigned int
inst->frame_buf[i].stride = stride;
inst->frame_buf[i].height = height;
inst->frame_buf[i].map_type = COMPRESSED_FRAME_MAP;
- inst->frame_buf[i].endian = VDI_128BIT_LITTLE_ENDIAN;
inst->frame_buf[i].buf_y_size = size_luma;
inst->frame_buf[i].buf_cb = inst->frame_buf[i].buf_y + size_luma;
inst->frame_buf[i].buf_cb_size = size_chroma;
@@ -863,45 +804,19 @@ static int wave5_check_enc_param(struct vpu_instance *inst, struct enc_param *pa
if (!param)
return -EINVAL;
- if (!param->skip_picture && !param->source_frame)
+ if (!param->source_frame)
return -EINVAL;
if (p_enc_info->open_param.bit_rate == 0 && inst->std == W_HEVC_ENC) {
- if (param->force_pic_qp_enable &&
- (param->force_pic_qp_i > MAX_INTRA_QP || param->force_pic_qp_p > MAX_INTRA_QP ||
- param->force_pic_qp_b > MAX_INTRA_QP))
- return -EINVAL;
- if (!p_enc_info->ring_buffer_enable &&
- (param->pic_stream_buffer_addr % 16 || param->pic_stream_buffer_size == 0))
+ if (param->pic_stream_buffer_addr % 16 || param->pic_stream_buffer_size == 0)
return -EINVAL;
}
- if (!p_enc_info->ring_buffer_enable &&
- (param->pic_stream_buffer_addr % 8 || param->pic_stream_buffer_size == 0))
+ if (param->pic_stream_buffer_addr % 8 || param->pic_stream_buffer_size == 0)
return -EINVAL;
return 0;
}
-static uint64_t wave5_get_timestamp(struct vpu_instance *inst)
-{
- struct enc_info *p_enc_info;
- u64 pts;
- u32 fps;
-
- if (!inst->codec_info)
- return 0;
-
- p_enc_info = &inst->codec_info->enc_info;
- fps = p_enc_info->open_param.frame_rate_info;
- if (fps == 0)
- fps = 30;
-
- pts = p_enc_info->cur_pts;
- p_enc_info->cur_pts += 90000 / fps; /* 90_k_hz/fps */
-
- return pts;
-}
-
int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *param, u32 *fail_res)
{
struct enc_info *p_enc_info = &inst->codec_info->enc_info;
@@ -910,7 +825,7 @@ int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *p
*fail_res = 0;
- if (p_enc_info->stride == 0) // this means frame buffers have not been registered.
+ if (p_enc_info->stride == 0) /* this means frame buffers have not been registered. */
return -EINVAL;
ret = wave5_check_enc_param(inst, param);
@@ -921,8 +836,7 @@ int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *p
if (ret)
return ret;
- p_enc_info->pts_map[param->src_idx] = p_enc_info->open_param.enable_pts ?
- wave5_get_timestamp(inst) : param->pts;
+ p_enc_info->pts_map[param->src_idx] = param->pts;
ret = wave5_vpu_encode(inst, param, fail_res);