mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 08:31:55 +00:00
Merge branch 'pm-cpufreq'
* pm-cpufreq: cpufreq: tegra186: don't pass GFP_DMA32 to dma_alloc_coherent() cpufreq: conservative: Take limits changes into account properly Documentation: intel_pstate: Add base_frequency information cpufreq: intel_pstate: Add base_frequency attribute ACPI / CPPC: Add support for guaranteed performance cpufreq: imx6q: read OCOTP through nvmem for imx6ul/imx6ull cpufreq: dt-platdev: allow RK3399 to have separate tunables per cluster cpufreq / CPPC: Mark acpi_ids as used cpufreq: dt: Add support for r8a7744 cpufreq: Convert to using %pOFn instead of device_node.name cpufreq: remove unnecessary unlikely()
This commit is contained in:
commit
d1551f7a5a
@ -465,6 +465,13 @@ Next, the following policy attributes have special meaning if
|
||||
policy for the time interval between the last two invocations of the
|
||||
driver's utilization update callback by the CPU scheduler for that CPU.
|
||||
|
||||
One more policy attribute is present if the `HWP feature is enabled in the
|
||||
processor <Active Mode With HWP_>`_:
|
||||
|
||||
``base_frequency``
|
||||
Shows the base frequency of the CPU. Any frequency above this will be
|
||||
in the turbo frequency range.
|
||||
|
||||
The meaning of these attributes in the `passive mode <Passive Mode_>`_ is the
|
||||
same as for other scaling drivers.
|
||||
|
||||
|
@ -1061,9 +1061,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
|
||||
{
|
||||
struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
|
||||
struct cpc_register_resource *highest_reg, *lowest_reg,
|
||||
*lowest_non_linear_reg, *nominal_reg,
|
||||
*lowest_non_linear_reg, *nominal_reg, *guaranteed_reg,
|
||||
*low_freq_reg = NULL, *nom_freq_reg = NULL;
|
||||
u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0;
|
||||
u64 high, low, guaranteed, nom, min_nonlinear, low_f = 0, nom_f = 0;
|
||||
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
|
||||
struct cppc_pcc_data *pcc_ss_data = NULL;
|
||||
int ret = 0, regs_in_pcc = 0;
|
||||
@ -1079,6 +1079,7 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
|
||||
nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];
|
||||
low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ];
|
||||
nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ];
|
||||
guaranteed_reg = &cpc_desc->cpc_regs[GUARANTEED_PERF];
|
||||
|
||||
/* Are any of the regs PCC ?*/
|
||||
if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) ||
|
||||
@ -1107,6 +1108,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
|
||||
cpc_read(cpunum, nominal_reg, &nom);
|
||||
perf_caps->nominal_perf = nom;
|
||||
|
||||
cpc_read(cpunum, guaranteed_reg, &guaranteed);
|
||||
perf_caps->guaranteed_perf = guaranteed;
|
||||
|
||||
cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
|
||||
perf_caps->lowest_nonlinear_perf = min_nonlinear;
|
||||
|
||||
|
@ -428,7 +428,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
late_initcall(cppc_cpufreq_init);
|
||||
|
||||
static const struct acpi_device_id cppc_acpi_ids[] = {
|
||||
static const struct acpi_device_id cppc_acpi_ids[] __used = {
|
||||
{ACPI_PROCESSOR_DEVICE_HID, },
|
||||
{}
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ static const struct of_device_id whitelist[] __initconst = {
|
||||
{ .compatible = "renesas,r8a73a4", },
|
||||
{ .compatible = "renesas,r8a7740", },
|
||||
{ .compatible = "renesas,r8a7743", },
|
||||
{ .compatible = "renesas,r8a7744", },
|
||||
{ .compatible = "renesas,r8a7745", },
|
||||
{ .compatible = "renesas,r8a7778", },
|
||||
{ .compatible = "renesas,r8a7779", },
|
||||
@ -78,7 +79,10 @@ static const struct of_device_id whitelist[] __initconst = {
|
||||
{ .compatible = "rockchip,rk3328", },
|
||||
{ .compatible = "rockchip,rk3366", },
|
||||
{ .compatible = "rockchip,rk3368", },
|
||||
{ .compatible = "rockchip,rk3399", },
|
||||
{ .compatible = "rockchip,rk3399",
|
||||
.data = &(struct cpufreq_dt_platform_data)
|
||||
{ .have_governor_per_policy = true, },
|
||||
},
|
||||
|
||||
{ .compatible = "st-ericsson,u8500", },
|
||||
{ .compatible = "st-ericsson,u8540", },
|
||||
|
@ -403,7 +403,7 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);
|
||||
void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
|
||||
struct cpufreq_freqs *freqs, int transition_failed)
|
||||
{
|
||||
if (unlikely(WARN_ON(!policy->transition_ongoing)))
|
||||
if (WARN_ON(!policy->transition_ongoing))
|
||||
return;
|
||||
|
||||
cpufreq_notify_post_transition(policy, freqs, transition_failed);
|
||||
|
@ -80,8 +80,10 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
|
||||
* changed in the meantime, so fall back to current frequency in that
|
||||
* case.
|
||||
*/
|
||||
if (requested_freq > policy->max || requested_freq < policy->min)
|
||||
if (requested_freq > policy->max || requested_freq < policy->min) {
|
||||
requested_freq = policy->cur;
|
||||
dbs_info->requested_freq = requested_freq;
|
||||
}
|
||||
|
||||
freq_step = get_freq_step(cs_tuners, policy);
|
||||
|
||||
@ -92,7 +94,7 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
|
||||
if (policy_dbs->idle_periods < UINT_MAX) {
|
||||
unsigned int freq_steps = policy_dbs->idle_periods * freq_step;
|
||||
|
||||
if (requested_freq > freq_steps)
|
||||
if (requested_freq > policy->min + freq_steps)
|
||||
requested_freq -= freq_steps;
|
||||
else
|
||||
requested_freq = policy->min;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/pm_opp.h>
|
||||
@ -290,20 +291,32 @@ put_node:
|
||||
#define OCOTP_CFG3_6ULL_SPEED_792MHZ 0x2
|
||||
#define OCOTP_CFG3_6ULL_SPEED_900MHZ 0x3
|
||||
|
||||
static void imx6ul_opp_check_speed_grading(struct device *dev)
|
||||
static int imx6ul_opp_check_speed_grading(struct device *dev)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
|
||||
if (!np)
|
||||
return;
|
||||
if (of_find_property(dev->of_node, "nvmem-cells", NULL)) {
|
||||
ret = nvmem_cell_read_u32(dev, "speed_grade", &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
dev_err(dev, "failed to map ocotp\n");
|
||||
goto put_node;
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
|
||||
if (!np)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -314,7 +327,6 @@ static void imx6ul_opp_check_speed_grading(struct device *dev)
|
||||
* 2b'11: 900000000Hz on i.MX6ULL only;
|
||||
* We need to set the max speed of ARM according to fuse map.
|
||||
*/
|
||||
val = readl_relaxed(base + OCOTP_CFG3);
|
||||
val >>= OCOTP_CFG3_SPEED_SHIFT;
|
||||
val &= 0x3;
|
||||
|
||||
@ -334,9 +346,7 @@ static void imx6ul_opp_check_speed_grading(struct device *dev)
|
||||
dev_warn(dev, "failed to disable 900MHz OPP\n");
|
||||
}
|
||||
|
||||
iounmap(base);
|
||||
put_node:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx6q_cpufreq_probe(struct platform_device *pdev)
|
||||
@ -394,10 +404,18 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (of_machine_is_compatible("fsl,imx6ul") ||
|
||||
of_machine_is_compatible("fsl,imx6ull"))
|
||||
imx6ul_opp_check_speed_grading(cpu_dev);
|
||||
else
|
||||
of_machine_is_compatible("fsl,imx6ull")) {
|
||||
ret = imx6ul_opp_check_speed_grading(cpu_dev);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
if (ret) {
|
||||
dev_err(cpu_dev, "failed to read ocotp: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
imx6q_opp_check_speed_grading(cpu_dev);
|
||||
}
|
||||
|
||||
/* Because we have added the OPPs here, we must free them */
|
||||
free_opp = true;
|
||||
|
@ -373,10 +373,28 @@ static void intel_pstate_set_itmt_prio(int cpu)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_pstate_get_cppc_guranteed(int cpu)
|
||||
{
|
||||
struct cppc_perf_caps cppc_perf;
|
||||
int ret;
|
||||
|
||||
ret = cppc_get_perf_caps(cpu, &cppc_perf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return cppc_perf.guaranteed_perf;
|
||||
}
|
||||
|
||||
#else
|
||||
static void intel_pstate_set_itmt_prio(int cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static int intel_pstate_get_cppc_guranteed(int cpu)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
|
||||
@ -699,9 +717,29 @@ static ssize_t show_energy_performance_preference(
|
||||
|
||||
cpufreq_freq_attr_rw(energy_performance_preference);
|
||||
|
||||
static ssize_t show_base_frequency(struct cpufreq_policy *policy, char *buf)
|
||||
{
|
||||
struct cpudata *cpu;
|
||||
u64 cap;
|
||||
int ratio;
|
||||
|
||||
ratio = intel_pstate_get_cppc_guranteed(policy->cpu);
|
||||
if (ratio <= 0) {
|
||||
rdmsrl_on_cpu(policy->cpu, MSR_HWP_CAPABILITIES, &cap);
|
||||
ratio = HWP_GUARANTEED_PERF(cap);
|
||||
}
|
||||
|
||||
cpu = all_cpu_data[policy->cpu];
|
||||
|
||||
return sprintf(buf, "%d\n", ratio * cpu->pstate.scaling);
|
||||
}
|
||||
|
||||
cpufreq_freq_attr_ro(base_frequency);
|
||||
|
||||
static struct freq_attr *hwp_cpufreq_attrs[] = {
|
||||
&energy_performance_preference,
|
||||
&energy_performance_available_preferences,
|
||||
&base_frequency,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -611,8 +611,8 @@ static int s5pv210_cpufreq_probe(struct platform_device *pdev)
|
||||
for_each_compatible_node(np, NULL, "samsung,s5pv210-dmc") {
|
||||
id = of_alias_get_id(np, "dmc");
|
||||
if (id < 0 || id >= ARRAY_SIZE(dmc_base)) {
|
||||
pr_err("%s: failed to get alias of dmc node '%s'\n",
|
||||
__func__, np->name);
|
||||
pr_err("%s: failed to get alias of dmc node '%pOFn'\n",
|
||||
__func__, np);
|
||||
of_node_put(np);
|
||||
return id;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||
void *virt;
|
||||
|
||||
virt = dma_alloc_coherent(bpmp->dev, sizeof(*data), &phys,
|
||||
GFP_KERNEL | GFP_DMA32);
|
||||
GFP_KERNEL);
|
||||
if (!virt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -104,6 +104,7 @@ enum cppc_regs {
|
||||
* today.
|
||||
*/
|
||||
struct cppc_perf_caps {
|
||||
u32 guaranteed_perf;
|
||||
u32 highest_perf;
|
||||
u32 nominal_perf;
|
||||
u32 lowest_perf;
|
||||
|
Loading…
Reference in New Issue
Block a user