static int bdisp_get_bufs(struct bdisp_ctx *ctx) { struct bdisp_frame *src, *dst; struct vb2_buffer *src_vb, *dst_vb; int ret; src = &ctx->src; dst = &ctx->dst; src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); ret = bdisp_get_addr(ctx, src_vb, src, src->paddr); if (ret) return ret; dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); ret = bdisp_get_addr(ctx, dst_vb, dst, dst->paddr); if (ret) return ret; dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp; return 0; }
static int gsc_get_bufs(struct gsc_ctx *ctx) { struct gsc_frame *s_frame, *d_frame; struct vb2_buffer *src_vb, *dst_vb; int ret; s_frame = &ctx->s_frame; d_frame = &ctx->d_frame; src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); ret = gsc_prepare_addr(ctx, src_vb, s_frame, &s_frame->addr); if (ret) return ret; dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); ret = gsc_prepare_addr(ctx, dst_vb, d_frame, &d_frame->addr); if (ret) return ret; dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp; return 0; }
static int gsc_get_bufs(struct gsc_ctx *ctx) { struct gsc_frame *s_frame, *d_frame; struct vb2_buffer *src_vb = NULL; struct vb2_buffer *dst_vb = NULL; int ret = 0; s_frame = &ctx->s_frame; d_frame = &ctx->d_frame; src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); ret = gsc_prepare_addr(ctx, src_vb, s_frame, &s_frame->addr); if (ret) return ret; dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); ret = gsc_prepare_addr(ctx, dst_vb, d_frame, &d_frame->addr); memcpy(&dst_vb->v4l2_buf.timestamp, &src_vb->v4l2_buf.timestamp, sizeof(dst_vb->v4l2_buf.timestamp)); return ret; }
/* * msm_jpegdma_device_run - Dma device run. * @priv: Pointer dma context. */ static void msm_jpegdma_device_run(void *priv) { struct vb2_buffer *src_buf; struct vb2_buffer *dst_buf; struct jpegdma_ctx *ctx = priv; dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma device run E\n"); dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (src_buf == NULL || dst_buf == NULL) { dev_err(ctx->jdma_device->dev, "Error, buffer list empty\n"); return; } if (ctx->pending_config) { msm_jpegdma_schedule_next_config(ctx); ctx->pending_config = 0; } msm_jpegdma_process_buffers(ctx, src_buf, dst_buf); dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma device run X\n"); }
static void fimc_device_run(void *priv) { struct vb2_buffer *src_vb, *dst_vb; struct fimc_ctx *ctx = priv; struct fimc_frame *sf, *df; struct fimc_dev *fimc; unsigned long flags; int ret; if (WARN(!ctx, "Null context\n")) return; fimc = ctx->fimc_dev; spin_lock_irqsave(&fimc->slock, flags); set_bit(ST_M2M_PEND, &fimc->state); sf = &ctx->s_frame; df = &ctx->d_frame; if (ctx->state & FIMC_PARAMS) { /* Prepare the DMA offsets for scaler */ fimc_prepare_dma_offset(ctx, sf); fimc_prepare_dma_offset(ctx, df); } src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); ret = fimc_prepare_addr(ctx, src_vb, sf, &sf->paddr); if (ret) goto dma_unlock; dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); ret = fimc_prepare_addr(ctx, dst_vb, df, &df->paddr); if (ret) goto dma_unlock; dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp; /* Reconfigure hardware if the context has changed. */ if (fimc->m2m.ctx != ctx) { ctx->state |= FIMC_PARAMS; fimc->m2m.ctx = ctx; } if (ctx->state & FIMC_PARAMS) { fimc_set_yuv_order(ctx); fimc_hw_set_input_path(ctx); fimc_hw_set_in_dma(ctx); ret = fimc_set_scaler_info(ctx); if (ret) goto dma_unlock; fimc_hw_set_prescaler(ctx); fimc_hw_set_mainscaler(ctx); fimc_hw_set_target_format(ctx); fimc_hw_set_rotation(ctx); fimc_hw_set_effect(ctx); fimc_hw_set_out_dma(ctx); if (fimc->drv_data->alpha_color) fimc_hw_set_rgb_alpha(ctx); fimc_hw_set_output_path(ctx); } fimc_hw_set_input_addr(fimc, &sf->paddr); fimc_hw_set_output_addr(fimc, &df->paddr, -1); fimc_activate_capture(ctx); ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); fimc_hw_activate_input_dma(fimc, true); dma_unlock: spin_unlock_irqrestore(&fimc->slock, flags); }
static void mtk_vdec_worker(struct work_struct *work) { struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, decode_work); struct mtk_vcodec_dev *dev = ctx->dev; struct vb2_buffer *src_buf, *dst_buf; struct mtk_vcodec_mem buf; struct vdec_fb *pfb; bool res_chg = false; int ret; struct mtk_video_dec_buf *dst_buf_info, *src_buf_info; struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); if (src_buf == NULL) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id); return; } dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); if (dst_buf == NULL) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); return; } src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf); src_buf_info = container_of(src_vb2_v4l2, struct mtk_video_dec_buf, vb); dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); dst_buf_info = container_of(dst_vb2_v4l2, struct mtk_video_dec_buf, vb); pfb = &dst_buf_info->frame_buffer; pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0); pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); pfb->base_y.size = ctx->picinfo.y_bs_sz + ctx->picinfo.y_len_sz; pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1); pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1); pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz; pfb->status = 0; mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); mtk_v4l2_debug(3, "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx", dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size); if (src_buf_info->lastframe) { mtk_v4l2_debug(1, "Got empty flush input buffer."); src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); /* update dst buf status */ dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); mutex_lock(&ctx->lock); dst_buf_info->used = false; mutex_unlock(&ctx->lock); vdec_if_decode(ctx, NULL, NULL, &res_chg); clean_display_buffer(ctx); vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0); vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0); dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_LAST; v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE); clean_free_buffer(ctx); v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); return; } buf.va = vb2_plane_vaddr(src_buf, 0); buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); buf.size = (size_t)src_buf->planes[0].bytesused; if (!buf.va) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", ctx->id, src_buf->index); return; } mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p", ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf); dst_buf_info->vb.vb2_buf.timestamp = src_buf_info->vb.vb2_buf.timestamp; dst_buf_info->vb.timecode = src_buf_info->vb.timecode; mutex_lock(&ctx->lock); dst_buf_info->used = true; mutex_unlock(&ctx->lock); src_buf_info->used = true; ret = vdec_if_decode(ctx, &buf, pfb, &res_chg); if (ret) { mtk_v4l2_err( " <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>", ctx->id, src_buf->index, buf.size, src_buf_info->vb.vb2_buf.timestamp, dst_buf->index, ret, res_chg); src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); } else if (res_chg == false) { /* * we only return src buffer with VB2_BUF_STATE_DONE * when decode success without resolution change */ src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE); } dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); clean_display_buffer(ctx); clean_free_buffer(ctx); if (!ret && res_chg) { mtk_vdec_pic_info_update(ctx); /* * On encountering a resolution change in the stream. * The driver must first process and decode all * remaining buffers from before the resolution change * point, so call flush decode here */ mtk_vdec_flush_decoder(ctx); /* * After all buffers containing decoded frames from * before the resolution change point ready to be * dequeued on the CAPTURE queue, the driver sends a * V4L2_EVENT_SOURCE_CHANGE event for source change * type V4L2_EVENT_SRC_CH_RESOLUTION */ mtk_vdec_queue_res_chg_event(ctx); } v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); }
static void jpeg_device_dec_run(void *priv) { struct jpeg_ctx *ctx = priv; struct jpeg_dev *dev = ctx->dev; struct jpeg_dec_param dec_param; struct vb2_buffer *vb = NULL; unsigned long flags; dev = ctx->dev; spin_lock_irqsave(&ctx->dev->slock, flags); printk(KERN_DEBUG "dec_run.\n"); if (timer_pending(&ctx->dev->watchdog_timer) == 0) { ctx->dev->watchdog_timer.expires = jiffies + msecs_to_jiffies(JPEG_WATCHDOG_INTERVAL); add_timer(&ctx->dev->watchdog_timer); } set_bit(0, &ctx->dev->hw_run); dev->mode = DECODING; dec_param = ctx->param.dec_param; jpeg_sw_reset(dev->reg_base); jpeg_set_interrupt(dev->reg_base); jpeg_set_encode_tbl_select(dev->reg_base, 0); vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); jpeg_set_stream_buf_address(dev->reg_base, dev->vb2->plane_addr(vb, 0)); vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); if (dec_param.out_plane == 1) jpeg_set_frame_buf_address(dev->reg_base, dec_param.out_fmt, dev->vb2->plane_addr(vb, 0), 0, 0); else if (dec_param.out_plane == 2) { jpeg_set_frame_buf_address(dev->reg_base, dec_param.out_fmt, dev->vb2->plane_addr(vb, 0), dev->vb2->plane_addr(vb, 1), 0); } else if (dec_param.out_plane == 3) jpeg_set_frame_buf_address(dev->reg_base, dec_param.out_fmt, dev->vb2->plane_addr(vb, 0), dev->vb2->plane_addr(vb, 1), dev->vb2->plane_addr(vb, 2)); if (dec_param.out_width > 0 && dec_param.out_height > 0) { if ((dec_param.out_width * 2 == dec_param.in_width) && (dec_param.out_height * 2 == dec_param.in_height)) jpeg_set_dec_scaling(dev->reg_base, JPEG_SCALE_2, JPEG_SCALE_2); else if ((dec_param.out_width * 4 == dec_param.in_width) && (dec_param.out_height * 4 == dec_param.in_height)) jpeg_set_dec_scaling(dev->reg_base, JPEG_SCALE_4, JPEG_SCALE_4); else jpeg_set_dec_scaling(dev->reg_base, JPEG_SCALE_NORMAL, JPEG_SCALE_NORMAL); } jpeg_set_dec_out_fmt(dev->reg_base, dec_param.out_fmt); jpeg_set_dec_bitstream_size(dev->reg_base, dec_param.size); jpeg_set_enc_dec_mode(dev->reg_base, DECODING); spin_unlock_irqrestore(&ctx->dev->slock, flags); }