diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c')
| -rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 81 | 
1 files changed, 36 insertions, 45 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 758261e8ac73..1dc5dbe58572 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -12,6 +12,7 @@  #include <linux/kthread.h>  #include <linux/seq_file.h> +#include <drm/drm_atomic.h>  #include <drm/drm_crtc.h>  #include <drm/drm_file.h>  #include <drm/drm_probe_helper.h> @@ -544,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)  static struct msm_display_topology dpu_encoder_get_topology(  			struct dpu_encoder_virt *dpu_enc,  			struct dpu_kms *dpu_kms, -			struct drm_display_mode *mode) +			struct drm_display_mode *mode, +			struct drm_crtc_state *crtc_state)  {  	struct msm_display_topology topology = {0};  	int i, intf_count = 0; @@ -562,8 +564,7 @@ static struct msm_display_topology dpu_encoder_get_topology(  	 * 1 LM, 1 INTF  	 * 2 LM, 1 INTF (stream merge to support high resolution interfaces)  	 * -	 * Adding color blocks only to primary interface if available in -	 * sufficient number +	 * Add dspps to the reservation requirements if ctm is requested  	 */  	if (intf_count == 2)  		topology.num_lm = 2; @@ -572,11 +573,8 @@ static struct msm_display_topology dpu_encoder_get_topology(  	else  		topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; -	if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { -		if (dpu_kms->catalog->dspp && -			(dpu_kms->catalog->dspp_count >= topology.num_lm)) -			topology.num_dspp = topology.num_lm; -	} +	if (crtc_state->ctm) +		topology.num_dspp = topology.num_lm;  	topology.num_intf = intf_count; @@ -637,25 +635,22 @@ static int dpu_encoder_virt_atomic_check(  		if (ret) {  			DPU_ERROR_ENC(dpu_enc,  					"mode unsupported, phys idx %d\n", i); -			break; +			return ret;  		}  	} -	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); +	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state); -	/* Reserve dynamic resources now. */ -	if (!ret) { -		/* -		 * Release and Allocate resources on every modeset -		 * Dont allocate when active is false. -		 */ -		if (drm_atomic_crtc_needs_modeset(crtc_state)) { -			dpu_rm_release(global_state, drm_enc); +	/* +	 * Release and Allocate resources on every modeset +	 * Dont allocate when active is false. +	 */ +	if (drm_atomic_crtc_needs_modeset(crtc_state)) { +		dpu_rm_release(global_state, drm_enc); -			if (!crtc_state->active_changed || crtc_state->active) -				ret = dpu_rm_reserve(&dpu_kms->rm, global_state, -						drm_enc, crtc_state, topology); -		} +		if (!crtc_state->active_changed || crtc_state->enable) +			ret = dpu_rm_reserve(&dpu_kms->rm, global_state, +					drm_enc, crtc_state, topology);  	}  	trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); @@ -1171,7 +1166,8 @@ out:  	mutex_unlock(&dpu_enc->enc_lock);  } -static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, +					struct drm_atomic_state *state)  {  	struct dpu_encoder_virt *dpu_enc = NULL;  	int ret = 0; @@ -1207,14 +1203,28 @@ out:  	mutex_unlock(&dpu_enc->enc_lock);  } -static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, +					struct drm_atomic_state *state)  {  	struct dpu_encoder_virt *dpu_enc = NULL; +	struct drm_crtc *crtc; +	struct drm_crtc_state *old_state = NULL;  	int i = 0;  	dpu_enc = to_dpu_encoder_virt(drm_enc);  	DPU_DEBUG_ENC(dpu_enc, "\n"); +	crtc = drm_atomic_get_old_crtc_for_encoder(state, drm_enc); +	if (crtc) +		old_state = drm_atomic_get_old_crtc_state(state, crtc); + +	/* +	 * The encoder is already disabled if self refresh mode was set earlier, +	 * in the old_state for the corresponding crtc. +	 */ +	if (old_state && old_state->self_refresh_active) +		return; +  	mutex_lock(&dpu_enc->enc_lock);  	dpu_enc->enabled = false; @@ -2078,25 +2088,6 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)  	ctl->ops.clear_pending_flush(ctl);  } -void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc) -{ -	struct dpu_encoder_virt *dpu_enc; -	struct dpu_encoder_phys *phys; -	int i; - -	if (!drm_enc) { -		DPU_ERROR("invalid encoder\n"); -		return; -	} -	dpu_enc = to_dpu_encoder_virt(drm_enc); - -	for (i = 0; i < dpu_enc->num_phys_encs; i++) { -		phys = dpu_enc->phys_encs[i]; -		if (phys->ops.prepare_commit) -			phys->ops.prepare_commit(phys); -	} -} -  #ifdef CONFIG_DEBUG_FS  static int _dpu_encoder_status_show(struct seq_file *s, void *data)  { @@ -2388,8 +2379,8 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)  static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {  	.atomic_mode_set = dpu_encoder_virt_atomic_mode_set, -	.disable = dpu_encoder_virt_disable, -	.enable = dpu_encoder_virt_enable, +	.atomic_disable = dpu_encoder_virt_atomic_disable, +	.atomic_enable = dpu_encoder_virt_atomic_enable,  	.atomic_check = dpu_encoder_virt_atomic_check,  };  |