diff options
Diffstat (limited to 'drivers/media/platform/qcom/iris/iris_buffer.c')
-rw-r--r-- | drivers/media/platform/qcom/iris/iris_buffer.c | 222 |
1 files changed, 178 insertions, 44 deletions
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index 6425e4919e3b..c0900038e7de 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -63,7 +63,12 @@ static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst) { u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines; - struct v4l2_format *f = inst->fmt_dst; + struct v4l2_format *f; + + if (inst->domain == DECODER) + f = inst->fmt_dst; + else + f = inst->fmt_src; y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); @@ -194,7 +199,7 @@ static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst) return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K); } -static u32 iris_bitstream_buffer_size(struct iris_inst *inst) +static u32 iris_dec_bitstream_buffer_size(struct iris_inst *inst) { struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; u32 base_res_mbs = NUM_MBS_4K; @@ -219,18 +224,58 @@ static u32 iris_bitstream_buffer_size(struct iris_inst *inst) return ALIGN(frame_size, PIXELS_4K); } +static u32 iris_enc_bitstream_buffer_size(struct iris_inst *inst) +{ + u32 aligned_width, aligned_height, bitstream_size, yuv_size; + int bitrate_mode, frame_rc; + struct v4l2_format *f; + + f = inst->fmt_dst; + + bitrate_mode = inst->fw_caps[BITRATE_MODE].value; + frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value; + + aligned_width = ALIGN(f->fmt.pix_mp.width, 32); + aligned_height = ALIGN(f->fmt.pix_mp.height, 32); + bitstream_size = aligned_width * aligned_height * 3; + yuv_size = (aligned_width * aligned_height * 3) >> 1; + if (aligned_width * aligned_height > (4096 * 2176)) + /* bitstream_size = 0.25 * yuv_size; */ + bitstream_size = (bitstream_size >> 3); + else if (aligned_width * aligned_height > (1280 * 720)) + /* bitstream_size = 0.5 * yuv_size; */ + bitstream_size = (bitstream_size >> 2); + + if ((!frame_rc || bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) && + bitstream_size < yuv_size) + bitstream_size = (bitstream_size << 1); + + return ALIGN(bitstream_size, 4096); +} + int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) { - switch (buffer_type) { - case BUF_INPUT: - return iris_bitstream_buffer_size(inst); - case BUF_OUTPUT: - return iris_yuv_buffer_size_nv12(inst); - case BUF_DPB: - return iris_yuv_buffer_size_qc08c(inst); - default: - return 0; + if (inst->domain == DECODER) { + switch (buffer_type) { + case BUF_INPUT: + return iris_dec_bitstream_buffer_size(inst); + case BUF_OUTPUT: + return iris_yuv_buffer_size_nv12(inst); + case BUF_DPB: + return iris_yuv_buffer_size_qc08c(inst); + default: + return 0; + } + } else { + switch (buffer_type) { + case BUF_INPUT: + return iris_yuv_buffer_size_nv12(inst); + case BUF_OUTPUT: + return iris_enc_bitstream_buffer_size(inst); + default: + return 0; + } } } @@ -239,7 +284,7 @@ static void iris_fill_internal_buf_info(struct iris_inst *inst, { struct iris_buffers *buffers = &inst->buffers[buffer_type]; - buffers->size = iris_vpu_buf_size(inst, buffer_type); + buffers->size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, buffer_type); buffers->min_count = iris_vpu_buf_count(inst, buffer_type); } @@ -249,16 +294,30 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane) 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]); + if (inst->domain == DECODER) { + 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]); + } } 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]); + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->enc_ip_int_buf_tbl; + internal_buffer_count = platform_data->enc_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->enc_op_int_buf_tbl; + internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + for (i = 0; i < internal_buffer_count; i++) + iris_fill_internal_buf_info(inst, internal_buf_type[i]); + } } } @@ -299,12 +358,22 @@ int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) 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; + if (inst->domain == DECODER) { + 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; + } } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->enc_ip_int_buf_tbl; + internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + } else { + internal_buf_type = platform_data->enc_op_int_buf_tbl; + internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + } } for (i = 0; i < internal_buffer_count; i++) { @@ -334,6 +403,29 @@ int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) return 0; } +int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + struct iris_buffer *buffer, *next; + struct iris_buffers *buffers; + int ret = 0; + + buffers = &inst->buffers[buffer_type]; + 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; + + if (buffer->attr & BUF_ATTR_DEFERRED) { + ret = iris_queue_buffer(inst, buffer); + if (ret) + return ret; + } + } + + return ret; +} + int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) { const struct iris_platform_data *platform_data = inst->core->iris_platform_data; @@ -343,12 +435,22 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) 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; + if (inst->domain == DECODER) { + 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; + } } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->enc_ip_int_buf_tbl; + internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + } else { + internal_buf_type = platform_data->enc_op_int_buf_tbl; + internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + } } for (i = 0; i < internal_buffer_count; i++) { @@ -358,6 +460,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) continue; if (buffer->attr & BUF_ATTR_QUEUED) continue; + if (buffer->type == BUF_DPB && inst->state != IRIS_INST_STREAMING) { + buffer->attr |= BUF_ATTR_DEFERRED; + continue; + } ret = iris_queue_buffer(inst, buffer); if (ret) return ret; @@ -388,12 +494,22 @@ static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool 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; + if (inst->domain == DECODER) { + 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; + } } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - len = platform_data->dec_op_int_buf_tbl_size; + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->enc_ip_int_buf_tbl; + len = platform_data->enc_ip_int_buf_tbl_size; + } else { + internal_buf_type = platform_data->enc_op_int_buf_tbl; + len = platform_data->enc_op_int_buf_tbl_size; + } } for (i = 0; i < len; i++) { @@ -413,6 +529,19 @@ static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool } } + if (force) { + if (inst->domain == DECODER) + buffers = &inst->buffers[BUF_PERSIST]; + else + buffers = &inst->buffers[BUF_ARP]; + + list_for_each_entry_safe(buf, next, &buffers->list, list) { + ret = iris_destroy_internal_buffer(inst, buf); + if (ret) + return ret; + } + } + return 0; } @@ -455,8 +584,13 @@ static int iris_release_input_internal_buffers(struct iris_inst *inst) u32 internal_buffer_count, i; int ret; - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + if (inst->domain == DECODER) { + 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->enc_ip_int_buf_tbl; + internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + } for (i = 0; i < internal_buffer_count; i++) { ret = iris_release_internal_buffers(inst, internal_buf_type[i]); @@ -467,9 +601,9 @@ static int iris_release_input_internal_buffers(struct iris_inst *inst) return 0; } -int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) +int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst, enum iris_buffer_type buffer_type) { - struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST]; + struct iris_buffers *buffers = &inst->buffers[buffer_type]; struct iris_buffer *buffer, *next; int ret; u32 i; @@ -477,10 +611,10 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) if (!list_empty(&buffers->list)) return 0; - iris_fill_internal_buf_info(inst, BUF_PERSIST); + iris_fill_internal_buf_info(inst, buffer_type); for (i = 0; i < buffers->min_count; i++) { - ret = iris_create_internal_buffer(inst, BUF_PERSIST, i); + ret = iris_create_internal_buffer(inst, buffer_type, i); if (ret) return ret; } @@ -614,6 +748,8 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) vb2 = &vbuf->vb2_buf; + vbuf->flags |= buf->flags; + if (buf->flags & V4L2_BUF_FLAG_ERROR) { state = VB2_BUF_STATE_ERROR; vb2_set_plane_payload(vb2, 0, 0); @@ -622,8 +758,6 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) return 0; } - vbuf->flags |= buf->flags; - if (V4L2_TYPE_IS_CAPTURE(type)) { vb2_set_plane_payload(vb2, 0, buf->data_size); vbuf->sequence = inst->sequence_cap++; |