diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index 9bc3c3213724..5bbf86324cda 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -2,6 +2,7 @@
 armada-y	:= armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
 		   armada_gem.o armada_overlay.o armada_plane.o armada_trace.o
 armada-y	+= armada_510.o
+armada-y	+= armada_610.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
 obj-$(CONFIG_DRM_ARMADA) := armada.o
diff --git a/drivers/gpu/drm/armada/armada_610.c b/drivers/gpu/drm/armada/armada_610.c
new file mode 100644
index 000000000000..278b204038ea
--- /dev/null
+++ b/drivers/gpu/drm/armada/armada_610.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 Russell King
+ * Copyright (C) 2018,2019 Lubomir Rintel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Armada MMP2 variant support
+ */
+#include <linux/clk.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_crtc.h>
+#include "armada_crtc.h"
+#include "armada_drm.h"
+#include "armada_hw.h"
+
+static int armada610_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
+{
+	struct clk *clk;
+
+	clk = devm_clk_get(dev, "disp0");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER : PTR_ERR(clk);
+
+	dcrtc->extclk[0] = clk;
+
+	return 0;
+}
+
+/*
+ * This gets called with sclk = NULL to test whether the mode is
+ * supportable, and again with sclk != NULL to set the clocks up for
+ * that.  The former can return an error, but the latter is expected
+ * not to.
+ */
+static int armada610_crtc_compute_clock(struct armada_crtc *dcrtc,
+	const struct drm_display_mode *mode, uint32_t *sclk)
+{
+	struct clk *clk = dcrtc->extclk[0];
+	uint32_t ret, rate, ref, div;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	rate = mode->clock * 1000;
+	ref = clk_get_rate(clk);
+	div = DIV_ROUND_UP(ref, rate);
+
+	if (div < 2)
+		return -EINVAL;
+
+	if (dcrtc->clk != clk) {
+		ret = clk_prepare_enable(clk);
+		if (ret)
+			return ret;
+		dcrtc->clk = clk;
+	}
+
+	if (sclk) {
+		*sclk = 0x00001000; /* No idea */
+		*sclk |= 1 << 8; /* MIPI clock bypass */
+		*sclk |= SCLK_610_DISP0;
+		*sclk |= div;
+	}
+
+	return 0;
+}
+
+static void armada610_crtc_disable(struct armada_crtc *dcrtc)
+{
+	if (!IS_ERR(dcrtc->clk)) {
+		clk_disable_unprepare(dcrtc->clk);
+		dcrtc->clk = ERR_PTR(-EINVAL);
+	}
+}
+
+static void armada610_crtc_enable(struct armada_crtc *dcrtc,
+	const struct drm_display_mode *mode)
+{
+	if (IS_ERR(dcrtc->clk)) {
+		dcrtc->clk = dcrtc->extclk[0];
+		WARN_ON(clk_prepare_enable(dcrtc->clk));
+	}
+}
+
+const struct armada_variant armada610_ops = {
+	.init = armada610_crtc_init,
+	.compute_clock = armada610_crtc_compute_clock,
+	.disable = armada610_crtc_disable,
+	.enable = armada610_crtc_enable,
+};
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index da9360688b55..927be8898eb7 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -884,6 +884,10 @@ static const struct of_device_id armada_lcd_of_match[] = {
 		.compatible	= "marvell,dove-lcd",
 		.data		= &armada510_ops,
 	},
+	{
+		.compatible	= "marvell,mmp2-lcd",
+		.data		= &armada610_ops,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index f09083ff15d3..7cbcf33d0304 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -52,6 +52,7 @@ struct armada_variant {
 
 /* Variant ops */
 extern const struct armada_variant armada510_ops;
+extern const struct armada_variant armada610_ops;
 
 struct armada_private {
 	struct drm_device	drm;
diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h
index 277580b36758..df2ff77b9c07 100644
--- a/drivers/gpu/drm/armada/armada_hw.h
+++ b/drivers/gpu/drm/armada/armada_hw.h
@@ -205,6 +205,16 @@ enum {
 	SCLK_510_FRAC_DIV_MASK	= 0xfff << 16,
 	SCLK_510_INT_DIV_MASK	= 0xffff << 0,
 
+	/* Armada 610 */
+	SCLK_610_AXI		= 0x0 << 30,
+	SCLK_610_DISP0		= 0x1 << 30,	/* LCD Display 1 */
+	SCLK_610_DISP1		= 0x2 << 30,	/* LCD Display 2 */
+	SCLK_610_PLL		= 0x3 << 30,	/* HDMI PLL clock */
+	SCLK_610_PANEL_CLK_DIS	= 0x1 << 28,	/* 1 = panel clock disabled */
+	SCLK_610_FRAC_DIV_MASK	= 0xfff << 16,
+	SCLK_610_MIPI_DIV_MASK	= 0xf << 8,	/* 0 = off, 1 = bypass, ... */
+	SCLK_610_INT_DIV_MASK	= 0xff << 0,
+
 	/* Armada 16x */
 	SCLK_16X_AHB		= 0x0 << 28,
 	SCLK_16X_PCLK		= 0x1 << 28,
