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

Commit 201164f2 authored by Raju P.L.S.S.S.N's avatar Raju P.L.S.S.S.N Committed by Mahesh Sivasubramanian
Browse files

lpm-levels: Compute minimum residencies for LPM levels



Minimum residency of current level is maximum residency of previous
level + 1. If none of the previous levels are enabled, minimum
residency of currenct level is time_overhead of current level.

Minimum residencies are used for New LPM level selection using
prediction logic.

Change-Id: I5e69a847d78d14ecbb7caeac383287a1897f7ce8
Signed-off-by: default avatarRaju P.L.S.S.S.N <rplsssn@codeaurora.org>
parent 7aef3b1f
Loading
Loading
Loading
Loading
+37 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ static const struct lpm_type_str lpm_types[] = {
};

static DEFINE_PER_CPU(uint32_t *, max_residency);
static DEFINE_PER_CPU(uint32_t *, min_residency);
static struct lpm_level_avail *cpu_level_available[NR_CPUS];
static struct platform_device *lpm_pdev;

@@ -75,7 +76,8 @@ static void set_optimum_cpu_residency(struct lpm_cpu *cpu, int cpu_id,
{
	int i, j;
	bool mode_avail;
	uint32_t *residency = per_cpu(max_residency, cpu_id);
	uint32_t *maximum_residency = per_cpu(max_residency, cpu_id);
	uint32_t *minimum_residency = per_cpu(min_residency, cpu_id);

	for (i = 0; i < cpu->nlevels; i++) {
		struct power_params *pwr = &cpu->levels[i].pwr;
@@ -84,19 +86,28 @@ static void set_optimum_cpu_residency(struct lpm_cpu *cpu, int cpu_id,
			lpm_cpu_mode_allow(cpu_id, i, true);

		if (!mode_avail) {
			residency[i] = 0;
			maximum_residency[i] = 0;
			minimum_residency[i] = 0;
			continue;
		}

		residency[i] = ~0;
		maximum_residency[i] = ~0;
		for (j = i + 1; j < cpu->nlevels; j++) {
			mode_avail = probe_time ||
					lpm_cpu_mode_allow(cpu_id, j, true);

			if (mode_avail &&
				(residency[i] > pwr->residencies[j]) &&
				(maximum_residency[i] > pwr->residencies[j]) &&
				(pwr->residencies[j] != 0))
				residency[i] = pwr->residencies[j];
				maximum_residency[i] = pwr->residencies[j];
		}

		minimum_residency[i] = pwr->time_overhead_us;
		for (j = i-1; j >= 0; j--) {
			if (probe_time || lpm_cpu_mode_allow(cpu_id, j, true)) {
				minimum_residency[i] = maximum_residency[j] + 1;
				break;
			}
		}
	}
}
@@ -116,6 +127,7 @@ static void set_optimum_cluster_residency(struct lpm_cluster *cluster,

		if (!mode_avail) {
			pwr->max_residency = 0;
			pwr->min_residency = 0;
			continue;
		}

@@ -129,6 +141,16 @@ static void set_optimum_cluster_residency(struct lpm_cluster *cluster,
				(pwr->residencies[j] != 0))
				pwr->max_residency = pwr->residencies[j];
		}

		pwr->min_residency = pwr->time_overhead_us;
		for (j = i-1;  j >= 0; j--) {
			if (probe_time ||
				lpm_cluster_mode_allow(cluster, j, true)) {
				pwr->min_residency =
				  cluster->levels[j].pwr.max_residency + 1;
				break;
			}
		}
	}
}

@@ -137,6 +159,10 @@ uint32_t *get_per_cpu_max_residency(int cpu)
	return per_cpu(max_residency, cpu);
}

uint32_t *get_per_cpu_min_residency(int cpu)
{
	return per_cpu(min_residency, cpu);
}
ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr,
				char *buf)
{
@@ -930,6 +956,12 @@ struct lpm_cluster *parse_cluster(struct device_node *node,
					GFP_KERNEL);
				if (!per_cpu(max_residency, i))
					return ERR_PTR(-ENOMEM);
				per_cpu(min_residency, i) = devm_kzalloc(
					&lpm_pdev->dev,
					sizeof(uint32_t) * c->cpu->nlevels,
					GFP_KERNEL);
				if (!per_cpu(min_residency, i))
					return ERR_PTR(-ENOMEM);
				set_optimum_cpu_residency(c->cpu, i, true);
			}
		}
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct power_params {
	uint32_t energy_overhead;	/* Enter + exit over head */
	uint32_t time_overhead_us;	/* Enter + exit overhead */
	uint32_t residencies[NR_LPM_LEVELS];
	uint32_t min_residency;
	uint32_t max_residency;
};

@@ -125,6 +126,7 @@ bool lpm_cpu_mode_allow(unsigned int cpu,
bool lpm_cluster_mode_allow(struct lpm_cluster *cluster,
		unsigned int mode, bool from_idle);
uint32_t *get_per_cpu_max_residency(int cpu);
uint32_t *get_per_cpu_min_residency(int cpu);
extern struct lpm_cluster *lpm_root_node;

#ifdef CONFIG_SMP