Skip to content

Commit 6b7195d

Browse files
committed
Merge tag 'cpufreq-arm-updates-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Merge ARM cpufreq updates for 6.9 from Viresh Kumar: "- General enhancements / cleanups to cpufreq drivers (tianyu2, Nícolas F. R. A. Prado, Erick Archer, Arnd Bergmann, Anastasia Belova). - Update cpufreq-dt-platdev to block/approve devices (Richard Acayan). - scmi: get transition delay from firmware (Pierre Gondois)." * tag 'cpufreq-arm-updates-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: scmi: Set transition_delay_us firmware: arm_scmi: Populate fast channel rate_limit firmware: arm_scmi: Populate perf commands rate_limit cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency cpufreq: dt-platdev: block SDM670 in cpufreq-dt-platdev cpufreq: mediatek-hw: Don't error out if supply is not found Documentation: power: Use kcalloc() instead of kzalloc() cpufreq: mediatek-hw: Wait for CPU supplies before probing cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value cpufreq: imx6: use regmap to read ocotp register
2 parents e4d0d7f + ad2a910 commit 6b7195d

File tree

13 files changed

+137
-43
lines changed

13 files changed

+137
-43
lines changed

Documentation/power/opp.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ dev_pm_opp_get_opp_count
305305
{
306306
/* Do things */
307307
num_available = dev_pm_opp_get_opp_count(dev);
308-
speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
308+
speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL);
309309
/* populate the table in increasing order */
310310
freq = 0;
311311
while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {

Documentation/translations/zh_CN/power/opp.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ dev_pm_opp_get_opp_count
274274
{
275275
/* 做一些事情 */
276276
num_available = dev_pm_opp_get_opp_count(dev);
277-
speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
277+
speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL);
278278
/* 按升序填充表 */
279279
freq = 0;
280280
while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {

drivers/cpufreq/Kconfig.arm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ config ARM_QCOM_CPUFREQ_NVMEM
173173
config ARM_QCOM_CPUFREQ_HW
174174
tristate "QCOM CPUFreq HW driver"
175175
depends on ARCH_QCOM || COMPILE_TEST
176+
depends on COMMON_CLK
176177
help
177178
Support for the CPUFreq HW driver.
178179
Some QCOM chipsets have a HW engine to offload the steps

drivers/cpufreq/brcmstb-avs-cpufreq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ static bool brcm_avs_is_firmware_loaded(struct private_data *priv)
481481
static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
482482
{
483483
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
484+
if (!policy)
485+
return 0;
484486
struct private_data *priv = policy->driver_data;
485487

486488
cpufreq_cpu_put(policy);

drivers/cpufreq/cpufreq-dt-platdev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ static const struct of_device_id blocklist[] __initconst = {
156156
{ .compatible = "qcom,sc7280", },
157157
{ .compatible = "qcom,sc8180x", },
158158
{ .compatible = "qcom,sc8280xp", },
159+
{ .compatible = "qcom,sdm670", },
159160
{ .compatible = "qcom,sdm845", },
160161
{ .compatible = "qcom,sdx75", },
161162
{ .compatible = "qcom,sm6115", },

drivers/cpufreq/imx6q-cpufreq.c

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <linux/pm_opp.h>
1515
#include <linux/platform_device.h>
1616
#include <linux/regulator/consumer.h>
17+
#include <linux/mfd/syscon.h>
18+
#include <linux/regmap.h>
1719

1820
#define PU_SOC_VOLTAGE_NORMAL 1250000
1921
#define PU_SOC_VOLTAGE_HIGH 1275000
@@ -225,8 +227,6 @@ static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq)
225227

226228
static int imx6q_opp_check_speed_grading(struct device *dev)
227229
{
228-
struct device_node *np;
229-
void __iomem *base;
230230
u32 val;
231231
int ret;
232232

@@ -235,16 +235,11 @@ static int imx6q_opp_check_speed_grading(struct device *dev)
235235
if (ret)
236236
return ret;
237237
} else {
238-
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
239-
if (!np)
240-
return -ENOENT;
238+
struct regmap *ocotp;
241239

242-
base = of_iomap(np, 0);
243-
of_node_put(np);
244-
if (!base) {
245-
dev_err(dev, "failed to map ocotp\n");
246-
return -EFAULT;
247-
}
240+
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6q-ocotp");
241+
if (IS_ERR(ocotp))
242+
return -ENOENT;
248243

249244
/*
250245
* SPEED_GRADING[1:0] defines the max speed of ARM:
@@ -254,8 +249,7 @@ static int imx6q_opp_check_speed_grading(struct device *dev)
254249
* 2b'00: 792000000Hz;
255250
* We need to set the max speed of ARM according to fuse map.
256251
*/
257-
val = readl_relaxed(base + OCOTP_CFG3);
258-
iounmap(base);
252+
regmap_read(ocotp, OCOTP_CFG3, &val);
259253
}
260254

261255
val >>= OCOTP_CFG3_SPEED_SHIFT;
@@ -290,25 +284,16 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
290284
if (ret)
291285
return ret;
292286
} else {
293-
struct device_node *np;
294-
void __iomem *base;
295-
296-
np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
297-
if (!np)
298-
np = of_find_compatible_node(NULL, NULL,
299-
"fsl,imx6ull-ocotp");
300-
if (!np)
301-
return -ENOENT;
287+
struct regmap *ocotp;
302288

303-
base = of_iomap(np, 0);
304-
of_node_put(np);
305-
if (!base) {
306-
dev_err(dev, "failed to map ocotp\n");
307-
return -EFAULT;
308-
}
289+
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ul-ocotp");
290+
if (IS_ERR(ocotp))
291+
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ull-ocotp");
292+
293+
if (IS_ERR(ocotp))
294+
return -ENOENT;
309295

310-
val = readl_relaxed(base + OCOTP_CFG3);
311-
iounmap(base);
296+
regmap_read(ocotp, OCOTP_CFG3, &val);
312297
}
313298

314299
/*

drivers/cpufreq/mediatek-cpufreq-hw.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/of.h>
1414
#include <linux/of_platform.h>
1515
#include <linux/platform_device.h>
16+
#include <linux/regulator/consumer.h>
1617
#include <linux/slab.h>
1718

1819
#define LUT_MAX_ENTRIES 32U
@@ -300,7 +301,23 @@ static struct cpufreq_driver cpufreq_mtk_hw_driver = {
300301
static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
301302
{
302303
const void *data;
303-
int ret;
304+
int ret, cpu;
305+
struct device *cpu_dev;
306+
struct regulator *cpu_reg;
307+
308+
/* Make sure that all CPU supplies are available before proceeding. */
309+
for_each_possible_cpu(cpu) {
310+
cpu_dev = get_cpu_device(cpu);
311+
if (!cpu_dev)
312+
return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
313+
"Failed to get cpu%d device\n", cpu);
314+
315+
cpu_reg = devm_regulator_get(cpu_dev, "cpu");
316+
if (IS_ERR(cpu_reg))
317+
return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
318+
"CPU%d regulator get failed\n", cpu);
319+
}
320+
304321

305322
data = of_device_get_match_data(&pdev->dev);
306323
if (!data)

drivers/cpufreq/scmi-cpufreq.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,29 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
144144
return 0;
145145
}
146146

147+
static int
148+
scmi_get_rate_limit(u32 domain, bool has_fast_switch)
149+
{
150+
int ret, rate_limit;
151+
152+
if (has_fast_switch) {
153+
/*
154+
* Fast channels are used whenever available,
155+
* so use their rate_limit value if populated.
156+
*/
157+
ret = perf_ops->fast_switch_rate_limit(ph, domain,
158+
&rate_limit);
159+
if (!ret && rate_limit)
160+
return rate_limit;
161+
}
162+
163+
ret = perf_ops->rate_limit_get(ph, domain, &rate_limit);
164+
if (ret)
165+
return 0;
166+
167+
return rate_limit;
168+
}
169+
147170
static int scmi_cpufreq_init(struct cpufreq_policy *policy)
148171
{
149172
int ret, nr_opp, domain;
@@ -250,6 +273,9 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
250273
policy->fast_switch_possible =
251274
perf_ops->fast_switch_possible(ph, domain);
252275

276+
policy->transition_delay_us =
277+
scmi_get_rate_limit(domain, policy->fast_switch_possible);
278+
253279
return 0;
254280

255281
out_free_opp:

drivers/firmware/arm_scmi/driver.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@ static void
16171617
scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
16181618
u8 describe_id, u32 message_id, u32 valid_size,
16191619
u32 domain, void __iomem **p_addr,
1620-
struct scmi_fc_db_info **p_db)
1620+
struct scmi_fc_db_info **p_db, u32 *rate_limit)
16211621
{
16221622
int ret;
16231623
u32 flags;
@@ -1661,6 +1661,9 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
16611661
goto err_xfer;
16621662
}
16631663

1664+
if (rate_limit)
1665+
*rate_limit = le32_to_cpu(resp->rate_limit) & GENMASK(19, 0);
1666+
16641667
phys_addr = le32_to_cpu(resp->chan_addr_low);
16651668
phys_addr |= (u64)le32_to_cpu(resp->chan_addr_high) << 32;
16661669
addr = devm_ioremap(ph->dev, phys_addr, size);

drivers/firmware/arm_scmi/perf.c

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct perf_dom_info {
153153
bool perf_fastchannels;
154154
bool level_indexing_mode;
155155
u32 opp_count;
156+
u32 rate_limit_us;
156157
u32 sustained_freq_khz;
157158
u32 sustained_perf_level;
158159
unsigned long mult_factor;
@@ -266,6 +267,8 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
266267
if (PROTOCOL_REV_MAJOR(version) >= 0x4)
267268
dom_info->level_indexing_mode =
268269
SUPPORTS_LEVEL_INDEXING(flags);
270+
dom_info->rate_limit_us = le32_to_cpu(attr->rate_limit_us) &
271+
GENMASK(19, 0);
269272
dom_info->sustained_freq_khz =
270273
le32_to_cpu(attr->sustained_freq_khz);
271274
dom_info->sustained_perf_level =
@@ -786,23 +789,27 @@ static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph,
786789

787790
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
788791
PERF_LEVEL_GET, 4, dom->id,
789-
&fc[PERF_FC_LEVEL].get_addr, NULL);
792+
&fc[PERF_FC_LEVEL].get_addr, NULL,
793+
&fc[PERF_FC_LEVEL].rate_limit);
790794

791795
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
792796
PERF_LIMITS_GET, 8, dom->id,
793-
&fc[PERF_FC_LIMIT].get_addr, NULL);
797+
&fc[PERF_FC_LIMIT].get_addr, NULL,
798+
&fc[PERF_FC_LIMIT].rate_limit);
794799

795800
if (dom->info.set_perf)
796801
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
797802
PERF_LEVEL_SET, 4, dom->id,
798803
&fc[PERF_FC_LEVEL].set_addr,
799-
&fc[PERF_FC_LEVEL].set_db);
804+
&fc[PERF_FC_LEVEL].set_db,
805+
&fc[PERF_FC_LEVEL].rate_limit);
800806

801807
if (dom->set_limits)
802808
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
803809
PERF_LIMITS_SET, 8, dom->id,
804810
&fc[PERF_FC_LIMIT].set_addr,
805-
&fc[PERF_FC_LIMIT].set_db);
811+
&fc[PERF_FC_LIMIT].set_db,
812+
&fc[PERF_FC_LIMIT].rate_limit);
806813

807814
dom->fc_info = fc;
808815
}
@@ -855,6 +862,23 @@ scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph,
855862
return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
856863
}
857864

865+
static int
866+
scmi_dvfs_rate_limit_get(const struct scmi_protocol_handle *ph,
867+
u32 domain, u32 *rate_limit)
868+
{
869+
struct perf_dom_info *dom;
870+
871+
if (!rate_limit)
872+
return -EINVAL;
873+
874+
dom = scmi_perf_domain_lookup(ph, domain);
875+
if (IS_ERR(dom))
876+
return PTR_ERR(dom);
877+
878+
*rate_limit = dom->rate_limit_us;
879+
return 0;
880+
}
881+
858882
static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
859883
unsigned long freq, bool poll)
860884
{
@@ -954,6 +978,25 @@ static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph,
954978
return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr;
955979
}
956980

981+
static int scmi_fast_switch_rate_limit(const struct scmi_protocol_handle *ph,
982+
u32 domain, u32 *rate_limit)
983+
{
984+
struct perf_dom_info *dom;
985+
986+
if (!rate_limit)
987+
return -EINVAL;
988+
989+
dom = scmi_perf_domain_lookup(ph, domain);
990+
if (IS_ERR(dom))
991+
return PTR_ERR(dom);
992+
993+
if (!dom->fc_info)
994+
return -EINVAL;
995+
996+
*rate_limit = dom->fc_info[PERF_FC_LEVEL].rate_limit;
997+
return 0;
998+
}
999+
9571000
static enum scmi_power_scale
9581001
scmi_power_scale_get(const struct scmi_protocol_handle *ph)
9591002
{
@@ -970,11 +1013,13 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
9701013
.level_set = scmi_perf_level_set,
9711014
.level_get = scmi_perf_level_get,
9721015
.transition_latency_get = scmi_dvfs_transition_latency_get,
1016+
.rate_limit_get = scmi_dvfs_rate_limit_get,
9731017
.device_opps_add = scmi_dvfs_device_opps_add,
9741018
.freq_set = scmi_dvfs_freq_set,
9751019
.freq_get = scmi_dvfs_freq_get,
9761020
.est_power_get = scmi_dvfs_est_power_get,
9771021
.fast_switch_possible = scmi_fast_switch_possible,
1022+
.fast_switch_rate_limit = scmi_fast_switch_rate_limit,
9781023
.power_scale_get = scmi_power_scale_get,
9791024
};
9801025

0 commit comments

Comments
 (0)