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

Commit a1939689 authored by Alan Kwong's avatar Alan Kwong
Browse files

drm/msm/sde: update bandwidth/clock at frame done event



The current bandwidth & clock logic lowers clock &
bandwidth when parameters are not updated. However, this
function is not invoked at frame done when parameters are
not changing. Add call to update bandwidth & clock at
frame done event time for video mode panel.

Move perf state update to atomic check to make perf data
persistent over state duplication.

CRs-Fixed: 2009714
Change-Id: I9f981e902ddf3ecbcd99cb2ab2bd0d85e7f6bdda
Signed-off-by: default avatarAlan Kwong <akwong@codeaurora.org>
parent 823e0419
Loading
Loading
Loading
Loading
+37 −31
Original line number Diff line number Diff line
@@ -72,6 +72,31 @@ static bool _sde_core_video_mode_intf_connected(struct drm_crtc *crtc)
	return intf_connected;
}

static void _sde_core_perf_calc_crtc(struct drm_crtc *crtc,
		struct drm_crtc_state *state,
		struct sde_core_perf_params *perf)
{
	struct sde_crtc_state *sde_cstate;

	if (!crtc || !state || !perf) {
		SDE_ERROR("invalid parameters\n");
		return;
	}

	sde_cstate = to_sde_crtc_state(state);
	memset(perf, 0, sizeof(struct sde_core_perf_params));

	perf->bw_ctl = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB);
	perf->max_per_pipe_ib =
			sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_IB);
	perf->core_clk_rate =
			sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_CLK);

	SDE_DEBUG("crtc=%d clk_rate=%u ib=%llu ab=%llu\n",
			crtc->base.id, perf->core_clk_rate,
			perf->max_per_pipe_ib, perf->bw_ctl);
}

int sde_core_perf_crtc_check(struct drm_crtc *crtc,
		struct drm_crtc_state *state)
{
@@ -100,7 +125,11 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc,

	sde_cstate = to_sde_crtc_state(state);

	bw_sum_of_intfs = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB);
	/* swap state and obtain new values */
	sde_cstate->cur_perf = sde_cstate->new_perf;
	_sde_core_perf_calc_crtc(crtc, state, &sde_cstate->new_perf);

	bw_sum_of_intfs = sde_cstate->new_perf.bw_ctl;
	curr_client_type = sde_crtc_get_client_type(crtc);

	drm_for_each_crtc(tmp_crtc, crtc->dev) {
@@ -110,7 +139,7 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc,
			struct sde_crtc_state *tmp_cstate =
					to_sde_crtc_state(tmp_crtc->state);

			bw_sum_of_intfs += tmp_cstate->cur_perf.bw_ctl;
			bw_sum_of_intfs += tmp_cstate->new_perf.bw_ctl;
		}
	}

@@ -126,11 +155,11 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc,
	SDE_DEBUG("final threshold bw limit = %d\n", threshold);

	if (!threshold) {
		sde_cstate->cur_perf.bw_ctl = 0;
		sde_cstate->new_perf = sde_cstate->cur_perf;
		SDE_ERROR("no bandwidth limits specified\n");
		return -E2BIG;
	} else if (bw > threshold) {
		sde_cstate->cur_perf.bw_ctl = 0;
		sde_cstate->new_perf = sde_cstate->cur_perf;
		SDE_ERROR("exceeds bandwidth: %ukb > %ukb\n", bw, threshold);
		return -E2BIG;
	}
@@ -138,26 +167,6 @@ int sde_core_perf_crtc_check(struct drm_crtc *crtc,
	return 0;
}

static void _sde_core_perf_calc_crtc(struct sde_kms *kms,
		struct drm_crtc *crtc,
		struct sde_core_perf_params *perf)
{
	struct sde_crtc_state *sde_cstate;

	sde_cstate = to_sde_crtc_state(crtc->state);
	memset(perf, 0, sizeof(struct sde_core_perf_params));

	perf->bw_ctl = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_AB);
	perf->max_per_pipe_ib =
			sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_IB);
	perf->core_clk_rate =
			sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_CLK);

	SDE_DEBUG("crtc=%d clk_rate=%u ib=%llu ab=%llu\n",
			crtc->base.id, perf->core_clk_rate,
			perf->max_per_pipe_ib, perf->bw_ctl);
}

static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
		struct drm_crtc *crtc)
{
@@ -175,13 +184,13 @@ static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
			sde_cstate = to_sde_crtc_state(tmp_crtc->state);

			perf.max_per_pipe_ib = max(perf.max_per_pipe_ib,
				sde_cstate->cur_perf.max_per_pipe_ib);
				sde_cstate->new_perf.max_per_pipe_ib);

			bw_sum_of_intfs += sde_cstate->cur_perf.bw_ctl;
			bw_sum_of_intfs += sde_cstate->new_perf.bw_ctl;

			SDE_DEBUG("crtc=%d bw=%llu\n",
				tmp_crtc->base.id,
				sde_cstate->cur_perf.bw_ctl);
				sde_cstate->new_perf.bw_ctl);
		}
	}

@@ -282,7 +291,7 @@ static u32 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms)
	drm_for_each_crtc(crtc, kms->dev) {
		if (_sde_core_perf_crtc_is_power_on(crtc)) {
			sde_cstate = to_sde_crtc_state(crtc->state);
			clk_rate = max(sde_cstate->cur_perf.core_clk_rate,
			clk_rate = max(sde_cstate->new_perf.core_clk_rate,
							clk_rate);
			clk_rate = clk_round_rate(kms->perf.core_clk, clk_rate);
		}
@@ -327,9 +336,6 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
	new = &sde_cstate->new_perf;

	if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) {
		if (params_changed)
			_sde_core_perf_calc_crtc(kms, crtc, new);

		/*
		 * cases for bus bandwidth update.
		 * 1. new bandwidth vote or writeback output vote
+6 −1
Original line number Diff line number Diff line
@@ -1399,6 +1399,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
	struct sde_crtc_frame_event *fevent;
	struct drm_crtc *crtc;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct sde_kms *sde_kms;
	unsigned long flags;

@@ -1408,13 +1409,14 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
	}

	fevent = container_of(work, struct sde_crtc_frame_event, work);
	if (!fevent->crtc) {
	if (!fevent->crtc || !fevent->crtc->state) {
		SDE_ERROR("invalid crtc\n");
		return;
	}

	crtc = fevent->crtc;
	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);

	sde_kms = _sde_crtc_get_kms(crtc);
	if (!sde_kms) {
@@ -1453,6 +1455,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
			SDE_EVT32_VERBOSE(DRMID(crtc), fevent->event,
							SDE_EVTLOG_FUNC_CASE3);
		}

		if (fevent->event == SDE_ENCODER_FRAME_EVENT_DONE)
			sde_core_perf_crtc_update(crtc, 0, false);
	} else {
		SDE_ERROR("crtc%d ts:%lld unknown event %u\n", crtc->base.id,
				ktime_to_ns(fevent->ts),