diff options
| author | Taniya Das <taniya.das@oss.qualcomm.com> | 2026-05-22 20:46:23 +0530 |
|---|---|---|
| committer | Viresh Kumar <viresh.kumar@linaro.org> | 2026-06-08 10:58:07 +0530 |
| commit | 4b5d3b847218b466527fb98990e193874081e0c7 (patch) | |
| tree | 8beae35f8f38d3d1c2d364807056034302c08397 /drivers/cpufreq | |
| parent | ef92354d0e6261e0ed792666972ef0b257cc0d8f (diff) | |
| download | linux-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.c | 23 |
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); |
