From 433e5da577f2e9325444ef96c9763a71f025811f Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Fri, 2 Dec 2016 11:27:13 +0800 Subject: [PATCH] drm/rockchip: vop: fix display logo flash with line flag Use standy with dsp_hold intr would effect display timing, Some display controller can't not allow this, such as edp, edp panel would flash with it. Use line flag instead it seems good. Change-Id: Iecf818c0dbd5a7833e6cec0da60fe3e693b3dc9d Signed-off-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 56 +++++++++++++++------ 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index a80deb50d27d..4a16d310aac1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -305,6 +306,16 @@ static bool vop_is_cfg_done_complete(struct vop *vop) return VOP_CTRL_GET(vop, cfg_done) ? false : true; } +static bool vop_fs_irq_is_active(struct vop *vop) +{ + return VOP_INTR_GET_TYPE(vop, status, FS_INTR); +} + +static bool vop_line_flag_is_active(struct vop *vop) +{ + return VOP_INTR_GET_TYPE(vop, status, LINE_FLAG_INTR); +} + static bool has_rb_swapped(uint32_t format) { switch (format) { @@ -1612,7 +1623,6 @@ static void vop_cfg_update(struct drm_crtc *crtc, VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en); VOP_CTRL_SET(vop, dsp_layer_sel, s->dsp_layer_sel); - vop_cfg_done(vop); spin_unlock(&vop->reg_lock); } @@ -1622,32 +1632,50 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, { struct vop *vop = to_vop(crtc); + vop_cfg_update(crtc, old_crtc_state); + if (!vop->is_iommu_enabled && vop->is_iommu_needed) { + bool need_wait_vblank = !vop_is_allwin_disabled(vop); int ret; - if (!vop_is_allwin_disabled(vop)) { - reinit_completion(&vop->dsp_hold_completion); - vop_dsp_hold_valid_irq_enable(vop); - vop_cfg_update(crtc, old_crtc_state); - spin_lock(&vop->reg_lock); + if (need_wait_vblank) { + bool active; + + disable_irq(vop->irq); + drm_crtc_vblank_get(crtc); + VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); - VOP_CTRL_SET(vop, standby, 1); + ret = readx_poll_timeout_atomic(vop_fs_irq_is_active, + vop, active, active, + 0, 50 * 1000); + if (ret) + dev_err(vop->dev, "wait fs irq timeout\n"); - spin_unlock(&vop->reg_lock); + VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1); + vop_cfg_done(vop); - wait_for_completion(&vop->dsp_hold_completion); + ret = readx_poll_timeout_atomic(vop_line_flag_is_active, + vop, active, active, + 0, 50 * 1000); + if (ret) + dev_err(vop->dev, "wait line flag timeout\n"); - vop_dsp_hold_valid_irq_disable(vop); + enable_irq(vop->irq); } ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev); - if (ret) { - dev_err(vop->dev, "failed to attach dma mapping, %d\n", ret); + if (ret) + dev_err(vop->dev, "failed to attach dma mapping, %d\n", + ret); + + if (need_wait_vblank) { + VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0); + drm_crtc_vblank_put(crtc); } - VOP_CTRL_SET(vop, standby, 0); + vop->is_iommu_enabled = true; } - vop_cfg_update(crtc, old_crtc_state); + vop_cfg_done(vop); } static void vop_crtc_atomic_begin(struct drm_crtc *crtc, -- 2.34.1