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

Commit 9b5c639b 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: handle RM when continuous splash is enabled"

parents 9164de4e 8477612f
Loading
Loading
Loading
Loading
+163 −11
Original line number Diff line number Diff line
@@ -714,7 +714,8 @@ static bool _sde_rm_check_lm_and_get_connected_blks(
static int _sde_rm_reserve_lms(
		struct sde_rm *rm,
		struct sde_rm_rsvp *rsvp,
		struct sde_rm_requirements *reqs)
		struct sde_rm_requirements *reqs,
		u8 *_lm_ids)

{
	struct sde_rm_hw_blk *lm[MAX_BLOCKS];
@@ -742,6 +743,14 @@ static int _sde_rm_reserve_lms(
		lm_count = 0;
		lm[lm_count] = iter_i.blk;

		SDE_DEBUG("blk id = %d, _lm_ids[%d] = %d\n",
			iter_i.blk->id,
			lm_count,
			_lm_ids ? _lm_ids[lm_count] : -1);

		if (_lm_ids && (lm[lm_count])->id != _lm_ids[lm_count])
			continue;

		if (!_sde_rm_check_lm_and_get_connected_blks(
				rm, rsvp, reqs, lm[lm_count],
				&dspp[lm_count], &ds[lm_count],
@@ -765,6 +774,14 @@ static int _sde_rm_reserve_lms(
				continue;

			lm[lm_count] = iter_j.blk;
			SDE_DEBUG("blk id = %d, _lm_ids[%d] = %d\n",
				iter_i.blk->id,
				lm_count,
				_lm_ids ? _lm_ids[lm_count] : -1);

			if (_lm_ids && (lm[lm_count])->id != _lm_ids[lm_count])
				continue;

			++lm_count;
		}
	}
@@ -818,7 +835,8 @@ static int _sde_rm_reserve_ctls(
		struct sde_rm *rm,
		struct sde_rm_rsvp *rsvp,
		struct sde_rm_requirements *reqs,
		const struct sde_rm_topology_def *top)
		const struct sde_rm_topology_def *top,
		u8 *_ctl_ids)
{
	struct sde_rm_hw_blk *ctls[MAX_BLOCKS];
	struct sde_rm_hw_iter iter;
@@ -845,7 +863,7 @@ static int _sde_rm_reserve_ctls(
		 * bypass rest feature checks on finding CTL preferred
		 * for primary displays.
		 */
		if (!primary_pref) {
		if (!primary_pref && !_ctl_ids) {
			if (top->needs_split_display != has_split_display)
				continue;

@@ -860,6 +878,14 @@ static int _sde_rm_reserve_ctls(
		}

		ctls[i] = iter.blk;

		SDE_DEBUG("blk id = %d, _ctl_ids[%d] = %d\n",
			iter.blk->id, i,
			_ctl_ids ? _ctl_ids[i] : -1);

		if (_ctl_ids && (ctls[i]->id != _ctl_ids[i]))
			continue;

		SDE_DEBUG("ctl %d match\n", iter.blk->id);

		if (++i == top->num_ctl)
@@ -880,7 +906,8 @@ static int _sde_rm_reserve_ctls(
static int _sde_rm_reserve_dsc(
		struct sde_rm *rm,
		struct sde_rm_rsvp *rsvp,
		const struct sde_rm_topology_def *top)
		const struct sde_rm_topology_def *top,
		u8 *_dsc_ids)
{
	struct sde_rm_hw_iter iter;
	int alloc_count = 0;
@@ -895,6 +922,14 @@ static int _sde_rm_reserve_dsc(
		if (RESERVED_BY_OTHER(iter.blk, rsvp))
			continue;

		SDE_DEBUG("blk id = %d, _dsc_ids[%d] = %d\n",
			iter.blk->id,
			alloc_count,
			_dsc_ids ? _dsc_ids[alloc_count] : -1);

		if (_dsc_ids && (iter.blk->id != _dsc_ids[alloc_count]))
			continue;

		iter.blk->rsvp_nxt = rsvp;
		SDE_EVT32(iter.blk->type, rsvp->enc_id, iter.blk->id);

@@ -1043,10 +1078,96 @@ static int _sde_rm_make_next_rsvp(
	 * - Check mixers without DSPPs
	 * - Only then allow to grab from mixers with DSPP capability
	 */
	ret = _sde_rm_reserve_lms(rm, rsvp, reqs);
	ret = _sde_rm_reserve_lms(rm, rsvp, reqs, NULL);
	if (ret && !RM_RQ_DSPP(reqs)) {
		reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_DSPP);
		ret = _sde_rm_reserve_lms(rm, rsvp, reqs, NULL);
	}

	if (ret) {
		SDE_ERROR("unable to find appropriate mixers\n");
		return ret;
	}

	/*
	 * Do assignment preferring to give away low-resource CTLs first:
	 * - Check mixers without Split Display
	 * - Only then allow to grab from CTLs with split display capability
	 */
	_sde_rm_reserve_ctls(rm, rsvp, reqs, reqs->topology, NULL);
	if (ret && !reqs->topology->needs_split_display) {
		memcpy(&topology, reqs->topology, sizeof(topology));
		topology.needs_split_display = true;
		_sde_rm_reserve_ctls(rm, rsvp, reqs, &topology, NULL);
	}
	if (ret) {
		SDE_ERROR("unable to find appropriate CTL\n");
		return ret;
	}

	/* Assign INTFs, WBs, and blks whose usage is tied to them: CTL & CDM */
	ret = _sde_rm_reserve_intf_related_hw(rm, rsvp, &reqs->hw_res);
	if (ret)
		return ret;

	ret = _sde_rm_reserve_dsc(rm, rsvp, reqs->topology, NULL);
	if (ret)
		return ret;

	return ret;
}

static int _sde_rm_make_next_rsvp_for_cont_splash(
		struct sde_rm *rm,
		struct drm_encoder *enc,
		struct drm_crtc_state *crtc_state,
		struct drm_connector_state *conn_state,
		struct sde_rm_rsvp *rsvp,
		struct sde_rm_requirements *reqs)
{
	int ret;
	struct sde_rm_topology_def topology;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	int i;

	if (!enc->dev || !enc->dev->dev_private) {
		SDE_ERROR("drm device invalid\n");
		return -EINVAL;
	}
	priv = enc->dev->dev_private;
	if (!priv->kms) {
		SDE_ERROR("invalid kms\n");
		return -EINVAL;
	}
	sde_kms = to_sde_kms(priv->kms);

	for (i = 0; i < sde_kms->splash_data.lm_cnt; i++)
		SDE_DEBUG("splash_data.lm_ids[%d] = %d\n",
			i, sde_kms->splash_data.lm_ids[i]);

	if (sde_kms->splash_data.lm_cnt !=
			reqs->topology->num_lm)
		SDE_DEBUG("Configured splash screen LMs != needed LM cnt\n");

	/* Create reservation info, tag reserved blocks with it as we go */
	rsvp->seq = ++rm->rsvp_next_seq;
	rsvp->enc_id = enc->base.id;
	rsvp->topology = reqs->topology->top_name;
	list_add_tail(&rsvp->list, &rm->rsvps);

	/*
	 * Assign LMs and blocks whose usage is tied to them: DSPP & Pingpong.
	 * Do assignment preferring to give away low-resource mixers first:
	 * - Check mixers without DSPPs
	 * - Only then allow to grab from mixers with DSPP capability
	 */
	ret = _sde_rm_reserve_lms(rm, rsvp, reqs,
				sde_kms->splash_data.lm_ids);
	if (ret && !RM_RQ_DSPP(reqs)) {
		reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_DSPP);
		ret = _sde_rm_reserve_lms(rm, rsvp, reqs);
		ret = _sde_rm_reserve_lms(rm, rsvp, reqs,
					sde_kms->splash_data.lm_ids);
	}

	if (ret) {
@@ -1059,11 +1180,17 @@ static int _sde_rm_make_next_rsvp(
	 * - Check mixers without Split Display
	 * - Only then allow to grab from CTLs with split display capability
	 */
	_sde_rm_reserve_ctls(rm, rsvp, reqs, reqs->topology);
	for (i = 0; i < sde_kms->splash_data.ctl_top_cnt; i++)
		SDE_DEBUG("splash_data.ctl_ids[%d] = %d\n",
			i, sde_kms->splash_data.ctl_ids[i]);

	_sde_rm_reserve_ctls(rm, rsvp, reqs, reqs->topology,
			sde_kms->splash_data.ctl_ids);
	if (ret && !reqs->topology->needs_split_display) {
		memcpy(&topology, reqs->topology, sizeof(topology));
		topology.needs_split_display = true;
		_sde_rm_reserve_ctls(rm, rsvp, reqs, &topology);
		_sde_rm_reserve_ctls(rm, rsvp, reqs, &topology,
				sde_kms->splash_data.ctl_ids);
	}
	if (ret) {
		SDE_ERROR("unable to find appropriate CTL\n");
@@ -1075,7 +1202,12 @@ static int _sde_rm_make_next_rsvp(
	if (ret)
		return ret;

	ret = _sde_rm_reserve_dsc(rm, rsvp, reqs->topology);
	for (i = 0; i < sde_kms->splash_data.dsc_cnt; i++)
		SDE_DEBUG("splash_data.dsc_ids[%d] = %d\n",
			i, sde_kms->splash_data.dsc_ids[i]);

	ret = _sde_rm_reserve_dsc(rm, rsvp, reqs->topology,
				sde_kms->splash_data.dsc_ids);
	if (ret)
		return ret;

@@ -1319,6 +1451,8 @@ int sde_rm_reserve(
{
	struct sde_rm_rsvp *rsvp_cur, *rsvp_nxt;
	struct sde_rm_requirements reqs;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	int ret;

	if (!rm || !enc || !crtc_state || !conn_state) {
@@ -1326,8 +1460,20 @@ int sde_rm_reserve(
		return -EINVAL;
	}

	if (!enc->dev || !enc->dev->dev_private) {
		SDE_ERROR("drm device invalid\n");
		return -EINVAL;
	}
	priv = enc->dev->dev_private;
	if (!priv->kms) {
		SDE_ERROR("invalid kms\n");
		return -EINVAL;
	}
	sde_kms = to_sde_kms(priv->kms);

	/* Check if this is just a page-flip */
	if (!drm_atomic_crtc_needs_modeset(crtc_state))
	if (!sde_kms->cont_splash_en &&
			!drm_atomic_crtc_needs_modeset(crtc_state))
		return 0;

	SDE_DEBUG("reserving hw for conn %d enc %d crtc %d test_only %d\n",
@@ -1378,8 +1524,14 @@ int sde_rm_reserve(
	}

	/* Check the proposed reservation, store it in hw's "next" field */
	if (sde_kms->cont_splash_en) {
		SDE_DEBUG("cont_splash feature enabled\n");
		ret = _sde_rm_make_next_rsvp_for_cont_splash
			(rm, enc, crtc_state, conn_state, rsvp_nxt, &reqs);
	} else {
		ret = _sde_rm_make_next_rsvp(rm, enc, crtc_state, conn_state,
			rsvp_nxt, &reqs);
	}

	_sde_rm_print_rsvps(rm, SDE_RM_STAGE_AFTER_RSVPNEXT);