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

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

Merge "drm/msm/sde: fix to disable autorefresh from cont splash" into dev/msm-4.14-display

parents 7ceacd70 17834dcf
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;