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, CPPCv3 and CPPCv4 support */ 21 #define CPPC_V2_REV 2 22 #define CPPC_V3_REV 3 23 #define CPPC_V4_REV 4 24 #define CPPC_V2_NUM_ENT 21 25 #define CPPC_V3_NUM_ENT 23 26 #define CPPC_V4_NUM_ENT 25 27 28 #define PCC_CMD_COMPLETE_MASK (1 << 0) 29 #define PCC_ERROR_MASK (1 << 2) 30 31 #define MAX_CPC_REG_ENT 23 32 33 /* CPPC specific PCC commands. */ 34 #define CMD_READ 0 35 #define CMD_WRITE 1 36 37 #define CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE (7) 38 #define CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE (3) 39 #define CPPC_AUTO_ACT_WINDOW_MAX_SIG ((1 << CPPC_AUTO_ACT_WINDOW_SIG_BIT_SIZE) - 1) 40 #define CPPC_AUTO_ACT_WINDOW_MAX_EXP ((1 << CPPC_AUTO_ACT_WINDOW_EXP_BIT_SIZE) - 1) 41 /* CPPC_AUTO_ACT_WINDOW_MAX_SIG is 127, so 128 and 129 will decay to 127 when writing */ 42 #define CPPC_AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129 43 44 #define CPPC_EPP_PERFORMANCE_PREF 0x00 45 #define CPPC_EPP_ENERGY_EFFICIENCY_PREF 0xFF 46 47 #define CPPC_PERF_LIMITED_DESIRED_EXCURSION BIT(0) 48 #define CPPC_PERF_LIMITED_MINIMUM_EXCURSION BIT(1) 49 #define CPPC_PERF_LIMITED_MASK (CPPC_PERF_LIMITED_DESIRED_EXCURSION | \ 50 CPPC_PERF_LIMITED_MINIMUM_EXCURSION) 51 52 /* Each register has the folowing format. */ 53 struct cpc_reg { 54 u8 descriptor; 55 u16 length; 56 u8 space_id; 57 u8 bit_width; 58 u8 bit_offset; 59 u8 access_width; 60 u64 address; 61 } __packed; 62 63 /* 64 * Each entry in the CPC table is either 65 * of type ACPI_TYPE_BUFFER or 66 * ACPI_TYPE_INTEGER. 67 */ 68 struct cpc_register_resource { 69 acpi_object_type type; 70 u64 __iomem *sys_mem_vaddr; 71 union { 72 struct { 73 struct cpc_reg reg; 74 bool use_rmw_lock; 75 bool read_unsupported; 76 bool write_unsupported; 77 }; 78 u64 int_value; 79 } cpc_entry; 80 }; 81 82 struct cpc_sysmem_node; 83 struct cpc_non_mmio_node; 84 85 /* Container to hold the CPC details for each CPU */ 86 struct cpc_desc { 87 int num_entries; 88 int version; 89 int cpu_id; 90 int write_cmd_status; 91 int write_cmd_id; 92 /* Serialize partial SystemMemory writes within this descriptor. */ 93 raw_spinlock_t rmw_lock; 94 struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT]; 95 struct acpi_psd_package domain_info; 96 struct cpc_sysmem_node *sysmem_nodes; 97 struct cpc_non_mmio_node *non_mmio_nodes; 98 struct kobject kobj; 99 }; 100 101 /* These are indexes into the per-cpu cpc_regs[]. Order is important. */ 102 enum cppc_regs { 103 HIGHEST_PERF, 104 NOMINAL_PERF, 105 LOW_NON_LINEAR_PERF, 106 LOWEST_PERF, 107 GUARANTEED_PERF, 108 DESIRED_PERF, 109 MIN_PERF, 110 MAX_PERF, 111 PERF_REDUC_TOLERANCE, 112 TIME_WINDOW, 113 CTR_WRAP_TIME, 114 REFERENCE_CTR, 115 DELIVERED_CTR, 116 PERF_LIMITED, 117 ENABLE, 118 AUTO_SEL_ENABLE, 119 AUTO_ACT_WINDOW, 120 ENERGY_PERF, 121 REFERENCE_PERF, 122 LOWEST_FREQ, 123 NOMINAL_FREQ, 124 OSPM_NOMINAL_PERF, 125 RESOURCE_PRIORITY, 126 }; 127 128 /* 129 * Categorization of registers as described 130 * in the ACPI v.5.1 spec. 131 * XXX: Only filling up ones which are used by governors 132 * today. 133 */ 134 struct cppc_perf_caps { 135 u32 guaranteed_perf; 136 u32 highest_perf; 137 u32 nominal_perf; 138 u32 reference_perf; 139 u32 lowest_perf; 140 u32 lowest_nonlinear_perf; 141 u32 lowest_freq; 142 u32 nominal_freq; 143 }; 144 145 struct cppc_perf_ctrls { 146 u32 max_perf; 147 u32 min_perf; 148 u32 desired_perf; 149 u32 energy_perf; 150 bool auto_sel; 151 /* Allow an explicit zero minimum; otherwise zero omits the update. */ 152 bool min_perf_valid; 153 }; 154 155 struct cppc_perf_fb_ctrs { 156 u64 reference; 157 u64 delivered; 158 u64 wraparound_time; 159 }; 160 161 /* Per CPU container for runtime CPPC management. */ 162 struct cppc_cpudata { 163 struct cppc_perf_caps perf_caps; 164 struct cppc_perf_ctrls perf_ctrls; 165 struct cppc_perf_fb_ctrs perf_fb_ctrs; 166 unsigned int shared_type; 167 cpumask_var_t shared_cpu_map; 168 }; 169 170 #ifdef CONFIG_ACPI_CPPC_LIB 171 extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); 172 extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); 173 extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf); 174 extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); 175 extern int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); 176 extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); 177 extern int cppc_set_enable(int cpu, bool enable); 178 extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); 179 extern bool cppc_perf_ctrs_in_pcc_cpu(unsigned int cpu); 180 extern bool cppc_perf_ctrs_in_pcc(void); 181 extern u64 cppc_get_dmi_max_khz(void); 182 extern unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf); 183 extern unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq); 184 extern bool acpi_cpc_valid(void); 185 bool cppc_allow_fast_switch(const struct cpumask *cpus); 186 extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); 187 extern int cppc_get_transition_latency(int cpu); 188 extern bool cpc_ffh_supported(void); 189 extern bool cpc_supported_by_cpu(void); 190 extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); 191 extern int cpc_read_ffh_fb_ctrs(int cpu, struct cpc_reg *reg1, u64 *val1, 192 struct cpc_reg *reg2, u64 *val2); 193 extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); 194 extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf); 195 extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable); 196 extern int cppc_set_epp(int cpu, u64 epp_val); 197 extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window); 198 extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window); 199 extern int cppc_get_auto_sel(int cpu, bool *enable); 200 bool cppc_auto_sel_is_immutable(int cpu); 201 extern int cppc_set_auto_sel(int cpu, bool enable); 202 extern int cppc_get_perf_limited(int cpu, u64 *perf_limited); 203 extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear); 204 extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf); 205 extern int amd_get_effective_highest_perf(unsigned int cpu); 206 extern int amd_get_max_frequency(unsigned int cpu); 207 extern int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator); 208 extern int amd_detect_prefcore(bool *detected); 209 #else /* !CONFIG_ACPI_CPPC_LIB */ 210 static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf) 211 { 212 return -EOPNOTSUPP; 213 } 214 static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) 215 { 216 return -EOPNOTSUPP; 217 } 218 static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf) 219 { 220 return -EOPNOTSUPP; 221 } 222 static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) 223 { 224 return -EOPNOTSUPP; 225 } 226 static inline int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) 227 { 228 return -EOPNOTSUPP; 229 } 230 static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) 231 { 232 return -EOPNOTSUPP; 233 } 234 static inline int cppc_set_enable(int cpu, bool enable) 235 { 236 return -EOPNOTSUPP; 237 } 238 static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps) 239 { 240 return -EOPNOTSUPP; 241 } 242 static inline bool cppc_perf_ctrs_in_pcc_cpu(unsigned int cpu) 243 { 244 return false; 245 } 246 static inline bool cppc_perf_ctrs_in_pcc(void) 247 { 248 return false; 249 } 250 static inline bool acpi_cpc_valid(void) 251 { 252 return false; 253 } 254 255 static inline bool cppc_allow_fast_switch(const struct cpumask *cpus) 256 { 257 return false; 258 } 259 static inline int cppc_get_transition_latency(int cpu) 260 { 261 return -ENODATA; 262 } 263 static inline bool cpc_ffh_supported(void) 264 { 265 return false; 266 } 267 static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) 268 { 269 return -EOPNOTSUPP; 270 } 271 static inline int cpc_read_ffh_fb_ctrs(int cpu, struct cpc_reg *reg1, u64 *val1, 272 struct cpc_reg *reg2, u64 *val2) 273 { 274 return -EOPNOTSUPP; 275 } 276 static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) 277 { 278 return -EOPNOTSUPP; 279 } 280 static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable) 281 { 282 return -EOPNOTSUPP; 283 } 284 static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf) 285 { 286 return -EOPNOTSUPP; 287 } 288 static inline int cppc_set_epp(int cpu, u64 epp_val) 289 { 290 return -EOPNOTSUPP; 291 } 292 static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window) 293 { 294 return -EOPNOTSUPP; 295 } 296 static inline int cppc_set_auto_act_window(int cpu, u64 auto_act_window) 297 { 298 return -EOPNOTSUPP; 299 } 300 static inline int cppc_get_auto_sel(int cpu, bool *enable) 301 { 302 return -EOPNOTSUPP; 303 } 304 305 static inline bool cppc_auto_sel_is_immutable(int cpu) 306 { 307 return false; 308 } 309 310 static inline int cppc_set_auto_sel(int cpu, bool enable) 311 { 312 return -EOPNOTSUPP; 313 } 314 static inline int cppc_get_perf_limited(int cpu, u64 *perf_limited) 315 { 316 return -EOPNOTSUPP; 317 } 318 static inline int cppc_set_perf_limited(int cpu, u64 bits_to_clear) 319 { 320 return -EOPNOTSUPP; 321 } 322 static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf) 323 { 324 return -ENODEV; 325 } 326 static inline int amd_get_effective_highest_perf(unsigned int cpu) 327 { 328 return -EOPNOTSUPP; 329 } 330 static inline int amd_get_max_frequency(unsigned int cpu) 331 { 332 return 0; 333 } 334 static inline int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator) 335 { 336 return -EOPNOTSUPP; 337 } 338 static inline int amd_detect_prefcore(bool *detected) 339 { 340 return -ENODEV; 341 } 342 #endif /* !CONFIG_ACPI_CPPC_LIB */ 343 344 #endif /* _CPPC_ACPI_H*/ 345