dc9aec795f
Instead of switching capture mode depending on how many buffers are available use a scratch buffer and always run in continuous mode. By using a scratch buffer the responsiveness of the capture loop is increased as it can keep running even if there are no buffers available from userspace. As soon as a userspace queues a buffer it is inserted into the capture loop and returned as soon as it is filled. This is a improvement on the previous logic where the whole capture loop was stopped and switched to single capture mode if userspace did not feed the VIN driver buffers at the same time it consumed them. To make matters worse it was difficult for the driver to reenter continuous mode if it entered single mode even if userspace started to queue buffers faster. This resulted in suboptimal performance where if userspace where delayed for a short period the ongoing capture would be slowed down and run in single mode until the capturing process where restarted. An additional effect of this change is that the capture logic can be made much simple as we know that continuous mode will always be used. Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
170 lines
4.2 KiB
C
170 lines
4.2 KiB
C
/*
|
|
* Driver for Renesas R-Car VIN
|
|
*
|
|
* Copyright (C) 2016 Renesas Electronics Corp.
|
|
* Copyright (C) 2011-2013 Renesas Solutions Corp.
|
|
* Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
|
|
* Copyright (C) 2008 Magnus Damm
|
|
*
|
|
* Based on the soc-camera rcar_vin driver
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*/
|
|
|
|
#ifndef __RCAR_VIN__
|
|
#define __RCAR_VIN__
|
|
|
|
#include <media/v4l2-async.h>
|
|
#include <media/v4l2-ctrls.h>
|
|
#include <media/v4l2-dev.h>
|
|
#include <media/v4l2-device.h>
|
|
#include <media/videobuf2-v4l2.h>
|
|
|
|
/* Number of HW buffers */
|
|
#define HW_BUFFER_NUM 3
|
|
|
|
/* Address alignment mask for HW buffers */
|
|
#define HW_BUFFER_MASK 0x7f
|
|
|
|
enum chip_id {
|
|
RCAR_H1,
|
|
RCAR_M1,
|
|
RCAR_GEN2,
|
|
};
|
|
|
|
/**
|
|
* STOPPED - No operation in progress
|
|
* RUNNING - Operation in progress have buffers
|
|
* STOPPING - Stopping operation
|
|
*/
|
|
enum rvin_dma_state {
|
|
STOPPED = 0,
|
|
RUNNING,
|
|
STOPPING,
|
|
};
|
|
|
|
/**
|
|
* struct rvin_source_fmt - Source information
|
|
* @width: Width from source
|
|
* @height: Height from source
|
|
*/
|
|
struct rvin_source_fmt {
|
|
u32 width;
|
|
u32 height;
|
|
};
|
|
|
|
/**
|
|
* struct rvin_video_format - Data format stored in memory
|
|
* @fourcc: Pixelformat
|
|
* @bpp: Bytes per pixel
|
|
*/
|
|
struct rvin_video_format {
|
|
u32 fourcc;
|
|
u8 bpp;
|
|
};
|
|
|
|
/**
|
|
* struct rvin_graph_entity - Video endpoint from async framework
|
|
* @asd: sub-device descriptor for async framework
|
|
* @subdev: subdevice matched using async framework
|
|
* @code: Media bus format from source
|
|
* @mbus_cfg: Media bus format from DT
|
|
* @source_pad: source pad of remote subdevice
|
|
* @sink_pad: sink pad of remote subdevice
|
|
*/
|
|
struct rvin_graph_entity {
|
|
struct v4l2_async_subdev asd;
|
|
struct v4l2_subdev *subdev;
|
|
|
|
u32 code;
|
|
struct v4l2_mbus_config mbus_cfg;
|
|
|
|
unsigned int source_pad;
|
|
unsigned int sink_pad;
|
|
};
|
|
|
|
/**
|
|
* struct rvin_dev - Renesas VIN device structure
|
|
* @dev: (OF) device
|
|
* @base: device I/O register space remapped to virtual memory
|
|
* @chip: type of VIN chip
|
|
*
|
|
* @vdev: V4L2 video device associated with VIN
|
|
* @v4l2_dev: V4L2 device
|
|
* @ctrl_handler: V4L2 control handler
|
|
* @notifier: V4L2 asynchronous subdevs notifier
|
|
* @digital: entity in the DT for local digital subdevice
|
|
*
|
|
* @lock: protects @queue
|
|
* @queue: vb2 buffers queue
|
|
* @scratch: cpu address for scratch buffer
|
|
* @scratch_phys: physical address of the scratch buffer
|
|
*
|
|
* @qlock: protects @queue_buf, @buf_list, @sequence
|
|
* @state
|
|
* @queue_buf: Keeps track of buffers given to HW slot
|
|
* @buf_list: list of queued buffers
|
|
* @sequence: V4L2 buffers sequence number
|
|
* @state: keeps track of operation state
|
|
*
|
|
* @source: active format from the video source
|
|
* @format: active V4L2 pixel format
|
|
*
|
|
* @crop: active cropping
|
|
* @compose: active composing
|
|
*/
|
|
struct rvin_dev {
|
|
struct device *dev;
|
|
void __iomem *base;
|
|
enum chip_id chip;
|
|
|
|
struct video_device vdev;
|
|
struct v4l2_device v4l2_dev;
|
|
struct v4l2_ctrl_handler ctrl_handler;
|
|
struct v4l2_async_notifier notifier;
|
|
struct rvin_graph_entity *digital;
|
|
|
|
struct mutex lock;
|
|
struct vb2_queue queue;
|
|
void *scratch;
|
|
dma_addr_t scratch_phys;
|
|
|
|
spinlock_t qlock;
|
|
struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
|
|
struct list_head buf_list;
|
|
unsigned int sequence;
|
|
enum rvin_dma_state state;
|
|
|
|
struct rvin_source_fmt source;
|
|
struct v4l2_pix_format format;
|
|
|
|
struct v4l2_rect crop;
|
|
struct v4l2_rect compose;
|
|
};
|
|
|
|
#define vin_to_source(vin) ((vin)->digital->subdev)
|
|
|
|
/* Debug */
|
|
#define vin_dbg(d, fmt, arg...) dev_dbg(d->dev, fmt, ##arg)
|
|
#define vin_info(d, fmt, arg...) dev_info(d->dev, fmt, ##arg)
|
|
#define vin_warn(d, fmt, arg...) dev_warn(d->dev, fmt, ##arg)
|
|
#define vin_err(d, fmt, arg...) dev_err(d->dev, fmt, ##arg)
|
|
|
|
int rvin_dma_probe(struct rvin_dev *vin, int irq);
|
|
void rvin_dma_remove(struct rvin_dev *vin);
|
|
|
|
int rvin_v4l2_probe(struct rvin_dev *vin);
|
|
void rvin_v4l2_remove(struct rvin_dev *vin);
|
|
|
|
const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
|
|
|
|
/* Cropping, composing and scaling */
|
|
void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
|
|
u32 width, u32 height);
|
|
void rvin_crop_scale_comp(struct rvin_dev *vin);
|
|
|
|
#endif
|