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

Commit 17834dcf authored by Ingrid Gallardo's avatar Ingrid Gallardo
Browse files

drm/msm/sde: fix to disable autorefresh from cont splash



With latest hw, autorefresh feature needs to be disabled
in the hw interface. This change makes sure that during
the continuous splash use case, the interface api's get
called to disable auto-refresh when required.

Change-Id: If4864443498efbba5b3c53478ec5a152672457a4
Signed-off-by: default avatarIngrid Gallardo <ingridg@codeaurora.org>
parent 38fc2a8e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -254,7 +254,9 @@ static void sde_encoder_phys_cmd_autorefresh_done_irq(void *arg, int irq_idx)
	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);

	SDE_EVT32_IRQ(DRMID(phys_enc->parent),
			phys_enc->hw_pp->idx - PINGPONG_0, new_cnt);
			phys_enc->hw_pp->idx - PINGPONG_0,
			phys_enc->hw_intf->idx - INTF_0,
			new_cnt);

	/* Signal any waiting atomic commit thread */
	wake_up_all(&cmd_enc->autorefresh.kickoff_wq);
+130 −28
Original line number Diff line number Diff line
@@ -1215,47 +1215,132 @@ static u32 _sde_rm_poll_intr_status_for_cont_splash(struct sde_hw_intr *intr,
	return -ETIMEDOUT;
}

static inline bool _sde_rm_autorefresh_validate(struct sde_hw_pingpong *pp,
		struct sde_hw_intf *intf,
		bool hw_intf_te)
{

	if ((hw_intf_te && !intf) ||
		(!hw_intf_te && !pp)) {
		SDE_ERROR("autorefresh wrong params!\n");
		return true;
	}

	if (hw_intf_te) {
		if (!intf->ops.get_autorefresh ||
				!intf->ops.setup_autorefresh ||
				!intf->ops.connect_external_te ||
				!intf->ops.get_vsync_info) {
			SDE_ERROR("intf autorefresh apis not supported\n");
			return true;
		}
	} else {
		if (!pp->ops.get_autorefresh ||
				!pp->ops.setup_autorefresh ||
				!pp->ops.connect_external_te ||
				!pp->ops.get_vsync_info) {
			SDE_ERROR("pp autorefresh apis not supported\n");
			return true;
		}
	}

	return false;
}

static inline void _sde_rm_autorefresh_get_cfg(
		struct sde_hw_pingpong *pp,
		struct sde_hw_intf *intf,
		struct sde_hw_autorefresh *cfg,
		bool hw_intf_te)
{
	if (hw_intf_te)
		intf->ops.get_autorefresh(intf, cfg);
	else
		pp->ops.get_autorefresh(pp, cfg);
}

static inline void _sde_rm_autorefresh_connect_external_te(
		struct sde_hw_pingpong *pp,
		struct sde_hw_intf *intf,
		bool hw_intf_te,
		bool enable)
{
	if (hw_intf_te)
		intf->ops.connect_external_te(intf, enable);
	else
		pp->ops.connect_external_te(pp, enable);
}

static inline void _sde_rm_autorefresh_setup(struct sde_hw_pingpong *pp,
		struct sde_hw_intf *intf,
		struct sde_hw_autorefresh *cfg,
		bool hw_intf_te)
{
	if (hw_intf_te)
		intf->ops.setup_autorefresh(intf, cfg);
	else
		pp->ops.setup_autorefresh(pp, cfg);
}

static inline void _sde_rm_autorefresh_get_vsync_info(
		struct sde_hw_pingpong *pp,
		struct sde_hw_intf *intf,
		struct sde_hw_pp_vsync_info *info,
		bool hw_intf_te)
{
	if (hw_intf_te)
		intf->ops.get_vsync_info(intf, info);
	else
		pp->ops.get_vsync_info(pp, info);
}

static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp,
		struct sde_hw_intr *hw_intr)
		struct sde_hw_intf *intf,
		struct sde_hw_intr *hw_intr,
		bool hw_intf_te)
{
	u32 const timeout_ms = 35; /* Max two vsyncs delay */
	int rc = 0, i, loop = 3;
	struct sde_hw_pp_vsync_info info;
	int irq_idx_pp_done = -1, irq_idx_autorefresh = -1;
	struct sde_hw_autorefresh cfg = {0};
	int dbg_idx;
	int te_irq_idx;

	if (!pp->ops.get_autorefresh || !pp->ops.setup_autorefresh ||
		!pp->ops.connect_external_te || !pp->ops.get_vsync_info) {
		SDE_ERROR("autorefresh update api not supported\n");
	if (_sde_rm_autorefresh_validate(pp, intf, hw_intf_te))
		return 0;
	}

	dbg_idx = hw_intf_te ? intf->idx - INTF_0 : pp->idx - PINGPONG_0;
	te_irq_idx = hw_intf_te ? intf->idx : pp->idx;

	/* read default autorefresh configuration */
	pp->ops.get_autorefresh(pp, &cfg);
	_sde_rm_autorefresh_get_cfg(pp, intf, &cfg, hw_intf_te);

	if (!cfg.enable) {
		SDE_DEBUG("autorefresh already disabled\n");
		SDE_EVT32(pp->idx - PINGPONG_0, SDE_EVTLOG_FUNC_CASE1);
		SDE_DEBUG("autorefresh already disabled idx:%d\n",
			dbg_idx);
		SDE_EVT32(dbg_idx, SDE_EVTLOG_FUNC_CASE1);
		return 0;
	}

	/* disable external TE first */
	pp->ops.connect_external_te(pp, false);
	_sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, false);

	/* get all IRQ indexes */
	if (hw_intr->ops.irq_idx_lookup) {
		irq_idx_pp_done = hw_intr->ops.irq_idx_lookup(
				SDE_IRQ_TYPE_PING_PONG_COMP, pp->idx);
				SDE_IRQ_TYPE_PING_PONG_COMP, te_irq_idx);
		irq_idx_autorefresh = hw_intr->ops.irq_idx_lookup(
				SDE_IRQ_TYPE_PING_PONG_AUTO_REF, pp->idx);
		SDE_DEBUG("pp_done itr_idx = %d autorefresh irq_idx:%d\n",
				SDE_IRQ_TYPE_PING_PONG_AUTO_REF, te_irq_idx);
		SDE_DEBUG("pp_done irq_idx = %d autorefresh irq_idx:%d\n",
				irq_idx_pp_done, irq_idx_autorefresh);
	}

	/* disable autorefresh */
	cfg.enable = false;
	pp->ops.setup_autorefresh(pp, &cfg);
	_sde_rm_autorefresh_setup(pp, intf, &cfg, hw_intf_te);

	SDE_EVT32(pp->idx - PINGPONG_0, irq_idx_pp_done, irq_idx_autorefresh);
	SDE_EVT32(dbg_idx, irq_idx_pp_done, irq_idx_autorefresh);
	_sde_rm_clear_irq_status(hw_intr, irq_idx_pp_done, irq_idx_autorefresh);

	/*
@@ -1267,9 +1352,9 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp,
	for (i = 0; i < loop; i++) {
		info.wr_ptr_line_count = 0;
		info.rd_ptr_init_val = 0;
		pp->ops.get_vsync_info(pp, &info);
		_sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te);

		SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count,
		SDE_EVT32(dbg_idx, info.wr_ptr_line_count,
			info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE1);

		/* wait for read ptr intr */
@@ -1278,10 +1363,11 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp,

		info.wr_ptr_line_count = 0;
		info.rd_ptr_init_val = 0;
		pp->ops.get_vsync_info(pp, &info);
		SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count);

		SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count,
		_sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te);

		SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count);
		SDE_EVT32(dbg_idx, info.wr_ptr_line_count,
			info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE2);

		/* log line count and return */
@@ -1295,7 +1381,7 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp,
		usleep_range(3000, 4000);
	}

	pp->ops.connect_external_te(pp, true);
	_sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, true);

	return rc;
}
@@ -1315,29 +1401,33 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm,
{
	int index = 0;
	int value, dsc_cnt = 0;
	struct sde_rm_hw_iter iter_pp;
	struct sde_rm_hw_iter iter_pp, intf_iter;
	bool hw_intf_te_supported;
	struct sde_hw_intr *hw_intr = NULL;

	if (!rm || !sde_kms || !dsc_ids) {
		SDE_ERROR("invalid input parameters\n");
		return 0;
	}

	hw_intf_te_supported = sde_hw_intf_te_supported(sde_kms->catalog);
	hw_intr = sde_kms->hw_intr;
	if (!hw_intr) {
		SDE_ERROR("hw_intr handler not initialized\n");
		return 0;
	}

	SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt);
	sde_rm_init_hw_iter(&iter_pp, 0, SDE_HW_BLK_PINGPONG);
	while (_sde_rm_get_hw_locked(rm, &iter_pp)) {
		struct sde_hw_pingpong *pp =
				to_sde_hw_pingpong(iter_pp.blk->hw);
		struct sde_hw_intr *hw_intr = NULL;

		if (!pp->ops.get_dsc_status) {
			SDE_ERROR("get_dsc_status ops not initialized\n");
			return 0;
		}
		hw_intr = sde_kms->hw_intr;
		if (!hw_intr) {
			SDE_ERROR("hw_intr handler not initialized\n");
			return 0;
		}

		value = pp->ops.get_dsc_status(pp);
		SDE_DEBUG("DSC[%d]=0x%x, dsc_cnt = %d\n",
				index, value, dsc_cnt);
@@ -1347,7 +1437,19 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm,
		}
		index++;

		_sde_rm_autorefresh_disable(pp, hw_intr);
		if (!hw_intf_te_supported)
			_sde_rm_autorefresh_disable(pp, NULL, hw_intr,
				hw_intf_te_supported);
	}

	sde_rm_init_hw_iter(&intf_iter, 0, SDE_HW_BLK_INTF);
	while (_sde_rm_get_hw_locked(rm, &intf_iter)) {
		struct sde_hw_intf *intf =
			to_sde_hw_intf(intf_iter.blk->hw);

		if (hw_intf_te_supported)
			_sde_rm_autorefresh_disable(NULL, intf, hw_intr,
				hw_intf_te_supported);
	}

	return dsc_cnt;