mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
ARM cpufreq updates for 6.9
- 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). -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmXu2CMACgkQ0rkcPK6B EhxGMQ/+IBFDtHVRzPO6dQRWO1AFgUB3/XAWLPVjvVB3bhsBQS4BGFkkElyfUyfa vIQlZnerhgWbhw3pkLwbirN+yW9DWkBIgHwOtGaYaK9LeXEQfZ2+Yezc9uUe6syN HtHVLHntGetDP6FRQarTIeWYSE5FJOf1QhREIwBbXCmB4VvudcBuafAgykbKN92T p0bVHfKhaHlbYlOui3hJVBfRdDAgHlimawkqzOwqtugsoZ7rQcJDxO1OaE+ovH1E 5KlXTbugcDkct1g66SPOZxx6APQ4EeXFanlmBaQAmgT1unVRuqMQpLrkxgiFywcm ypMz7SGwXsh41J0aZAEhpRvwPu3pGLtdQOTK3Pwa24xKkn17I6yYlyLyCGseXiCY wZz4W+Y6WBP4wwUnYBB6TuwfROdY7wy9KTswxd/qWP4Q7LKXyangB6d0pXV6eSUc XPyZ21NiTw4BUCkzOzl5+4um2uF2t62sTWh1hg/KOKwnlAkBqnt8/BvkuoNYqRte sX3xiWjcF0sq1kZlkHtE8USFqiSioBgQm2KCjnuc5N5rsK9Qmc7fBHEe4sP975HV otHYlBai/Y5D5piTOJMVv92+Ghw9jjLPUmn1IUppt8QVLv0RY1nPmp1WSu2yh80/ 2a2d9bR5llDfyt1vh75X7Tdt1Bsf9LSJyYptfxJvge/L/7jrGhI= =Hu43 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
6b7195d305
13 changed files with 136 additions and 42 deletions
|
@ -305,7 +305,7 @@ dev_pm_opp_get_opp_count
|
|||
{
|
||||
/* Do things */
|
||||
num_available = dev_pm_opp_get_opp_count(dev);
|
||||
speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
|
||||
speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL);
|
||||
/* populate the table in increasing order */
|
||||
freq = 0;
|
||||
while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
|
||||
|
|
|
@ -274,7 +274,7 @@ dev_pm_opp_get_opp_count
|
|||
{
|
||||
/* 做一些事情 */
|
||||
num_available = dev_pm_opp_get_opp_count(dev);
|
||||
speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
|
||||
speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL);
|
||||
/* 按升序填充表 */
|
||||
freq = 0;
|
||||
while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
|
||||
|
|
|
@ -173,6 +173,7 @@ config ARM_QCOM_CPUFREQ_NVMEM
|
|||
config ARM_QCOM_CPUFREQ_HW
|
||||
tristate "QCOM CPUFreq HW driver"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
help
|
||||
Support for the CPUFreq HW driver.
|
||||
Some QCOM chipsets have a HW engine to offload the steps
|
||||
|
|
|
@ -481,6 +481,8 @@ static bool brcm_avs_is_firmware_loaded(struct private_data *priv)
|
|||
static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
|
||||
{
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
|
||||
if (!policy)
|
||||
return 0;
|
||||
struct private_data *priv = policy->driver_data;
|
||||
|
||||
cpufreq_cpu_put(policy);
|
||||
|
|
|
@ -156,6 +156,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
|||
{ .compatible = "qcom,sc7280", },
|
||||
{ .compatible = "qcom,sc8180x", },
|
||||
{ .compatible = "qcom,sc8280xp", },
|
||||
{ .compatible = "qcom,sdm670", },
|
||||
{ .compatible = "qcom,sdm845", },
|
||||
{ .compatible = "qcom,sdx75", },
|
||||
{ .compatible = "qcom,sm6115", },
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/pm_opp.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define PU_SOC_VOLTAGE_NORMAL 1250000
|
||||
#define PU_SOC_VOLTAGE_HIGH 1275000
|
||||
|
@ -225,8 +227,6 @@ static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq)
|
|||
|
||||
static int imx6q_opp_check_speed_grading(struct device *dev)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
|
@ -235,16 +235,11 @@ static int imx6q_opp_check_speed_grading(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
struct regmap *ocotp;
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!base) {
|
||||
dev_err(dev, "failed to map ocotp\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6q-ocotp");
|
||||
if (IS_ERR(ocotp))
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* SPEED_GRADING[1:0] defines the max speed of ARM:
|
||||
|
@ -254,8 +249,7 @@ static int imx6q_opp_check_speed_grading(struct device *dev)
|
|||
* 2b'00: 792000000Hz;
|
||||
* We need to set the max speed of ARM according to fuse map.
|
||||
*/
|
||||
val = readl_relaxed(base + OCOTP_CFG3);
|
||||
iounmap(base);
|
||||
regmap_read(ocotp, OCOTP_CFG3, &val);
|
||||
}
|
||||
|
||||
val >>= OCOTP_CFG3_SPEED_SHIFT;
|
||||
|
@ -290,25 +284,16 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
struct regmap *ocotp;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
|
||||
if (!np)
|
||||
np = of_find_compatible_node(NULL, NULL,
|
||||
"fsl,imx6ull-ocotp");
|
||||
if (!np)
|
||||
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ul-ocotp");
|
||||
if (IS_ERR(ocotp))
|
||||
ocotp = syscon_regmap_lookup_by_compatible("fsl,imx6ull-ocotp");
|
||||
|
||||
if (IS_ERR(ocotp))
|
||||
return -ENOENT;
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!base) {
|
||||
dev_err(dev, "failed to map ocotp\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
val = readl_relaxed(base + OCOTP_CFG3);
|
||||
iounmap(base);
|
||||
regmap_read(ocotp, OCOTP_CFG3, &val);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define LUT_MAX_ENTRIES 32U
|
||||
|
@ -300,7 +301,23 @@ static struct cpufreq_driver cpufreq_mtk_hw_driver = {
|
|||
static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
const void *data;
|
||||
int ret;
|
||||
int ret, cpu;
|
||||
struct device *cpu_dev;
|
||||
struct regulator *cpu_reg;
|
||||
|
||||
/* Make sure that all CPU supplies are available before proceeding. */
|
||||
for_each_possible_cpu(cpu) {
|
||||
cpu_dev = get_cpu_device(cpu);
|
||||
if (!cpu_dev)
|
||||
return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
|
||||
"Failed to get cpu%d device\n", cpu);
|
||||
|
||||
cpu_reg = devm_regulator_get(cpu_dev, "cpu");
|
||||
if (IS_ERR(cpu_reg))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
|
||||
"CPU%d regulator get failed\n", cpu);
|
||||
}
|
||||
|
||||
|
||||
data = of_device_get_match_data(&pdev->dev);
|
||||
if (!data)
|
||||
|
|
|
@ -144,6 +144,29 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
scmi_get_rate_limit(u32 domain, bool has_fast_switch)
|
||||
{
|
||||
int ret, rate_limit;
|
||||
|
||||
if (has_fast_switch) {
|
||||
/*
|
||||
* Fast channels are used whenever available,
|
||||
* so use their rate_limit value if populated.
|
||||
*/
|
||||
ret = perf_ops->fast_switch_rate_limit(ph, domain,
|
||||
&rate_limit);
|
||||
if (!ret && rate_limit)
|
||||
return rate_limit;
|
||||
}
|
||||
|
||||
ret = perf_ops->rate_limit_get(ph, domain, &rate_limit);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return rate_limit;
|
||||
}
|
||||
|
||||
static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int ret, nr_opp, domain;
|
||||
|
@ -250,6 +273,9 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
|||
policy->fast_switch_possible =
|
||||
perf_ops->fast_switch_possible(ph, domain);
|
||||
|
||||
policy->transition_delay_us =
|
||||
scmi_get_rate_limit(domain, policy->fast_switch_possible);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_opp:
|
||||
|
|
|
@ -1617,7 +1617,7 @@ static void
|
|||
scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
|
||||
u8 describe_id, u32 message_id, u32 valid_size,
|
||||
u32 domain, void __iomem **p_addr,
|
||||
struct scmi_fc_db_info **p_db)
|
||||
struct scmi_fc_db_info **p_db, u32 *rate_limit)
|
||||
{
|
||||
int ret;
|
||||
u32 flags;
|
||||
|
@ -1661,6 +1661,9 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
|
|||
goto err_xfer;
|
||||
}
|
||||
|
||||
if (rate_limit)
|
||||
*rate_limit = le32_to_cpu(resp->rate_limit) & GENMASK(19, 0);
|
||||
|
||||
phys_addr = le32_to_cpu(resp->chan_addr_low);
|
||||
phys_addr |= (u64)le32_to_cpu(resp->chan_addr_high) << 32;
|
||||
addr = devm_ioremap(ph->dev, phys_addr, size);
|
||||
|
|
|
@ -153,6 +153,7 @@ struct perf_dom_info {
|
|||
bool perf_fastchannels;
|
||||
bool level_indexing_mode;
|
||||
u32 opp_count;
|
||||
u32 rate_limit_us;
|
||||
u32 sustained_freq_khz;
|
||||
u32 sustained_perf_level;
|
||||
unsigned long mult_factor;
|
||||
|
@ -266,6 +267,8 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
|
|||
if (PROTOCOL_REV_MAJOR(version) >= 0x4)
|
||||
dom_info->level_indexing_mode =
|
||||
SUPPORTS_LEVEL_INDEXING(flags);
|
||||
dom_info->rate_limit_us = le32_to_cpu(attr->rate_limit_us) &
|
||||
GENMASK(19, 0);
|
||||
dom_info->sustained_freq_khz =
|
||||
le32_to_cpu(attr->sustained_freq_khz);
|
||||
dom_info->sustained_perf_level =
|
||||
|
@ -786,23 +789,27 @@ static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph,
|
|||
|
||||
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
|
||||
PERF_LEVEL_GET, 4, dom->id,
|
||||
&fc[PERF_FC_LEVEL].get_addr, NULL);
|
||||
&fc[PERF_FC_LEVEL].get_addr, NULL,
|
||||
&fc[PERF_FC_LEVEL].rate_limit);
|
||||
|
||||
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
|
||||
PERF_LIMITS_GET, 8, dom->id,
|
||||
&fc[PERF_FC_LIMIT].get_addr, NULL);
|
||||
&fc[PERF_FC_LIMIT].get_addr, NULL,
|
||||
&fc[PERF_FC_LIMIT].rate_limit);
|
||||
|
||||
if (dom->info.set_perf)
|
||||
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
|
||||
PERF_LEVEL_SET, 4, dom->id,
|
||||
&fc[PERF_FC_LEVEL].set_addr,
|
||||
&fc[PERF_FC_LEVEL].set_db);
|
||||
&fc[PERF_FC_LEVEL].set_db,
|
||||
&fc[PERF_FC_LEVEL].rate_limit);
|
||||
|
||||
if (dom->set_limits)
|
||||
ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
|
||||
PERF_LIMITS_SET, 8, dom->id,
|
||||
&fc[PERF_FC_LIMIT].set_addr,
|
||||
&fc[PERF_FC_LIMIT].set_db);
|
||||
&fc[PERF_FC_LIMIT].set_db,
|
||||
&fc[PERF_FC_LIMIT].rate_limit);
|
||||
|
||||
dom->fc_info = fc;
|
||||
}
|
||||
|
@ -855,6 +862,23 @@ scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph,
|
|||
return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
|
||||
}
|
||||
|
||||
static int
|
||||
scmi_dvfs_rate_limit_get(const struct scmi_protocol_handle *ph,
|
||||
u32 domain, u32 *rate_limit)
|
||||
{
|
||||
struct perf_dom_info *dom;
|
||||
|
||||
if (!rate_limit)
|
||||
return -EINVAL;
|
||||
|
||||
dom = scmi_perf_domain_lookup(ph, domain);
|
||||
if (IS_ERR(dom))
|
||||
return PTR_ERR(dom);
|
||||
|
||||
*rate_limit = dom->rate_limit_us;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
|
||||
unsigned long freq, bool poll)
|
||||
{
|
||||
|
@ -954,6 +978,25 @@ static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph,
|
|||
return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr;
|
||||
}
|
||||
|
||||
static int scmi_fast_switch_rate_limit(const struct scmi_protocol_handle *ph,
|
||||
u32 domain, u32 *rate_limit)
|
||||
{
|
||||
struct perf_dom_info *dom;
|
||||
|
||||
if (!rate_limit)
|
||||
return -EINVAL;
|
||||
|
||||
dom = scmi_perf_domain_lookup(ph, domain);
|
||||
if (IS_ERR(dom))
|
||||
return PTR_ERR(dom);
|
||||
|
||||
if (!dom->fc_info)
|
||||
return -EINVAL;
|
||||
|
||||
*rate_limit = dom->fc_info[PERF_FC_LEVEL].rate_limit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum scmi_power_scale
|
||||
scmi_power_scale_get(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
|
@ -970,11 +1013,13 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
|
|||
.level_set = scmi_perf_level_set,
|
||||
.level_get = scmi_perf_level_get,
|
||||
.transition_latency_get = scmi_dvfs_transition_latency_get,
|
||||
.rate_limit_get = scmi_dvfs_rate_limit_get,
|
||||
.device_opps_add = scmi_dvfs_device_opps_add,
|
||||
.freq_set = scmi_dvfs_freq_set,
|
||||
.freq_get = scmi_dvfs_freq_get,
|
||||
.est_power_get = scmi_dvfs_est_power_get,
|
||||
.fast_switch_possible = scmi_fast_switch_possible,
|
||||
.fast_switch_rate_limit = scmi_fast_switch_rate_limit,
|
||||
.power_scale_get = scmi_power_scale_get,
|
||||
};
|
||||
|
||||
|
|
|
@ -703,20 +703,24 @@ static void scmi_powercap_domain_init_fc(const struct scmi_protocol_handle *ph,
|
|||
ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
|
||||
POWERCAP_CAP_SET, 4, domain,
|
||||
&fc[POWERCAP_FC_CAP].set_addr,
|
||||
&fc[POWERCAP_FC_CAP].set_db);
|
||||
&fc[POWERCAP_FC_CAP].set_db,
|
||||
&fc[POWERCAP_FC_CAP].rate_limit);
|
||||
|
||||
ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
|
||||
POWERCAP_CAP_GET, 4, domain,
|
||||
&fc[POWERCAP_FC_CAP].get_addr, NULL);
|
||||
&fc[POWERCAP_FC_CAP].get_addr, NULL,
|
||||
&fc[POWERCAP_FC_CAP].rate_limit);
|
||||
|
||||
ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
|
||||
POWERCAP_PAI_SET, 4, domain,
|
||||
&fc[POWERCAP_FC_PAI].set_addr,
|
||||
&fc[POWERCAP_FC_PAI].set_db);
|
||||
&fc[POWERCAP_FC_PAI].set_db,
|
||||
&fc[POWERCAP_FC_PAI].rate_limit);
|
||||
|
||||
ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
|
||||
POWERCAP_PAI_GET, 4, domain,
|
||||
&fc[POWERCAP_FC_PAI].get_addr, NULL);
|
||||
&fc[POWERCAP_FC_PAI].get_addr, NULL,
|
||||
&fc[POWERCAP_PAI_GET].rate_limit);
|
||||
|
||||
*p_fc = fc;
|
||||
}
|
||||
|
|
|
@ -234,6 +234,7 @@ struct scmi_fc_info {
|
|||
void __iomem *set_addr;
|
||||
void __iomem *get_addr;
|
||||
struct scmi_fc_db_info *set_db;
|
||||
u32 rate_limit;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -268,7 +269,8 @@ struct scmi_proto_helpers_ops {
|
|||
u8 describe_id, u32 message_id,
|
||||
u32 valid_size, u32 domain,
|
||||
void __iomem **p_addr,
|
||||
struct scmi_fc_db_info **p_db);
|
||||
struct scmi_fc_db_info **p_db,
|
||||
u32 *rate_limit);
|
||||
void (*fastchannel_db_ring)(struct scmi_fc_db_info *db);
|
||||
};
|
||||
|
||||
|
|
|
@ -128,6 +128,8 @@ struct scmi_perf_domain_info {
|
|||
* @level_set: sets the performance level of a domain
|
||||
* @level_get: gets the performance level of a domain
|
||||
* @transition_latency_get: gets the DVFS transition latency for a given device
|
||||
* @rate_limit_get: gets the minimum time (us) required between successive
|
||||
* requests
|
||||
* @device_opps_add: adds all the OPPs for a given device
|
||||
* @freq_set: sets the frequency for a given device using sustained frequency
|
||||
* to sustained performance level mapping
|
||||
|
@ -137,6 +139,8 @@ struct scmi_perf_domain_info {
|
|||
* at a given frequency
|
||||
* @fast_switch_possible: indicates if fast DVFS switching is possible or not
|
||||
* for a given device
|
||||
* @fast_switch_rate_limit: gets the minimum time (us) required between
|
||||
* successive fast_switching requests
|
||||
* @power_scale_mw_get: indicates if the power values provided are in milliWatts
|
||||
* or in some other (abstract) scale
|
||||
*/
|
||||
|
@ -154,6 +158,8 @@ struct scmi_perf_proto_ops {
|
|||
u32 *level, bool poll);
|
||||
int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
|
||||
u32 domain);
|
||||
int (*rate_limit_get)(const struct scmi_protocol_handle *ph,
|
||||
u32 domain, u32 *rate_limit);
|
||||
int (*device_opps_add)(const struct scmi_protocol_handle *ph,
|
||||
struct device *dev, u32 domain);
|
||||
int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
|
||||
|
@ -164,6 +170,8 @@ struct scmi_perf_proto_ops {
|
|||
unsigned long *rate, unsigned long *power);
|
||||
bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
|
||||
u32 domain);
|
||||
int (*fast_switch_rate_limit)(const struct scmi_protocol_handle *ph,
|
||||
u32 domain, u32 *rate_limit);
|
||||
enum scmi_power_scale (*power_scale_get)(const struct scmi_protocol_handle *ph);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue