Re: [v1,1/2] drm/mediatek: Fixup external display black screen issue
From: Hsin-Yi Wang
Date: Thu Dec 05 2019 - 01:16:29 EST
On Wed, Nov 27, 2019 at 1:17 AM <yongqiang.niu@xxxxxxxxxxxx> wrote:
>
> From: Yongqiang Niu <yongqiang.niu@xxxxxxxxxxxx>
>
> Problem:
> overlay hangup when external display hotplut test
>
> Fix:
> disable overlay when crtc disable
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu@xxxxxxxxxxxx>
> ---
> 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 ]---
>