drm: rcar-du: Implement support for interlaced modes

Accept interlaced modes on the VGA and HDMI connectors and configure the
hardware accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index fb3ea4f..50f2f2b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -104,14 +104,22 @@
 {
 	struct rcar_du_group *rgrp = plane->group;
 	unsigned int index = plane->hwindex;
+	bool interlaced;
 	u32 mwr;
 
-	/* Memory pitch (expressed in pixels) */
+	interlaced = plane->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE;
+
+	/* Memory pitch (expressed in pixels). Must be doubled for interlaced
+	 * operation with 32bpp formats.
+	 */
 	if (plane->format->planes == 2)
 		mwr = plane->pitch;
 	else
 		mwr = plane->pitch * 8 / plane->format->bpp;
 
+	if (interlaced && plane->format->bpp == 32)
+		mwr *= 2;
+
 	rcar_du_plane_write(rgrp, index, PnMWR, mwr);
 
 	/* The Y position is expressed in raster line units and must be doubled
@@ -119,12 +127,16 @@
 	 * doubling the Y position is found in the R8A7779 datasheet, but the
 	 * rule seems to apply there as well.
 	 *
+	 * Despite not being documented, doubling seem not to be needed when
+	 * operating in interlaced mode.
+	 *
 	 * Similarly, for the second plane, NV12 and NV21 formats seem to
-	 * require a halved Y position value.
+	 * require a halved Y position value, in both progressive and interlaced
+	 * modes.
 	 */
 	rcar_du_plane_write(rgrp, index, PnSPXR, plane->src_x);
 	rcar_du_plane_write(rgrp, index, PnSPYR, plane->src_y *
-			    (plane->format->bpp == 32 ? 2 : 1));
+			    (!interlaced && plane->format->bpp == 32 ? 2 : 1));
 	rcar_du_plane_write(rgrp, index, PnDSA0R, plane->dma[0]);
 
 	if (plane->format->planes == 2) {