staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc op
tegra_channel_fmt_align() takes care of the size constraints, alignment and rounding requirements of the Tegra210 VI peripheral. Tegra20 has different constraints. In preparation for adding Tegra20 support, move this function to a new op in the soc-specific `struct tegra_vi_ops` . Also move to tegra210.c the T210-specific defines used in the moved code. No functional changes. Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Reviewed-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
parent
c973880dfb
commit
1a3ea975d7
|
@ -17,6 +17,13 @@
|
|||
#include "csi.h"
|
||||
#include "vi.h"
|
||||
|
||||
#define TEGRA210_MIN_WIDTH 32U
|
||||
#define TEGRA210_MAX_WIDTH 32768U
|
||||
#define TEGRA210_MIN_HEIGHT 32U
|
||||
#define TEGRA210_MAX_HEIGHT 32768U
|
||||
|
||||
#define SURFACE_ALIGN_BYTES 64
|
||||
|
||||
#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT msecs_to_jiffies(200)
|
||||
|
||||
/* Tegra210 VI registers */
|
||||
|
@ -172,6 +179,34 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 portno,
|
|||
/*
|
||||
* Tegra210 VI channel capture operations
|
||||
*/
|
||||
static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
|
||||
{
|
||||
unsigned int min_bpl;
|
||||
unsigned int max_bpl;
|
||||
unsigned int bpl;
|
||||
|
||||
/*
|
||||
* The transfer alignment requirements are expressed in bytes.
|
||||
* Clamp the requested width and height to the limits.
|
||||
*/
|
||||
pix->width = clamp(pix->width, TEGRA210_MIN_WIDTH, TEGRA210_MAX_WIDTH);
|
||||
pix->height = clamp(pix->height, TEGRA210_MIN_HEIGHT, TEGRA210_MAX_HEIGHT);
|
||||
|
||||
/* Clamp the requested bytes per line value. If the maximum bytes per
|
||||
* line value is zero, the module doesn't support user configurable
|
||||
* line sizes. Override the requested value with the minimum in that
|
||||
* case.
|
||||
*/
|
||||
min_bpl = pix->width * bpp;
|
||||
max_bpl = rounddown(TEGRA210_MAX_WIDTH, SURFACE_ALIGN_BYTES);
|
||||
bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
|
||||
|
||||
pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
|
||||
pix->sizeimage = pix->bytesperline * pix->height;
|
||||
if (pix->pixelformat == V4L2_PIX_FMT_NV16)
|
||||
pix->sizeimage *= 2;
|
||||
}
|
||||
|
||||
static int tegra_channel_capture_setup(struct tegra_vi_channel *chan,
|
||||
u8 portno)
|
||||
{
|
||||
|
@ -718,6 +753,7 @@ static const struct tegra_video_format tegra210_video_formats[] = {
|
|||
|
||||
/* Tegra210 VI operations */
|
||||
static const struct tegra_vi_ops tegra210_vi_ops = {
|
||||
.vi_fmt_align = tegra210_fmt_align,
|
||||
.vi_start_streaming = tegra210_vi_start_streaming,
|
||||
.vi_stop_streaming = tegra210_vi_stop_streaming,
|
||||
};
|
||||
|
|
|
@ -473,36 +473,6 @@ static int tegra_channel_get_format(struct file *file, void *fh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_channel_fmt_align(struct tegra_vi_channel *chan,
|
||||
struct v4l2_pix_format *pix,
|
||||
unsigned int bpp)
|
||||
{
|
||||
unsigned int min_bpl;
|
||||
unsigned int max_bpl;
|
||||
unsigned int bpl;
|
||||
|
||||
/*
|
||||
* The transfer alignment requirements are expressed in bytes.
|
||||
* Clamp the requested width and height to the limits.
|
||||
*/
|
||||
pix->width = clamp(pix->width, TEGRA_MIN_WIDTH, TEGRA_MAX_WIDTH);
|
||||
pix->height = clamp(pix->height, TEGRA_MIN_HEIGHT, TEGRA_MAX_HEIGHT);
|
||||
|
||||
/* Clamp the requested bytes per line value. If the maximum bytes per
|
||||
* line value is zero, the module doesn't support user configurable
|
||||
* line sizes. Override the requested value with the minimum in that
|
||||
* case.
|
||||
*/
|
||||
min_bpl = pix->width * bpp;
|
||||
max_bpl = rounddown(TEGRA_MAX_WIDTH, SURFACE_ALIGN_BYTES);
|
||||
bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
|
||||
|
||||
pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
|
||||
pix->sizeimage = pix->bytesperline * pix->height;
|
||||
if (pix->pixelformat == V4L2_PIX_FMT_NV16)
|
||||
pix->sizeimage *= 2;
|
||||
}
|
||||
|
||||
static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
|
||||
struct v4l2_pix_format *pix)
|
||||
{
|
||||
|
@ -579,7 +549,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
|
|||
return ret;
|
||||
|
||||
v4l2_fill_pix_format(pix, &fmt.format);
|
||||
tegra_channel_fmt_align(chan, pix, fmtinfo->bpp);
|
||||
chan->vi->ops->vi_fmt_align(pix, fmtinfo->bpp);
|
||||
|
||||
__v4l2_subdev_state_free(sd_state);
|
||||
|
||||
|
@ -632,7 +602,7 @@ static int tegra_channel_set_format(struct file *file, void *fh,
|
|||
return ret;
|
||||
|
||||
v4l2_fill_pix_format(pix, &fmt.format);
|
||||
tegra_channel_fmt_align(chan, pix, fmtinfo->bpp);
|
||||
chan->vi->ops->vi_fmt_align(pix, fmtinfo->bpp);
|
||||
|
||||
chan->format = *pix;
|
||||
chan->fmtinfo = fmtinfo;
|
||||
|
@ -668,7 +638,7 @@ static int tegra_channel_set_subdev_active_fmt(struct tegra_vi_channel *chan)
|
|||
chan->format.bytesperline = chan->format.width * chan->fmtinfo->bpp;
|
||||
chan->format.sizeimage = chan->format.bytesperline *
|
||||
chan->format.height;
|
||||
tegra_channel_fmt_align(chan, &chan->format, chan->fmtinfo->bpp);
|
||||
chan->vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
|
||||
tegra_channel_update_gangports(chan);
|
||||
|
||||
return 0;
|
||||
|
@ -837,7 +807,7 @@ static int tegra_channel_s_dv_timings(struct file *file, void *fh,
|
|||
chan->format.height = bt->height;
|
||||
chan->format.bytesperline = bt->width * chan->fmtinfo->bpp;
|
||||
chan->format.sizeimage = chan->format.bytesperline * bt->height;
|
||||
tegra_channel_fmt_align(chan, &chan->format, chan->fmtinfo->bpp);
|
||||
chan->vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
|
||||
tegra_channel_update_gangports(chan);
|
||||
|
||||
return 0;
|
||||
|
@ -1240,7 +1210,7 @@ static int tegra_channel_init(struct tegra_vi_channel *chan)
|
|||
chan->format.height = TEGRA_DEF_HEIGHT;
|
||||
chan->format.bytesperline = TEGRA_DEF_WIDTH * chan->fmtinfo->bpp;
|
||||
chan->format.sizeimage = chan->format.bytesperline * TEGRA_DEF_HEIGHT;
|
||||
tegra_channel_fmt_align(chan, &chan->format, chan->fmtinfo->bpp);
|
||||
vi->ops->vi_fmt_align(&chan->format, chan->fmtinfo->bpp);
|
||||
|
||||
ret = tegra_channel_host1x_syncpt_init(chan);
|
||||
if (ret)
|
||||
|
|
|
@ -25,17 +25,11 @@
|
|||
|
||||
#define V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY (V4L2_CTRL_CLASS_CAMERA | 0x1001)
|
||||
|
||||
#define TEGRA_MIN_WIDTH 32U
|
||||
#define TEGRA_MAX_WIDTH 32768U
|
||||
#define TEGRA_MIN_HEIGHT 32U
|
||||
#define TEGRA_MAX_HEIGHT 32768U
|
||||
|
||||
#define TEGRA_DEF_WIDTH 1920
|
||||
#define TEGRA_DEF_HEIGHT 1080
|
||||
#define TEGRA_IMAGE_FORMAT_DEF 32
|
||||
|
||||
#define MAX_FORMAT_NUM 64
|
||||
#define SURFACE_ALIGN_BYTES 64
|
||||
|
||||
enum tegra_vi_pg_mode {
|
||||
TEGRA_VI_PG_DISABLED = 0,
|
||||
|
@ -45,6 +39,8 @@ enum tegra_vi_pg_mode {
|
|||
|
||||
/**
|
||||
* struct tegra_vi_ops - Tegra VI operations
|
||||
* @vi_fmt_align: modify `pix` to fit the hardware alignment
|
||||
* requirements and fill image geometry
|
||||
* @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
|
||||
* VI for capture and runs capture start and capture finish
|
||||
* kthreads for capturing frames to buffer and returns them back.
|
||||
|
@ -52,6 +48,7 @@ enum tegra_vi_pg_mode {
|
|||
* back any queued buffers.
|
||||
*/
|
||||
struct tegra_vi_ops {
|
||||
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
|
||||
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
|
||||
void (*vi_stop_streaming)(struct vb2_queue *vq);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue