#define VNELPRC_REG    0x10    /* Video n End Line Pre-Clip Register */
 #define VNSPPRC_REG    0x14    /* Video n Start Pixel Pre-Clip Register */
 #define VNEPPRC_REG    0x18    /* Video n End Pixel Pre-Clip Register */
-#define VNSLPOC_REG    0x1C    /* Video n Start Line Post-Clip Register */
-#define VNELPOC_REG    0x20    /* Video n End Line Post-Clip Register */
-#define VNSPPOC_REG    0x24    /* Video n Start Pixel Post-Clip Register */
-#define VNEPPOC_REG    0x28    /* Video n End Pixel Post-Clip Register */
 #define VNIS_REG       0x2C    /* Video n Image Stride Register */
 #define VNMB_REG(m)    (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
 #define VNIE_REG       0x40    /* Video n Interrupt Enable Register */
 #define VNINTS_REG     0x44    /* Video n Interrupt Status Register */
 #define VNSI_REG       0x48    /* Video n Scanline Interrupt Register */
 #define VNMTC_REG      0x4C    /* Video n Memory Transfer Control Register */
-#define VNYS_REG       0x50    /* Video n Y Scale Register */
-#define VNXS_REG       0x54    /* Video n X Scale Register */
 #define VNDMR_REG      0x58    /* Video n Data Mode Register */
 #define VNDMR2_REG     0x5C    /* Video n Data Mode Register 2 */
 #define VNUVAOF_REG    0x60    /* Video n UV Address Offset Register */
+
+/* Register offsets specific for Gen2 */
+#define VNSLPOC_REG    0x1C    /* Video n Start Line Post-Clip Register */
+#define VNELPOC_REG    0x20    /* Video n End Line Post-Clip Register */
+#define VNSPPOC_REG    0x24    /* Video n Start Pixel Post-Clip Register */
+#define VNEPPOC_REG    0x28    /* Video n End Pixel Post-Clip Register */
+#define VNYS_REG       0x50    /* Video n Y Scale Register */
+#define VNXS_REG       0x54    /* Video n X Scale Register */
 #define VNC1A_REG      0x80    /* Video n Coefficient Set C1A Register */
 #define VNC1B_REG      0x84    /* Video n Coefficient Set C1B Register */
 #define VNC1C_REG      0x88    /* Video n Coefficient Set C1C Register */
 #define VNC8B_REG      0xF4    /* Video n Coefficient Set C8B Register */
 #define VNC8C_REG      0xF8    /* Video n Coefficient Set C8C Register */
 
+/* Register offsets specific for Gen3 */
+#define VNCSI_IFMD_REG         0x20 /* Video n CSI2 Interface Mode Register */
 
 /* Register bit fields for R-Car VIN */
 /* Video n Main Control Register bits */
+#define VNMC_DPINE             (1 << 27) /* Gen3 specific */
+#define VNMC_SCLE              (1 << 26) /* Gen3 specific */
 #define VNMC_FOC               (1 << 21)
 #define VNMC_YCAL              (1 << 19)
 #define VNMC_INF_YUV8_BT656    (0 << 16)
 #define VNDMR2_FTEV            (1 << 17)
 #define VNDMR2_VLV(n)          ((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES1                (1 << 26)
+#define VNCSI_IFMD_DES0                (1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 struct rvin_buffer {
        struct vb2_v4l2_buffer vb;
        struct list_head list;
        rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
        u32 xs, ys;
 
-       /* Set Start/End Pixel/Line Pre-Clip */
-       rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-       rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-       switch (vin->format.field) {
-       case V4L2_FIELD_INTERLACED:
-       case V4L2_FIELD_INTERLACED_TB:
-       case V4L2_FIELD_INTERLACED_BT:
-               rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-               rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-                          VNELPRC_REG);
-               break;
-       default:
-               rvin_write(vin, vin->crop.top, VNSLPRC_REG);
-               rvin_write(vin, vin->crop.top + vin->crop.height - 1,
-                          VNELPRC_REG);
-               break;
-       }
-
        /* Set scaling coefficient */
        ys = 0;
        if (vin->crop.height != vin->compose.height)
                break;
        }
 
-       if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
-               rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
-       else
-               rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
-
        vin_dbg(vin,
                "Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n",
                vin->crop.width, vin->crop.height, vin->crop.left,
                0, 0);
 }
 
+void rvin_crop_scale_comp(struct rvin_dev *vin)
+{
+       /* Set Start/End Pixel/Line Pre-Clip */
+       rvin_write(vin, vin->crop.left, VNSPPRC_REG);
+       rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
+
+       switch (vin->format.field) {
+       case V4L2_FIELD_INTERLACED:
+       case V4L2_FIELD_INTERLACED_TB:
+       case V4L2_FIELD_INTERLACED_BT:
+               rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
+               rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
+                          VNELPRC_REG);
+               break;
+       default:
+               rvin_write(vin, vin->crop.top, VNSLPRC_REG);
+               rvin_write(vin, vin->crop.top + vin->crop.height - 1,
+                          VNELPRC_REG);
+               break;
+       }
+
+       /* TODO: Add support for the UDS scaler. */
+       if (vin->info->model != RCAR_GEN3)
+               rvin_crop_scale_comp_gen2(vin);
+
+       if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
+               rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
+       else
+               rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
+}
+
 /* -----------------------------------------------------------------------------
  * Hardware setup
  */
        }
 
        /* Enable VSYNC Field Toogle mode after one VSYNC input */
-       dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
+       if (vin->info->model == RCAR_GEN3)
+               dmr2 = VNDMR2_FTEV;
+       else
+               dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
 
        /* Hsync Signal Polarity Select */
        if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
        if (input_is_yuv == output_is_yuv)
                vnmc |= VNMC_BPS;
 
+       if (vin->info->model == RCAR_GEN3) {
+               /* Select between CSI-2 and Digital input */
+               if (vin->mbus_cfg.type == V4L2_MBUS_CSI2)
+                       vnmc &= ~VNMC_DPINE;
+               else
+                       vnmc |= VNMC_DPINE;
+       }
+
        /* Progressive or interlaced mode */
        interrupts = progressive ? VNIE_FIE : VNIE_EFE;