diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 2031c8c5e70b4a8961a004c52b80a7e35715ddd2..b2df8f0cc614be1728d457d913425260500f6b2e 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; @@ -12778,6 +12780,7 @@ 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); + 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 +14476,14 @@ 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)) + 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"); + } + ret = of_clk_set_defaults(child, false); if (ret) { DRM_DEV_ERROR(dev, "Failed to set clock defaults %d\n", ret);