diff options
author | Som Qin <som.qin@starfivetech.com> | 2023-02-09 10:31:40 +0800 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2023-10-05 18:25:23 +0900 |
commit | ba32ea8fc4196f4ef618ca37f1dcdd3d9dbaa3a2 (patch) | |
tree | 8e0e1eea8acc4087d3f7bbc23144ba842a1c914b | |
parent | aeb0c1e01b775d911162e5246a48c7e06ce31d30 (diff) | |
download | linux-starfive-ba32ea8fc4196f4ef618ca37f1dcdd3d9dbaa3a2.tar.gz linux-starfive-ba32ea8fc4196f4ef618ca37f1dcdd3d9dbaa3a2.tar.bz2 linux-starfive-ba32ea8fc4196f4ef618ca37f1dcdd3d9dbaa3a2.zip |
Media:wave5: wave5 v4l2 driver support gst/ffmpeg
Signed-off-by: Som Qin <som.qin@starfivetech.com>
[sw0312.kim: cherry-pick the commit 3f710b8fa137 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel
- update sifive cache function name properly and add guard for its config option]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: Ib264712e893c737a28c42a566607b7a55d7f7117
6 files changed, 180 insertions, 67 deletions
diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.c b/drivers/media/platform/chips-media/wave5/wave5-helper.c index fb9c94d07853..09dfb20e9a20 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-helper.c +++ b/drivers/media/platform/chips-media/wave5/wave5-helper.c @@ -47,7 +47,7 @@ int wave5_vpu_release_device(struct file *filp, break; if (fail_res != WAVE5_SYSERR_VPU_STILL_RUNNING) break; - if (!wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT)) + if (!wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT/10)) break; } while (--retry_count); @@ -106,7 +106,6 @@ int wave5_vpu_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscr { struct vpu_instance *inst = wave5_to_vpu_inst(fh); bool is_decoder = inst->type == VPU_INST_TYPE_DEC; - printk("wave5 subscribe event type: %d id: %d | flags: %d\n",sub->type, sub->id, sub->flags); dev_dbg(inst->dev->dev, "%s: [%s] type: %u id: %u | flags: %u\n", __func__, is_decoder ? "decoder" : "encoder", sub->type, sub->id, sub->flags); @@ -130,8 +129,13 @@ 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; - f->fmt.pix_mp.width = inst->src_fmt.width; - f->fmt.pix_mp.height = inst->src_fmt.height; + 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.pixelformat = inst->src_fmt.pixelformat; f->fmt.pix_mp.field = inst->src_fmt.field; f->fmt.pix_mp.flags = inst->src_fmt.flags; diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.h b/drivers/media/platform/chips-media/wave5/wave5-helper.h index d586d624275e..8a8dda8242f6 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-helper.h +++ b/drivers/media/platform/chips-media/wave5/wave5-helper.h @@ -11,7 +11,7 @@ #include "wave5-vpu.h" #define FMT_TYPES 2 -#define MAX_FMTS 6 +#define MAX_FMTS 3 void wave5_cleanup_instance(struct vpu_instance *inst); int wave5_vpu_release_device(struct file *filp, diff --git a/drivers/media/platform/chips-media/wave5/wave5-hw.c b/drivers/media/platform/chips-media/wave5/wave5-hw.c index 3c8328699201..57bbc3862be2 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-hw.c +++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c @@ -584,6 +584,17 @@ static void wave5_get_dec_seq_result(struct vpu_instance *inst, struct dec_initi info->f_rate_numerator = vpu_read_reg(inst->dev, W5_RET_DEC_FRAME_RATE_NR); info->f_rate_denominator = vpu_read_reg(inst->dev, W5_RET_DEC_FRAME_RATE_DR); + if (info->f_rate_numerator > 0 && info->f_rate_denominator >0) { + if (inst->std == W_HEVC_DEC) + info->ns_per_frame = 1000000000 * (u64)info->f_rate_denominator / (u64)info->f_rate_numerator; + else if (inst->std == W_AVC_DEC) + info->ns_per_frame = 1000000000 * 2 * (u64)info->f_rate_denominator / (u64)info->f_rate_numerator; + else + info->ns_per_frame = 1000000000 / 30; //30fps + } else { + info->ns_per_frame = 1000000000 / 30; //30fps + } + reg_val = vpu_read_reg(inst->dev, W5_RET_DEC_COLOR_SAMPLE_INFO); info->luma_bitdepth = reg_val & 0xf; info->chroma_bitdepth = (reg_val >> 4) & 0xf; @@ -820,10 +831,15 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b p_dec_info->vb_fbc_c_tbl[i] = vb_buf; } } - pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height); - if (init_info->pic_width != inst->display_fmt.width || - init_info->pic_height != inst->display_fmt.height) + + if ((init_info->pic_width - init_info->pic_crop_rect.right != inst->display_fmt.width) || + init_info->pic_height - init_info->pic_crop_rect.bottom != inst->display_fmt.height) { + pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height); scale_en = 1; + } else { + pic_size = (init_info->pic_width << 16) | (init_info->pic_height); + scale_en = 0; + } // allocate task_buffer vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) + @@ -839,10 +855,14 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b p_dec_info->vb_task.daddr); vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, vb_buf.size); } else { - pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height); - if (init_info->pic_width != inst->display_fmt.width || - init_info->pic_height != inst->display_fmt.height) + if ((init_info->pic_width - init_info->pic_crop_rect.right != inst->display_fmt.width) || + init_info->pic_height - init_info->pic_crop_rect.bottom != inst->display_fmt.height) { + pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height); scale_en = 1; + } else { + pic_size = (init_info->pic_width << 16) | (init_info->pic_height); + scale_en = 0; + } } dev_dbg(inst->dev->dev, "set pic_size 0x%x\n", pic_size); endian = wave5_vdi_convert_endian(inst->dev, fb_arr[0].endian); @@ -859,7 +879,8 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b (color_format << 19) | (nv21 << 17) | (cbcr_interleave << 16) | - inst->display_fmt.width; + (scale_en ? inst->display_fmt.width : fb_arr[0].stride); + //inst->display_fmt.width; dev_dbg(inst->dev->dev, "set W5_COMMON_PIC_INFO 0x%x\n",reg_val); vpu_write_reg(inst->dev, W5_COMMON_PIC_INFO, reg_val); diff --git a/drivers/media/platform/chips-media/wave5/wave5-vdi.c b/drivers/media/platform/chips-media/wave5/wave5-vdi.c index ec8b6cb80361..e2b7dab60bed 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vdi.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vdi.c @@ -10,7 +10,9 @@ #include "wave5-vpu.h" #include "wave5-regdefine.h" #include <linux/delay.h> +#ifdef CONFIG_SIFIVE_FLUSH #include <soc/sifive/sifive_l2_cache.h> +#endif #define VDI_SRAM_BASE_ADDR 0x00 @@ -95,7 +97,9 @@ int wave5_vdi_clear_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb) } memset(vb->vaddr, 0, vb->size); - sifive_l2_flush64_range(vb->daddr, vb->size); +#ifdef CONFIG_SIFIVE_FLUSH + sifive_flush64_range(vb->daddr, vb->size); +#endif return vb->size; } @@ -117,7 +121,9 @@ int wave5_vdi_write_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb, size_ wave5_swap_endian(vpu_dev, data, len, endian); memcpy(vb->vaddr + offset, data, len); - sifive_l2_flush64_range(vb->daddr + offset, len); +#ifdef CONFIG_SIFIVE_FLUSH + sifive_flush64_range(vb->daddr + offset, len); +#endif return len; } @@ -138,7 +144,9 @@ int wave5_vdi_allocate_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb vb->vaddr = vaddr; vb->daddr = daddr; - sifive_l2_flush64_range(daddr, vb->size); +#ifdef CONFIG_SIFIVE_FLUSH + sifive_flush64_range(daddr, vb->size); +#endif return 0; } diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c index bba48cbc8080..275db3e04c57 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -29,7 +29,7 @@ static const struct vpu_format dec_fmt_list[FMT_TYPES][MAX_FMTS] = { }, }, [VPU_FMT_TYPE_RAW] = { - { + /*{ .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420, .max_width = 8192, .min_width = 8, @@ -49,7 +49,7 @@ static const struct vpu_format dec_fmt_list[FMT_TYPES][MAX_FMTS] = { .min_width = 8, .max_height = 4320, .min_height = 8, - }, + },*/ { .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M, .max_width = 8192, @@ -202,6 +202,46 @@ static void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp, unsigned case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: pix_mp->width = round_up(width, 32); + pix_mp->height = round_up(height, 16); + pix_mp->plane_fmt[0].bytesperline = round_up(width, 32); + pix_mp->plane_fmt[0].sizeimage = width * height * 3 / 2; + break; + case V4L2_PIX_FMT_YUV420M: + pix_mp->width = round_up(width, 32); + pix_mp->height = round_up(height, 16); + pix_mp->plane_fmt[0].bytesperline = round_up(width, 32); + pix_mp->plane_fmt[0].sizeimage = width * height; + pix_mp->plane_fmt[1].bytesperline = round_up(width, 32) / 2; + pix_mp->plane_fmt[1].sizeimage = width * height / 4; + pix_mp->plane_fmt[2].bytesperline = round_up(width, 32) / 2; + pix_mp->plane_fmt[2].sizeimage = width * height / 4; + break; + case V4L2_PIX_FMT_NV12M: + case V4L2_PIX_FMT_NV21M: + pix_mp->width = round_up(width, 32); + pix_mp->height = round_up(height, 16); + pix_mp->plane_fmt[0].bytesperline = round_up(width, 32); + pix_mp->plane_fmt[0].sizeimage = width * height; + pix_mp->plane_fmt[1].bytesperline = round_up(width, 32); + pix_mp->plane_fmt[1].sizeimage = width * height / 2; + break; + default: + pix_mp->width = width; + pix_mp->height = height; + pix_mp->plane_fmt[0].bytesperline = 0; + pix_mp->plane_fmt[0].sizeimage = width * height; + break; + } +} + +static void wave5_update_pix_fmt_r8(struct v4l2_pix_format_mplane *pix_mp, unsigned int width, + unsigned int height) +{ + switch (pix_mp->pixelformat) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + pix_mp->width = round_up(width, 32); pix_mp->height = round_up(height, 8); pix_mp->plane_fmt[0].bytesperline = round_up(width, 32); pix_mp->plane_fmt[0].sizeimage = width * height * 3 / 2; @@ -261,6 +301,7 @@ static void wave5_vpu_dec_start_decode(struct vpu_instance *inst) src_buf = v4l2_m2m_src_buf_remove(inst->v4l2_fh.m2m_ctx); inst->state = VPU_INST_STATE_STOP; + //printk("%d wave5 state = %d\n",__LINE__, inst->state); v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); } } @@ -271,6 +312,7 @@ static void wave5_vpu_dec_stop_decode(struct vpu_instance *inst) int ret; inst->state = VPU_INST_STATE_STOP; + //printk("%d wave5 state = %d\n",__LINE__, inst->state); ret = wave5_vpu_dec_update_bitstream_buffer(inst, 0); if (ret) { @@ -314,14 +356,12 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) struct vb2_v4l2_buffer *dst_buf = v4l2_m2m_dst_buf_remove_by_idx(inst->v4l2_fh.m2m_ctx, dec_output_info.index_frame_display); - int stride = dec_output_info.disp_frame.stride; - int height = dec_output_info.disp_pic_height - - dec_output_info.rc_display.bottom; - if (dec_output_info.disp_pic_height != inst->display_fmt.height) - height = inst->display_fmt.height; + + int stride = inst->display_fmt.width; + int height =inst->display_fmt.height; dev_dbg(inst->dev->dev, "%s %d disp_pic_height %u rc_display.bottom %u\n", __func__, __LINE__, dec_output_info.disp_pic_height, dec_output_info.rc_display.bottom); - dev_dbg(inst->dev->dev, "%s %d stride %u height %u\n", __func__, __LINE__, stride, height); + dev_dbg(inst->dev->dev, "%s %d stride %u height %u num %d\n", __func__, __LINE__, stride, height,inst->dst_fmt.num_planes); if (inst->dst_fmt.num_planes == 1) { vb2_set_plane_payload(&dst_buf->vb2_buf, 0, @@ -340,7 +380,12 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) ((stride / 2) * (height / 2))); } - dst_buf->vb2_buf.timestamp = inst->timestamp; + if (inst->timestamp) { + dst_buf->vb2_buf.timestamp = inst->timestamp; + } else { + dst_buf->vb2_buf.timestamp = inst->timestamp_cnt++ * inst->codec_info->dec_info.initial_info.ns_per_frame; + } + dst_buf->field = V4L2_FIELD_NONE; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); @@ -380,7 +425,7 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); inst->eos = TRUE; - pr_err("wave5 queue event type: %d id: %d\n",vpu_event_eos.type, vpu_event_eos.id); + //pr_err("wave5 queue event type: %d id: %d\n",vpu_event_eos.type, vpu_event_eos.id); v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_eos); v4l2_m2m_job_finish(inst->v4l2_m2m_dev, inst->v4l2_fh.m2m_ctx); @@ -453,7 +498,7 @@ static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo if (!vpu_fmt) { f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat; f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes; - wave5_update_pix_fmt(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height); + wave5_update_pix_fmt_r8(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height); } else { int width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width); int height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height); @@ -461,7 +506,7 @@ static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt; f->fmt.pix_mp.num_planes = info->mem_planes; - wave5_update_pix_fmt(&f->fmt.pix_mp, width, height); + wave5_update_pix_fmt_r8(&f->fmt.pix_mp, width, height); } f->fmt.pix_mp.flags = 0; @@ -482,7 +527,7 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form int i, ret; unsigned int scalew, scaleh; - printk( + dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u colorspace: %u field: %u\n", __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.colorspace, f->fmt.pix_mp.field); @@ -495,28 +540,30 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form scalew = inst->src_fmt.width / f->fmt.pix_mp.width; scaleh = inst->src_fmt.height / f->fmt.pix_mp.height; - if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) { - dev_err(inst->dev->dev,"Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. \n"); - return -EINVAL; - } - - inst->dst_fmt.width = f->fmt.pix_mp.width; - inst->dst_fmt.height = f->fmt.pix_mp.height; + //if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) { + // dev_err(inst->dev->dev,"Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. \n"); + // return -EINVAL; + //} + + inst->display_fmt.width = f->fmt.pix_mp.width; + inst->display_fmt.height = f->fmt.pix_mp.height; + inst->display_fmt.pixelformat = f->fmt.pix_mp.pixelformat; + inst->display_fmt.field = f->fmt.pix_mp.field; + inst->display_fmt.flags = f->fmt.pix_mp.flags; + inst->display_fmt.num_planes = f->fmt.pix_mp.num_planes; inst->dst_fmt.pixelformat = f->fmt.pix_mp.pixelformat; - inst->dst_fmt.field = f->fmt.pix_mp.field; - inst->dst_fmt.flags = f->fmt.pix_mp.flags; inst->dst_fmt.num_planes = f->fmt.pix_mp.num_planes; - for (i = 0; i < inst->dst_fmt.num_planes; i++) { - inst->dst_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline; - inst->dst_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; + for (i = 0; i < inst->display_fmt.num_planes; i++) { + inst->display_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline; + inst->display_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; } - if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12 || - inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12M) { + if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12 || + inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12M) { inst->cbcr_interleave = true; inst->nv21 = false; - } else if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21 || - inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21M) { + } else if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21 || + inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21M) { inst->cbcr_interleave = true; inst->nv21 = true; } else { @@ -524,8 +571,6 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form inst->nv21 = false; } - memcpy((void *)&inst->display_fmt, (void *)&inst->dst_fmt, sizeof(struct v4l2_pix_format_mplane)); - return 0; } @@ -610,11 +655,12 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form struct vpu_instance *inst = wave5_to_vpu_inst(fh); int i, ret; - printk( + dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n", __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field); + ret = wave5_vpu_dec_try_fmt_out(file, fh, f); if (ret) return ret; @@ -636,7 +682,9 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form inst->quantization = f->fmt.pix_mp.quantization; inst->xfer_func = f->fmt.pix_mp.xfer_func; - wave5_update_pix_fmt(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); + + wave5_update_pix_fmt_r8(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); + wave5_update_pix_fmt_r8(&inst->display_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); return 0; } @@ -713,7 +761,10 @@ static int wave5_vpu_dec_decoder_cmd(struct file *file, void *fh, struct v4l2_de switch (dc->cmd) { case V4L2_DEC_CMD_STOP: + wave5_handle_bitstream_buffer(inst); + inst->ops->start_process(inst); inst->state = VPU_INST_STATE_STOP; + //printk("%d wave5 state = %d\n",__LINE__, inst->state); ret = wave5_vpu_dec_update_bitstream_buffer(inst, 0); if (ret) { @@ -854,6 +905,8 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff if (inst->state == VPU_INST_STATE_NONE && q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { struct dec_open_param open_param; + *num_buffers = 4; + memset(&open_param, 0, sizeof(struct dec_open_param)); wave5_set_default_dec_openparam(&open_param); @@ -883,6 +936,7 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff } inst->state = VPU_INST_STATE_OPEN; + //printk("wave5 state = %d\n",inst->state); if (inst->thumbnail_mode) wave5_vpu_dec_give_command(inst, ENABLE_DEC_THUMBNAIL_MODE, NULL); @@ -893,9 +947,9 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff u32 fb_stride, fb_height; u32 luma_size, chroma_size; - if (*num_buffers > inst->min_dst_buf_count && - *num_buffers < WAVE5_MAX_FBS) - inst->dst_buf_count = *num_buffers; + //if (*num_buffers > inst->min_dst_buf_count && + // *num_buffers < WAVE5_MAX_FBS) + // inst->dst_buf_count = *num_buffers; *num_buffers = inst->dst_buf_count; non_linear_num = inst->dst_buf_count; @@ -951,17 +1005,17 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst) ret = wave5_vpu_dec_issue_seq_init(inst); if (ret) { - dev_dbg(inst->dev->dev, "%s: wave5_vpu_dec_issue_seq_init, fail: %d\n", + dev_err(inst->dev->dev, "%s: wave5_vpu_dec_issue_seq_init, fail: %d\n", __func__, ret); return ret; } if (wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT) < 0) - dev_dbg(inst->dev->dev, "%s: failed to call vpu_wait_interrupt()\n", __func__); + dev_err(inst->dev->dev, "%s: failed to call vpu_wait_interrupt()\n", __func__); ret = wave5_vpu_dec_complete_seq_init(inst, &initial_info); if (ret) { - dev_dbg(inst->dev->dev, "%s: vpu_dec_complete_seq_init, fail: %d, reason: %u\n", + dev_err(inst->dev->dev, "%s: vpu_dec_complete_seq_init, fail: %d, reason: %u\n", __func__, ret, initial_info.seq_init_err_reason); } else { static const struct v4l2_event vpu_event_src_ch = { @@ -975,6 +1029,7 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst) initial_info.profile, initial_info.min_frame_buffer_count); inst->state = VPU_INST_STATE_INIT_SEQ; + //printk("wave5 state = %d\n",inst->state); inst->min_dst_buf_count = initial_info.min_frame_buffer_count + 1; inst->dst_buf_count = inst->min_dst_buf_count; @@ -988,11 +1043,20 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst) if (initial_info.pic_width != inst->src_fmt.width || initial_info.pic_height != inst->src_fmt.height) { - wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width, - initial_info.pic_height); - wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width, - initial_info.pic_height); + if (inst->std == W_AVC_DEC) { + wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width, + initial_info.pic_height); + wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width, + initial_info.pic_height); + } else { //HEVC + wave5_update_pix_fmt_r8(&inst->src_fmt, initial_info.pic_width, + initial_info.pic_height); + wave5_update_pix_fmt_r8(&inst->dst_fmt, initial_info.pic_width, + initial_info.pic_height); + } } + inst->crop_rect.right = initial_info.pic_crop_rect.right; + inst->crop_rect.bottom = initial_info.pic_crop_rect.bottom; scalew = inst->dst_fmt.width / inst->display_fmt.width; scaleh = inst->dst_fmt.height / inst->display_fmt.height; @@ -1002,7 +1066,7 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst) inst->dst_fmt.height); } - printk("wave5 queue event type: %d id: %d\n",vpu_event_src_ch.type, vpu_event_src_ch.id); + dev_dbg(inst->dev->dev, "wave5 queue event type: %d id: %d\n",vpu_event_src_ch.type, vpu_event_src_ch.id); v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_src_ch); wave5_handle_src_buffer(inst); @@ -1028,6 +1092,7 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst) src_buf = v4l2_m2m_src_buf_remove(inst->v4l2_fh.m2m_ctx); inst->state = VPU_INST_STATE_STOP; + //printk("%d wave5 state = %d\n",__LINE__, inst->state); v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); dev_dbg(inst->dev->dev, "%s: wave5_vpu_dec_start_one_frame\n", __func__); return ret; @@ -1070,11 +1135,20 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst) if (initial_info.pic_width != inst->src_fmt.width || initial_info.pic_height != inst->src_fmt.height) { - wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width, - initial_info.pic_height); - wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width, - initial_info.pic_height); + if (inst->std == W_AVC_DEC) { + wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width, + initial_info.pic_height); + wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width, + initial_info.pic_height); + } else { //HEVC + wave5_update_pix_fmt_r8(&inst->src_fmt, initial_info.pic_width, + initial_info.pic_height); + wave5_update_pix_fmt_r8(&inst->dst_fmt, initial_info.pic_width, + initial_info.pic_height); + } } + inst->crop_rect.right = initial_info.pic_crop_rect.right; + inst->crop_rect.bottom = initial_info.pic_crop_rect.bottom; scalew = inst->dst_fmt.width / inst->display_fmt.width; scaleh = inst->dst_fmt.height / inst->display_fmt.height; @@ -1172,8 +1246,8 @@ static void wave5_vpu_dec_buf_queue(struct vb2_buffer *vb) struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue); dev_dbg(inst->dev->dev, "%s: type: %4u index: %4u size: ([0]=%4lu, [1]=%4lu, [2]=%4lu)\n", - __func__, vb->type, vb->index, vb2_plane_size(&vbuf->vb2_buf, 0), - vb2_plane_size(&vbuf->vb2_buf, 1), vb2_plane_size(&vbuf->vb2_buf, 2)); + __func__, vb->type, vb->index, vb2_get_plane_payload(&vbuf->vb2_buf, 0), + vb2_get_plane_payload(&vbuf->vb2_buf, 1), vb2_get_plane_payload(&vbuf->vb2_buf, 2)); v4l2_m2m_buf_queue(inst->v4l2_fh.m2m_ctx, vbuf); @@ -1215,6 +1289,7 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q) { struct vpu_instance *inst = vb2_get_drv_priv(q); struct vb2_v4l2_buffer *buf; + int try_cnt = 0; bool check_cmd = TRUE; dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type); @@ -1222,7 +1297,6 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q) while (check_cmd) { struct queue_status_info q_status; struct dec_output_info dec_output_info; - int try_cnt = 0; wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status); @@ -1231,7 +1305,7 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q) if (wave5_vpu_wait_interrupt(inst, 600) < 0){ try_cnt++; - if (try_cnt >= 100) + if (try_cnt >= 10) break; continue; } @@ -1288,6 +1362,7 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q) if (inst->eos) { inst->eos = FALSE; inst->state = VPU_INST_STATE_INIT_SEQ; + //printk("wave5 state = %d\n",inst->state); } inst->queued_dst_buf_num = 0; } @@ -1336,9 +1411,11 @@ static void wave5_vpu_dec_device_run(void *priv) { struct vpu_instance *inst = priv; + wave5_handle_bitstream_buffer(inst); inst->ops->start_process(inst); inst->state = VPU_INST_STATE_PIC_RUN; + //printk("wave5 state = %d\n",inst->state); } static void wave5_vpu_dec_job_abort(void *priv) diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h index 0a4dc20ddec3..dcd061b1aa9c 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h +++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h @@ -473,6 +473,7 @@ struct dec_initial_info { u32 pic_height; s32 f_rate_numerator; /* the numerator part of frame rate fraction */ s32 f_rate_denominator; /* the denominator part of frame rate fraction */ + u64 ns_per_frame; struct vpu_rect pic_crop_rect; u32 min_frame_buffer_count; /* between 1 to 16 */ u32 frame_buf_delay; @@ -1057,6 +1058,7 @@ struct vpu_instance { enum vpu_instance_state state; enum vpu_instance_type type; const struct vpu_instance_ops *ops; + struct vpu_rect crop_rect; enum wave_std std; s32 id; @@ -1073,6 +1075,7 @@ struct vpu_instance { u32 conf_win_width; u32 conf_win_height; u64 timestamp; + u64 timestamp_cnt; bool cbcr_interleave; bool nv21; bool eos; |