diff options
Diffstat (limited to 'drivers/media/platform/chips-media/wave5/wave5-helper.c')
-rw-r--r-- | drivers/media/platform/chips-media/wave5/wave5-helper.c | 90 |
1 files changed, 60 insertions, 30 deletions
diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.c b/drivers/media/platform/chips-media/wave5/wave5-helper.c index 09dfb20e9a20..ec710b838dfe 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-helper.c +++ b/drivers/media/platform/chips-media/wave5/wave5-helper.c @@ -2,29 +2,45 @@ /* * Wave5 series multi-standard codec IP - decoder interface * - * Copyright (C) 2021 CHIPS&MEDIA INC + * Copyright (C) 2021-2023 CHIPS&MEDIA INC */ #include "wave5-helper.h" +const char *state_to_str(enum vpu_instance_state state) +{ + switch (state) { + case VPU_INST_STATE_NONE: + return "NONE"; + case VPU_INST_STATE_OPEN: + return "OPEN"; + case VPU_INST_STATE_INIT_SEQ: + return "INIT_SEQ"; + case VPU_INST_STATE_PIC_RUN: + return "PIC_RUN"; + case VPU_INST_STATE_STOP: + return "STOP"; + default: + return "UNKNOWN"; + } +} + void wave5_cleanup_instance(struct vpu_instance *inst) { int i; - for (i = 0; i < inst->dst_buf_count; i++) - wave5_vdi_free_dma_memory(inst->dev, &inst->frame_vbuf[i]); + for (i = 0; i < inst->fbc_buf_count; i++) + wave5_vpu_dec_reset_framebuffer(inst, i); wave5_vdi_free_dma_memory(inst->dev, &inst->bitstream_vbuf); v4l2_ctrl_handler_free(&inst->v4l2_ctrl_hdl); - if (inst->v4l2_m2m_dev != NULL) - v4l2_m2m_release(inst->v4l2_m2m_dev); - if (inst->v4l2_fh.vdev != NULL) { + if (inst->v4l2_fh.vdev) { v4l2_fh_del(&inst->v4l2_fh); v4l2_fh_exit(&inst->v4l2_fh); } list_del_init(&inst->list); - kfifo_free(&inst->irq_status); ida_free(&inst->dev->inst_ida, inst->id); + kfree(inst->codec_info); kfree(inst); } @@ -37,23 +53,12 @@ int wave5_vpu_release_device(struct file *filp, v4l2_m2m_ctx_release(inst->v4l2_fh.m2m_ctx); if (inst->state != VPU_INST_STATE_NONE) { u32 fail_res; - int retry_count = 10; int ret; - do { - fail_res = 0; - ret = close_func(inst, &fail_res); - if (ret && ret != -EIO) - break; - if (fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) - break; - if (!wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT/10)) - break; - } while (--retry_count); - + ret = close_func(inst, &fail_res); if (fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING) { dev_err(inst->dev->dev, "%s close failed, device is still running\n", - name); + name); return -EBUSY; } if (ret && ret != -EIO) { @@ -78,7 +83,7 @@ int wave5_vpu_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue src_vq->mem_ops = &vb2_dma_contig_memops; src_vq->ops = ops; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - src_vq->buf_struct_size = sizeof(struct vpu_buffer); + src_vq->buf_struct_size = sizeof(struct vpu_src_buffer); src_vq->drv_priv = inst; src_vq->lock = &inst->dev->dev_lock; src_vq->dev = inst->dev->v4l2_dev.dev; @@ -91,7 +96,7 @@ int wave5_vpu_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue dst_vq->mem_ops = &vb2_dma_contig_memops; dst_vq->ops = ops; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - dst_vq->buf_struct_size = sizeof(struct vpu_buffer); + dst_vq->buf_struct_size = sizeof(struct vpu_src_buffer); dst_vq->drv_priv = inst; dst_vq->lock = &inst->dev->dev_lock; dst_vq->dev = inst->dev->v4l2_dev.dev; @@ -129,13 +134,8 @@ int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f) struct vpu_instance *inst = wave5_to_vpu_inst(fh); int i; - if (inst->state >= VPU_INST_STATE_INIT_SEQ){ - f->fmt.pix_mp.width = inst->src_fmt.width - inst->crop_rect.right; - f->fmt.pix_mp.height = inst->src_fmt.height - inst->crop_rect.bottom; - } else { - f->fmt.pix_mp.width = inst->src_fmt.width; - f->fmt.pix_mp.height = inst->src_fmt.height; - } + f->fmt.pix_mp.width = inst->src_fmt.width; + f->fmt.pix_mp.height = inst->src_fmt.height; f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat; f->fmt.pix_mp.field = inst->src_fmt.field; f->fmt.pix_mp.flags = inst->src_fmt.flags; @@ -147,7 +147,6 @@ int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f) f->fmt.pix_mp.colorspace = inst->colorspace; f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc; - f->fmt.pix_mp.hsv_enc = inst->hsv_enc; f->fmt.pix_mp.quantization = inst->quantization; f->fmt.pix_mp.xfer_func = inst->xfer_func; @@ -178,3 +177,34 @@ const struct vpu_format *wave5_find_vpu_fmt_by_idx(unsigned int idx, return &fmt_list[idx]; } + +enum wave_std wave5_to_vpu_std(unsigned int v4l2_pix_fmt, enum vpu_instance_type type) +{ + switch (v4l2_pix_fmt) { + case V4L2_PIX_FMT_H264: + return type == VPU_INST_TYPE_DEC ? W_AVC_DEC : W_AVC_ENC; + case V4L2_PIX_FMT_HEVC: + return type == VPU_INST_TYPE_DEC ? W_HEVC_DEC : W_HEVC_ENC; + default: + return STD_UNKNOWN; + } +} + +void wave5_return_bufs(struct vb2_queue *q, u32 state) +{ + struct vpu_instance *inst = vb2_get_drv_priv(q); + struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx; + struct v4l2_ctrl_handler v4l2_ctrl_hdl = inst->v4l2_ctrl_hdl; + struct vb2_v4l2_buffer *vbuf; + + for (;;) { + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + vbuf = v4l2_m2m_src_buf_remove(m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(m2m_ctx); + if (!vbuf) + return; + v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, &v4l2_ctrl_hdl); + v4l2_m2m_buf_done(vbuf, state); + } +} |