Skip to content

Commit 14c620c

Browse files
committed
Merge branch 'cpufreq/arm/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull cpufreq-arm fixes for 5.10-rc5 from Viresh Kumar: "- tegra186: Fix ->get() callback. - arm/scmi: Add dummy clock provider to fix failure." * 'cpufreq/arm/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: scmi: Fix OPP addition failure with a dummy clock provider cpufreq: tegra186: Fix get frequency callback
2 parents 09162bc + 8410e7f commit 14c620c

2 files changed

Lines changed: 27 additions & 12 deletions

File tree

drivers/cpufreq/scmi-cpufreq.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1010

11+
#include <linux/clk-provider.h>
1112
#include <linux/cpu.h>
1213
#include <linux/cpufreq.h>
1314
#include <linux/cpumask.h>
@@ -228,12 +229,17 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
228229
static int scmi_cpufreq_probe(struct scmi_device *sdev)
229230
{
230231
int ret;
232+
struct device *dev = &sdev->dev;
231233

232234
handle = sdev->handle;
233235

234236
if (!handle || !handle->perf_ops)
235237
return -ENODEV;
236238

239+
/* dummy clock provider as needed by OPP if clocks property is used */
240+
if (of_find_property(dev->of_node, "#clock-cells", NULL))
241+
devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL);
242+
237243
ret = cpufreq_register_driver(&scmi_cpufreq_driver);
238244
if (ret) {
239245
dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n",

drivers/cpufreq/tegra186-cpufreq.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ static const struct tegra186_cpufreq_cluster_info tegra186_clusters[] = {
4242
struct tegra186_cpufreq_cluster {
4343
const struct tegra186_cpufreq_cluster_info *info;
4444
struct cpufreq_frequency_table *table;
45+
u32 ref_clk_khz;
46+
u32 div;
4547
};
4648

4749
struct tegra186_cpufreq_data {
@@ -94,7 +96,7 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
9496

9597
static unsigned int tegra186_cpufreq_get(unsigned int cpu)
9698
{
97-
struct cpufreq_frequency_table *tbl;
99+
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
98100
struct cpufreq_policy *policy;
99101
void __iomem *edvd_reg;
100102
unsigned int i, freq = 0;
@@ -104,17 +106,23 @@ static unsigned int tegra186_cpufreq_get(unsigned int cpu)
104106
if (!policy)
105107
return 0;
106108

107-
tbl = policy->freq_table;
108109
edvd_reg = policy->driver_data;
109110
ndiv = readl(edvd_reg) & EDVD_CORE_VOLT_FREQ_F_MASK;
110111

111-
for (i = 0; tbl[i].frequency != CPUFREQ_TABLE_END; i++) {
112-
if ((tbl[i].driver_data & EDVD_CORE_VOLT_FREQ_F_MASK) == ndiv) {
113-
freq = tbl[i].frequency;
114-
break;
112+
for (i = 0; i < data->num_clusters; i++) {
113+
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
114+
int core;
115+
116+
for (core = 0; core < ARRAY_SIZE(cluster->info->cpus); core++) {
117+
if (cluster->info->cpus[core] != policy->cpu)
118+
continue;
119+
120+
freq = (cluster->ref_clk_khz * ndiv) / cluster->div;
121+
goto out;
115122
}
116123
}
117124

125+
out:
118126
cpufreq_cpu_put(policy);
119127

120128
return freq;
@@ -133,7 +141,7 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
133141

134142
static struct cpufreq_frequency_table *init_vhint_table(
135143
struct platform_device *pdev, struct tegra_bpmp *bpmp,
136-
unsigned int cluster_id)
144+
struct tegra186_cpufreq_cluster *cluster)
137145
{
138146
struct cpufreq_frequency_table *table;
139147
struct mrq_cpu_vhint_request req;
@@ -152,7 +160,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
152160

153161
memset(&req, 0, sizeof(req));
154162
req.addr = phys;
155-
req.cluster_id = cluster_id;
163+
req.cluster_id = cluster->info->bpmp_cluster_id;
156164

157165
memset(&msg, 0, sizeof(msg));
158166
msg.mrq = MRQ_CPU_VHINT;
@@ -185,6 +193,9 @@ static struct cpufreq_frequency_table *init_vhint_table(
185193
goto free;
186194
}
187195

196+
cluster->ref_clk_khz = data->ref_clk_hz / 1000;
197+
cluster->div = data->pdiv * data->mdiv;
198+
188199
for (i = data->vfloor, j = 0; i <= data->vceil; i++) {
189200
struct cpufreq_frequency_table *point;
190201
u16 ndiv = data->ndiv[i];
@@ -202,8 +213,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
202213

203214
point = &table[j++];
204215
point->driver_data = edvd_val;
205-
point->frequency = data->ref_clk_hz * ndiv / data->pdiv /
206-
data->mdiv / 1000;
216+
point->frequency = (cluster->ref_clk_khz * ndiv) / cluster->div;
207217
}
208218

209219
table[j].frequency = CPUFREQ_TABLE_END;
@@ -245,8 +255,7 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
245255
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
246256

247257
cluster->info = &tegra186_clusters[i];
248-
cluster->table = init_vhint_table(
249-
pdev, bpmp, cluster->info->bpmp_cluster_id);
258+
cluster->table = init_vhint_table(pdev, bpmp, cluster);
250259
if (IS_ERR(cluster->table)) {
251260
err = PTR_ERR(cluster->table);
252261
goto put_bpmp;

0 commit comments

Comments
 (0)