diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index d28efd0dbf11..8e0cf03e45eb 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -23,6 +23,7 @@
 #include "meson_registers.h"
 #include "meson_venc.h"
 #include "meson_viu.h"
+#include "meson_rdma.h"
 #include "meson_vpp.h"
 #include "meson_osd_afbcd.h"
 
@@ -39,8 +40,6 @@ struct meson_crtc {
 	void (*enable_osd1_afbc)(struct meson_drm *priv);
 	void (*disable_osd1_afbc)(struct meson_drm *priv);
 	unsigned int viu_offset;
-	bool vsync_forced;
-	bool vsync_disabled;
 };
 #define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
 
@@ -51,7 +50,6 @@ static int meson_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 	struct meson_drm *priv = meson_crtc->priv;
 
-	meson_crtc->vsync_disabled = false;
 	meson_venc_enable_vsync(priv);
 
 	return 0;
@@ -62,10 +60,7 @@ static void meson_crtc_disable_vblank(struct drm_crtc *crtc)
 	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 	struct meson_drm *priv = meson_crtc->priv;
 
-	if (!meson_crtc->vsync_forced) {
-		meson_crtc->vsync_disabled = true;
-		meson_venc_disable_vsync(priv);
-	}
+	meson_venc_disable_vsync(priv);
 }
 
 static const struct drm_crtc_funcs meson_crtc_funcs = {
@@ -368,10 +363,11 @@ void meson_crtc_irq(struct meson_drm *priv)
 		if (meson_crtc->enable_osd1)
 			meson_crtc->enable_osd1(priv);
 
-		if (priv->viu.osd1_afbcd)
-			meson_crtc->vsync_forced = true;
-		else
-			meson_crtc->vsync_forced = false;
+		if (priv->viu.osd1_afbcd) {
+			priv->afbcd.ops->reset(priv);
+			priv->afbcd.ops->setup(priv);
+			priv->afbcd.ops->enable(priv);
+		}
 
 		priv->viu.osd1_commit = false;
 	}
@@ -595,15 +591,6 @@ void meson_crtc_irq(struct meson_drm *priv)
 		priv->viu.vd1_commit = false;
 	}
 
-	if (meson_crtc->vsync_forced && priv->viu.osd1_afbcd) {
-		priv->afbcd.ops->reset(priv);
-		priv->afbcd.ops->setup(priv);
-		priv->afbcd.ops->enable(priv);
-	}
-
-	if (meson_crtc->vsync_disabled)
-		return;
-
 	drm_crtc_handle_vblank(priv->crtc);
 
 	spin_lock_irqsave(&priv->drm->event_lock, flags);
diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.c b/drivers/gpu/drm/meson/meson_osd_afbcd.c
index aae4341bedaf..6d97bb4be3ca 100644
--- a/drivers/gpu/drm/meson/meson_osd_afbcd.c
+++ b/drivers/gpu/drm/meson/meson_osd_afbcd.c
@@ -12,6 +12,7 @@
 #include "meson_drv.h"
 #include "meson_registers.h"
 #include "meson_viu.h"
+#include "meson_rdma.h"
 #include "meson_osd_afbcd.h"
 
 /*
@@ -270,6 +271,14 @@ static bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format)
 
 static int meson_g12a_afbcd_init(struct meson_drm *priv)
 {
+	int ret;
+
+	ret = meson_rdma_init(priv);
+	if (ret)
+		return ret;
+
+	meson_rdma_setup(priv);
+
 	/* Handle AFBC Decoder reset manually */
 	writel_bits_relaxed(MALI_AFBCD_MANUAL_RESET, MALI_AFBCD_MANUAL_RESET,
 			    priv->io_base + _REG(MALI_AFBCD_TOP_CTRL));
@@ -279,27 +288,32 @@ static int meson_g12a_afbcd_init(struct meson_drm *priv)
 
 static int meson_g12a_afbcd_reset(struct meson_drm *priv)
 {
-	writel_relaxed(VIU_SW_RESET_G12A_AFBC_ARB |
-		       VIU_SW_RESET_G12A_OSD1_AFBCD,
-		       priv->io_base + _REG(VIU_SW_RESET));
-	writel_relaxed(0, priv->io_base + _REG(VIU_SW_RESET));
+	meson_rdma_stop(priv);
+
+	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
+			       VIU_SW_RESET_G12A_OSD1_AFBCD,
+			       VIU_SW_RESET);
+	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
 
 	return 0;
 }
 
 static int meson_g12a_afbcd_enable(struct meson_drm *priv)
 {
-	writel_relaxed(VPU_MAFBC_IRQ_SURFACES_COMPLETED |
-		       VPU_MAFBC_IRQ_CONFIGURATION_SWAPPED |
-		       VPU_MAFBC_IRQ_DECODE_ERROR |
-		       VPU_MAFBC_IRQ_DETILING_ERROR,
-		       priv->io_base + _REG(VPU_MAFBC_IRQ_MASK));
+	meson_rdma_writel_sync(priv, VPU_MAFBC_IRQ_SURFACES_COMPLETED |
+			       VPU_MAFBC_IRQ_CONFIGURATION_SWAPPED |
+			       VPU_MAFBC_IRQ_DECODE_ERROR |
+			       VPU_MAFBC_IRQ_DETILING_ERROR,
+			       VPU_MAFBC_IRQ_MASK);
 
-	writel_bits_relaxed(VPU_MAFBC_S0_ENABLE, VPU_MAFBC_S0_ENABLE,
-			    priv->io_base + _REG(VPU_MAFBC_SURFACE_CFG));
+	meson_rdma_writel_sync(priv, VPU_MAFBC_S0_ENABLE,
+			       VPU_MAFBC_SURFACE_CFG);
+
+	meson_rdma_writel_sync(priv, VPU_MAFBC_DIRECT_SWAP,
+			       VPU_MAFBC_COMMAND);
 
-	writel_relaxed(VPU_MAFBC_DIRECT_SWAP,
-		       priv->io_base + _REG(VPU_MAFBC_COMMAND));
+	/* This will enable the RDMA replaying the register writes on vsync */
+	meson_rdma_flush(priv);
 
 	return 0;
 }
@@ -330,36 +344,36 @@ static int meson_g12a_afbcd_setup(struct meson_drm *priv)
 		AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
 		format |= FIELD_PREP(VPU_MAFBC_SUPER_BLOCK_ASPECT, 1);
 
-	writel_relaxed(format,
-		       priv->io_base + _REG(VPU_MAFBC_FORMAT_SPECIFIER_S0));
-
-	writel_relaxed(priv->viu.osd1_addr,
-		       priv->io_base + _REG(VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0));
-	writel_relaxed(0,
-		       priv->io_base + _REG(VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0));
-
-	writel_relaxed(priv->viu.osd1_width,
-		       priv->io_base + _REG(VPU_MAFBC_BUFFER_WIDTH_S0));
-	writel_relaxed(ALIGN(priv->viu.osd1_height, 32),
-		       priv->io_base + _REG(VPU_MAFBC_BUFFER_HEIGHT_S0));
-
-	writel_relaxed(0,
-		       priv->io_base + _REG(VPU_MAFBC_BOUNDING_BOX_X_START_S0));
-	writel_relaxed(priv->viu.osd1_width - 1,
-		       priv->io_base + _REG(VPU_MAFBC_BOUNDING_BOX_X_END_S0));
-	writel_relaxed(0,
-		       priv->io_base + _REG(VPU_MAFBC_BOUNDING_BOX_Y_START_S0));
-	writel_relaxed(priv->viu.osd1_height - 1,
-		       priv->io_base + _REG(VPU_MAFBC_BOUNDING_BOX_Y_END_S0));
-
-	writel_relaxed(MESON_G12A_AFBCD_OUT_ADDR,
-		       priv->io_base + _REG(VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0));
-	writel_relaxed(0,
-		       priv->io_base + _REG(VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0));
-
-	writel_relaxed(priv->viu.osd1_width *
-		       (meson_g12a_afbcd_bpp(priv->afbcd.format) / 8),
-		       priv->io_base + _REG(VPU_MAFBC_OUTPUT_BUF_STRIDE_S0));
+	meson_rdma_writel_sync(priv, format,
+			       VPU_MAFBC_FORMAT_SPECIFIER_S0);
+
+	meson_rdma_writel_sync(priv, priv->viu.osd1_addr,
+			       VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0);
+	meson_rdma_writel_sync(priv, 0,
+			       VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0);
+
+	meson_rdma_writel_sync(priv, priv->viu.osd1_width,
+			       VPU_MAFBC_BUFFER_WIDTH_S0);
+	meson_rdma_writel_sync(priv, ALIGN(priv->viu.osd1_height, 32),
+			       VPU_MAFBC_BUFFER_HEIGHT_S0);
+
+	meson_rdma_writel_sync(priv, 0,
+			       VPU_MAFBC_BOUNDING_BOX_X_START_S0);
+	meson_rdma_writel_sync(priv, priv->viu.osd1_width - 1,
+			       VPU_MAFBC_BOUNDING_BOX_X_END_S0);
+	meson_rdma_writel_sync(priv, 0,
+			       VPU_MAFBC_BOUNDING_BOX_Y_START_S0);
+	meson_rdma_writel_sync(priv, priv->viu.osd1_height - 1,
+			       VPU_MAFBC_BOUNDING_BOX_Y_END_S0);
+
+	meson_rdma_writel_sync(priv, MESON_G12A_AFBCD_OUT_ADDR,
+			       VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0);
+	meson_rdma_writel_sync(priv, 0,
+			       VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0);
+
+	meson_rdma_writel_sync(priv, priv->viu.osd1_width *
+			       (meson_g12a_afbcd_bpp(priv->afbcd.format) / 8),
+			       VPU_MAFBC_OUTPUT_BUF_STRIDE_S0);
 
 	return 0;
 }
