VI in Tegra20/Tegra30 has 2 VI outputs with different set of supported
formats. Convert output registers to macros for simpler work with both
outputs since apart formats their layout matches.

Signed-off-by: Svyatoslav Ryhel <clamo...@gmail.com>
---
 drivers/staging/media/tegra-video/tegra20.c | 80 ++++++++++++---------
 1 file changed, 45 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra20.c 
b/drivers/staging/media/tegra-video/tegra20.c
index 3e2d746638b6..54512d1ecf83 100644
--- a/drivers/staging/media/tegra-video/tegra20.c
+++ b/drivers/staging/media/tegra-video/tegra20.c
@@ -28,13 +28,19 @@
 #define TEGRA20_MIN_HEIGHT     32U
 #define TEGRA20_MAX_HEIGHT     8190U
 
+/* Tegra20/Tegra30 has 2 outputs in VI */
+enum {
+       OUT_1,
+       OUT_2,
+};
+
 /* --------------------------------------------------------------------------
  * Registers
  */
 
-#define TEGRA_VI_CONT_SYNCPT_OUT_1                     0x0060
-#define       VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT   BIT(8)
-#define       VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT      0
+#define TEGRA_VI_CONT_SYNCPT_OUT(n)                    (0x0060 + (n) * 4)
+#define       VI_CONT_SYNCPT_OUT_CONTINUOUS_SYNCPT     BIT(8)
+#define       VI_CONT_SYNCPT_OUT_SYNCPT_IDX_SFT                0
 
 #define TEGRA_VI_VI_INPUT_CONTROL                      0x0088
 #define       VI_INPUT_FIELD_DETECT                    BIT(27)
@@ -46,6 +52,7 @@
 #define       VI_INPUT_YUV_INPUT_FORMAT_YVYU           (3 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
 #define       VI_INPUT_INPUT_FORMAT_SFT                        2  /* bits 
[5:2] */
 #define       VI_INPUT_INPUT_FORMAT_YUV422             (0 << 
VI_INPUT_INPUT_FORMAT_SFT)
+#define       VI_INPUT_INPUT_FORMAT_BAYER              (2 << 
VI_INPUT_INPUT_FORMAT_SFT)
 #define       VI_INPUT_VIP_INPUT_ENABLE                        BIT(1)
 
 #define TEGRA_VI_VI_CORE_CONTROL                       0x008c
@@ -66,7 +73,7 @@
 #define       VI_VI_CORE_CONTROL_OUTPUT_TO_EPP_SFT     2
 #define       VI_VI_CORE_CONTROL_OUTPUT_TO_ISP_SFT     0
 
-#define TEGRA_VI_VI_FIRST_OUTPUT_CONTROL               0x0090
+#define TEGRA_VI_VI_OUTPUT_CONTROL(n)                  (0x0090 + (n) * 4)
 #define       VI_OUTPUT_FORMAT_EXT                     BIT(22)
 #define       VI_OUTPUT_V_DIRECTION                    BIT(20)
 #define       VI_OUTPUT_H_DIRECTION                    BIT(19)
@@ -80,6 +87,7 @@
 #define       VI_OUTPUT_OUTPUT_FORMAT_SFT              0
 #define       VI_OUTPUT_OUTPUT_FORMAT_YUV422POST       (3 << 
VI_OUTPUT_OUTPUT_FORMAT_SFT)
 #define       VI_OUTPUT_OUTPUT_FORMAT_YUV420PLANAR     (6 << 
VI_OUTPUT_OUTPUT_FORMAT_SFT)
+#define       VI_OUTPUT_OUTPUT_FORMAT_VIP_BAYER_DIRECT (9 << 
VI_OUTPUT_OUTPUT_FORMAT_SFT)
 
 #define TEGRA_VI_VIP_H_ACTIVE                          0x00a4
 #define       VI_VIP_H_ACTIVE_PERIOD_SFT               16 /* active 
pixels/line, must be even */
@@ -89,26 +97,26 @@
 #define       VI_VIP_V_ACTIVE_PERIOD_SFT               16 /* active lines */
 #define       VI_VIP_V_ACTIVE_START_SFT                        0
 
-#define TEGRA_VI_VB0_START_ADDRESS_FIRST               0x00c4
-#define TEGRA_VI_VB0_BASE_ADDRESS_FIRST                        0x00c8
+#define TEGRA_VI_VB0_START_ADDRESS(n)                  (0x00c4 + (n) * 44)
+#define TEGRA_VI_VB0_BASE_ADDRESS(n)                   (0x00c8 + (n) * 44)
 #define TEGRA_VI_VB0_START_ADDRESS_U                   0x00cc
 #define TEGRA_VI_VB0_BASE_ADDRESS_U                    0x00d0
 #define TEGRA_VI_VB0_START_ADDRESS_V                   0x00d4
 #define TEGRA_VI_VB0_BASE_ADDRESS_V                    0x00d8
 
-#define TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE               0x00e0
-#define       VI_FIRST_OUTPUT_FRAME_HEIGHT_SFT         16
-#define       VI_FIRST_OUTPUT_FRAME_WIDTH_SFT          0
+#define TEGRA_VI_OUTPUT_FRAME_SIZE(n)                  (0x00e0 + (n) * 24)
+#define       VI_OUTPUT_FRAME_HEIGHT_SFT               16
+#define       VI_OUTPUT_FRAME_WIDTH_SFT                        0
 
-#define TEGRA_VI_VB0_COUNT_FIRST                       0x00e4
+#define TEGRA_VI_VB0_COUNT(n)                          (0x00e4 + (n) * 24)
 
-#define TEGRA_VI_VB0_SIZE_FIRST                                0x00e8
-#define       VI_VB0_SIZE_FIRST_V_SFT                  16
-#define       VI_VB0_SIZE_FIRST_H_SFT                  0
+#define TEGRA_VI_VB0_SIZE(n)                           (0x00e8 + (n) * 24)
+#define       VI_VB0_SIZE_V_SFT                                16
+#define       VI_VB0_SIZE_H_SFT                                0
 
-#define TEGRA_VI_VB0_BUFFER_STRIDE_FIRST               0x00ec
-#define       VI_VB0_BUFFER_STRIDE_FIRST_CHROMA_SFT    30
-#define       VI_VB0_BUFFER_STRIDE_FIRST_LUMA_SFT      0
+#define TEGRA_VI_VB0_BUFFER_STRIDE(n)                  (0x00ec + (n) * 24)
+#define       VI_VB0_BUFFER_STRIDE_CHROMA_SFT          30
+#define       VI_VB0_BUFFER_STRIDE_LUMA_SFT            0
 
 #define TEGRA_VI_H_LPF_CONTROL                         0x0108
 #define       VI_H_LPF_CONTROL_CHROMA_SFT              16
@@ -136,7 +144,7 @@
 #define       VI_CAMERA_CONTROL_TEST_MODE              BIT(1)
 #define       VI_CAMERA_CONTROL_VIP_ENABLE             BIT(0)
 
-#define TEGRA_VI_VI_ENABLE                             0x01a4
+#define TEGRA_VI_VI_ENABLE(n)                          (0x01a4 + (n) * 4)
 #define       VI_VI_ENABLE_SW_FLOW_CONTROL_OUT1                BIT(1)
 #define       VI_VI_ENABLE_FIRST_OUTPUT_TO_MEM_DISABLE BIT(0)
 
@@ -366,8 +374,8 @@ static void tegra20_channel_vi_buffer_setup(struct 
tegra_vi_channel *chan,
        case V4L2_PIX_FMT_VYUY:
        case V4L2_PIX_FMT_YUYV:
        case V4L2_PIX_FMT_YVYU:
-               tegra20_vi_write(chan, TEGRA_VI_VB0_BASE_ADDRESS_FIRST,  base);
-               tegra20_vi_write(chan, TEGRA_VI_VB0_START_ADDRESS_FIRST, base + 
chan->start_offset);
+               tegra20_vi_write(chan, TEGRA_VI_VB0_BASE_ADDRESS(OUT_1),  base);
+               tegra20_vi_write(chan, TEGRA_VI_VB0_START_ADDRESS(OUT_1), base 
+ chan->start_offset);
                break;
        }
 }
@@ -455,6 +463,7 @@ static void tegra20_camera_capture_setup(struct 
tegra_vi_channel *chan)
        int stride_l = chan->format.bytesperline;
        int stride_c = (output_fourcc == V4L2_PIX_FMT_YUV420 ||
                        output_fourcc == V4L2_PIX_FMT_YVU420) ? 1 : 0;
+       int output_channel = OUT_1;
        int main_output_format;
        int yuv_output_format;
 
@@ -472,33 +481,33 @@ static void tegra20_camera_capture_setup(struct 
tegra_vi_channel *chan)
        /* Set up raise-on-edge, so we get an interrupt on end of frame. */
        tegra20_vi_write(chan, TEGRA_VI_VI_RAISE, VI_VI_RAISE_ON_EDGE);
 
-       tegra20_vi_write(chan, TEGRA_VI_VI_FIRST_OUTPUT_CONTROL,
+       tegra20_vi_write(chan, TEGRA_VI_VI_OUTPUT_CONTROL(output_channel),
                         (chan->vflip ? VI_OUTPUT_V_DIRECTION : 0) |
                         (chan->hflip ? VI_OUTPUT_H_DIRECTION : 0) |
                         yuv_output_format << VI_OUTPUT_YUV_OUTPUT_FORMAT_SFT |
                         main_output_format << VI_OUTPUT_OUTPUT_FORMAT_SFT);
 
        /* Set up frame size */
-       tegra20_vi_write(chan, TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE,
-                        height << VI_FIRST_OUTPUT_FRAME_HEIGHT_SFT |
-                        width  << VI_FIRST_OUTPUT_FRAME_WIDTH_SFT);
+       tegra20_vi_write(chan, TEGRA_VI_OUTPUT_FRAME_SIZE(output_channel),
+                        height << VI_OUTPUT_FRAME_HEIGHT_SFT |
+                        width  << VI_OUTPUT_FRAME_WIDTH_SFT);
 
        /* First output memory enabled */
-       tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE, 0);
+       tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE(output_channel), 0);
 
        /* Set the number of frames in the buffer */
-       tegra20_vi_write(chan, TEGRA_VI_VB0_COUNT_FIRST, 1);
+       tegra20_vi_write(chan, TEGRA_VI_VB0_COUNT(output_channel), 1);
 
        /* Set up buffer frame size */
-       tegra20_vi_write(chan, TEGRA_VI_VB0_SIZE_FIRST,
-                        height << VI_VB0_SIZE_FIRST_V_SFT |
-                        width  << VI_VB0_SIZE_FIRST_H_SFT);
+       tegra20_vi_write(chan, TEGRA_VI_VB0_SIZE(output_channel),
+                        height << VI_VB0_SIZE_V_SFT |
+                        width  << VI_VB0_SIZE_H_SFT);
 
-       tegra20_vi_write(chan, TEGRA_VI_VB0_BUFFER_STRIDE_FIRST,
-                        stride_l << VI_VB0_BUFFER_STRIDE_FIRST_LUMA_SFT |
-                        stride_c << VI_VB0_BUFFER_STRIDE_FIRST_CHROMA_SFT);
+       tegra20_vi_write(chan, TEGRA_VI_VB0_BUFFER_STRIDE(output_channel),
+                        stride_l << VI_VB0_BUFFER_STRIDE_LUMA_SFT |
+                        stride_c << VI_VB0_BUFFER_STRIDE_CHROMA_SFT);
 
-       tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE, 0);
+       tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE(output_channel), 0);
 }
 
 static int tegra20_vi_start_streaming(struct vb2_queue *vq, u32 count)
@@ -607,6 +616,7 @@ static int tegra20_vip_start_streaming(struct 
tegra_vip_channel *vip_chan)
        struct tegra_vi_channel *vi_chan = 
v4l2_get_subdev_hostdata(&vip_chan->subdev);
        int width  = vi_chan->format.width;
        int height = vi_chan->format.height;
+       int output_channel = OUT_1;
 
        unsigned int main_input_format;
        unsigned int yuv_input_format;
@@ -637,10 +647,10 @@ static int tegra20_vip_start_streaming(struct 
tegra_vip_channel *vip_chan)
                         GENMASK(9, 2) << VI_DATA_INPUT_SFT);
        tegra20_vi_write(vi_chan, TEGRA_VI_PIN_INVERSION, 0);
 
-       tegra20_vi_write(vi_chan, TEGRA_VI_CONT_SYNCPT_OUT_1,
-                        VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT |
+       tegra20_vi_write(vi_chan, TEGRA_VI_CONT_SYNCPT_OUT(output_channel),
+                        VI_CONT_SYNCPT_OUT_CONTINUOUS_SYNCPT |
                         host1x_syncpt_id(vi_chan->mw_ack_sp[0])
-                        << VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT);
+                        << VI_CONT_SYNCPT_OUT_SYNCPT_IDX_SFT);
 
        tegra20_vi_write(vi_chan, TEGRA_VI_CAMERA_CONTROL, 
VI_CAMERA_CONTROL_STOP_CAPTURE);
 
-- 
2.48.1

Reply via email to