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

Commit c9eb6c11 authored by Amine Najahi's avatar Amine Najahi
Browse files

disp: msm: sde: fix mixer count calculation for 4LM topologies



Currently mixer calculation does not take the number of LMs into
consideration when it is greater than 2. This changes adjusts mixer
count for 4LM use cases based on maximum clock and pipe width.

Change-Id: I05631dee3beadaa0d50548282a539835bcb548c0
Signed-off-by: default avatarAmine Najahi <anajahi@codeaurora.org>
parent 8dd5deed
Loading
Loading
Loading
Loading
+48 −22
Original line number Diff line number Diff line
@@ -2413,17 +2413,23 @@ static int sde_kms_get_mixer_count(const struct msm_kms *kms,
	struct sde_kms *sde_kms;
	s64 mode_clock_hz = 0;
	s64 max_mdp_clock_hz = 0;
	s64 mdp_fudge_factor = 0;
	s64 temp = 0;
	s64 max_lm_width = 0;
	s64 hdisplay_fp = 0;
	s64 htotal_fp = 0;
	s64 vtotal_fp = 0;
	s64 vrefresh_fp = 0;
	s64 mdp_fudge_factor = 0;
	s64 num_lm_fp = 0;
	s64 lm_clk_fp = 0;
	s64 lm_width_fp = 0;
	int rc = 0;

	if (!num_lm) {
		SDE_ERROR("invalid num_lm pointer\n");
		return -EINVAL;
	}

	/* default to 1 layer mixer */
	*num_lm = 1;
	if (!kms || !mode || !res) {
		SDE_ERROR("invalid input args\n");
@@ -2432,31 +2438,51 @@ static int sde_kms_get_mixer_count(const struct msm_kms *kms,

	sde_kms = to_sde_kms(kms);

	max_mdp_clock_hz = drm_fixp_from_fraction(
			sde_kms->perf.max_core_clk_rate, 1);
	mdp_fudge_factor = drm_fixp_from_fraction(105, 100); /* 1.05 */
	htotal_fp = drm_fixp_from_fraction(mode->htotal, 1);
	vtotal_fp = drm_fixp_from_fraction(mode->vtotal, 1);
	vrefresh_fp = drm_fixp_from_fraction(mode->vrefresh, 1);
	max_mdp_clock_hz = drm_int2fixp(sde_kms->perf.max_core_clk_rate);
	max_lm_width = drm_int2fixp(res->max_mixer_width);
	hdisplay_fp = drm_int2fixp(mode->hdisplay);
	htotal_fp = drm_int2fixp(mode->htotal);
	vtotal_fp = drm_int2fixp(mode->vtotal);
	vrefresh_fp = drm_int2fixp(mode->vrefresh);
	mdp_fudge_factor = drm_fixp_from_fraction(105, 100);

	/* mode clock = [(h * v * fps * 1.05) / (num_lm)] */
	mode_clock_hz = drm_fixp_mul(htotal_fp, vtotal_fp);
	mode_clock_hz = drm_fixp_mul(mode_clock_hz, vrefresh_fp);
	mode_clock_hz = drm_fixp_mul(mode_clock_hz, mdp_fudge_factor);

	temp = drm_fixp_mul(htotal_fp, vtotal_fp);
	temp = drm_fixp_mul(temp, vrefresh_fp);
	mode_clock_hz = drm_fixp_mul(temp, mdp_fudge_factor);
	if (mode_clock_hz > max_mdp_clock_hz ||
			mode->hdisplay > res->max_mixer_width) {
		*num_lm = 2;
		if ((mode_clock_hz >> 1) > max_mdp_clock_hz) {
			SDE_DEBUG("[%s] clock %d exceeds max_mdp_clk %d\n",
					mode->name, mode_clock_hz,
					max_mdp_clock_hz);
			return -EINVAL;
			hdisplay_fp > max_lm_width) {
		*num_lm = 0;
		do {
			*num_lm += 2;
			num_lm_fp = drm_int2fixp(*num_lm);
			lm_clk_fp = drm_fixp_div(mode_clock_hz, num_lm_fp);
			lm_width_fp = drm_fixp_div(hdisplay_fp, num_lm_fp);

			if (*num_lm > 4) {
				rc = -EINVAL;
				goto error;
			}

		} while (lm_clk_fp > max_mdp_clock_hz ||
				lm_width_fp > max_lm_width);

		mode_clock_hz = lm_clk_fp;
	}
	SDE_DEBUG("[%s] h=%d, v=%d, fps=%d, max_mdp_clk_hz=%llu, num_lm=%d\n",
	SDE_DEBUG("[%s] h=%d v=%d fps=%d lm=%d mode_clk=%llu max_clk=%llu\n",
			mode->name, mode->htotal, mode->vtotal, mode->vrefresh,
			sde_kms->perf.max_core_clk_rate, *num_lm);

			*num_lm, drm_fixp2int(mode_clock_hz),
			sde_kms->perf.max_core_clk_rate);
	return 0;

error:
	SDE_ERROR("required mode clk exceeds max mdp clk\n");
	SDE_ERROR("[%s] h=%d v=%d fps=%d lm=%d mode_clk=%llu max_clk=%llu\n",
			mode->name, mode->htotal, mode->vtotal, mode->vrefresh,
			*num_lm, drm_fixp2int(mode_clock_hz),
			sde_kms->perf.max_core_clk_rate);
	return rc;
}

static void _sde_kms_null_commit(struct drm_device *dev,