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: Sultan Alsawaf <sultan@kerneltoast.com>
Change-Id: Ibb92aa78b858b00b6687340f2efe66f86b866514
Signed-off-by: Nauval Rizky <enuma.alrizky@gmail.com>
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
This commit is contained in:
Sultan Alsawaf
2021-01-09 01:16:28 -08:00
committed by Pranav Vashi
parent 63279adc83
commit c08630a3b4
2 changed files with 29 additions and 1 deletions

View File

@@ -85,6 +85,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;
@@ -657,7 +664,7 @@ static int osm_cpufreq_cpu_init(struct cpufreq_policy *policy)
struct clk_osm *c, *parent;
struct clk_hw *p_hw;
int ret;
unsigned int i;
unsigned int i, cpu;
c = osm_configure_policy(policy);
if (!c) {
@@ -720,6 +727,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);
@@ -757,6 +768,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;
@@ -1270,6 +1291,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;

View File

@@ -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",