Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * CPPC (Collaborative Processor Performance Control) methods used
4 * by CPUfreq drivers.
5 *
6 * (C) Copyright 2014, 2015 Linaro Ltd.
7 * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
8 */
9
10#ifndef _CPPC_ACPI_H
11#define _CPPC_ACPI_H
12
13#include <linux/acpi.h>
14#include <linux/cpufreq.h>
15#include <linux/types.h>
16
17#include <acpi/pcc.h>
18#include <acpi/processor.h>
19
20/* CPPCv2 and CPPCv3 support */
21#define CPPC_V2_REV 2
22#define CPPC_V3_REV 3
23#define CPPC_V2_NUM_ENT 21
24#define CPPC_V3_NUM_ENT 23
25
26#define PCC_CMD_COMPLETE_MASK (1 << 0)
27#define PCC_ERROR_MASK (1 << 2)
28
29#define MAX_CPC_REG_ENT 21
30
31/* CPPC specific PCC commands. */
32#define CMD_READ 0
33#define CMD_WRITE 1
34
35#define CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE (7)
36#define CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE (3)
37#define CPPC_AUTO_ACT_WINDOW_MAX_SIG ((1 << CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE) - 1)
38#define CPPC_AUTO_ACT_WINDOW_MAX_EXP ((1 << CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE) - 1)
39/* CPPC_AUTO_ACT_WINDOW_MAX_SIG is 127, so 128 and 129 will decay to 127 when writing */
40#define CPPC_AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129
41
42#define CPPC_EPP_PERFORMANCE_PREF 0x00
43#define CPPC_EPP_ENERGY_EFFICIENCY_PREF 0xFF
44
45#define CPPC_PERF_LIMITED_DESIRED_EXCURSION BIT(0)
46#define CPPC_PERF_LIMITED_MINIMUM_EXCURSION BIT(1)
47#define CPPC_PERF_LIMITED_MASK (CPPC_PERF_LIMITED_DESIRED_EXCURSION | \
48 CPPC_PERF_LIMITED_MINIMUM_EXCURSION)
49
50/* Each register has the folowing format. */
51struct cpc_reg {
52 u8 descriptor;
53 u16 length;
54 u8 space_id;
55 u8 bit_width;
56 u8 bit_offset;
57 u8 access_width;
58 u64 address;
59} __packed;
60
61/*
62 * Each entry in the CPC table is either
63 * of type ACPI_TYPE_BUFFER or
64 * ACPI_TYPE_INTEGER.
65 */
66struct cpc_register_resource {
67 acpi_object_type type;
68 u64 __iomem *sys_mem_vaddr;
69 union {
70 struct cpc_reg reg;
71 u64 int_value;
72 } cpc_entry;
73};
74
75/* Container to hold the CPC details for each CPU */
76struct cpc_desc {
77 int num_entries;
78 int version;
79 int cpu_id;
80 int write_cmd_status;
81 int write_cmd_id;
82 /* Lock used for RMW operations in cpc_write() */
83 raw_spinlock_t rmw_lock;
84 struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
85 struct acpi_psd_package domain_info;
86 struct kobject kobj;
87};
88
89/* These are indexes into the per-cpu cpc_regs[]. Order is important. */
90enum cppc_regs {
91 HIGHEST_PERF,
92 NOMINAL_PERF,
93 LOW_NON_LINEAR_PERF,
94 LOWEST_PERF,
95 GUARANTEED_PERF,
96 DESIRED_PERF,
97 MIN_PERF,
98 MAX_PERF,
99 PERF_REDUC_TOLERANCE,
100 TIME_WINDOW,
101 CTR_WRAP_TIME,
102 REFERENCE_CTR,
103 DELIVERED_CTR,
104 PERF_LIMITED,
105 ENABLE,
106 AUTO_SEL_ENABLE,
107 AUTO_ACT_WINDOW,
108 ENERGY_PERF,
109 REFERENCE_PERF,
110 LOWEST_FREQ,
111 NOMINAL_FREQ,
112};
113
114/*
115 * Categorization of registers as described
116 * in the ACPI v.5.1 spec.
117 * XXX: Only filling up ones which are used by governors
118 * today.
119 */
120struct cppc_perf_caps {
121 u32 guaranteed_perf;
122 u32 highest_perf;
123 u32 nominal_perf;
124 u32 reference_perf;
125 u32 lowest_perf;
126 u32 lowest_nonlinear_perf;
127 u32 lowest_freq;
128 u32 nominal_freq;
129};
130
131struct cppc_perf_ctrls {
132 u32 max_perf;
133 u32 min_perf;
134 u32 desired_perf;
135 u32 energy_perf;
136 bool auto_sel;
137};
138
139struct cppc_perf_fb_ctrs {
140 u64 reference;
141 u64 delivered;
142 u64 wraparound_time;
143};
144
145/* Per CPU container for runtime CPPC management. */
146struct cppc_cpudata {
147 struct cppc_perf_caps perf_caps;
148 struct cppc_perf_ctrls perf_ctrls;
149 struct cppc_perf_fb_ctrs perf_fb_ctrs;
150 unsigned int shared_type;
151 cpumask_var_t shared_cpu_map;
152};
153
154#ifdef CONFIG_ACPI_CPPC_LIB
155extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
156extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
157extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf);
158extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
159extern int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
160extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
161extern int cppc_set_enable(int cpu, bool enable);
162extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
163extern bool cppc_perf_ctrs_in_pcc_cpu(unsigned int cpu);
164extern bool cppc_perf_ctrs_in_pcc(void);
165extern u64 cppc_get_dmi_max_khz(void);
166extern unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf);
167extern unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq);
168extern bool acpi_cpc_valid(void);
169extern bool cppc_allow_fast_switch(void);
170extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
171extern int cppc_get_transition_latency(int cpu);
172extern bool cpc_ffh_supported(void);
173extern bool cpc_supported_by_cpu(void);
174extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
175extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
176extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
177extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
178extern int cppc_set_epp(int cpu, u64 epp_val);
179extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
180extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
181extern int cppc_get_auto_sel(int cpu, bool *enable);
182extern int cppc_set_auto_sel(int cpu, bool enable);
183extern int cppc_get_perf_limited(int cpu, u64 *perf_limited);
184extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear);
185extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
186extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
187extern int amd_detect_prefcore(bool *detected);
188#else /* !CONFIG_ACPI_CPPC_LIB */
189static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
190{
191 return -EOPNOTSUPP;
192}
193static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
194{
195 return -EOPNOTSUPP;
196}
197static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
198{
199 return -EOPNOTSUPP;
200}
201static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
202{
203 return -EOPNOTSUPP;
204}
205static inline int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
206{
207 return -EOPNOTSUPP;
208}
209static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
210{
211 return -EOPNOTSUPP;
212}
213static inline int cppc_set_enable(int cpu, bool enable)
214{
215 return -EOPNOTSUPP;
216}
217static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
218{
219 return -EOPNOTSUPP;
220}
221static inline bool cppc_perf_ctrs_in_pcc_cpu(unsigned int cpu)
222{
223 return false;
224}
225static inline bool cppc_perf_ctrs_in_pcc(void)
226{
227 return false;
228}
229static inline bool acpi_cpc_valid(void)
230{
231 return false;
232}
233static inline bool cppc_allow_fast_switch(void)
234{
235 return false;
236}
237static inline int cppc_get_transition_latency(int cpu)
238{
239 return -ENODATA;
240}
241static inline bool cpc_ffh_supported(void)
242{
243 return false;
244}
245static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
246{
247 return -EOPNOTSUPP;
248}
249static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
250{
251 return -EOPNOTSUPP;
252}
253static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
254{
255 return -EOPNOTSUPP;
256}
257static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
258{
259 return -EOPNOTSUPP;
260}
261static inline int cppc_set_epp(int cpu, u64 epp_val)
262{
263 return -EOPNOTSUPP;
264}
265static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window)
266{
267 return -EOPNOTSUPP;
268}
269static inline int cppc_set_auto_act_window(int cpu, u64 auto_act_window)
270{
271 return -EOPNOTSUPP;
272}
273static inline int cppc_get_auto_sel(int cpu, bool *enable)
274{
275 return -EOPNOTSUPP;
276}
277static inline int cppc_set_auto_sel(int cpu, bool enable)
278{
279 return -EOPNOTSUPP;
280}
281static inline int cppc_get_perf_limited(int cpu, u64 *perf_limited)
282{
283 return -EOPNOTSUPP;
284}
285static inline int cppc_set_perf_limited(int cpu, u64 bits_to_clear)
286{
287 return -EOPNOTSUPP;
288}
289static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf)
290{
291 return -ENODEV;
292}
293static inline int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
294{
295 return -EOPNOTSUPP;
296}
297static inline int amd_detect_prefcore(bool *detected)
298{
299 return -ENODEV;
300}
301#endif /* !CONFIG_ACPI_CPPC_LIB */
302
303#endif /* _CPPC_ACPI_H*/