Lines Matching +full:venus +full:- +full:decoder
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
12 #include <media/v4l2-ioctl.h>
13 #include <media/v4l2-event.h>
14 #include <media/v4l2-ctrls.h>
15 #include <media/v4l2-mem2mem.h>
16 #include <media/videobuf2-dma-contig.h>
28 * - the MPLANE formats allow only one plane to be used
29 * - the downstream driver use MPLANE formats too
30 * - future firmware versions could add support for >1 planes
140 !(inst->bit_depth == VIDC_BITDEPTH_10)) in find_format()
168 !(inst->bit_depth == VIDC_BITDEPTH_10)) in find_format_by_index()
187 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; in vdec_try_fmt_common()
188 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; in vdec_try_fmt_common()
193 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); in vdec_try_fmt_common()
195 fmt = find_format(inst, pixmp->pixelformat, f->type); in vdec_try_fmt_common()
197 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in vdec_try_fmt_common()
198 pixmp->pixelformat = V4L2_PIX_FMT_NV12; in vdec_try_fmt_common()
199 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in vdec_try_fmt_common()
200 pixmp->pixelformat = V4L2_PIX_FMT_H264; in vdec_try_fmt_common()
203 fmt = find_format(inst, pixmp->pixelformat, f->type); in vdec_try_fmt_common()
208 pixmp->width = clamp(pixmp->width, frame_width_min(inst), in vdec_try_fmt_common()
210 pixmp->height = clamp(pixmp->height, frame_height_min(inst), in vdec_try_fmt_common()
213 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in vdec_try_fmt_common()
214 pixmp->height = ALIGN(pixmp->height, 32); in vdec_try_fmt_common()
216 if (pixmp->field == V4L2_FIELD_ANY) in vdec_try_fmt_common()
217 pixmp->field = V4L2_FIELD_NONE; in vdec_try_fmt_common()
218 pixmp->num_planes = fmt->num_planes; in vdec_try_fmt_common()
219 pixmp->flags = 0; in vdec_try_fmt_common()
221 szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width, in vdec_try_fmt_common()
222 pixmp->height); in vdec_try_fmt_common()
224 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_try_fmt_common()
225 unsigned int stride = pixmp->width; in vdec_try_fmt_common()
227 if (pixmp->pixelformat == V4L2_PIX_FMT_P010) in vdec_try_fmt_common()
254 if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE && in vdec_check_src_change()
255 inst->codec_state == VENUS_DEC_STATE_INIT && in vdec_check_src_change()
256 !inst->reconfig) in vdec_check_src_change()
257 return -EINVAL; in vdec_check_src_change()
259 if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE) in vdec_check_src_change()
268 if (inst->codec_state != VENUS_DEC_STATE_INIT) in vdec_check_src_change()
271 ret = wait_event_timeout(inst->reconf_wait, inst->reconfig, in vdec_check_src_change()
274 return -EINVAL; in vdec_check_src_change()
276 if (!(inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) || in vdec_check_src_change()
277 !inst->reconfig) in vdec_check_src_change()
278 dev_dbg(inst->core->dev, VDBGH "wrong state\n"); in vdec_check_src_change()
288 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; in vdec_g_fmt()
291 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in vdec_g_fmt()
292 fmt = inst->fmt_cap; in vdec_g_fmt()
293 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in vdec_g_fmt()
294 fmt = inst->fmt_out; in vdec_g_fmt()
296 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_g_fmt()
302 pixmp->pixelformat = fmt->pixfmt; in vdec_g_fmt()
304 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_g_fmt()
305 pixmp->width = inst->width; in vdec_g_fmt()
306 pixmp->height = inst->height; in vdec_g_fmt()
307 pixmp->colorspace = inst->colorspace; in vdec_g_fmt()
308 pixmp->ycbcr_enc = inst->ycbcr_enc; in vdec_g_fmt()
309 pixmp->quantization = inst->quantization; in vdec_g_fmt()
310 pixmp->xfer_func = inst->xfer_func; in vdec_g_fmt()
311 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { in vdec_g_fmt()
312 pixmp->width = inst->out_width; in vdec_g_fmt()
313 pixmp->height = inst->out_height; in vdec_g_fmt()
324 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; in vdec_s_fmt()
331 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); in vdec_s_fmt()
333 return -EINVAL; in vdec_s_fmt()
336 return -EBUSY; in vdec_s_fmt()
342 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { in vdec_s_fmt()
343 pixfmt_out = pixmp->pixelformat; in vdec_s_fmt()
344 pixfmt_cap = inst->fmt_cap->pixfmt; in vdec_s_fmt()
345 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_s_fmt()
346 pixfmt_cap = pixmp->pixelformat; in vdec_s_fmt()
347 pixfmt_out = inst->fmt_out->pixfmt; in vdec_s_fmt()
358 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { in vdec_s_fmt()
359 inst->out_width = format.fmt.pix_mp.width; in vdec_s_fmt()
360 inst->out_height = format.fmt.pix_mp.height; in vdec_s_fmt()
361 inst->colorspace = pixmp->colorspace; in vdec_s_fmt()
362 inst->ycbcr_enc = pixmp->ycbcr_enc; in vdec_s_fmt()
363 inst->quantization = pixmp->quantization; in vdec_s_fmt()
364 inst->xfer_func = pixmp->xfer_func; in vdec_s_fmt()
365 inst->input_buf_size = pixmp->plane_fmt[0].sizeimage; in vdec_s_fmt()
376 inst->width = format.fmt.pix_mp.width; in vdec_s_fmt()
377 inst->height = format.fmt.pix_mp.height; in vdec_s_fmt()
378 inst->crop.top = 0; in vdec_s_fmt()
379 inst->crop.left = 0; in vdec_s_fmt()
380 inst->crop.width = inst->width; in vdec_s_fmt()
381 inst->crop.height = inst->height; in vdec_s_fmt()
383 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in vdec_s_fmt()
384 inst->fmt_out = fmt; in vdec_s_fmt()
385 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_s_fmt()
386 inst->fmt_cap = fmt; in vdec_s_fmt()
387 inst->output2_buf_size = in vdec_s_fmt()
399 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && in vdec_g_selection()
400 s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vdec_g_selection()
401 return -EINVAL; in vdec_g_selection()
403 s->r.top = 0; in vdec_g_selection()
404 s->r.left = 0; in vdec_g_selection()
406 switch (s->target) { in vdec_g_selection()
410 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vdec_g_selection()
411 return -EINVAL; in vdec_g_selection()
412 s->r.width = inst->out_width; in vdec_g_selection()
413 s->r.height = inst->out_height; in vdec_g_selection()
417 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in vdec_g_selection()
418 return -EINVAL; in vdec_g_selection()
419 s->r.width = inst->width; in vdec_g_selection()
420 s->r.height = inst->height; in vdec_g_selection()
424 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in vdec_g_selection()
425 return -EINVAL; in vdec_g_selection()
426 s->r = inst->crop; in vdec_g_selection()
429 return -EINVAL; in vdec_g_selection()
438 strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); in vdec_querycap()
439 strscpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card)); in vdec_querycap()
440 strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); in vdec_querycap()
450 memset(f->reserved, 0, sizeof(f->reserved)); in vdec_enum_fmt()
452 fmt = find_format_by_index(inst, f->index, f->type); in vdec_enum_fmt()
454 return -EINVAL; in vdec_enum_fmt()
456 f->pixelformat = fmt->pixfmt; in vdec_enum_fmt()
457 f->flags = fmt->flags; in vdec_enum_fmt()
465 struct v4l2_captureparm *cap = &a->parm.capture; in vdec_s_parm()
466 struct v4l2_fract *timeperframe = &cap->timeperframe; in vdec_s_parm()
469 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && in vdec_s_parm()
470 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in vdec_s_parm()
471 return -EINVAL; in vdec_s_parm()
473 memset(cap->reserved, 0, sizeof(cap->reserved)); in vdec_s_parm()
474 if (!timeperframe->denominator) in vdec_s_parm()
475 timeperframe->denominator = inst->timeperframe.denominator; in vdec_s_parm()
476 if (!timeperframe->numerator) in vdec_s_parm()
477 timeperframe->numerator = inst->timeperframe.numerator; in vdec_s_parm()
478 cap->readbuffers = 0; in vdec_s_parm()
479 cap->extendedmode = 0; in vdec_s_parm()
480 cap->capability = V4L2_CAP_TIMEPERFRAME; in vdec_s_parm()
481 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; in vdec_s_parm()
482 do_div(us_per_frame, timeperframe->denominator); in vdec_s_parm()
485 return -EINVAL; in vdec_s_parm()
490 inst->fps = fps; in vdec_s_parm()
491 inst->timeperframe = *timeperframe; in vdec_s_parm()
502 fmt = find_format(inst, fsize->pixel_format, in vdec_enum_framesizes()
505 fmt = find_format(inst, fsize->pixel_format, in vdec_enum_framesizes()
508 return -EINVAL; in vdec_enum_framesizes()
511 if (fsize->index) in vdec_enum_framesizes()
512 return -EINVAL; in vdec_enum_framesizes()
514 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in vdec_enum_framesizes()
516 fsize->stepwise.min_width = frame_width_min(inst); in vdec_enum_framesizes()
517 fsize->stepwise.max_width = frame_width_max(inst); in vdec_enum_framesizes()
518 fsize->stepwise.step_width = frame_width_step(inst); in vdec_enum_framesizes()
519 fsize->stepwise.min_height = frame_height_min(inst); in vdec_enum_framesizes()
520 fsize->stepwise.max_height = frame_height_max(inst); in vdec_enum_framesizes()
521 fsize->stepwise.step_height = frame_height_step(inst); in vdec_enum_framesizes()
532 switch (sub->type) { in vdec_subscribe_event()
539 inst->subscriptions |= V4L2_EVENT_SOURCE_CHANGE; in vdec_subscribe_event()
544 return -EINVAL; in vdec_subscribe_event()
560 mutex_lock(&inst->lock); in vdec_decoder_cmd()
562 if (cmd->cmd == V4L2_DEC_CMD_STOP) { in vdec_decoder_cmd()
565 * decoder input to signal EOS. in vdec_decoder_cmd()
567 if (!(inst->streamon_out && inst->streamon_cap)) in vdec_decoder_cmd()
572 if (IS_V6(inst->core) && is_fw_rev_or_older(inst->core, 1, 0, 87)) in vdec_decoder_cmd()
579 if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) { in vdec_decoder_cmd()
580 inst->codec_state = VENUS_DEC_STATE_DRAIN; in vdec_decoder_cmd()
581 inst->drain_active = true; in vdec_decoder_cmd()
583 } else if (cmd->cmd == V4L2_DEC_CMD_START && in vdec_decoder_cmd()
584 inst->codec_state == VENUS_DEC_STATE_STOPPED) { in vdec_decoder_cmd()
585 dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx, in vdec_decoder_cmd()
589 inst->codec_state = VENUS_DEC_STATE_DECODING; in vdec_decoder_cmd()
593 mutex_unlock(&inst->lock); in vdec_decoder_cmd()
627 struct venus_core *core = inst->core; in vdec_pm_get()
628 struct device *dev = core->dev_dec; in vdec_pm_get()
631 mutex_lock(&core->pm_lock); in vdec_pm_get()
633 mutex_unlock(&core->pm_lock); in vdec_pm_get()
640 struct venus_core *core = inst->core; in vdec_pm_put()
641 struct device *dev = core->dev_dec; in vdec_pm_put()
644 mutex_lock(&core->pm_lock); in vdec_pm_put()
651 mutex_unlock(&core->pm_lock); in vdec_pm_put()
658 struct venus_core *core = inst->core; in vdec_pm_get_put()
659 struct device *dev = core->dev_dec; in vdec_pm_get_put()
662 mutex_lock(&core->pm_lock); in vdec_pm_get_put()
673 mutex_unlock(&core->pm_lock); in vdec_pm_get_put()
680 pm_runtime_mark_last_busy(inst->core->dev_dec); in vdec_pm_touch()
685 struct vdec_controls *ctr = &inst->controls.dec; in vdec_set_properties()
690 if (ctr->post_loop_deb_mode) { in vdec_set_properties()
697 if (ctr->display_delay_enable && ctr->display_delay == 0) { in vdec_set_properties()
706 if (is_fw_rev_or_newer(inst->core, 5, 4, 51)) { in vdec_set_properties()
714 conceal = ctr->conceal_color & 0xffff; in vdec_set_properties()
715 conceal |= ((ctr->conceal_color >> 16) & 0xffff) << 10; in vdec_set_properties()
716 conceal |= ((ctr->conceal_color >> 32) & 0xffff) << 20; in vdec_set_properties()
730 if (!(IS_IRIS2(inst->core) || IS_IRIS2_1(inst->core))) in vdec_set_work_route()
733 wr.video_work_route = inst->core->res->num_vpp_pipes; in vdec_set_work_route()
745 struct venus_core *core = inst->core; in vdec_output_conf()
748 u32 width = inst->width; in vdec_output_conf()
749 u32 height = inst->height; in vdec_output_conf()
759 if (core->res->hfi_version == HFI_VERSION_1XX) { in vdec_output_conf()
770 /* For Venus v4/v6 UBWC format is mandatory */ in vdec_output_conf()
774 ret = venus_helper_get_out_fmts(inst, inst->fmt_cap->pixfmt, &out_fmt, in vdec_output_conf()
779 inst->output_buf_size = in vdec_output_conf()
781 inst->output2_buf_size = in vdec_output_conf()
785 inst->opb_buftype = HFI_BUFFER_OUTPUT2; in vdec_output_conf()
786 inst->opb_fmt = out2_fmt; in vdec_output_conf()
787 inst->dpb_buftype = HFI_BUFFER_OUTPUT; in vdec_output_conf()
788 inst->dpb_fmt = out_fmt; in vdec_output_conf()
790 inst->opb_buftype = HFI_BUFFER_OUTPUT; in vdec_output_conf()
791 inst->opb_fmt = out_fmt; in vdec_output_conf()
792 inst->dpb_buftype = HFI_BUFFER_OUTPUT2; in vdec_output_conf()
793 inst->dpb_fmt = out2_fmt; in vdec_output_conf()
795 inst->opb_buftype = HFI_BUFFER_OUTPUT; in vdec_output_conf()
796 inst->opb_fmt = out_fmt; in vdec_output_conf()
797 inst->dpb_buftype = 0; in vdec_output_conf()
798 inst->dpb_fmt = 0; in vdec_output_conf()
801 ret = venus_helper_set_raw_format(inst, inst->opb_fmt, in vdec_output_conf()
802 inst->opb_buftype); in vdec_output_conf()
810 if (inst->dpb_fmt) { in vdec_output_conf()
815 ret = venus_helper_set_raw_format(inst, inst->dpb_fmt, in vdec_output_conf()
816 inst->dpb_buftype); in vdec_output_conf()
831 if (bufreq.size > inst->output_buf_size) in vdec_output_conf()
832 return -EINVAL; in vdec_output_conf()
834 if (inst->dpb_fmt) { in vdec_output_conf()
840 if (bufreq.size > inst->output2_buf_size) in vdec_output_conf()
841 return -EINVAL; in vdec_output_conf()
844 if (inst->output2_buf_size) { in vdec_output_conf()
846 inst->output2_buf_size, in vdec_output_conf()
852 if (inst->output_buf_size) { in vdec_output_conf()
854 inst->output_buf_size, in vdec_output_conf()
873 if (ret == -EALREADY) in vdec_session_init()
892 enum hfi_version ver = inst->core->res->hfi_version; in vdec_num_buffers()
918 struct venus_core *core = inst->core; in vdec_queue_setup()
925 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && in vdec_queue_setup()
926 *num_planes != inst->fmt_out->num_planes) in vdec_queue_setup()
927 return -EINVAL; in vdec_queue_setup()
929 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && in vdec_queue_setup()
930 *num_planes != inst->fmt_cap->num_planes) in vdec_queue_setup()
931 return -EINVAL; in vdec_queue_setup()
933 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && in vdec_queue_setup()
934 sizes[0] < inst->input_buf_size) in vdec_queue_setup()
935 return -EINVAL; in vdec_queue_setup()
937 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && in vdec_queue_setup()
939 return -EINVAL; in vdec_queue_setup()
944 if (test_bit(0, &core->sys_error)) { in vdec_queue_setup()
945 if (inst->nonblock) in vdec_queue_setup()
946 return -EAGAIN; in vdec_queue_setup()
948 ret = wait_event_interruptible(core->sys_err_done, in vdec_queue_setup()
949 !test_bit(0, &core->sys_error)); in vdec_queue_setup()
970 switch (q->type) { in vdec_queue_setup()
972 *num_planes = inst->fmt_out->num_planes; in vdec_queue_setup()
973 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, in vdec_queue_setup()
974 inst->out_width, in vdec_queue_setup()
975 inst->out_height); in vdec_queue_setup()
976 sizes[0] = max(sizes[0], inst->input_buf_size); in vdec_queue_setup()
977 inst->input_buf_size = sizes[0]; in vdec_queue_setup()
979 inst->num_input_bufs = *num_buffers; in vdec_queue_setup()
980 inst->num_output_bufs = out_num; in vdec_queue_setup()
983 *num_planes = inst->fmt_cap->num_planes; in vdec_queue_setup()
984 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, in vdec_queue_setup()
985 inst->width, in vdec_queue_setup()
986 inst->height); in vdec_queue_setup()
987 inst->output_buf_size = sizes[0]; in vdec_queue_setup()
989 inst->num_output_bufs = *num_buffers; in vdec_queue_setup()
991 mutex_lock(&inst->lock); in vdec_queue_setup()
992 if (inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) in vdec_queue_setup()
993 inst->codec_state = VENUS_DEC_STATE_STOPPED; in vdec_queue_setup()
994 mutex_unlock(&inst->lock); in vdec_queue_setup()
997 ret = -EINVAL; in vdec_queue_setup()
1010 enum hfi_version ver = inst->core->res->hfi_version; in vdec_verify_conf()
1014 if (!inst->num_input_bufs || !inst->num_output_bufs) in vdec_verify_conf()
1015 return -EINVAL; in vdec_verify_conf()
1021 if (inst->num_output_bufs < bufreq.count_actual || in vdec_verify_conf()
1022 inst->num_output_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) in vdec_verify_conf()
1023 return -EINVAL; in vdec_verify_conf()
1029 if (inst->num_input_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) in vdec_verify_conf()
1030 return -EINVAL; in vdec_verify_conf()
1039 if (!inst->streamon_out) in vdec_start_capture()
1042 if (inst->codec_state == VENUS_DEC_STATE_DECODING) { in vdec_start_capture()
1043 if (inst->reconfig) in vdec_start_capture()
1048 inst->streamon_cap = 1; in vdec_start_capture()
1052 if (inst->codec_state != VENUS_DEC_STATE_STOPPED) in vdec_start_capture()
1060 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, in vdec_start_capture()
1071 inst->next_buf_last = false; in vdec_start_capture()
1089 inst->codec_state = VENUS_DEC_STATE_DECODING; in vdec_start_capture()
1091 if (inst->drain_active) in vdec_start_capture()
1092 inst->codec_state = VENUS_DEC_STATE_DRAIN; in vdec_start_capture()
1094 inst->streamon_cap = 1; in vdec_start_capture()
1095 inst->sequence_cap = 0; in vdec_start_capture()
1096 inst->reconfig = false; in vdec_start_capture()
1097 inst->drain_active = false; in vdec_start_capture()
1111 if (inst->codec_state == VENUS_DEC_STATE_SEEK) { in vdec_start_output()
1113 if (inst->next_buf_last) in vdec_start_output()
1114 inst->codec_state = VENUS_DEC_STATE_DRC; in vdec_start_output()
1116 inst->codec_state = VENUS_DEC_STATE_DECODING; in vdec_start_output()
1120 if (inst->codec_state == VENUS_DEC_STATE_INIT || in vdec_start_output()
1121 inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) { in vdec_start_output()
1126 if (inst->codec_state != VENUS_DEC_STATE_DEINIT) in vdec_start_output()
1127 return -EINVAL; in vdec_start_output()
1130 inst->sequence_out = 0; in vdec_start_output()
1131 inst->reconfig = false; in vdec_start_output()
1132 inst->next_buf_last = false; in vdec_start_output()
1150 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, in vdec_start_output()
1163 inst->codec_state = VENUS_DEC_STATE_INIT; in vdec_start_output()
1166 inst->streamon_out = 1; in vdec_start_output()
1175 mutex_lock(&inst->lock); in vdec_start_streaming()
1177 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { in vdec_start_streaming()
1198 mutex_unlock(&inst->lock); in vdec_start_streaming()
1204 venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED); in vdec_start_streaming()
1205 mutex_unlock(&inst->lock); in vdec_start_streaming()
1213 while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx))) in vdec_cancel_dst_buffers()
1221 switch (inst->codec_state) { in vdec_stop_capture()
1226 inst->codec_state = VENUS_DEC_STATE_STOPPED; in vdec_stop_capture()
1227 inst->drain_active = false; in vdec_stop_capture()
1234 inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; in vdec_stop_capture()
1248 switch (inst->codec_state) { in vdec_stop_output()
1254 inst->codec_state = VENUS_DEC_STATE_SEEK; in vdec_stop_output()
1270 int ret = -EINVAL; in vdec_stop_streaming()
1274 mutex_lock(&inst->lock); in vdec_stop_streaming()
1276 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in vdec_stop_streaming()
1281 venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); in vdec_stop_streaming()
1283 inst->session_error = 0; in vdec_stop_streaming()
1288 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) in vdec_stop_streaming()
1289 inst->streamon_out = 0; in vdec_stop_streaming()
1291 inst->streamon_cap = 0; in vdec_stop_streaming()
1294 mutex_unlock(&inst->lock); in vdec_stop_streaming()
1299 struct venus_core *core = inst->core; in vdec_session_release()
1304 mutex_lock(&inst->lock); in vdec_session_release()
1305 inst->codec_state = VENUS_DEC_STATE_DEINIT; in vdec_session_release()
1308 abort = (ret && ret != -EINVAL) ? 1 : 0; in vdec_session_release()
1310 abort = (ret && ret != -EINVAL) ? 1 : 0; in vdec_session_release()
1312 abort = (ret && ret != -EINVAL) ? 1 : 0; in vdec_session_release()
1314 abort = (ret && ret != -EINVAL) ? 1 : 0; in vdec_session_release()
1316 abort = (ret && ret != -EINVAL) ? 1 : 0; in vdec_session_release()
1318 if (inst->session_error || test_bit(0, &core->sys_error)) in vdec_session_release()
1326 INIT_LIST_HEAD(&inst->registeredbufs); in vdec_session_release()
1327 mutex_unlock(&inst->lock); in vdec_session_release()
1335 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); in vdec_buf_init()
1337 inst->buf_count++; in vdec_buf_init()
1344 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); in vdec_buf_cleanup()
1348 mutex_lock(&inst->lock); in vdec_buf_cleanup()
1349 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) in vdec_buf_cleanup()
1350 if (!list_empty(&inst->registeredbufs)) in vdec_buf_cleanup()
1351 list_del_init(&buf->reg_list); in vdec_buf_cleanup()
1352 mutex_unlock(&inst->lock); in vdec_buf_cleanup()
1354 inst->buf_count--; in vdec_buf_cleanup()
1355 if (!inst->buf_count) in vdec_buf_cleanup()
1361 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); in vdec_vb2_buf_queue()
1367 mutex_lock(&inst->lock); in vdec_vb2_buf_queue()
1369 if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && in vdec_vb2_buf_queue()
1370 inst->codec_state == VENUS_DEC_STATE_DRC) { in vdec_vb2_buf_queue()
1371 vbuf->flags |= V4L2_BUF_FLAG_LAST; in vdec_vb2_buf_queue()
1372 vbuf->sequence = inst->sequence_cap++; in vdec_vb2_buf_queue()
1373 vbuf->field = V4L2_FIELD_NONE; in vdec_vb2_buf_queue()
1376 v4l2_event_queue_fh(&inst->fh, &eos); in vdec_vb2_buf_queue()
1377 inst->next_buf_last = false; in vdec_vb2_buf_queue()
1378 mutex_unlock(&inst->lock); in vdec_vb2_buf_queue()
1383 mutex_unlock(&inst->lock); in vdec_vb2_buf_queue()
1418 vbuf->flags = flags; in vdec_buf_done()
1419 vbuf->field = V4L2_FIELD_NONE; in vdec_buf_done()
1420 vb = &vbuf->vb2_buf; in vdec_buf_done()
1424 vb->planes[0].data_offset = data_offset; in vdec_buf_done()
1425 vb->timestamp = timestamp_us * NSEC_PER_USEC; in vdec_buf_done()
1426 vbuf->sequence = inst->sequence_cap++; in vdec_buf_done()
1428 if (vbuf->flags & V4L2_BUF_FLAG_LAST) { in vdec_buf_done()
1431 v4l2_event_queue_fh(&inst->fh, &ev); in vdec_buf_done()
1433 if (inst->codec_state == VENUS_DEC_STATE_DRAIN) { in vdec_buf_done()
1434 inst->drain_active = false; in vdec_buf_done()
1435 inst->codec_state = VENUS_DEC_STATE_STOPPED; in vdec_buf_done()
1442 vbuf->sequence = inst->sequence_out++; in vdec_buf_done()
1456 vb->timestamp = 0; in vdec_buf_done()
1468 struct device *dev = inst->core->dev_dec; in vdec_event_change()
1471 mutex_lock(&inst->lock); in vdec_event_change()
1474 format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt; in vdec_event_change()
1475 format.fmt.pix_mp.width = ev_data->width; in vdec_event_change()
1476 format.fmt.pix_mp.height = ev_data->height; in vdec_event_change()
1480 inst->width = format.fmt.pix_mp.width; in vdec_event_change()
1481 inst->height = format.fmt.pix_mp.height; in vdec_event_change()
1486 if (ev_data->input_crop.width > 0 && ev_data->input_crop.height > 0) { in vdec_event_change()
1487 inst->crop.left = ev_data->input_crop.left; in vdec_event_change()
1488 inst->crop.top = ev_data->input_crop.top; in vdec_event_change()
1489 inst->crop.width = ev_data->input_crop.width; in vdec_event_change()
1490 inst->crop.height = ev_data->input_crop.height; in vdec_event_change()
1492 inst->crop.left = 0; in vdec_event_change()
1493 inst->crop.top = 0; in vdec_event_change()
1494 inst->crop.width = ev_data->width; in vdec_event_change()
1495 inst->crop.height = ev_data->height; in vdec_event_change()
1498 inst->fw_min_cnt = ev_data->buf_count; in vdec_event_change()
1500 if (inst->hfi_codec == HFI_VIDEO_CODEC_VP9) in vdec_event_change()
1501 inst->fw_min_cnt = 11; in vdec_event_change()
1503 inst->out_width = ev_data->width; in vdec_event_change()
1504 inst->out_height = ev_data->height; in vdec_event_change()
1506 if (inst->bit_depth != ev_data->bit_depth) { in vdec_event_change()
1507 inst->bit_depth = ev_data->bit_depth; in vdec_event_change()
1508 if (inst->bit_depth == VIDC_BITDEPTH_10) in vdec_event_change()
1509 inst->fmt_cap = &vdec_formats[VENUS_FMT_P010]; in vdec_event_change()
1511 inst->fmt_cap = &vdec_formats[VENUS_FMT_NV12]; in vdec_event_change()
1514 if (inst->pic_struct != ev_data->pic_struct) in vdec_event_change()
1515 inst->pic_struct = ev_data->pic_struct; in vdec_event_change()
1518 sufficient ? "" : "not", ev_data->width, ev_data->height); in vdec_event_change()
1520 switch (inst->codec_state) { in vdec_event_change()
1522 inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; in vdec_event_change()
1526 inst->codec_state = VENUS_DEC_STATE_DRC; in vdec_event_change()
1535 * itself doesn't mark the last decoder output buffer with HFI EOS flag. in vdec_event_change()
1538 if (inst->codec_state == VENUS_DEC_STATE_DRC) { in vdec_event_change()
1541 inst->next_buf_last = true; in vdec_event_change()
1548 inst->next_buf_last = true; in vdec_event_change()
1549 inst->reconfig = true; in vdec_event_change()
1550 v4l2_event_queue_fh(&inst->fh, &ev); in vdec_event_change()
1551 wake_up(&inst->reconf_wait); in vdec_event_change()
1553 mutex_unlock(&inst->lock); in vdec_event_change()
1559 struct venus_core *core = inst->core; in vdec_event_notify()
1560 struct device *dev = core->dev_dec; in vdec_event_notify()
1566 inst->session_error = true; in vdec_event_notify()
1568 dev_err(dev, "dec: event session error %x\n", inst->error); in vdec_event_notify()
1571 switch (data->event_type) { in vdec_event_notify()
1579 venus_helper_release_buf_ref(inst, data->tag); in vdec_event_notify()
1592 dev_dbg(inst->core->dev_dec, VDBGH "flush done\n"); in vdec_flush_done()
1603 inst->hfi_codec = HFI_VIDEO_CODEC_H264; in vdec_inst_init()
1604 inst->fmt_out = &vdec_formats[VENUS_FMT_H264]; in vdec_inst_init()
1605 inst->fmt_cap = &vdec_formats[VENUS_FMT_NV12]; in vdec_inst_init()
1606 inst->width = frame_width_min(inst); in vdec_inst_init()
1607 inst->height = ALIGN(frame_height_min(inst), 32); in vdec_inst_init()
1608 inst->crop.left = 0; in vdec_inst_init()
1609 inst->crop.top = 0; in vdec_inst_init()
1610 inst->crop.width = inst->width; in vdec_inst_init()
1611 inst->crop.height = inst->height; in vdec_inst_init()
1612 inst->fw_min_cnt = 8; in vdec_inst_init()
1613 inst->out_width = frame_width_min(inst); in vdec_inst_init()
1614 inst->out_height = frame_height_min(inst); in vdec_inst_init()
1615 inst->fps = 30; in vdec_inst_init()
1616 inst->timeperframe.numerator = 1; in vdec_inst_init()
1617 inst->timeperframe.denominator = 30; in vdec_inst_init()
1618 inst->opb_buftype = HFI_BUFFER_OUTPUT; in vdec_inst_init()
1636 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; in m2m_queue_init()
1637 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in m2m_queue_init()
1638 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in m2m_queue_init()
1639 src_vq->ops = &vdec_vb2_ops; in m2m_queue_init()
1640 src_vq->mem_ops = &vb2_dma_contig_memops; in m2m_queue_init()
1641 src_vq->drv_priv = inst; in m2m_queue_init()
1642 src_vq->buf_struct_size = sizeof(struct venus_buffer); in m2m_queue_init()
1643 src_vq->allow_zero_bytesused = 1; in m2m_queue_init()
1644 src_vq->min_queued_buffers = 0; in m2m_queue_init()
1645 src_vq->dev = inst->core->dev; in m2m_queue_init()
1646 src_vq->lock = &inst->ctx_q_lock; in m2m_queue_init()
1651 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in m2m_queue_init()
1652 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in m2m_queue_init()
1653 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in m2m_queue_init()
1654 dst_vq->ops = &vdec_vb2_ops; in m2m_queue_init()
1655 dst_vq->mem_ops = &vb2_dma_contig_memops; in m2m_queue_init()
1656 dst_vq->drv_priv = inst; in m2m_queue_init()
1657 dst_vq->buf_struct_size = sizeof(struct venus_buffer); in m2m_queue_init()
1658 dst_vq->allow_zero_bytesused = 1; in m2m_queue_init()
1659 dst_vq->min_queued_buffers = 0; in m2m_queue_init()
1660 dst_vq->dev = inst->core->dev; in m2m_queue_init()
1661 dst_vq->lock = &inst->ctx_q_lock; in m2m_queue_init()
1673 return -ENOMEM; in vdec_open()
1675 INIT_LIST_HEAD(&inst->dpbbufs); in vdec_open()
1676 INIT_LIST_HEAD(&inst->registeredbufs); in vdec_open()
1677 INIT_LIST_HEAD(&inst->internalbufs); in vdec_open()
1678 INIT_LIST_HEAD(&inst->list); in vdec_open()
1679 mutex_init(&inst->lock); in vdec_open()
1680 mutex_init(&inst->ctx_q_lock); in vdec_open()
1682 inst->core = core; in vdec_open()
1683 inst->session_type = VIDC_SESSION_TYPE_DEC; in vdec_open()
1684 inst->num_output_bufs = 1; in vdec_open()
1685 inst->codec_state = VENUS_DEC_STATE_DEINIT; in vdec_open()
1686 inst->buf_count = 0; in vdec_open()
1687 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; in vdec_open()
1688 inst->core_acquired = false; in vdec_open()
1689 inst->bit_depth = VIDC_BITDEPTH_8; in vdec_open()
1690 inst->pic_struct = HFI_INTERLACE_FRAME_PROGRESSIVE; in vdec_open()
1691 init_waitqueue_head(&inst->reconf_wait); in vdec_open()
1692 inst->nonblock = file->f_flags & O_NONBLOCK; in vdec_open()
1706 ida_init(&inst->dpb_ids); in vdec_open()
1712 inst->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops); in vdec_open()
1713 if (IS_ERR(inst->m2m_dev)) { in vdec_open()
1714 ret = PTR_ERR(inst->m2m_dev); in vdec_open()
1718 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); in vdec_open()
1719 if (IS_ERR(inst->m2m_ctx)) { in vdec_open()
1720 ret = PTR_ERR(inst->m2m_ctx); in vdec_open()
1724 v4l2_fh_init(&inst->fh, core->vdev_dec); in vdec_open()
1726 inst->fh.ctrl_handler = &inst->ctrl_handler; in vdec_open()
1727 v4l2_fh_add(&inst->fh); in vdec_open()
1728 inst->fh.m2m_ctx = inst->m2m_ctx; in vdec_open()
1729 file->private_data = &inst->fh; in vdec_open()
1734 v4l2_m2m_release(inst->m2m_dev); in vdec_open()
1750 cancel_work_sync(&inst->delayed_process_work); in vdec_close()
1751 v4l2_m2m_ctx_release(inst->m2m_ctx); in vdec_close()
1752 v4l2_m2m_release(inst->m2m_dev); in vdec_close()
1754 ida_destroy(&inst->dpb_ids); in vdec_close()
1756 mutex_destroy(&inst->lock); in vdec_close()
1757 mutex_destroy(&inst->ctx_q_lock); in vdec_close()
1758 v4l2_fh_del(&inst->fh); in vdec_close()
1759 v4l2_fh_exit(&inst->fh); in vdec_close()
1778 struct device *dev = &pdev->dev; in vdec_probe()
1783 if (!dev->parent) in vdec_probe()
1784 return -EPROBE_DEFER; in vdec_probe()
1786 core = dev_get_drvdata(dev->parent); in vdec_probe()
1788 return -EPROBE_DEFER; in vdec_probe()
1792 if (core->pm_ops->vdec_get) { in vdec_probe()
1793 ret = core->pm_ops->vdec_get(dev); in vdec_probe()
1800 return -ENOMEM; in vdec_probe()
1802 strscpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name)); in vdec_probe()
1803 vdev->release = video_device_release; in vdec_probe()
1804 vdev->fops = &vdec_fops; in vdec_probe()
1805 vdev->ioctl_ops = &vdec_ioctl_ops; in vdec_probe()
1806 vdev->vfl_dir = VFL_DIR_M2M; in vdec_probe()
1807 vdev->v4l2_dev = &core->v4l2_dev; in vdec_probe()
1808 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; in vdec_probe()
1810 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in vdec_probe()
1814 core->vdev_dec = vdev; in vdec_probe()
1815 core->dev_dec = dev; in vdec_probe()
1831 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); in vdec_remove()
1833 video_unregister_device(core->vdev_dec); in vdec_remove()
1834 pm_runtime_disable(core->dev_dec); in vdec_remove()
1836 if (core->pm_ops->vdec_put) in vdec_remove()
1837 core->pm_ops->vdec_put(core->dev_dec); in vdec_remove()
1843 const struct venus_pm_ops *pm_ops = core->pm_ops; in vdec_runtime_suspend()
1846 if (pm_ops->vdec_power) in vdec_runtime_suspend()
1847 ret = pm_ops->vdec_power(dev, POWER_OFF); in vdec_runtime_suspend()
1855 const struct venus_pm_ops *pm_ops = core->pm_ops; in vdec_runtime_resume()
1858 if (pm_ops->vdec_power) in vdec_runtime_resume()
1859 ret = pm_ops->vdec_power(dev, POWER_ON); in vdec_runtime_resume()
1871 { .compatible = "venus-decoder" },
1880 .name = "qcom-venus-decoder",
1887 MODULE_ALIAS("platform:qcom-venus-decoder");
1888 MODULE_DESCRIPTION("Qualcomm Venus video decoder driver");