diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_drm_crtc.c')
| -rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 23 | 
1 files changed, 14 insertions, 9 deletions
| diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 8b0de90156c6..40df2c823187 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -61,6 +61,7 @@ struct mtk_drm_crtc {  	/* lock for display hardware access */  	struct mutex			hw_lock; +	bool				config_updating;  };  struct mtk_crtc_state { @@ -97,7 +98,7 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)  static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)  {  	drm_crtc_handle_vblank(&mtk_crtc->base); -	if (mtk_crtc->pending_needs_vblank) { +	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {  		mtk_drm_crtc_finish_page_flip(mtk_crtc);  		mtk_crtc->pending_needs_vblank = false;  	} @@ -425,7 +426,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,  	}  } -static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc) +static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc, +				       bool needs_vblank)  {  #if IS_REACHABLE(CONFIG_MTK_CMDQ)  	struct cmdq_pkt *cmdq_handle; @@ -436,6 +438,10 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)  	int i;  	mutex_lock(&mtk_crtc->hw_lock); +	mtk_crtc->config_updating = true; +	if (needs_vblank) +		mtk_crtc->pending_needs_vblank = true; +  	for (i = 0; i < mtk_crtc->layer_nr; i++) {  		struct drm_plane *plane = &mtk_crtc->planes[i];  		struct mtk_plane_state *plane_state; @@ -472,6 +478,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)  		cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);  	}  #endif +	mtk_crtc->config_updating = false;  	mutex_unlock(&mtk_crtc->hw_lock);  } @@ -522,7 +529,7 @@ int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,  }  void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane, -			       struct drm_plane_state *new_state) +			       struct drm_atomic_state *state)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);  	const struct drm_plane_helper_funcs *plane_helper_funcs = @@ -531,8 +538,8 @@ void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,  	if (!mtk_crtc->enabled)  		return; -	plane_helper_funcs->atomic_update(plane, new_state); -	mtk_drm_crtc_hw_config(mtk_crtc); +	plane_helper_funcs->atomic_update(plane, state); +	mtk_drm_crtc_update_config(mtk_crtc, false);  }  static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, @@ -582,7 +589,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,  	}  	mtk_crtc->pending_planes = true; -	mtk_drm_crtc_hw_config(mtk_crtc); +	mtk_drm_crtc_update_config(mtk_crtc, false);  	/* Wait for planes to be disabled */  	drm_crtc_wait_one_vblank(crtc); @@ -618,14 +625,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);  	int i; -	if (mtk_crtc->event) -		mtk_crtc->pending_needs_vblank = true;  	if (crtc->state->color_mgmt_changed)  		for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {  			mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);  			mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);  		} -	mtk_drm_crtc_hw_config(mtk_crtc); +	mtk_drm_crtc_update_config(mtk_crtc, !!mtk_crtc->event);  }  static const struct drm_crtc_funcs mtk_crtc_funcs = { | 
