コード例 #1
0
ファイル: fimc-capture.c プロジェクト: artynet/linux-3.3.8
static int start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct fimc_ctx *ctx = q->drv_priv;
	struct fimc_dev *fimc = ctx->fimc_dev;
	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
	int min_bufs;
	int ret;

	vid_cap->frame_count = 0;

	ret = fimc_init_capture(fimc);
	if (ret)
		goto error;

	set_bit(ST_CAPT_PEND, &fimc->state);

	min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;

	if (vid_cap->active_buf_cnt >= min_bufs &&
	    !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
		fimc_activate_capture(ctx);

		if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
			fimc_pipeline_s_stream(fimc, 1);
	}

	return 0;
error:
	fimc_capture_state_cleanup(fimc, false);
	return ret;
}
コード例 #2
0
static void buffer_queue(struct vb2_buffer *vb)
{
	struct fimc_vid_buffer *buf
		= container_of(vb, struct fimc_vid_buffer, vb);
	struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct fimc_dev *fimc = ctx->fimc_dev;
	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
	unsigned long flags;
	int min_bufs;

	spin_lock_irqsave(&fimc->slock, flags);
	fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);

	if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
	    !test_bit(ST_CAPT_STREAM, &fimc->state) &&
	    vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
		/* Setup the buffer directly for processing. */
		int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
				vid_cap->buf_index;

		fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
		buf->index = vid_cap->buf_index;
		fimc_active_queue_add(vid_cap, buf);

		if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
			vid_cap->buf_index = 0;
	} else {
		fimc_pending_queue_add(vid_cap, buf);
	}

	min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;


	if (vb2_is_streaming(&vid_cap->vbq) &&
	    vid_cap->active_buf_cnt >= min_bufs &&
	    !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
		fimc_activate_capture(ctx);
		spin_unlock_irqrestore(&fimc->slock, flags);

		if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
			fimc_pipeline_call(fimc, set_stream,
					   &fimc->pipeline, 1);
		return;
	}
	spin_unlock_irqrestore(&fimc->slock, flags);
}
コード例 #3
0
ファイル: fimc-m2m.c プロジェクト: Niisp/MT6795.kernel
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);
}