Exemplo n.º 1
0
/*
 * isp_video_buffer_queue - Add buffer to streaming queue
 * @buf: Video buffer
 *
 * In memory-to-memory mode, start streaming on the pipeline if buffers are
 * queued on both the input and the output, if the pipeline isn't already busy.
 * If the pipeline is busy, it will be restarted in the output module interrupt
 * handler.
 */
static void isp_video_buffer_queue(struct isp_video_buffer *buf)
{
    struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
    struct isp_buffer *buffer = to_isp_buffer(buf);
    struct isp_video *video = vfh->video;
    struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
    enum isp_pipeline_state state;
    unsigned long flags;
    unsigned int empty;
    unsigned int start;

    empty = list_empty(&video->dmaqueue);
    list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);

    if (empty) {
        if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
            state = ISP_PIPELINE_QUEUE_OUTPUT;
        else
            state = ISP_PIPELINE_QUEUE_INPUT;

        spin_lock_irqsave(&pipe->lock, flags);
        pipe->state |= state;
        video->ops->queue(video, buffer);
        video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;

        start = isp_pipeline_ready(pipe);
        if (start)
            pipe->state |= ISP_PIPELINE_STREAM;
        spin_unlock_irqrestore(&pipe->lock, flags);

        if (start)
            omap3isp_pipeline_set_stream(pipe,
                                         ISP_PIPELINE_STREAM_SINGLESHOT);
    }
}
Exemplo n.º 2
0
static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
{
    struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
    struct isp_buffer *buffer = to_isp_buffer(buf);
    struct isp_video *video = vfh->video;
    unsigned long addr;

    /* Refuse to prepare the buffer is the video node has registered an
     * error. We don't need to take any lock here as the operation is
     * inherently racy. The authoritative check will be performed in the
     * queue handler, which can't return an error, this check is just a best
     * effort to notify userspace as early as possible.
     */
    if (unlikely(video->error))
        return -EIO;

    addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
    if (IS_ERR_VALUE(addr))
        return -EIO;

    if (!IS_ALIGNED(addr, 32)) {
        dev_dbg(video->isp->dev, "Buffer address must be "
                "aligned to 32 bytes boundary.\n");
        ispmmu_vunmap(video->isp, buffer->isp_addr);
        return -EINVAL;
    }

    buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
    buffer->isp_addr = addr;
    return 0;
}
Exemplo n.º 3
0
static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
{
    struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
    struct isp_buffer *buffer = to_isp_buffer(buf);
    struct isp_video *video = vfh->video;

    if (buffer->isp_addr) {
        ispmmu_vunmap(video->isp, buffer->isp_addr);
        buffer->isp_addr = 0;
    }
}
Exemplo n.º 4
0
static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
{
    struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
    struct isp_buffer *buffer = to_isp_buffer(buf);
    struct isp_video *video = vfh->video;
    unsigned long addr;

    addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
    if (IS_ERR_VALUE(addr))
        return -EIO;

    if (!IS_ALIGNED(addr, 32)) {
        dev_dbg(video->isp->dev, "Buffer address must be "
                "aligned to 32 bytes boundary.\n");
        ispmmu_vunmap(video->isp, buffer->isp_addr);
        return -EINVAL;
    }

    buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
    buffer->isp_addr = addr;
    return 0;
}