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

Commit 38fc2a8e authored by Ingrid Gallardo's avatar Ingrid Gallardo
Browse files

drm/msm/sde: fix pp-split boot up with continuous splash enabled



Current driver does not boot up properly when device
boots with continuous splash enabled and pp-split
configuration. Fix this problem by adding the
correct checks that were causing a null pointer
dereference and a wrong configuration.

Change-Id: I2b6b499a38305e5bd98a52e8ff606bd843dd0199
Signed-off-by: default avatarIngrid Gallardo <ingridg@codeaurora.org>
Signed-off-by: default avatarJayant Shekhar <jshekhar@codeaurora.org>
parent becb0856
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -2902,9 +2902,12 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
	sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_STOP);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		if (sde_enc->phys_encs[i])
		if (sde_enc->phys_encs[i]) {
			sde_enc->phys_encs[i]->cont_splash_settings = false;
			sde_enc->phys_encs[i]->cont_splash_single_flush = 0;
			sde_enc->phys_encs[i]->connector = NULL;
		}
	}

	sde_enc->cur_master = NULL;
	/*
@@ -4996,15 +4999,19 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder)
			return -EINVAL;
		}

		/* update connector for master and slave phys encoders */
		phys->connector = conn;
		phys->cont_splash_single_flush =
			sde_kms->splash_data.single_flush_en;
		phys->cont_splash_settings = true;

		phys->hw_pp = sde_enc->hw_pp[i];
		if (phys->ops.cont_splash_mode_set)
			phys->ops.cont_splash_mode_set(phys, drm_mode);

		if (phys->ops.is_master && phys->ops.is_master(phys)) {
			phys->connector = conn;
		if (phys->ops.is_master && phys->ops.is_master(phys))
			sde_enc->cur_master = phys;
	}
	}

	return ret;
}
+8 −2
Original line number Diff line number Diff line
@@ -269,6 +269,8 @@ struct sde_encoder_irq {
 * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
 * @irq:			IRQ tracking structures
 * @has_intf_te:		Interface TE configuration support
 * @cont_splash_single_flush	Variable to check if single flush is enabled.
 * @cont_splash_settings	Variable to store continuous splash settings.
 */
struct sde_encoder_phys {
	struct drm_encoder *parent;
@@ -300,6 +302,8 @@ struct sde_encoder_phys {
	wait_queue_head_t pending_kickoff_wq;
	struct sde_encoder_irq irq[INTR_IDX_MAX];
	bool has_intf_te;
	u32 cont_splash_single_flush;
	bool cont_splash_settings;
};

static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
@@ -665,7 +669,9 @@ static inline bool sde_encoder_phys_needs_single_flush(
	if (!phys_enc)
		return false;

	return phys_enc && (_sde_encoder_phys_is_ppsplit(phys_enc) ||
	return phys_enc->cont_splash_settings ?
			phys_enc->cont_splash_single_flush :
			(_sde_encoder_phys_is_ppsplit(phys_enc) ||
				_sde_encoder_phys_is_dual_ctl(phys_enc));
}
#endif /* __sde_encoder_phys_H__ */
+7 −0
Original line number Diff line number Diff line
@@ -426,6 +426,13 @@ static void sde_encoder_phys_cmd_cont_splash_mode_set(
	phys_enc->cached_mode = *adj_mode;
	phys_enc->enable_state = SDE_ENC_ENABLED;

	if (!phys_enc->hw_ctl || !phys_enc->hw_pp) {
		SDE_DEBUG("invalid ctl:%d pp:%d\n",
			(phys_enc->hw_ctl == NULL),
			(phys_enc->hw_pp == NULL));
		return;
	}

	_sde_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
}

+2 −0
Original line number Diff line number Diff line
@@ -587,6 +587,7 @@ struct ctl_top {
 * @lm_cnt:	stores the active number of MDSS "LM" blks for the current mode
 * @dsc_cnt:	stores the active number of MDSS "dsc" blks for the current mode
 * @cont_splash_en:	Stores the cont_splash status (enabled/disabled)
 * @single_flush_en: Stores if the single flush is enabled.
 */
struct sde_splash_data {
	bool resource_handoff_pending;
@@ -600,6 +601,7 @@ struct sde_splash_data {
	u8 lm_cnt;
	u8 dsc_cnt;
	bool cont_splash_en;
	bool single_flush_en;
};

/**
+13 −0
Original line number Diff line number Diff line
@@ -107,6 +107,18 @@ static void sde_hw_setup_split_pipe(struct sde_hw_mdp *mdp,
	SDE_REG_WRITE(c, SPLIT_DISPLAY_EN, cfg->en & 0x1);
}

static u32 sde_hw_get_split_flush(struct sde_hw_mdp *mdp)
{
	struct sde_hw_blk_reg_map *c;

	if (!mdp)
		return 0;

	c = &mdp->hw;

	return (SDE_REG_READ(c, SSPP_SPARE) & 0x1);
}

static void sde_hw_setup_pp_split(struct sde_hw_mdp *mdp,
		struct split_pipe_cfg *cfg)
{
@@ -411,6 +423,7 @@ static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,
	ops->get_danger_status = sde_hw_get_danger_status;
	ops->setup_vsync_source = sde_hw_setup_vsync_source;
	ops->get_safe_status = sde_hw_get_safe_status;
	ops->get_split_flush_status = sde_hw_get_split_flush;
	ops->setup_dce = sde_hw_setup_dce;
	ops->reset_ubwc = sde_hw_reset_ubwc;
	ops->intf_audio_select = sde_hw_intf_audio_select;
Loading