On Wed, Nov 27, 2019 at 1:17 AM yongqiang.niu@mediatek.com wrote:
From: Yongqiang Niu yongqiang.niu@mediatek.com
Problem: overlay hangup when external display hotplut test
Fix: disable overlay when crtc disable
Signed-off-by: Yongqiang Niu yongqiang.niu@mediatek.com
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 39 +++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-)
-- 1.8.1.1.dirty
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 4fb346c..7eca02f 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -369,6 +369,20 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) mtk_disp_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id); mtk_disp_mutex_enable(mtk_crtc->mutex);
/* Initially configure all planes */
for (i = 0; i < mtk_crtc->layer_nr; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state;
struct mtk_ddp_comp *comp;
unsigned int local_layer;
plane_state = to_mtk_plane_state(plane->state);
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state, NULL);
}
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i]; enum mtk_ddp_comp_id prev;
@@ -385,20 +399,6 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) mtk_ddp_comp_start(comp); }
/* Initially configure all planes */
for (i = 0; i < mtk_crtc->layer_nr; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state;
struct mtk_ddp_comp *comp;
unsigned int local_layer;
plane_state = to_mtk_plane_state(plane->state);
comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
if (comp)
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state, NULL);
}
return 0;
err_mutex_unprepare: @@ -607,10 +607,21 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, for (i = 0; i < mtk_crtc->layer_nr; i++) { struct drm_plane *plane = &mtk_crtc->planes[i]; struct mtk_plane_state *plane_state;
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp);
unsigned int local_layer; plane_state = to_mtk_plane_state(plane->state); plane_state->pending.enable = false; plane_state->pending.config = true;
if (i >= comp_layer_nr) {
comp = mtk_crtc->ddp_comp[1];
local_layer = i - comp_layer_nr;
} else
local_layer = i;
mtk_ddp_comp_layer_config(comp, local_layer,
plane_state, NULL);
This part should be moved to mtk_crtc_ddp_hw_fini(), or at least called after drm_crtc_vblank_off(). Otherwise we would see drm_wait_one_vblank warnings on 8173 when display turns off.
[ 25.696182] Call trace: [ 25.698624] drm_wait_one_vblank+0x1f0/0x1fc [ 25.702886] drm_crtc_wait_one_vblank+0x20/0x2c [ 25.707415] mtk_drm_crtc_atomic_disable+0xf0/0x308 [ 25.712287] drm_atomic_helper_commit_modeset_disables+0x1b8/0x3c0 [ 25.718461] mtk_atomic_complete+0x88/0x16c [ 25.722638] mtk_atomic_commit+0xa8/0xb0 [ 25.726553] drm_atomic_commit+0x50/0x5c [ 25.730469] drm_atomic_helper_set_config+0x98/0xa0 [ 25.735341] drm_mode_setcrtc+0x280/0x608 [ 25.739344] drm_ioctl_kernel+0xcc/0x10c [ 25.743261] drm_ioctl+0x240/0x3c0 [ 25.746658] drm_compat_ioctl+0xd8/0xe8 [ 25.750487] __se_compat_sys_ioctl+0x100/0x26fc [ 25.755009] __arm64_compat_sys_ioctl+0x20/0x2c [ 25.759534] el0_svc_common+0xa4/0x154 [ 25.763277] el0_svc_compat_handler+0x2c/0x38 [ 25.767628] el0_svc_compat+0x8/0x18 [ 25.771195] ---[ end trace f4619fdac8f1c0ff ]---