diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2031c8c5e70b4a8961a004c52b80a7e35715ddd2..7f1016c326418802492872a43c8a2c6f89e8349c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,6 +33,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/iopoll.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
@@ -580,6 +581,7 @@ struct vop2_video_port {
 	bool need_reset_p2i_flag;
 	atomic_t post_buf_empty_flag;
 	const struct vop2_video_port_regs *regs;
+	struct gpio_desc *vsync_gpio;
 
 	struct completion dsp_hold_completion;
 	struct completion line_flag_completion;
@@ -6717,6 +6719,8 @@ static int vop2_crtc_enable_vblank(struct drm_crtc *crtc)
 	if (WARN_ON(!vop2->is_enabled))
 		return -EPERM;
 
+	dev_info(vop2->dev, "enable vblank events\n");
+
 	spin_lock_irqsave(&vop2->irq_lock, flags);
 
 	VOP_INTR_SET_TYPE(vop2, intr, clear, FS_FIELD_INTR, 1);
@@ -6739,6 +6743,8 @@ static void vop2_crtc_disable_vblank(struct drm_crtc *crtc)
 	if (WARN_ON(!vop2->is_enabled))
 		return;
 
+	dev_info(vop2->dev, "disable vblank events\n");
+
 	spin_lock_irqsave(&vop2->irq_lock, flags);
 
 	VOP_INTR_SET_TYPE(vop2, intr, enable, FS_FIELD_INTR, 0);
@@ -12619,7 +12625,8 @@ static irqreturn_t vop2_isr(int irq, void *data)
 		}
 
 		if (active_irqs & FS_FIELD_INTR) {
-			rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d\n", vp->id);
+			rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d with GPIO %p\n", vp->id, vp->vsync_gpio);
+			gpiod_set_value(vp->vsync_gpio, !gpiod_get_value(vp->vsync_gpio));
 			vop2_wb_handler(vp);
 			if (likely(!vp->skip_vsync) || (vp->layer_sel_update == false)) {
 				drm_crtc_handle_vblank(crtc);
@@ -12777,7 +12784,8 @@ static irqreturn_t vop3_vp_isr(int irq, void *data)
 	}
 
 	if (active_irqs & FS_FIELD_INTR) {
-		rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d\n", vp->id);
+		rockchip_drm_dbg(vop2->dev, VOP_DEBUG_VSYNC, "vsync_vp%d with GPIO %p\n", vp->id, vp->vsync_gpio);
+		gpiod_set_value(vp->vsync_gpio, !gpiod_get_value(vp->vsync_gpio));
 		vop2_wb_handler(vp);
 		drm_crtc_handle_vblank(crtc);
 		vop2_handle_vblank(vop2, crtc);
@@ -14473,6 +14481,16 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
 
 			vop2->vps[vp_id].xmirror_en = of_property_read_bool(child, "xmirror-enable");
 
+			vop2->vps[vp_id].vsync_gpio = devm_fwnode_gpiod_get(dev, of_node_to_fwnode(child), "vsync-notify", GPIOD_OUT_LOW, fwnode_get_name(of_node_to_fwnode(child)));
+			if (IS_ERR(vop2->vps[vp_id].vsync_gpio)) {
+				if (PTR_ERR(vop2->vps[vp_id].vsync_gpio)) {
+					dev_err(dev, "No vsync-notify gpio for vp%d\n", vp_id);
+					vop2->vps[vp_id].vsync_gpio = NULL;
+				} else {
+					return dev_err_probe(dev, PTR_ERR(vop2->vps[vp_id].vsync_gpio), "failed to get vsync notify GPIO for vp%d", vp_id);
+				}
+			}
+
 			ret = of_clk_set_defaults(child, false);
 			if (ret) {
 				DRM_DEV_ERROR(dev, "Failed to set clock defaults %d\n", ret);