mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
CPUFreq arm updates for 7.2
- Add cpufreq scaling support for Qualcomm Shikra SoC (Taniya Das, and Imran Shaik). - Minor fixes for cpufreq drivers (Krzysztof Kozlowski, Akashdeep Kaur, Hans Zhang, Guangshuo Li, and Xueqin Luo). -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmomWYMACgkQ0rkcPK6B EhypdRAAnIHddDVfbl8mqMSVENcQrMBAgdSw4Foh6DcOfP2Nxu9+KSPR3xbFbNsy AxHc8M/merdjsHcuvA/03D/BgCzcpI80mb70k0u88LDneH7KbWbRMZ4nHFVzBui1 CUV/LZ17q8RRlNCNKySAZAK+jGeLMh4KIGK15RCZn0hv+KsinFQkKyER7EgqZANA 7TydPpwoQZakTh+YDJb27l2Cls/JXWZABuQbNtJIo1/SRBGnNQVpn+bEaYxhdeta G5OJrBw3i6fV0xfOEGQfwRy9qGr308qFvJEqoIJs0A/uBcY47TsYEYu/XHZfI5+C k8froLZIuClrHNEn+rAzS5n0PJTrp+bKaYMKCT31dDeOEB5KRMU0e/2Cj20dbjrz HB/2qufhhwR3C8W5N3l8POWvJJFUVABDO6N8vgOkp2qQYPdZmxKviTMcgKOYe0CA Z4DszH6DlwT9etP4lS4gv5rt8JmIdxFxSOrL6tYT2wVbpkA63H8wXIlKnob8wm5K CrQvUhSoxPqoHcKRd6RCSeOBDguVcpos9vgp8I6Mzdh4dVNvZRkKerJIJq+SBffw /SQhuBeireFMmDxoXb2nbKbQ05CNP4LM3AK35CLwu3Gz3Hm1o4m+IuoCmyZJkKAM pXcPQCZ2Es60sfkDXKLNSepQ3ux7d++TFIt0FcviyYTXICWnVVk= =hVKd -----END PGP SIGNATURE----- Merge tag 'cpufreq-arm-updates-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull CPUFreq Arm updates for 7.2 from Viresh Kumar: "- Add cpufreq scaling support for Qualcomm Shikra SoC (Taniya Das, and Imran Shaik). - Minor fixes for cpufreq drivers (Krzysztof Kozlowski, Akashdeep Kaur, Hans Zhang, Guangshuo Li, and Xueqin Luo)." * tag 'cpufreq-arm-updates-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: ti: Add EPROBE_DEFER for K3 SoCs cpufreq: qcom: Add cpufreq scaling support for Qualcomm Shikra SoC dt-bindings: cpufreq: Document Qualcomm Shikra SoC EPSS cpufreq: cppc: mask Desired_Excursion when autonomous selection is enabled cpufreq: qcom-cpufreq-hw: Fix possible double free cpufreq: apple-soc: Use FIELD_MODIFY() cpufreq/amd-pstate: Use FIELD_MODIFY() cpufreq: qcom: Unify user-visible "Qualcomm" name
This commit is contained in:
commit
11efcfc295
|
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/cpufreq/qcom,shikra-epss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Shikra SoC EPSS
|
||||
|
||||
maintainers:
|
||||
- Imran Shaik <imran.shaik@oss.qualcomm.com>
|
||||
- Taniya Das <taniya.das@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
EPSS is a hardware engine used by some Qualcomm SoCs to manage
|
||||
frequency in hardware. It is capable of controlling frequency for
|
||||
multiple clusters.
|
||||
|
||||
The Qualcomm Shikra SoC EPSS supports up to 12 frequency lookup table
|
||||
(LUT) entries.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,shikra-epss
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Frequency domain 0 register region
|
||||
- description: Frequency domain 1 register region
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: freq-domain0
|
||||
- const: freq-domain1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: XO Clock
|
||||
- description: GPLL0 Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: alternate
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: IRQ line for DCVSH 0
|
||||
- description: IRQ line for DCVSH 1
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: dcvsh-irq-0
|
||||
- const: dcvsh-irq-1
|
||||
|
||||
'#freq-domain-cells':
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- '#freq-domain-cells'
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpufreq@fd91000 {
|
||||
compatible = "qcom,shikra-epss";
|
||||
reg = <0x0fd91000 0x1000>, <0x0fd92000 0x1000>;
|
||||
reg-names = "freq-domain0", "freq-domain1";
|
||||
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gpll0>;
|
||||
clock-names = "xo", "alternate";
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1";
|
||||
#freq-domain-cells = <1>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -153,7 +153,7 @@ config ARM_QCOM_CPUFREQ_NVMEM
|
|||
If in doubt, say N.
|
||||
|
||||
config ARM_QCOM_CPUFREQ_HW
|
||||
tristate "QCOM CPUFreq HW driver"
|
||||
tristate "Qualcomm CPUFreq HW driver"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
help
|
||||
|
|
|
|||
|
|
@ -242,12 +242,10 @@ static int msr_update_perf(struct cpufreq_policy *policy, u8 min_perf,
|
|||
|
||||
value = prev = READ_ONCE(cpudata->cppc_req_cached);
|
||||
|
||||
value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK |
|
||||
AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK);
|
||||
value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp);
|
||||
FIELD_MODIFY(AMD_CPPC_MAX_PERF_MASK, &value, max_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_DES_PERF_MASK, &value, des_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_MIN_PERF_MASK, &value, min_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);
|
||||
|
||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
||||
union perf_cached perf = READ_ONCE(cpudata->perf);
|
||||
|
|
@ -296,8 +294,7 @@ static int msr_set_epp(struct cpufreq_policy *policy, u8 epp)
|
|||
int ret;
|
||||
|
||||
value = prev = READ_ONCE(cpudata->cppc_req_cached);
|
||||
value &= ~AMD_CPPC_EPP_PERF_MASK;
|
||||
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp);
|
||||
FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);
|
||||
|
||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
||||
union perf_cached perf = cpudata->perf;
|
||||
|
|
@ -437,8 +434,7 @@ static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
|
|||
}
|
||||
|
||||
value = READ_ONCE(cpudata->cppc_req_cached);
|
||||
value &= ~AMD_CPPC_EPP_PERF_MASK;
|
||||
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp);
|
||||
FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);
|
||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
||||
|
||||
return ret;
|
||||
|
|
@ -571,12 +567,10 @@ static int shmem_update_perf(struct cpufreq_policy *policy, u8 min_perf,
|
|||
|
||||
value = prev = READ_ONCE(cpudata->cppc_req_cached);
|
||||
|
||||
value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK |
|
||||
AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK);
|
||||
value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf);
|
||||
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp);
|
||||
FIELD_MODIFY(AMD_CPPC_MAX_PERF_MASK, &value, max_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_DES_PERF_MASK, &value, des_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_MIN_PERF_MASK, &value, min_perf);
|
||||
FIELD_MODIFY(AMD_CPPC_EPP_PERF_MASK, &value, epp);
|
||||
|
||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
||||
union perf_cached perf = READ_ONCE(cpudata->perf);
|
||||
|
|
|
|||
|
|
@ -187,10 +187,8 @@ static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy,
|
|||
|
||||
reg &= ~priv->info->ps1_mask;
|
||||
reg |= pstate << priv->info->ps1_shift;
|
||||
if (priv->info->has_ps2) {
|
||||
reg &= ~APPLE_DVFS_CMD_PS2;
|
||||
reg |= FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate);
|
||||
}
|
||||
if (priv->info->has_ps2)
|
||||
FIELD_MODIFY(APPLE_DVFS_CMD_PS2, ®, pstate);
|
||||
reg |= APPLE_DVFS_CMD_SET;
|
||||
|
||||
writeq_relaxed(reg, priv->reg_base + APPLE_DVFS_CMD);
|
||||
|
|
|
|||
|
|
@ -982,7 +982,34 @@ store_energy_performance_preference_val(struct cpufreq_policy *policy,
|
|||
return count;
|
||||
}
|
||||
|
||||
CPPC_CPUFREQ_ATTR_RW_U64(perf_limited, cppc_get_perf_limited,
|
||||
static int cppc_get_perf_limited_filtered(int cpu, u64 *perf_limited)
|
||||
{
|
||||
struct cpufreq_policy *policy;
|
||||
struct cppc_cpudata *cpu_data;
|
||||
int ret;
|
||||
|
||||
ret = cppc_get_perf_limited(cpu, perf_limited);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
policy = cpufreq_cpu_get_raw(cpu);
|
||||
if (!policy)
|
||||
return -EINVAL;
|
||||
|
||||
cpu_data = policy->driver_data;
|
||||
|
||||
/*
|
||||
* Desired Excursion is ignored when autonomous selection is
|
||||
* enabled. Clear the bit to avoid exposing meaningless state
|
||||
* to userspace.
|
||||
*/
|
||||
if (cpu_data && cpu_data->perf_ctrls.auto_sel)
|
||||
*perf_limited &= ~CPPC_PERF_LIMITED_DESIRED_EXCURSION;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPPC_CPUFREQ_ATTR_RW_U64(perf_limited, cppc_get_perf_limited_filtered,
|
||||
cppc_set_perf_limited)
|
||||
|
||||
cpufreq_freq_attr_ro(freqdomain_cpus);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -578,7 +595,6 @@ static void qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
|
|||
dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
|
||||
qcom_cpufreq_hw_lmh_exit(data);
|
||||
kfree(policy->freq_table);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ struct ti_cpufreq_soc_data {
|
|||
unsigned long efuse_shift;
|
||||
unsigned long rev_offset;
|
||||
bool multi_regulator;
|
||||
bool needs_k3_socinfo;
|
||||
/* Backward compatibility hack: Might have missing syscon */
|
||||
#define TI_QUIRK_SYSCON_MAY_BE_MISSING 0x1
|
||||
/* Backward compatibility hack: new syscon size is 1 register wide */
|
||||
|
|
@ -347,6 +348,7 @@ static struct ti_cpufreq_soc_data am625_soc_data = {
|
|||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.multi_regulator = false,
|
||||
.needs_k3_socinfo = true,
|
||||
.quirks = TI_QUIRK_SYSCON_IS_SINGLE_REG,
|
||||
};
|
||||
|
||||
|
|
@ -356,6 +358,7 @@ static struct ti_cpufreq_soc_data am62a7_soc_data = {
|
|||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.multi_regulator = false,
|
||||
.needs_k3_socinfo = true,
|
||||
};
|
||||
|
||||
static struct ti_cpufreq_soc_data am62l3_soc_data = {
|
||||
|
|
@ -364,6 +367,7 @@ static struct ti_cpufreq_soc_data am62l3_soc_data = {
|
|||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.multi_regulator = false,
|
||||
.needs_k3_socinfo = true,
|
||||
};
|
||||
|
||||
static struct ti_cpufreq_soc_data am62p5_soc_data = {
|
||||
|
|
@ -372,6 +376,7 @@ static struct ti_cpufreq_soc_data am62p5_soc_data = {
|
|||
.efuse_mask = 0x07c0,
|
||||
.efuse_shift = 0x6,
|
||||
.multi_regulator = false,
|
||||
.needs_k3_socinfo = true,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -443,6 +448,11 @@ static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Defer if k3-socinfo hasn't registered the SoC device yet */
|
||||
if (opp_data->soc_data->needs_k3_socinfo)
|
||||
return dev_err_probe(opp_data->cpu_dev, -EPROBE_DEFER,
|
||||
"SoC device not registered by k3-socinfo\n");
|
||||
|
||||
ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
|
||||
&revision);
|
||||
if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user