mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Merge "cpufreq: qcom: cpufreq-hw: Add support for SDPM rail voting"
This commit is contained in:
commit
4aeece1d4c
1 changed files with 67 additions and 6 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#define GT_IRQ_STATUS BIT(2)
|
||||
#define MAX_FN_SIZE 20
|
||||
#define LIMITS_POLLING_DELAY_MS 10
|
||||
#define MAX_ROW 2
|
||||
|
||||
#define CYCLE_CNTR_OFFSET(c, m, acc_count) \
|
||||
(acc_count ? ((c - cpumask_first(m) + 1) * 4) : 0)
|
||||
|
|
@ -60,6 +61,8 @@ struct cpufreq_qcom {
|
|||
struct cpufreq_frequency_table *table;
|
||||
void __iomem *base;
|
||||
void __iomem *pdmem_base;
|
||||
void __iomem **sdpm_base;
|
||||
int sdpm_base_count;
|
||||
cpumask_t related_cpus;
|
||||
unsigned long dcvsh_freq_limit;
|
||||
struct delayed_work freq_poll_work;
|
||||
|
|
@ -236,19 +239,25 @@ static int
|
|||
qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
|
||||
unsigned int index)
|
||||
{
|
||||
struct cpufreq_qcom *c;
|
||||
struct cpufreq_qcom *c = qcom_freq_domain_map[policy->cpu];
|
||||
unsigned long freq = policy->freq_table[index].frequency;
|
||||
int i;
|
||||
|
||||
if (perf_lock_support) {
|
||||
c = qcom_freq_domain_map[policy->cpu];
|
||||
if (c->pdmem_base)
|
||||
writel_relaxed(index, c->pdmem_base);
|
||||
}
|
||||
|
||||
for (i = 0; i < c->sdpm_base_count && freq > policy->cur; i++)
|
||||
writel_relaxed(freq / 1000, c->sdpm_base[i]);
|
||||
|
||||
writel_relaxed(index, policy->driver_data + offsets[REG_PERF_STATE]);
|
||||
arch_set_freq_scale(policy->related_cpus,
|
||||
policy->freq_table[index].frequency,
|
||||
arch_set_freq_scale(policy->related_cpus, freq,
|
||||
policy->cpuinfo.max_freq);
|
||||
|
||||
for (i = 0; i < c->sdpm_base_count && freq < policy->cur; i++)
|
||||
writel_relaxed(freq / 1000, c->sdpm_base[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -379,6 +388,30 @@ static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
|
|||
of_node_put(np);
|
||||
}
|
||||
|
||||
static int qcom_cpufreq_hw_suspend(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpufreq_qcom *c = qcom_freq_domain_map[policy->cpu];
|
||||
unsigned long freq = policy->freq_table[0].frequency;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < c->sdpm_base_count && freq < policy->cur; i++)
|
||||
writel_relaxed(freq / 1000, c->sdpm_base[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_cpufreq_hw_resume(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpufreq_qcom *c = qcom_freq_domain_map[policy->cpu];
|
||||
unsigned long freq = policy->cur;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < c->sdpm_base_count; i++)
|
||||
writel_relaxed(freq / 1000, c->sdpm_base[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver cpufreq_qcom_hw_driver = {
|
||||
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
|
||||
CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
|
||||
|
|
@ -391,6 +424,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
|
|||
.attr = qcom_cpufreq_hw_attr,
|
||||
.boost_enabled = true,
|
||||
.ready = qcom_cpufreq_ready,
|
||||
.suspend = qcom_cpufreq_hw_suspend,
|
||||
.resume = qcom_cpufreq_hw_resume,
|
||||
};
|
||||
|
||||
static int qcom_cpufreq_hw_read_lut(struct platform_device *pdev,
|
||||
|
|
@ -486,7 +521,8 @@ static int qcom_cpu_resources_init(struct platform_device *pdev,
|
|||
struct device *dev = &pdev->dev;
|
||||
void __iomem *base;
|
||||
char pdmem_name[MAX_FN_SIZE] = {};
|
||||
int ret, cpu_r;
|
||||
char sdpm_name[MAX_FN_SIZE] = {};
|
||||
int ret, cpu_r, len, reg, size, i, j;
|
||||
|
||||
c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
|
||||
if (!c)
|
||||
|
|
@ -543,6 +579,31 @@ static int qcom_cpu_resources_init(struct platform_device *pdev,
|
|||
c->pdmem_base = base;
|
||||
}
|
||||
|
||||
snprintf(sdpm_name, sizeof(sdpm_name), "qcom,sdpm-cx-mx-%d", index);
|
||||
len = of_property_count_u32_elems(dev->of_node, sdpm_name);
|
||||
if (len > 0) {
|
||||
c->sdpm_base_count = len / MAX_ROW;
|
||||
c->sdpm_base = devm_kcalloc(dev, c->sdpm_base_count,
|
||||
sizeof(*c->sdpm_base), GFP_KERNEL);
|
||||
if (!c->sdpm_base)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0, j = 0; i < c->sdpm_base_count; i++, j += 2) {
|
||||
of_property_read_u32_index(dev->of_node, sdpm_name,
|
||||
j, ®);
|
||||
of_property_read_u32_index(dev->of_node, sdpm_name,
|
||||
j + 1, &size);
|
||||
base = devm_ioremap(dev, reg, size);
|
||||
if (IS_ERR(base)) {
|
||||
dev_err(dev, "Failed to map base %d domain-%d\n",
|
||||
i, index);
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
c->sdpm_base[i] = base;
|
||||
}
|
||||
}
|
||||
|
||||
if (of_find_property(dev->of_node, "interrupts", NULL)) {
|
||||
c->dcvsh_irq = of_irq_get(dev->of_node, index);
|
||||
if (c->dcvsh_irq > 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue