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

Commit a5887ccd authored by Archana Sathyakumar's avatar Archana Sathyakumar Committed by Mahesh Sivasubramanian
Browse files

lpm-levels: Add QCOM cpuidle governor



Currently framework uses menu as governor and the mode selection happens
again in lpm driver. Register QCOM cpuidle governor, use the mode
selected for cpu to enter and further select the mode for the cluster to
enter.

Change-Id: Ifa98c4c90859f70fb5406715b53c89276ac1a4f4
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 51394f99
Loading
Loading
Loading
Loading
+45 −18
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ static int set_device_mode(struct lpm_cluster *cluster, int ndevice,
}

static int cpu_power_select(struct cpuidle_device *dev,
		struct lpm_cpu *cpu, int *index)
		struct lpm_cpu *cpu)
{
	int best_level = -1;
	uint32_t latency_us = pm_qos_request_for_cpu(PM_QOS_CPU_DMA_LATENCY,
@@ -806,15 +806,16 @@ bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
}
#endif

static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		struct cpuidle_driver *drv, int index)
static int lpm_cpuidle_select(struct cpuidle_driver *drv,
		struct cpuidle_device *dev)
{
	struct lpm_cluster *cluster = per_cpu(cpu_cluster, dev->cpu);
	int64_t time = ktime_to_ns(ktime_get());
	bool success = true;
	int idx = cpu_power_select(dev, cluster->cpu, &index);
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	struct power_params *pwr_params;
	int idx;

	if (!cluster)
		return 0;

	idx = cpu_power_select(dev, cluster->cpu);

	if (idx < 0) {
		local_irq_enable();
@@ -822,25 +823,35 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
	}

	trace_cpu_idle_rcuidle(idx, dev->cpu);
	return idx;
}

static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		struct cpuidle_driver *drv, int idx)
{
	struct lpm_cluster *cluster = per_cpu(cpu_cluster, dev->cpu);
	bool success = true;
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	int64_t start_time = ktime_to_ns(ktime_get()), end_time;
	struct power_params *pwr_params;

	pwr_params = &cluster->cpu->levels[idx].pwr;
	sched_set_cpu_cstate(smp_processor_id(), idx + 1,
		pwr_params->energy_overhead, pwr_params->latency_us);

	trace_cpu_idle_enter(idx);

	cpu_prepare(cluster, idx, true);
	cluster_prepare(cluster, cpumask, idx, true);
	lpm_stats_cpu_enter(idx);

	if (need_resched() || (idx < 0))
		goto exit;

	trace_cpu_idle_enter(idx);
	lpm_stats_cpu_enter(idx);

	if (!use_psci) {
		if (idx > 0)
			update_debug_pc_event(CPU_ENTER, idx, 0xdeaffeed,
					0xdeaffeed, true);

		success = msm_cpu_pm_enter_sleep(cluster->cpu->levels[idx].mode,
				true);

@@ -857,13 +868,12 @@ exit:
	cpu_unprepare(cluster, idx, true);

	sched_set_cpu_cstate(smp_processor_id(), 0, 0, 0);

	time = ktime_to_ns(ktime_get()) - time;
	do_div(time, 1000);
	dev->last_residency = (int)time;
	trace_cpu_idle_exit(idx, success);
	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
	end_time = ktime_to_ns(ktime_get()) - start_time;
	dev->last_residency = do_div(end_time, 1000);
	local_irq_enable();

	return idx;
}

@@ -910,6 +920,13 @@ static int cpuidle_register_cpu(struct cpuidle_driver *drv,
}
#endif

static struct cpuidle_governor lpm_governor = {
	.name =		"qcom",
	.rating =	30,
	.select =	lpm_cpuidle_select,
	.owner =	THIS_MODULE,
};

static int cluster_cpuidle_register(struct lpm_cluster *cl)
{
	int i = 0, ret = 0;
@@ -971,10 +988,19 @@ static int cluster_cpuidle_register(struct lpm_cluster *cl)
		kfree(cl->drv);
		return -ENOMEM;
	}

	return 0;
}

/**
 * init_lpm - initializes the governor
 */
static int __init init_lpm(void)
{
	return cpuidle_register_governor(&lpm_governor);
}

postcore_initcall(init_lpm);

static void register_cpu_lpm_stats(struct lpm_cpu *cpu,
		struct lpm_cluster *parent)
{
@@ -1299,3 +1325,4 @@ void lpm_cpu_hotplug_enter(unsigned int cpu)
	msm_cpu_pm_enter_sleep(mode, false);
}