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

Commit 99a974d4 authored by Sultan Alsawaf's avatar Sultan Alsawaf Committed by Harshit Jain
Browse files

clk: qcom: clk-cpu-osm: Set each CPU clock to its max when waking up



The default frequency on Qualcomm CPUs is the lowest frequency supported
by the CPU. This hurts latency when waking from suspend, as each CPU
coming online runs at its lowest frequency until the governor can take
over later. To speed up waking from suspend, hijack the CPUHP_AP_ONLINE
hook and use it to set the highest available frequency on each CPU as
they come online. This is done behind the governor's back but it's fine
because the governor isn't running at this point in time for a CPU
that's coming online.

This speeds up waking from suspend significantly.

Signed-off-by: default avatarSultan Alsawaf <sultan@kerneltoast.com>
Signed-off-by: default avatarYaroslav Furman <yaro330@gmail.com>
parent 62b3c081
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -86,6 +86,13 @@ struct clk_osm {
	cpumask_t related_cpus;
};

struct clk_osm_boost {
	struct clk_osm *c;
	unsigned int max_index;
};

static DEFINE_PER_CPU(struct clk_osm_boost, clk_boost_pcpu);

static bool is_sdmshrike;
static bool is_sm6150;
static bool is_sdmmagpie;
@@ -670,7 +677,7 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
	struct clk_osm *c, *parent;
	struct clk_hw *p_hw;
	int ret, of_len;
	unsigned int i;
	unsigned int i, cpu;
	u32 *of_table = NULL;
	char tbl_name[] = "qcom,cpufreq-table-##";

@@ -759,6 +766,10 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
	policy->dvfs_possible_from_any_cpu = true;
	policy->fast_switch_possible = true;
	policy->driver_data = c;
	for_each_cpu(cpu, &c->related_cpus) {
		per_cpu(clk_boost_pcpu, cpu).c = c;
		per_cpu(clk_boost_pcpu, cpu).max_index = i - 1;
	}

	cpumask_copy(policy->cpus, &c->related_cpus);

@@ -798,6 +809,16 @@ static struct cpufreq_driver qcom_osm_cpufreq_driver = {
	.boost_enabled	= true,
};

static int cpuhp_osm_online(unsigned int cpu)
{
	struct clk_osm_boost *b = &per_cpu(clk_boost_pcpu, cpu);
	struct clk_osm *c = b->c;

	/* Set the max frequency by default before the governor takes over */
	osm_set_index(c, b->max_index, c->core_num);
	return 0;
}

static u32 find_voltage(struct clk_osm *c, unsigned long rate)
{
	struct osm_entry *table = c->osm_table;
@@ -1312,6 +1333,11 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
	if (rc)
		goto provider_err;

	rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE, "osm-cpufreq:online",
				       cpuhp_osm_online, NULL);
	if (rc)
		dev_err(&pdev->dev, "CPUHP callback setup failed, rc=%d\n", rc);

	pr_info("OSM CPUFreq driver inited\n");
	return 0;

+2 −0
Original line number Diff line number Diff line
@@ -1592,11 +1592,13 @@ static struct cpuhp_step cpuhp_ap_states[] = {
		.startup.single		= NULL,
		.teardown.single	= smpcfd_dying_cpu,
	},
#ifndef CONFIG_CLOCK_CPU_OSM
	/* Entry state on starting. Interrupts enabled from here on. Transient
	 * state for synchronsization */
	[CPUHP_AP_ONLINE] = {
		.name			= "ap:online",
	},
#endif
	/* Handle smpboot threads park/unpark */
	[CPUHP_AP_SMPBOOT_THREADS] = {
		.name			= "smpboot/threads:online",