staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc op
authorLuca Ceresoli <luca.ceresoli@bootlin.com>
Tue, 18 Apr 2023 08:00:46 +0000 (10:00 +0200)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Thu, 25 May 2023 11:04:47 +0000 (13:04 +0200)
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>
drivers/staging/media/tegra-video/tegra210.c
drivers/staging/media/tegra-video/vi.c
drivers/staging/media/tegra-video/vi.h

index d58370a..d19ff6b 100644 (file)
 #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,
 };
index db0f0e4..2381197 100644 (file)
@@ -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)
index 9959cbe..213955c 100644 (file)
 
 #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);
 };