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 | /* Each register has the folowing format. */ |
36 | struct cpc_reg { |
37 | u8 descriptor; |
38 | u16 length; |
39 | u8 space_id; |
40 | u8 bit_width; |
41 | u8 bit_offset; |
42 | u8 access_width; |
43 | u64 address; |
44 | } __packed; |
45 | |
46 | /* |
47 | * Each entry in the CPC table is either |
48 | * of type ACPI_TYPE_BUFFER or |
49 | * ACPI_TYPE_INTEGER. |
50 | */ |
51 | struct cpc_register_resource { |
52 | acpi_object_type type; |
53 | u64 __iomem *sys_mem_vaddr; |
54 | union { |
55 | struct cpc_reg reg; |
56 | u64 int_value; |
57 | } cpc_entry; |
58 | }; |
59 | |
60 | /* Container to hold the CPC details for each CPU */ |
61 | struct cpc_desc { |
62 | int num_entries; |
63 | int version; |
64 | int cpu_id; |
65 | int write_cmd_status; |
66 | int write_cmd_id; |
67 | struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT]; |
68 | struct acpi_psd_package domain_info; |
69 | struct kobject kobj; |
70 | }; |
71 | |
72 | /* These are indexes into the per-cpu cpc_regs[]. Order is important. */ |
73 | enum cppc_regs { |
74 | HIGHEST_PERF, |
75 | NOMINAL_PERF, |
76 | LOW_NON_LINEAR_PERF, |
77 | LOWEST_PERF, |
78 | GUARANTEED_PERF, |
79 | DESIRED_PERF, |
80 | MIN_PERF, |
81 | MAX_PERF, |
82 | PERF_REDUC_TOLERANCE, |
83 | TIME_WINDOW, |
84 | CTR_WRAP_TIME, |
85 | REFERENCE_CTR, |
86 | DELIVERED_CTR, |
87 | PERF_LIMITED, |
88 | ENABLE, |
89 | AUTO_SEL_ENABLE, |
90 | AUTO_ACT_WINDOW, |
91 | ENERGY_PERF, |
92 | REFERENCE_PERF, |
93 | LOWEST_FREQ, |
94 | NOMINAL_FREQ, |
95 | }; |
96 | |
97 | /* |
98 | * Categorization of registers as described |
99 | * in the ACPI v.5.1 spec. |
100 | * XXX: Only filling up ones which are used by governors |
101 | * today. |
102 | */ |
103 | struct cppc_perf_caps { |
104 | u32 guaranteed_perf; |
105 | u32 highest_perf; |
106 | u32 nominal_perf; |
107 | u32 lowest_perf; |
108 | u32 lowest_nonlinear_perf; |
109 | u32 lowest_freq; |
110 | u32 nominal_freq; |
111 | u32 energy_perf; |
112 | bool auto_sel; |
113 | }; |
114 | |
115 | struct cppc_perf_ctrls { |
116 | u32 max_perf; |
117 | u32 min_perf; |
118 | u32 desired_perf; |
119 | u32 energy_perf; |
120 | }; |
121 | |
122 | struct cppc_perf_fb_ctrs { |
123 | u64 reference; |
124 | u64 delivered; |
125 | u64 reference_perf; |
126 | u64 wraparound_time; |
127 | }; |
128 | |
129 | /* Per CPU container for runtime CPPC management. */ |
130 | struct cppc_cpudata { |
131 | struct list_head node; |
132 | struct cppc_perf_caps perf_caps; |
133 | struct cppc_perf_ctrls perf_ctrls; |
134 | struct cppc_perf_fb_ctrs perf_fb_ctrs; |
135 | unsigned int shared_type; |
136 | cpumask_var_t shared_cpu_map; |
137 | }; |
138 | |
139 | #ifdef CONFIG_ACPI_CPPC_LIB |
140 | extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); |
141 | extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); |
142 | extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); |
143 | extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); |
144 | extern int cppc_set_enable(int cpu, bool enable); |
145 | extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); |
146 | extern bool cppc_perf_ctrs_in_pcc(void); |
147 | extern bool acpi_cpc_valid(void); |
148 | extern bool cppc_allow_fast_switch(void); |
149 | extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); |
150 | extern unsigned int cppc_get_transition_latency(int cpu); |
151 | extern bool cpc_ffh_supported(void); |
152 | extern bool cpc_supported_by_cpu(void); |
153 | extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); |
154 | extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); |
155 | extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf); |
156 | extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable); |
157 | extern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps); |
158 | extern int cppc_set_auto_sel(int cpu, bool enable); |
159 | #else /* !CONFIG_ACPI_CPPC_LIB */ |
160 | static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf) |
161 | { |
162 | return -ENOTSUPP; |
163 | } |
164 | static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) |
165 | { |
166 | return -ENOTSUPP; |
167 | } |
168 | static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) |
169 | { |
170 | return -ENOTSUPP; |
171 | } |
172 | static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) |
173 | { |
174 | return -ENOTSUPP; |
175 | } |
176 | static inline int cppc_set_enable(int cpu, bool enable) |
177 | { |
178 | return -ENOTSUPP; |
179 | } |
180 | static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps) |
181 | { |
182 | return -ENOTSUPP; |
183 | } |
184 | static inline bool cppc_perf_ctrs_in_pcc(void) |
185 | { |
186 | return false; |
187 | } |
188 | static inline bool acpi_cpc_valid(void) |
189 | { |
190 | return false; |
191 | } |
192 | static inline bool cppc_allow_fast_switch(void) |
193 | { |
194 | return false; |
195 | } |
196 | static inline unsigned int cppc_get_transition_latency(int cpu) |
197 | { |
198 | return CPUFREQ_ETERNAL; |
199 | } |
200 | static inline bool cpc_ffh_supported(void) |
201 | { |
202 | return false; |
203 | } |
204 | static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) |
205 | { |
206 | return -ENOTSUPP; |
207 | } |
208 | static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) |
209 | { |
210 | return -ENOTSUPP; |
211 | } |
212 | static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable) |
213 | { |
214 | return -ENOTSUPP; |
215 | } |
216 | static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf) |
217 | { |
218 | return -ENOTSUPP; |
219 | } |
220 | static inline int cppc_set_auto_sel(int cpu, bool enable) |
221 | { |
222 | return -ENOTSUPP; |
223 | } |
224 | static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps) |
225 | { |
226 | return -ENOTSUPP; |
227 | } |
228 | #endif /* !CONFIG_ACPI_CPPC_LIB */ |
229 | |
230 | #endif /* _CPPC_ACPI_H*/ |
231 | |