diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-02 04:45:08 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-02 04:45:08 +0300 |
commit | 73d21a3579818aa0e39de207474a39ca35c7d8cb (patch) | |
tree | ae723d1026a6f39aa22bbcb3e82d3966ac7f5dcc /drivers/media/platform/qcom/venus/vdec.c | |
parent | 6f2b76a4a384e05ac8d3349831f29dff5de1e1e2 (diff) | |
parent | 57c3b9f55ba875a6f6295fa59f0bdc0a01c544f8 (diff) | |
download | linux-73d21a3579818aa0e39de207474a39ca35c7d8cb.tar.xz |
Merge tag 'media/v5.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- New driver for SK Hynix Hi-846 8M pixel camera
- New driver for the ov13b10 camera
- New driver for Renesas R-Car ISP
- mtk-vcodec gained support for version 2 of decoder firmware ABI
- The legacy sir_ir driver got removed
- videobuf2: the vb2_mem_ops kAPI had some improvements
- lots of cleanups, fixes and new features at device drivers
* tag 'media/v5.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (328 commits)
media: venus: core: Add sdm660 DT compatible and resource struct
media: dt-bindings: media: venus: Add sdm660 dt schema
media: venus: vdec: decoded picture buffer handling during reconfig sequence
media: venus: Handle fatal errors during encoding and decoding
media: venus: helpers: Add helper to mark fatal vb2 error
media: venus: hfi: Check for sys error on session hfi functions
media: venus: Make sys_error flag an atomic bitops
media: venus: venc: Use pmruntime autosuspend
media: allegro: write vui parameters for HEVC
media: allegro: nal-hevc: implement generator for vui
media: allegro: write correct colorspace into SPS
media: allegro: extract nal value lookup functions to header
media: allegro: correctly scale the bit rate in SPS
media: allegro: remove external QP table
media: allegro: fix row and column in response message
media: allegro: add control to disable encoder buffer
media: allegro: add encoder buffer support
media: allegro: add pm_runtime support
media: allegro: lookup VCU settings
media: allegro: fix module removal if initialization failed
...
Diffstat (limited to 'drivers/media/platform/qcom/venus/vdec.c')
-rw-r--r-- | drivers/media/platform/qcom/venus/vdec.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 198e47eb63f4..91da3f509724 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -332,8 +332,11 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) inst->fmt_out = fmt; - else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { inst->fmt_cap = fmt; + inst->output2_buf_size = + venus_helper_get_framesz(pixfmt_cap, orig_pixmp.width, orig_pixmp.height); + } return 0; } @@ -653,6 +656,19 @@ static int vdec_set_properties(struct venus_inst *inst) return 0; } +static int vdec_set_work_route(struct venus_inst *inst) +{ + u32 ptype = HFI_PROPERTY_PARAM_WORK_ROUTE; + struct hfi_video_work_route wr; + + if (!IS_V6(inst->core)) + return 0; + + wr.video_work_route = inst->core->res->num_vpp_pipes; + + return hfi_session_set_property(inst, ptype, &wr); +} + #define is_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_UBWC_BASE)) static int vdec_output_conf(struct venus_inst *inst) @@ -830,6 +846,7 @@ static int vdec_queue_setup(struct vb2_queue *q, unsigned int sizes[], struct device *alloc_devs[]) { struct venus_inst *inst = vb2_get_drv_priv(q); + struct venus_core *core = inst->core; unsigned int in_num, out_num; int ret = 0; @@ -855,6 +872,16 @@ static int vdec_queue_setup(struct vb2_queue *q, return 0; } + if (test_bit(0, &core->sys_error)) { + if (inst->nonblock) + return -EAGAIN; + + ret = wait_event_interruptible(core->sys_err_done, + !test_bit(0, &core->sys_error)); + if (ret) + return ret; + } + ret = vdec_pm_get(inst); if (ret) return ret; @@ -970,23 +997,23 @@ reconfigure: if (ret) goto err; + venus_pm_load_scale(inst); + + inst->next_buf_last = false; + ret = venus_helper_alloc_dpb_bufs(inst); if (ret) goto err; - ret = venus_helper_queue_dpb_bufs(inst); + ret = hfi_session_continue(inst); if (ret) goto free_dpb_bufs; - ret = venus_helper_process_initial_cap_bufs(inst); + ret = venus_helper_queue_dpb_bufs(inst); if (ret) goto free_dpb_bufs; - venus_pm_load_scale(inst); - - inst->next_buf_last = false; - - ret = hfi_session_continue(inst); + ret = venus_helper_process_initial_cap_bufs(inst); if (ret) goto free_dpb_bufs; @@ -1039,6 +1066,10 @@ static int vdec_start_output(struct venus_inst *inst) if (ret) return ret; + ret = vdec_set_work_route(inst); + if (ret) + return ret; + ret = vdec_output_conf(inst); if (ret) return ret; @@ -1178,6 +1209,8 @@ static void vdec_stop_streaming(struct vb2_queue *q) venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); + inst->session_error = 0; + if (ret) goto unlock; @@ -1211,7 +1244,7 @@ static void vdec_session_release(struct venus_inst *inst) ret = hfi_session_deinit(inst); abort = (ret && ret != -EINVAL) ? 1 : 0; - if (inst->session_error || core->sys_error) + if (inst->session_error || test_bit(0, &core->sys_error)) abort = 1; if (abort) @@ -1306,8 +1339,10 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; vbuf = venus_helper_find_buf(inst, type, tag); - if (!vbuf) + if (!vbuf) { + venus_helper_change_dpb_owner(inst, vbuf, type, buf_type, tag); return; + } vbuf->flags = flags; vbuf->field = V4L2_FIELD_NONE; @@ -1389,6 +1424,11 @@ static void vdec_event_change(struct venus_inst *inst, inst->crop.height = ev_data->height; } + inst->fw_min_cnt = ev_data->buf_count; + /* overwriting this to 11 for vp9 due to fw bug */ + if (inst->hfi_codec == HFI_VIDEO_CODEC_VP9) + inst->fw_min_cnt = 11; + inst->out_width = ev_data->width; inst->out_height = ev_data->height; @@ -1448,6 +1488,7 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event, switch (event) { case EVT_SESSION_ERROR: inst->session_error = true; + venus_helper_vb2_queue_error(inst); dev_err(dev, "dec: event session error %x\n", inst->error); break; case EVT_SYS_EVENT_CHANGE: @@ -1492,6 +1533,7 @@ static void vdec_inst_init(struct venus_inst *inst) inst->crop.top = 0; inst->crop.width = inst->width; inst->crop.height = inst->height; + inst->fw_min_cnt = 8; inst->out_width = frame_width_min(inst); inst->out_height = frame_height_min(inst); inst->fps = 30; @@ -1568,6 +1610,8 @@ static int vdec_open(struct file *file) inst->bit_depth = VIDC_BITDEPTH_8; inst->pic_struct = HFI_INTERLACE_FRAME_PROGRESSIVE; init_waitqueue_head(&inst->reconf_wait); + inst->nonblock = file->f_flags & O_NONBLOCK; + venus_helper_init_instance(inst); ret = vdec_ctrl_init(inst); @@ -1580,6 +1624,8 @@ static int vdec_open(struct file *file) vdec_inst_init(inst); + ida_init(&inst->dpb_ids); + /* * create m2m device for every instance, the m2m context scheduling * is made by firmware side so we do not need to care about. @@ -1625,6 +1671,7 @@ static int vdec_close(struct file *file) v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); vdec_ctrl_deinit(inst); + ida_destroy(&inst->dpb_ids); hfi_session_destroy(inst); mutex_destroy(&inst->lock); v4l2_fh_del(&inst->fh); |