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->fh.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->fh.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; dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; dst_vb->v4l2_buf.flags |= src_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; /* 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 fimc_device_run(void *priv) { struct vb2_buffer *vb = NULL; struct fimc_ctx *ctx = priv; struct fimc_frame *sf, *df; struct fimc_dev *fimc; unsigned long flags; u32 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); } vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); ret = fimc_prepare_addr(ctx, vb, sf, &sf->paddr); if (ret) goto dma_unlock; vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); ret = fimc_prepare_addr(ctx, vb, df, &df->paddr); if (ret) goto dma_unlock; /* 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->variant->has_alpha) 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_SRC_FMT | FIMC_DST_FMT); fimc_hw_activate_input_dma(fimc, true); dma_unlock: spin_unlock_irqrestore(&fimc->slock, flags); }