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

Commit 72cd1631 authored by Ingrid Gallardo's avatar Ingrid Gallardo Committed by Jayant Shekhar
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 fce0dd25
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -2723,9 +2723,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;
	/*
@@ -4793,15 +4796,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;
}
+4 −0
Original line number Diff line number Diff line
@@ -261,6 +261,8 @@ struct sde_encoder_irq {
 *                              fences that have to be signalled.
 * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
 * @irq:			IRQ tracking structures
 * @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;
@@ -288,6 +290,8 @@ struct sde_encoder_phys {
	atomic_t pending_retire_fence_cnt;
	wait_queue_head_t pending_kickoff_wq;
	struct sde_encoder_irq irq[INTR_IDX_MAX];
	u32 cont_splash_single_flush;
	bool cont_splash_settings;
};

static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)
+18 −5
Original line number Diff line number Diff line
@@ -382,6 +382,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);
}

@@ -845,9 +852,8 @@ static void _sde_encoder_phys_cmd_pingpong_config(
	struct sde_encoder_phys_cmd *cmd_enc =
		to_sde_encoder_phys_cmd(phys_enc);

	if (!phys_enc || !phys_enc->hw_ctl || !phys_enc->hw_pp
			|| !phys_enc->hw_ctl->ops.setup_intf_cfg) {
		SDE_ERROR("invalid arg(s), enc %d\n", phys_enc != 0);
	if (!phys_enc || !phys_enc->hw_pp) {
		SDE_ERROR("invalid arg(s), enc %d\n", phys_enc != NULL);
		return;
	}

@@ -866,7 +872,9 @@ static bool sde_encoder_phys_cmd_needs_single_flush(
	if (!phys_enc)
		return false;

	return _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);
}

static void sde_encoder_phys_cmd_enable_helper(
@@ -875,7 +883,7 @@ static void sde_encoder_phys_cmd_enable_helper(
	struct sde_hw_ctl *ctl;
	u32 flush_mask = 0;

	if (!phys_enc || !phys_enc->hw_ctl || !phys_enc->hw_pp) {
	if (!phys_enc || !phys_enc->hw_pp) {
		SDE_ERROR("invalid arg(s), encoder %d\n", phys_enc != 0);
		return;
	}
@@ -892,6 +900,11 @@ static void sde_encoder_phys_cmd_enable_helper(
		!sde_encoder_phys_cmd_is_master(phys_enc))
		goto skip_flush;

	if (!phys_enc->hw_ctl) {
		SDE_ERROR("invalid ctl\n");
		return;
	}

	ctl = phys_enc->hw_ctl;
	ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->intf_idx);
	ctl->ops.update_pending_flush(ctl, flush_mask);
+5 −2
Original line number Diff line number Diff line
@@ -511,8 +511,11 @@ static bool _sde_encoder_phys_is_dual_ctl(struct sde_encoder_phys *phys_enc)
static bool sde_encoder_phys_vid_needs_single_flush(
		struct sde_encoder_phys *phys_enc)
{
	return phys_enc && (_sde_encoder_phys_is_ppsplit(phys_enc) ||
		_sde_encoder_phys_is_dual_ctl(phys_enc));
	return phys_enc && (
		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)));
}

static void _sde_encoder_phys_vid_setup_irq_hw_idx(
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -582,6 +582,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/disbled)
 * @single_flush_en: Stores if the single flush is enabled.
 */
struct sde_splash_data {
	bool smmu_handoff_pending;
@@ -595,6 +596,7 @@ struct sde_splash_data {
	u8 lm_cnt;
	u8 dsc_cnt;
	bool cont_splash_en;
	bool single_flush_en;
};

#endif  /* _SDE_HW_MDSS_H */
Loading