summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorTaniya Das <taniya.das@oss.qualcomm.com>2026-05-22 20:46:23 +0530
committerViresh Kumar <viresh.kumar@linaro.org>2026-06-08 10:58:07 +0530
commit4b5d3b847218b466527fb98990e193874081e0c7 (patch)
tree8beae35f8f38d3d1c2d364807056034302c08397 /drivers/cpufreq
parentef92354d0e6261e0ed792666972ef0b257cc0d8f (diff)
downloadlinux-next-4b5d3b847218b466527fb98990e193874081e0c7.tar.gz
linux-next-4b5d3b847218b466527fb98990e193874081e0c7.zip
cpufreq: qcom: Add cpufreq scaling support for Qualcomm Shikra SoC
The Qualcomm Shikra cpufreq hardware is functionally identical to EPSS, but supports only up to 12 frequency lookup table (LUT) entries. When all 12 entries are populated, the existing repetitive LUT entry check may read beyond valid entries and expose incorrect frequencies. Hence, introduce shikra_epss_soc_data that reuses EPSS configuration with appropriate LUT entries limit. Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/qcom-cpufreq-hw.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index ef19faedbfec..874ff3fb9d97 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitfield.h>
@@ -40,6 +41,7 @@ struct qcom_cpufreq_soc_data {
u32 reg_intr_clr;
u32 reg_current_vote;
u32 reg_perf_state;
+ u32 lut_max_entries;
u8 lut_row_size;
};
@@ -156,7 +158,7 @@ static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy)
soc_data = qcom_cpufreq.soc_data;
index = readl_relaxed(data->base + soc_data->reg_perf_state);
- index = min(index, LUT_MAX_ENTRIES - 1);
+ index = min(index, soc_data->lut_max_entries - 1);
return policy->freq_table[index].frequency;
}
@@ -211,7 +213,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
struct qcom_cpufreq_data *drv_data = policy->driver_data;
const struct qcom_cpufreq_soc_data *soc_data = qcom_cpufreq.soc_data;
- table = kzalloc_objs(*table, LUT_MAX_ENTRIES + 1);
+ table = kzalloc_objs(*table, soc_data->lut_max_entries + 1);
if (!table)
return -ENOMEM;
@@ -236,7 +238,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
icc_scaling_enabled = false;
}
- for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+ for (i = 0; i < soc_data->lut_max_entries; i++) {
data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut +
i * soc_data->lut_row_size);
src = FIELD_GET(LUT_SRC, data);
@@ -405,6 +407,7 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = {
.reg_current_vote = 0x704,
.reg_perf_state = 0x920,
.lut_row_size = 32,
+ .lut_max_entries = LUT_MAX_ENTRIES,
};
static const struct qcom_cpufreq_soc_data epss_soc_data = {
@@ -416,11 +419,25 @@ static const struct qcom_cpufreq_soc_data epss_soc_data = {
.reg_intr_clr = 0x308,
.reg_perf_state = 0x320,
.lut_row_size = 4,
+ .lut_max_entries = LUT_MAX_ENTRIES,
+};
+
+static const struct qcom_cpufreq_soc_data shikra_epss_soc_data = {
+ .reg_enable = 0x0,
+ .reg_domain_state = 0x20,
+ .reg_dcvs_ctrl = 0xb0,
+ .reg_freq_lut = 0x100,
+ .reg_volt_lut = 0x200,
+ .reg_intr_clr = 0x308,
+ .reg_perf_state = 0x320,
+ .lut_row_size = 4,
+ .lut_max_entries = 12,
};
static const struct of_device_id qcom_cpufreq_hw_match[] = {
{ .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data },
{ .compatible = "qcom,cpufreq-epss", .data = &epss_soc_data },
+ { .compatible = "qcom,shikra-epss", .data = &shikra_epss_soc_data },
{}
};
MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);