Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3092c8b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: only program LM size when needed" into display-kernel.lnx.5.4

parents 3ee8c556 b385a84e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4132,7 +4132,7 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en,
	return 0;
}

void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm)
void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm)
{
	struct sde_cp_node *prop_node = NULL, *n = NULL;
	struct sde_crtc *crtc;
+2 −2
Original line number Diff line number Diff line
@@ -201,10 +201,10 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en,
	struct sde_irq_callback *hist_irq);

/**
 * sde_cp_mode_switch_prop_dirty: API marks mode dependent features as dirty
 * sde_cp_crtc_res_change: API to handle LM resolution changes
 * @crtc_drm: Pointer to crtc.
 */
void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm);
void sde_cp_crtc_res_change(struct drm_crtc *crtc_drm);

/**
 * sde_cp_crtc_vm_primary_handoff: Properly handoff CRTC color mode features
+81 −47
Original line number Diff line number Diff line
@@ -433,7 +433,6 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc,
{
	SDE_DEBUG("\n");

	sde_cp_mode_switch_prop_dirty(crtc);
	if ((msm_is_mode_seamless(adjusted_mode) ||
	     (msm_is_mode_seamless_vrr(adjusted_mode) ||
	      msm_is_mode_seamless_dyn_clk(adjusted_mode))) &&
@@ -1113,30 +1112,30 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *crtc_state;
	struct sde_crtc_state *cstate;
	const struct sde_rect *lm_roi;
	struct sde_hw_mixer *hw_lm;
	bool right_mixer = false;
	bool lm_updated = false;
	int lm_idx;

	if (!crtc)
		return;

	sde_crtc = to_sde_crtc(crtc);
	crtc_state = to_sde_crtc_state(crtc->state);
	cstate = to_sde_crtc_state(crtc->state);

	for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
		struct sde_hw_mixer_cfg cfg;

		lm_roi = &crtc_state->lm_roi[lm_idx];
		lm_roi = &cstate->lm_roi[lm_idx];
		hw_lm = sde_crtc->mixers[lm_idx].hw_lm;
		if (!sde_crtc->mixers_swapped)
			right_mixer = lm_idx % MAX_MIXERS_PER_LAYOUT;

		SDE_EVT32(DRMID(crtc_state->base.crtc), lm_idx,
				lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h,
				right_mixer);

		if (lm_roi->w != hw_lm->cfg.out_width ||
				lm_roi->h != hw_lm->cfg.out_height ||
				right_mixer != hw_lm->cfg.right_mixer) {
			hw_lm->cfg.out_width = lm_roi->w;
			hw_lm->cfg.out_height = lm_roi->h;
			hw_lm->cfg.right_mixer = right_mixer;
@@ -1145,8 +1144,17 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
			cfg.out_height = lm_roi->h;
			cfg.right_mixer = right_mixer;
			cfg.flags = 0;

			hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
			lm_updated = true;
		}

		SDE_EVT32(DRMID(crtc), lm_idx, lm_roi->x, lm_roi->y, lm_roi->w,
				lm_roi->h, right_mixer, lm_updated);
	}

	if (lm_updated)
		sde_cp_crtc_res_change(crtc);
}

struct plane_state {
@@ -1533,8 +1541,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
		}
	}

	_sde_crtc_program_lm_output_roi(crtc);

end:
	kfree(pstates);
}
@@ -2165,8 +2171,6 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc)
				hw_ctl->ops.update_bitmask_mixer(
						hw_ctl, hw_lm->idx, 1);
		}

		sde_cp_mode_switch_prop_dirty(crtc);
	}
}

@@ -3901,12 +3905,63 @@ static void sde_crtc_reset(struct drm_crtc *crtc)
	crtc->state = &cstate->base;
}

static void sde_crtc_clear_cached_mixer_cfg(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
	struct sde_hw_mixer *hw_lm;
	int lm_idx;

	/* clearing lm cfg marks it dirty to force reprogramming next update */
	for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
		hw_lm = sde_crtc->mixers[lm_idx].hw_lm;
		hw_lm->cfg.out_width = 0;
		hw_lm->cfg.out_height = 0;
	}

	SDE_EVT32(DRMID(crtc));
}

static void sde_crtc_reset_sw_state_for_ipc(struct drm_crtc *crtc)
{
	struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state);
	struct drm_plane *plane;

	/* mark planes, mixers, and other blocks dirty for next update */
	drm_atomic_crtc_for_each_plane(plane, crtc)
		sde_plane_set_revalidate(plane, true);

	/* mark mixers dirty for next update */
	sde_crtc_clear_cached_mixer_cfg(crtc);

	/* mark other properties which need to be dirty for next update */
	set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty);
	if (cstate->num_ds_enabled)
		set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty);
}

static void sde_crtc_post_ipc(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct drm_encoder *encoder;

	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);

	/* restore encoder; crtc will be programmed during commit */
	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
		sde_encoder_virt_restore(encoder);

	/* restore UIDLE */
	sde_core_perf_crtc_update_uidle(crtc, true);

	sde_cp_crtc_post_ipc(crtc);
}

static void sde_crtc_handle_power_event(u32 event_type, void *arg)
{
	struct drm_crtc *crtc = arg;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct drm_plane *plane;
	struct drm_encoder *encoder;
	u32 power_on;
	unsigned long flags;
@@ -3919,7 +3974,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
		return;
	}
	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);

	mutex_lock(&sde_crtc->crtc_lock);

@@ -3927,15 +3981,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)

	switch (event_type) {
	case SDE_POWER_EVENT_POST_ENABLE:
		/* restore encoder; crtc will be programmed during commit */
		drm_for_each_encoder_mask(encoder, crtc->dev,
				crtc->state->encoder_mask) {
			sde_encoder_virt_restore(encoder);
		}

		/* restore UIDLE */
		sde_core_perf_crtc_update_uidle(crtc, true);

		spin_lock_irqsave(&sde_crtc->spin_lock, flags);
		list_for_each_entry(node, &sde_crtc->user_event_list, list) {
			ret = 0;
@@ -3947,10 +3992,9 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
		}
		spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);

		sde_cp_crtc_post_ipc(crtc);
		sde_crtc_post_ipc(crtc);
		break;
	case SDE_POWER_EVENT_PRE_DISABLE:

		drm_for_each_encoder_mask(encoder, crtc->dev,
				crtc->state->encoder_mask) {
			/*
@@ -3980,21 +4024,8 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
		sde_cp_crtc_pre_ipc(crtc);
		break;
	case SDE_POWER_EVENT_POST_DISABLE:
		/*
		 * set revalidate flag in planes, so it will be re-programmed
		 * in the next frame update
		 */
		drm_atomic_crtc_for_each_plane(plane, crtc)
			sde_plane_set_revalidate(plane, true);

		sde_crtc_reset_sw_state_for_ipc(crtc);
		sde_cp_crtc_suspend(crtc);

		/* reconfigure everything on next frame update */
		set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, cstate->dirty);

		if (cstate->num_ds_enabled)
			set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty);

		event.type = DRM_EVENT_SDE_POWER;
		event.length = sizeof(power_on);
		power_on = 0;
@@ -4014,6 +4045,9 @@ static void _sde_crtc_reset(struct drm_crtc *crtc)
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
	struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state);

	/* mark mixer cfgs dirty before wiping them */
	sde_crtc_clear_cached_mixer_cfg(crtc);

	memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers));
	sde_crtc->num_mixers = 0;
	sde_crtc->mixers_swapped = false;