Example #1
0
/*
 * At least one buffer on the pending_buf_q queue is required.
 * Locking: The caller holds fimc->slock spinlock.
 */
int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
			     struct fimc_vid_buffer *fimc_vb)
{
	struct fimc_vid_cap *cap = &fimc->vid_cap;
	struct fimc_ctx *ctx = cap->ctx;
	int ret = 0;

	BUG_ON(!fimc || !fimc_vb);

	ret = fimc_prepare_addr(ctx, fimc_vb, &ctx->d_frame,
				&fimc_vb->paddr);
	if (ret)
		return ret;

	if (test_bit(ST_CAPT_STREAM, &fimc->state)) {
		fimc_pending_queue_add(cap, fimc_vb);
	} else {
		/* Setup the buffer directly for processing. */
		int buf_id = (cap->reqbufs_count == 1) ? -1 : cap->buf_index;
		fimc_hw_set_output_addr(fimc, &fimc_vb->paddr, buf_id);

		fimc_vb->index = cap->buf_index;
		active_queue_add(cap, fimc_vb);

		if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
			cap->buf_index = 0;
	}
	return ret;
}
static void fimc_capture_irq_handler(struct fimc_dev *fimc)
{
	struct fimc_vid_cap *cap = &fimc->vid_cap;
	struct fimc_vid_buffer *v_buf;
	struct timeval *tv;
	struct timespec ts;

	if (!list_empty(&cap->active_buf_q) &&
	    test_bit(ST_CAPT_RUN, &fimc->state)) {
		ktime_get_real_ts(&ts);

		v_buf = active_queue_pop(cap);

		tv = &v_buf->vb.v4l2_buf.timestamp;
		tv->tv_sec = ts.tv_sec;
		tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
		v_buf->vb.v4l2_buf.sequence = cap->frame_count++;

		vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
	}

	if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
		wake_up(&fimc->irq_queue);
		return;
	}

	if (!list_empty(&cap->pending_buf_q)) {

		v_buf = pending_queue_pop(cap);
		fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
		v_buf->index = cap->buf_index;

		/* Move the buffer to the capture active queue */
		active_queue_add(cap, v_buf);

		dbg("next frame: %d, done frame: %d",
		    fimc_hw_get_frame_index(fimc), v_buf->index);

		if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
			cap->buf_index = 0;
	}

	if (cap->active_buf_cnt == 0) {
		clear_bit(ST_CAPT_RUN, &fimc->state);

		if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
			cap->buf_index = 0;
	} else {
		set_bit(ST_CAPT_RUN, &fimc->state);
	}

	dbg("frame: %d, active_buf_cnt: %d",
	    fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
}
Example #3
0
static void fimc_capture_irq_handler(struct fimc_dev *fimc)
{
	struct fimc_vid_cap *cap = &fimc->vid_cap;
	struct fimc_vid_buffer *v_buf;

	if (!list_empty(&cap->active_buf_q) &&
	    test_bit(ST_CAPT_RUN, &fimc->state)) {
		v_buf = active_queue_pop(cap);
		vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
	}

	if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
		wake_up(&fimc->irq_queue);
		return;
	}

	if (!list_empty(&cap->pending_buf_q)) {

		v_buf = pending_queue_pop(cap);
		fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
		v_buf->index = cap->buf_index;

		/* Move the buffer to the capture active queue */
		active_queue_add(cap, v_buf);

		dbg("next frame: %d, done frame: %d",
		    fimc_hw_get_frame_index(fimc), v_buf->index);

		if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
			cap->buf_index = 0;
	}

	if (cap->active_buf_cnt == 0) {
		clear_bit(ST_CAPT_RUN, &fimc->state);

		if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
			cap->buf_index = 0;
	} else {
		set_bit(ST_CAPT_RUN, &fimc->state);
	}

	dbg("frame: %d, active_buf_cnt: %d",
	    fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
}
Example #4
0
static void buffer_queue(struct vb2_buffer *vb)
{
    struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
    struct fimc_dev *fimc = ctx->fimc_dev;
    struct fimc_vid_buffer *buf
        = container_of(vb, struct fimc_vid_buffer, vb);
    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_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;
        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 (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);
}