From 29eeb1960456fe334ffaba1174771907254d491c Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Mon, 11 Mar 2024 10:21:56 +0800 Subject: [PATCH] drm/rockchip: vop2: fix iommu pagefault when commit close to fs At vop2_wait_for_irq_handler() we need to synchronize frame start irq, This is to avoid the ongoing commit very close to fs, and might be racing with a requested vblank interrupt, which would increment the software vblank counter before the changes being committed actually happen. besides, from rk3576 vop can support independent irq for each vp, we confirm vop2->merge_irq state at vop2_bind, and simplification other function logic. Signed-off-by: Sandy Huang Change-Id: If93d8de7840590645c53bd3720eaca2f818a3cbe --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index c343c03addc0..fa18ebc1851f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1419,7 +1419,10 @@ static void vop2_wait_for_irq_handler(struct drm_crtc *crtc) if (ret) DRM_DEV_ERROR(vop2->dev, "VOP vblank IRQ stuck for 10 ms\n"); - synchronize_irq(vop2->irq); + if (vop2->merge_irq) + synchronize_irq(vop2->irq); + else + synchronize_irq(vp->irq); } static bool vop2_vp_done_bit_status(struct vop2_video_port *vp) @@ -4178,7 +4181,7 @@ static void vop2_initial(struct drm_crtc *crtc) vop2_writel(vop2, 0xda4, 0x01000100); vop2_writel(vop2, 0xda8, 0x03ff0100); - if (vop2->version == VOP_VERSION_RK3576 && vop2->merge_irq == true) + if (vop2->merge_irq == true) VOP_CTRL_SET(vop2, vp_intr_merge_en, 1); VOP_CTRL_SET(vop2, lut_use_axi1, 0); } @@ -13384,7 +13387,11 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) vop2->disable_afbc_win = of_property_read_bool(dev->of_node, "disable-afbc-win"); vop2->disable_win_move = of_property_read_bool(dev->of_node, "disable-win-move"); vop2->skip_ref_fb = of_property_read_bool(dev->of_node, "skip-ref-fb"); - vop2->merge_irq = of_property_read_bool(dev->of_node, "rockchip,vop-merge-irq"); + if (!is_vop3(vop2) || + vop2->version == VOP_VERSION_RK3528 || vop2->version == VOP_VERSION_RK3562) + vop2->merge_irq = true; + else + vop2->merge_irq = of_property_read_bool(dev->of_node, "rockchip,vop-merge-irq"); ret = vop2_pd_data_init(vop2); if (ret) @@ -13562,7 +13569,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) INIT_WORK(&vop2->post_buf_empty_work, post_buf_empty_work_event); } - if (vop2->version == VOP_VERSION_RK3576 && vop2->merge_irq == false) + if (vop2->merge_irq == false) ret = devm_request_irq(dev, vop2->irq, vop3_sys_isr, IRQF_SHARED, dev_name(dev), vop2); else ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2); @@ -13575,7 +13582,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) if (registered_num_crtcs <= 0) return -ENODEV; - if (vop2->version == VOP_VERSION_RK3576 && vop2->merge_irq == false) { + if (vop2->merge_irq == false) { struct drm_crtc *crtc; char irq_name[12];