From 8c491732029c20296567010ee28130d048e08ce2 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Thu, 12 Jan 2023 09:16:41 +0800 Subject: [PATCH 01/16] Media:wave5: set default format for display_fmt Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit 6d80c00e9258 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: Ic0f74bf12580e72ba3209c766e8d167c204702c5 --- drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 1 + 1 file changed, 1 insertion(+) 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 f722924..bba48cb 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -1403,6 +1403,7 @@ static int wave5_vpu_open_dec(struct file *filp) v4l2_ctrl_handler_setup(&inst->v4l2_ctrl_hdl); wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt); + memcpy((void *)&inst->display_fmt, (void *)&inst->dst_fmt, sizeof(struct v4l2_pix_format_mplane)); inst->colorspace = V4L2_COLORSPACE_REC709; inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; inst->hsv_enc = 0; -- 2.7.4 From 8940838b71e2eddc6a83034eb28530a59c204475 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Thu, 9 Feb 2023 10:31:40 +0800 Subject: [PATCH 02/16] Media:wave5: wave5 v4l2 driver support gst/ffmpeg Signed-off-by: Som Qin [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 Change-Id: Ib264712e893c737a28c42a566607b7a55d7f7117 --- .../platform/chips-media/wave5/wave5-helper.c | 12 +- .../platform/chips-media/wave5/wave5-helper.h | 2 +- .../media/platform/chips-media/wave5/wave5-hw.c | 35 +++- .../media/platform/chips-media/wave5/wave5-vdi.c | 14 +- .../platform/chips-media/wave5/wave5-vpu-dec.c | 181 +++++++++++++++------ .../platform/chips-media/wave5/wave5-vpuapi.h | 3 + 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 fb9c94d..09dfb20 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 d586d62..8a8dda8 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 3c83286..57bbc38 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 ec8b6cb..e2b7dab 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 +#ifdef CONFIG_SIFIVE_FLUSH #include +#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 bba48cb..275db3e 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 0a4dc20..dcd061b1 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; -- 2.7.4 From 7b830733d9f8399d4a8aaab94b23bf766628b076 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Tue, 1 Aug 2023 14:09:12 +0800 Subject: [PATCH 03/16] Media:wave5: Fix stride mismatching of decoding frame buffers When bitstream format bitdepth > 8, stride of compressed frame map buffers shoule be recalculated. Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit a9830d5d01e9 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: I58b550e525c8dde7175d09c2934f4f81e08df3fc --- drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 275db3e..f3e8124 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -958,7 +958,14 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff struct frame_buffer *frame = &inst->frame_buf[i]; struct vpu_buf *vframe = &inst->frame_vbuf[i]; - fb_stride = inst->dst_fmt.width; + if (inst->codec_info->dec_info.initial_info.luma_bitdepth > 8 || + inst->codec_info->dec_info.initial_info.chroma_bitdepth > 8) { + fb_stride = ALIGN(ALIGN(inst->dst_fmt.width, 16) * 5, 32) / 4; + fb_stride = ALIGN(fb_stride, 32); + } else { + fb_stride = inst->dst_fmt.width; + } + fb_height = ALIGN(inst->dst_fmt.height, 32); luma_size = fb_stride * fb_height; chroma_size = ALIGN(fb_stride / 2, 16) * fb_height; -- 2.7.4 From b8a8a7e48193b63a11610e6a207ea40094db0a7a Mon Sep 17 00:00:00 2001 From: Som Qin Date: Tue, 1 Aug 2023 15:03:59 +0800 Subject: [PATCH 04/16] Media:wave5: Driver get clks from DTS instead of hard coding. Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit 167fdf2d4c34 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: I31ecc8cb300d21ab95c231d14875dcac93e337a6 --- .../media/platform/chips-media/wave5/wave5-vpu.c | 38 +++++----------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c b/drivers/media/platform/chips-media/wave5/wave5-vpu.c index 176bbe7..e378817 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c @@ -25,40 +25,11 @@ #define WAVE5_IS_ENC BIT(0) #define WAVE5_IS_DEC BIT(1) -struct clk_bulk_data vpu_clks[] = { - { .id = "apb_clk" }, - { .id = "axi_clk" }, - { .id = "bpu_clk" }, - { .id = "vce_clk" }, - { .id = "noc_bus" }, -}; - struct wave5_match_data { int flags; const char *fw_name; }; -static int vpu_clk_get(struct platform_device *pdev, struct vpu_device *vpu) -{ - struct device *dev = &pdev->dev; - int ret; - - vpu->clks = vpu_clks; - vpu->num_clks = ARRAY_SIZE(vpu_clks); - - vpu->resets = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(vpu->resets)) { - ret = PTR_ERR(vpu->resets); - dev_err(dev, "faied to get vpu reset controls\n"); - } - - ret = devm_clk_bulk_get(dev, vpu->num_clks, vpu->clks); - if (ret) - dev_err(dev, "faied to get vpu clk controls\n"); - - return 0; -} - int wave5_vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout) { int ret; @@ -229,13 +200,20 @@ static int wave5_vpu_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, dev); dev->dev = &pdev->dev; - ret = vpu_clk_get(pdev, dev); + ret = devm_clk_bulk_get_all(&pdev->dev, &dev->clks); /* continue without clock, assume externally managed */ if (ret < 0) { dev_err(&pdev->dev, "Getting clocks, fail: %d\n", ret); return ret; } + dev->num_clks = ret; + + dev->resets = devm_reset_control_array_get_exclusive(&pdev->dev); + if (IS_ERR(dev->resets)) { + dev_err(&pdev->dev, "faied to get vpu reset controls\n"); + return -ENODEV; + } dev->sram_buf.daddr = VDI_SRAM_BASE_ADDR; dev->sram_buf.size = VDI_WAVE511_SRAM_SIZE; -- 2.7.4 From e45c3cb26604821b25cb34dc1ab6d50ee88793fd Mon Sep 17 00:00:00 2001 From: Som Qin Date: Wed, 2 Aug 2023 11:38:51 +0800 Subject: [PATCH 05/16] Media:Wave5: Add contiguous planes format support (YUV420/NV12/NV21) Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit 80c6e7df80bd from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: I4203a253b3c7577a5849ca2582099a2cf07985ea --- drivers/media/platform/chips-media/wave5/wave5-helper.h | 2 +- drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.h b/drivers/media/platform/chips-media/wave5/wave5-helper.h index 8a8dda8..d586d62 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 3 +#define MAX_FMTS 6 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-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c index f3e8124..5d10f3c 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -29,43 +29,43 @@ static const struct vpu_format dec_fmt_list[FMT_TYPES][MAX_FMTS] = { }, }, [VPU_FMT_TYPE_RAW] = { - /*{ - .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420, + { + .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M, .max_width = 8192, .min_width = 8, .max_height = 4320, .min_height = 8, }, { - .v4l2_pix_fmt = V4L2_PIX_FMT_NV12, + .v4l2_pix_fmt = V4L2_PIX_FMT_NV12M, .max_width = 8192, .min_width = 8, .max_height = 4320, .min_height = 8, }, { - .v4l2_pix_fmt = V4L2_PIX_FMT_NV21, + .v4l2_pix_fmt = V4L2_PIX_FMT_NV21M, .max_width = 8192, .min_width = 8, .max_height = 4320, .min_height = 8, - },*/ + }, { - .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M, + .v4l2_pix_fmt = V4L2_PIX_FMT_YUV420, .max_width = 8192, .min_width = 8, .max_height = 4320, .min_height = 8, }, { - .v4l2_pix_fmt = V4L2_PIX_FMT_NV12M, + .v4l2_pix_fmt = V4L2_PIX_FMT_NV12, .max_width = 8192, .min_width = 8, .max_height = 4320, .min_height = 8, }, { - .v4l2_pix_fmt = V4L2_PIX_FMT_NV21M, + .v4l2_pix_fmt = V4L2_PIX_FMT_NV21, .max_width = 8192, .min_width = 8, .max_height = 4320, -- 2.7.4 From 4e60fe5ee38566a7de4d2cab5573051f28b6ac53 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Mon, 7 Aug 2023 15:21:30 +0800 Subject: [PATCH 06/16] Media:Wave5: Fix driver compile warning Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit 5d74ac40d250 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: If42384286243423071abcd9ab2107c0507bdc4e8 --- drivers/media/platform/chips-media/wave5/wave5-vdi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-vdi.c b/drivers/media/platform/chips-media/wave5/wave5-vdi.c index e2b7dab..4a0e4b8 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vdi.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vdi.c @@ -14,7 +14,6 @@ #include #endif -#define VDI_SRAM_BASE_ADDR 0x00 #define VDI_SYSTEM_ENDIAN VDI_LITTLE_ENDIAN #define VDI_128BIT_BUS_SYSTEM_ENDIAN VDI_128BIT_LITTLE_ENDIAN -- 2.7.4 From 5b5b09f98a57b6536c35af52518461670d2aae55 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Fri, 25 Aug 2023 16:13:01 +0800 Subject: [PATCH 07/16] Media: Wave5: Fix plane size mismatch Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit b4e474a223e8 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: If69aaf750c83daf21b57c459f576ee2200f9c40e --- .../media/platform/chips-media/wave5/wave5-hw.c | 24 +-- .../platform/chips-media/wave5/wave5-vpu-dec.c | 181 +++++---------------- .../platform/chips-media/wave5/wave5-vpuapi.h | 1 - 3 files changed, 47 insertions(+), 159 deletions(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-hw.c b/drivers/media/platform/chips-media/wave5/wave5-hw.c index 57bbc38..fdc5c7e 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-hw.c +++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c @@ -729,7 +729,6 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b struct vpu_buf vb_buf; u32 color_format = 0; u32 pixel_order = 1; - u32 scale_en = 0; u32 bwb_flag = (map_type == LINEAR_FRAME_MAP) ? 1 : 0; cbcr_interleave = inst->cbcr_interleave; @@ -831,15 +830,7 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b p_dec_info->vb_fbc_c_tbl[i] = vb_buf; } } - - 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; - } + pic_size = (init_info->pic_width << 16) | (init_info->pic_height); // allocate task_buffer vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) + @@ -855,14 +846,7 @@ 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 { - 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; - } + pic_size = (init_info->pic_width << 16) | (init_info->pic_height); } dev_dbg(inst->dev->dev, "set pic_size 0x%x\n", pic_size); endian = wave5_vdi_convert_endian(inst->dev, fb_arr[0].endian); @@ -872,15 +856,13 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b color_format = 0; reg_val = - (scale_en << 29) | (bwb_flag << 28) | (pixel_order << 23) | /* PIXEL ORDER in 128bit. first pixel in low address */ (yuv_format << 20) | (color_format << 19) | (nv21 << 17) | (cbcr_interleave << 16) | - (scale_en ? inst->display_fmt.width : fb_arr[0].stride); - //inst->display_fmt.width; + (fb_arr[0].stride); 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-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c index 5d10f3c..481273d 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -234,46 +234,6 @@ static void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp, unsigned } } -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; - break; - case V4L2_PIX_FMT_YUV420M: - 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; - 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, 8); - 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_vpu_dec_start_decode(struct vpu_instance *inst) { struct dec_param pic_param; @@ -301,7 +261,6 @@ 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); } } @@ -312,7 +271,6 @@ 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) { @@ -337,6 +295,7 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) struct dec_output_info dec_output_info; int ret; u32 irq_status; + u32 stride, height; if (kfifo_out(&inst->irq_status, &irq_status, sizeof(int))) wave5_vpu_clear_interrupt_ex(inst, irq_status); @@ -357,8 +316,9 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) v4l2_m2m_dst_buf_remove_by_idx(inst->v4l2_fh.m2m_ctx, dec_output_info.index_frame_display); - int stride = inst->display_fmt.width; - int height =inst->display_fmt.height; + stride = dec_output_info.disp_frame.stride; + height = dec_output_info.disp_pic_height - + dec_output_info.rc_display.bottom; 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 num %d\n", __func__, __LINE__, stride, height,inst->dst_fmt.num_planes); @@ -425,7 +385,6 @@ 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); v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_eos); v4l2_m2m_job_finish(inst->v4l2_m2m_dev, inst->v4l2_fh.m2m_ctx); @@ -498,7 +457,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_r8(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height); + wave5_update_pix_fmt(&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); @@ -506,7 +465,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_r8(&f->fmt.pix_mp, width, height); + wave5_update_pix_fmt(&f->fmt.pix_mp, width, height); } f->fmt.pix_mp.flags = 0; @@ -525,7 +484,6 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form { struct vpu_instance *inst = wave5_to_vpu_inst(fh); int i, ret; - unsigned int scalew, scaleh; dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u colorspace: %u field: %u\n", @@ -533,37 +491,26 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form f->fmt.pix_mp.num_planes, f->fmt.pix_mp.colorspace, f->fmt.pix_mp.field); ret = wave5_vpu_dec_try_fmt_cap(file, fh, f); - if (ret) return ret; - 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->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.width = f->fmt.pix_mp.width; + inst->dst_fmt.height = f->fmt.pix_mp.height; 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->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; + 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; } - if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12 || - inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12M) { + if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12 || + inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12M) { inst->cbcr_interleave = true; inst->nv21 = false; - } else if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21 || - inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21M) { + } else if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21 || + inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21M) { inst->cbcr_interleave = true; inst->nv21 = true; } else { @@ -579,15 +526,15 @@ static int wave5_vpu_dec_g_fmt_cap(struct file *file, void *fh, struct v4l2_form struct vpu_instance *inst = wave5_to_vpu_inst(fh); int i; - f->fmt.pix_mp.width = inst->display_fmt.width; - f->fmt.pix_mp.height = inst->display_fmt.height; - f->fmt.pix_mp.pixelformat = inst->display_fmt.pixelformat; - f->fmt.pix_mp.field = inst->display_fmt.field; - f->fmt.pix_mp.flags = inst->display_fmt.flags; - f->fmt.pix_mp.num_planes = inst->display_fmt.num_planes; + f->fmt.pix_mp.width = inst->dst_fmt.width; + f->fmt.pix_mp.height = inst->dst_fmt.height; + f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat; + f->fmt.pix_mp.field = inst->dst_fmt.field; + f->fmt.pix_mp.flags = inst->dst_fmt.flags; + f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { - f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->display_fmt.plane_fmt[i].bytesperline; - f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->display_fmt.plane_fmt[i].sizeimage; + f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->dst_fmt.plane_fmt[i].bytesperline; + f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->dst_fmt.plane_fmt[i].sizeimage; } f->fmt.pix_mp.colorspace = inst->colorspace; @@ -660,7 +607,6 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form __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; @@ -682,9 +628,7 @@ 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_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); + wave5_update_pix_fmt(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height); return 0; } @@ -764,7 +708,6 @@ static int wave5_vpu_dec_decoder_cmd(struct file *file, void *fh, struct v4l2_de 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) { @@ -865,7 +808,7 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff { struct vpu_instance *inst = vb2_get_drv_priv(q); struct v4l2_pix_format_mplane inst_format = - (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->display_fmt; + (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->dst_fmt; unsigned int i; int ret; @@ -936,7 +879,6 @@ 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); @@ -1005,7 +947,6 @@ free_bitstream_vbuf: static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst) { struct dec_initial_info initial_info; - unsigned int scalew, scaleh; int ret = 0; memset(&initial_info, 0, sizeof(struct dec_initial_info)); @@ -1036,7 +977,6 @@ 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; @@ -1050,29 +990,15 @@ 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) { - 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); - } + 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); } + 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; - - if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) { - wave5_update_pix_fmt(&inst->display_fmt, inst->dst_fmt.width, - inst->dst_fmt.height); - } - 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); @@ -1087,7 +1013,6 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst) struct dec_initial_info initial_info; struct dec_param pic_param; struct dec_output_info dec_output_info; - unsigned int scalew, scaleh; int ret = 0; u32 fail_res = 0; @@ -1099,7 +1024,6 @@ 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; @@ -1142,29 +1066,15 @@ 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) { - 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); - } + 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); } + 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; - - if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) { - wave5_update_pix_fmt(&inst->display_fmt, inst->dst_fmt.width, - inst->dst_fmt.height); - } - v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_src_ch); wave5_handle_src_buffer(inst); @@ -1206,22 +1116,22 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb) dma_addr_t buf_addr_y = 0, buf_addr_cb = 0, buf_addr_cr = 0; u32 buf_size = 0; u32 non_linear_num = inst->dst_buf_count; - u32 fb_stride = inst->display_fmt.width; - u32 luma_size = fb_stride * inst->display_fmt.height; - u32 chroma_size = (fb_stride / 2) * (inst->display_fmt.height / 2); + u32 fb_stride = inst->dst_fmt.width; + u32 luma_size = fb_stride * inst->dst_fmt.height; + u32 chroma_size = (fb_stride / 2) * (inst->dst_fmt.height / 2); - if (inst->display_fmt.num_planes == 1) { + if (inst->dst_fmt.num_planes == 1) { buf_size = vb2_plane_size(&vbuf->vb2_buf, 0); buf_addr_y = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); buf_addr_cb = buf_addr_y + luma_size; buf_addr_cr = buf_addr_cb + chroma_size; - } else if (inst->display_fmt.num_planes == 2) { + } else if (inst->dst_fmt.num_planes == 2) { buf_size = vb2_plane_size(&vbuf->vb2_buf, 0) + vb2_plane_size(&vbuf->vb2_buf, 1); buf_addr_y = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); buf_addr_cb = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 1); buf_addr_cr = buf_addr_cb + chroma_size; - } else if (inst->display_fmt.num_planes == 3) { + } else if (inst->dst_fmt.num_planes == 3) { buf_size = vb2_plane_size(&vbuf->vb2_buf, 0) + vb2_plane_size(&vbuf->vb2_buf, 1) + vb2_plane_size(&vbuf->vb2_buf, 2); @@ -1233,7 +1143,7 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb) inst->frame_buf[vb->index + non_linear_num].buf_cb = buf_addr_cb; inst->frame_buf[vb->index + non_linear_num].buf_cr = buf_addr_cr; inst->frame_buf[vb->index + non_linear_num].size = buf_size; - inst->frame_buf[vb->index + non_linear_num].width = inst->display_fmt.width; + inst->frame_buf[vb->index + non_linear_num].width = inst->src_fmt.width; inst->frame_buf[vb->index + non_linear_num].stride = fb_stride; inst->frame_buf[vb->index + non_linear_num].map_type = LINEAR_FRAME_MAP; inst->frame_buf[vb->index + non_linear_num].update_fb_info = true; @@ -1369,7 +1279,6 @@ 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; } @@ -1422,7 +1331,6 @@ static void wave5_vpu_dec_device_run(void *priv) 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) @@ -1487,7 +1395,6 @@ static int wave5_vpu_open_dec(struct file *filp) v4l2_ctrl_handler_setup(&inst->v4l2_ctrl_hdl); wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt); - memcpy((void *)&inst->display_fmt, (void *)&inst->dst_fmt, sizeof(struct v4l2_pix_format_mplane)); inst->colorspace = V4L2_COLORSPACE_REC709; inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; inst->hsv_enc = 0; diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h index dcd061b1..892eff2 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h +++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h @@ -1048,7 +1048,6 @@ struct vpu_instance { struct v4l2_pix_format_mplane src_fmt; struct v4l2_pix_format_mplane dst_fmt; - struct v4l2_pix_format_mplane display_fmt; enum v4l2_colorspace colorspace; enum v4l2_xfer_func xfer_func; enum v4l2_ycbcr_encoding ycbcr_enc; -- 2.7.4 From 986cb19183306a5b443c8e892e38f03290840aa9 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Tue, 29 Aug 2023 10:18:47 +0800 Subject: [PATCH 08/16] Media:Wave5: Fix segment fault when finish buffer Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit 9aea96f91ea6 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: Ic2bf17247ed6ec08582d5b98b4e0be24d6a07ce0 --- drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 5 +++++ 1 file changed, 5 insertions(+) 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 481273d..fda9090 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -316,6 +316,11 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) v4l2_m2m_dst_buf_remove_by_idx(inst->v4l2_fh.m2m_ctx, dec_output_info.index_frame_display); + if (!dst_buf) { + dev_dbg(inst->dev->dev,"find no dst_buf \n"); + return; + } + stride = dec_output_info.disp_frame.stride; height = dec_output_info.disp_pic_height - dec_output_info.rc_display.bottom; -- 2.7.4 From 92812acdd0161d35a15f9829e441c60a1125e45b Mon Sep 17 00:00:00 2001 From: Som Qin Date: Wed, 30 Aug 2023 09:23:21 +0800 Subject: [PATCH 09/16] Media:Wave5: Allocate more linear buffer to avoid block in gst-play Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit a95153b6cedf from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: I526c47f67fa196e27d7e4ad5e685252e8a034989 --- drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 fda9090..e97b3b0 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -345,11 +345,7 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) ((stride / 2) * (height / 2))); } - 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->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); @@ -897,6 +893,7 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff //if (*num_buffers > inst->min_dst_buf_count && // *num_buffers < WAVE5_MAX_FBS) // inst->dst_buf_count = *num_buffers; + inst->dst_buf_count += 2; *num_buffers = inst->dst_buf_count; non_linear_num = inst->dst_buf_count; -- 2.7.4 From 4ae8c528a8443d42d0225b4019f55685f3d925a3 Mon Sep 17 00:00:00 2001 From: Som Qin Date: Wed, 30 Aug 2023 14:10:50 +0800 Subject: [PATCH 10/16] Medis:wave5: Remove inexistent including File sifive_l2_cache.h is inexistent in sdk 6.1 version. Signed-off-by: Som Qin [sw0312.kim: cherry-pick the commit ed137a80cd88 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel - Change sifive cache flush function name properly] Signed-off-by: Seung-Woo Kim Change-Id: Id9d63d72fab1ab0ddeecdb46aeaa19cb0045ed36 --- drivers/media/platform/chips-media/wave5/wave5-vdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-vdi.c b/drivers/media/platform/chips-media/wave5/wave5-vdi.c index 4a0e4b8..9301dd2 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vdi.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vdi.c @@ -10,11 +10,11 @@ #include "wave5-vpu.h" #include "wave5-regdefine.h" #include + #ifdef CONFIG_SIFIVE_FLUSH -#include +extern void sifive_flush64_range(unsigned long start, unsigned long len); #endif - #define VDI_SYSTEM_ENDIAN VDI_LITTLE_ENDIAN #define VDI_128BIT_BUS_SYSTEM_ENDIAN VDI_128BIT_LITTLE_ENDIAN -- 2.7.4 From 14b3c5361aff26ff8360e137c2bc9f4b60513fdb Mon Sep 17 00:00:00 2001 From: Samin Guo Date: Thu, 8 Jun 2023 16:01:33 +0800 Subject: [PATCH 11/16] riscv: dts: starfive: jh7110: Add vpu/jpu nodes Add vpu/jpu nodes for jh7110 SOC Signed-off-by: Samin Guo [sw0312.kim: port the commit e2d1cdfe5ff5 from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel - Port upstream jh7110 clk and sys-reset controller macro name] Signed-off-by: Seung-Woo Kim Change-Id: Iae673d805d9549ba96f3c08ee93ea69148f68e1e --- arch/riscv/boot/dts/starfive/jh7110.dtsi | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index 954e336..c8c4f0b 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -1070,6 +1070,70 @@ status = "disabled"; }; + jpu: jpu@13090000 { + compatible = "starfive,jpu"; + reg = <0x0 0x13090000 0x0 0x300>; + interrupts = <14>; + clocks = <&syscrg JH7110_SYSCLK_CODAJ12_AXI>, + <&syscrg JH7110_SYSCLK_CODAJ12_CORE>, + <&syscrg JH7110_SYSCLK_CODAJ12_APB>, + <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>; + clock-names = "axi_clk", "core_clk", + "apb_clk", "noc_bus"; + resets = <&syscrg JH7110_SYSRST_CODAJ12_AXI>, + <&syscrg JH7110_SYSRST_CODAJ12_CORE>, + <&syscrg JH7110_SYSRST_CODAJ12_APB>; + reset-names = "rst_axi", "rst_core", "rst_apb"; + power-domains = <&pwrc JH7110_PD_VDEC>; + status = "disabled"; + }; + + vpu_dec: vpu_dec@130A0000 { + compatible = "starfive,vdec"; + reg = <0x0 0x130A0000 0x0 0x10000>; + interrupts = <13>; + clocks = <&syscrg JH7110_SYSCLK_WAVE511_AXI>, + <&syscrg JH7110_SYSCLK_WAVE511_BPU>, + <&syscrg JH7110_SYSCLK_WAVE511_VCE>, + <&syscrg JH7110_SYSCLK_WAVE511_APB>, + <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>; + clock-names = "axi_clk", "bpu_clk", "vce_clk", + "apb_clk", "noc_bus"; + resets = <&syscrg JH7110_SYSRST_WAVE511_AXI>, + <&syscrg JH7110_SYSRST_WAVE511_BPU>, + <&syscrg JH7110_SYSRST_WAVE511_VCE>, + <&syscrg JH7110_SYSRST_WAVE511_APB>, + <&syscrg JH7110_SYSRST_AXIMEM0_AXI>; + reset-names = "rst_axi", "rst_bpu", "rst_vce", + "rst_apb", "rst_sram"; + starfive,vdec_noc_ctrl; + power-domains = <&pwrc JH7110_PD_VDEC>; + status = "disabled"; + }; + + vpu_enc: vpu_enc@130B0000 { + compatible = "starfive,venc"; + reg = <0x0 0x130B0000 0x0 0x10000>; + interrupts = <15>; + clocks = <&syscrg JH7110_SYSCLK_VENC_AXI>, + <&syscrg JH7110_SYSCLK_WAVE420L_BPU>, + <&syscrg JH7110_SYSCLK_WAVE420L_VCE>, + <&syscrg JH7110_SYSCLK_WAVE420L_APB>, + <&syscrg JH7110_SYSCLK_NOC_BUS_VENC_AXI>; + clock-names = "axi_clk", "bpu_clk", "vce_clk", + "apb_clk", "noc_bus"; + resets = <&syscrg JH7110_SYSRST_WAVE420L_AXI>, + <&syscrg JH7110_SYSRST_WAVE420L_BPU>, + <&syscrg JH7110_SYSRST_WAVE420L_VCE>, + <&syscrg JH7110_SYSRST_WAVE420L_APB>, + <&syscrg JH7110_SYSRST_AXIMEM1_AXI>; + reset-names = "rst_axi", "rst_bpu", "rst_vce", + "rst_apb", "rst_sram"; + starfive,venc_noc_ctrl; + power-domains = <&pwrc JH7110_PD_VENC>; + status = "disabled"; + }; + dma: dma-controller@16050000 { compatible = "starfive,jh7110-axi-dma"; reg = <0x0 0x16050000 0x0 0x10000>; -- 2.7.4 From 026ddfd6de4593ea84bd9f2ee674234b9dd66b9f Mon Sep 17 00:00:00 2001 From: Samin Guo Date: Wed, 23 Aug 2023 10:43:54 +0800 Subject: [PATCH 12/16] riscv: dts: starfive: jh7110: add dma-coherent for vpu/jpu Use DMA-Coherent to avoid DIRECT_REMAP when allocating DMA buffers Signed-off-by: Samin Guo [sw0312.kim: cherry-pick the commit dfb44f0122ba from https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_6.1.y_devel] Signed-off-by: Seung-Woo Kim Change-Id: Ia0d3955010e963c0fb635e10081c1a2ab31155d4 --- arch/riscv/boot/dts/starfive/jh7110.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index c8c4f0b..4ac5ca7 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -1072,6 +1072,7 @@ jpu: jpu@13090000 { compatible = "starfive,jpu"; + dma-coherent; reg = <0x0 0x13090000 0x0 0x300>; interrupts = <14>; clocks = <&syscrg JH7110_SYSCLK_CODAJ12_AXI>, @@ -1090,6 +1091,7 @@ vpu_dec: vpu_dec@130A0000 { compatible = "starfive,vdec"; + dma-coherent; reg = <0x0 0x130A0000 0x0 0x10000>; interrupts = <13>; clocks = <&syscrg JH7110_SYSCLK_WAVE511_AXI>, @@ -1113,6 +1115,7 @@ vpu_enc: vpu_enc@130B0000 { compatible = "starfive,venc"; + dma-coherent; reg = <0x0 0x130B0000 0x0 0x10000>; interrupts = <15>; clocks = <&syscrg JH7110_SYSCLK_VENC_AXI>, -- 2.7.4 From 708a313fba9e9aea566c5276f7f41fd91e04f44f Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 24 Jan 2024 10:50:06 +0900 Subject: [PATCH 13/16] RISCV: dts: starfive: enable jpg, vpu_dec and vpu_enc nodes in visionfive-2 To support video codec, wave vpu, enable related jpg, vpu_dec and vpu_enc nodes in visionfive-2. NOTE: Only wave511 vpu_dec is supported with wave video codec driver because visionfive-2 vpu_enc wave420 is different from currently supported wave521 by the driver. Change-Id: Icdd828ce35c98eee9a90a82c69c13614e53bb970 Signed-off-by: Seung-Woo Kim --- .../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi index 77d5782..732d74a 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi @@ -280,6 +280,18 @@ status = "okay"; }; +&jpu { + status = "okay"; +}; + +&vpu_dec { + status = "okay"; +}; + +&vpu_enc { + status = "okay"; +}; + &i2c0 { clock-frequency = <100000>; i2c-sda-hold-time-ns = <300>; -- 2.7.4 From 23b2320e40935ba7f952060739a15b6e83973f8a Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 24 Jan 2024 10:50:20 +0900 Subject: [PATCH 14/16] media: chips-media: wave511: Fix null deference in wave5_vpu_dec_clr_disp_flag() If wave5_vpu_dec_open() is not called before calling wave5_vpu_dec_clr_disp_flag(), there is null deference. Fix the null deference by checking codec_info. Change-Id: I1a4d9a75681df293e1f67dd4338c6f770d789223 Signed-off-by: Seung-Woo Kim --- drivers/media/platform/chips-media/wave5/wave5-vpuapi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c index 5a0078a..4e38a4d 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.c @@ -625,10 +625,14 @@ err_out: int wave5_vpu_dec_clr_disp_flag(struct vpu_instance *inst, int index) { - struct dec_info *p_dec_info = &inst->codec_info->dec_info; + struct dec_info *p_dec_info; int ret = 0; struct vpu_device *vpu_dev = inst->dev; + if (!inst->codec_info) + return -EINVAL; + + p_dec_info = &inst->codec_info->dec_info; if (index >= p_dec_info->num_of_display_fbs) return -EINVAL; -- 2.7.4 From b9471f4b7c1a0981da24db958f4b29d4353f5dca Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 5 Feb 2024 16:24:00 +0900 Subject: [PATCH 15/16] RISCV: config: enable wave511 video codec driver as module Enable wave511 video codec driver as module and also enable all depending configs. Change-Id: I0aeb0dfc0a844a3cc17c5054df61454c3f88e5fb Signed-off-by: Seung-Woo Kim --- arch/riscv/configs/tizen_visionfive2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/configs/tizen_visionfive2_defconfig b/arch/riscv/configs/tizen_visionfive2_defconfig index 62219f0..e5ff49a 100644 --- a/arch/riscv/configs/tizen_visionfive2_defconfig +++ b/arch/riscv/configs/tizen_visionfive2_defconfig @@ -291,6 +291,7 @@ CONFIG_USB_GSPCA_ZC3XX=m CONFIG_USB_VIDEO_CLASS=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_WAVE_VPU=m CONFIG_DRM_VERISILICON=y CONFIG_DRM_VERISILICON_STARFIVE_HDMI=y CONFIG_DRM_IMG_ROGUE=y -- 2.7.4 From 99ff9f776cbffd8c0cb15c524c086d7bf5c78315 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 8 Feb 2024 13:36:53 +0100 Subject: [PATCH 16/16] RISCV: config: tizen_visionfive2: Disable JH7110 crypto driver JH7110 crypto driver seems to be causing memory trashing, so temporarily disable it until the issue is really fixed. This fixes the 'i2c controller timed out' and some other random issues. Signed-off-by: Marek Szyprowski Change-Id: I3c1030a0eaf41d7cf97b0fdc6d228bc61681ef5e --- arch/riscv/configs/tizen_visionfive2_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/riscv/configs/tizen_visionfive2_defconfig b/arch/riscv/configs/tizen_visionfive2_defconfig index e5ff49a..83211ed 100644 --- a/arch/riscv/configs/tizen_visionfive2_defconfig +++ b/arch/riscv/configs/tizen_visionfive2_defconfig @@ -406,7 +406,6 @@ CONFIG_CRYPTO_LZ4=y CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_DEV_VIRTIO=y -CONFIG_CRYPTO_DEV_JH7110=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_SCHED_STACK_END_CHECK=y -- 2.7.4