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 /* Lock used for RMW operations in cpc_write() */ 68 spinlock_t rmw_lock; 69 struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT]; 70 struct acpi_psd_package domain_info; 71 struct kobject kobj; 72 }; 73 74 /* These are indexes into the per-cpu cpc_regs[]. Order is important. */ 75 enum cppc_regs { 76 HIGHEST_PERF, 77 NOMINAL_PERF, 78 LOW_NON_LINEAR_PERF, 79 LOWEST_PERF, 80 GUARANTEED_PERF, 81 DESIRED_PERF, 82 MIN_PERF, 83 MAX_PERF, 84 PERF_REDUC_TOLERANCE, 85 TIME_WINDOW, 86 CTR_WRAP_TIME, 87 REFERENCE_CTR, 88 DELIVERED_CTR, 89 PERF_LIMITED, 90 ENABLE, 91 AUTO_SEL_ENABLE, 92 AUTO_ACT_WINDOW, 93 ENERGY_PERF, 94 REFERENCE_PERF, 95 LOWEST_FREQ, 96 NOMINAL_FREQ, 97 }; 98 99 /* 100 * Categorization of registers as described 101 * in the ACPI v.5.1 spec. 102 * XXX: Only filling up ones which are used by governors 103 * today. 104 */ 105 struct cppc_perf_caps { 106 u32 guaranteed_perf; 107 u32 highest_perf; 108 u32 nominal_perf; 109 u32 lowest_perf; 110 u32 lowest_nonlinear_perf; 111 u32 lowest_freq; 112 u32 nominal_freq; 113 u32 energy_perf; 114 bool auto_sel; 115 }; 116 117 struct cppc_perf_ctrls { 118 u32 max_perf; 119 u32 min_perf; 120 u32 desired_perf; 121 u32 energy_perf; 122 }; 123 124 struct cppc_perf_fb_ctrs { 125 u64 reference; 126 u64 delivered; 127 u64 reference_perf; 128 u64 wraparound_time; 129 }; 130 131 /* Per CPU container for runtime CPPC management. */ 132 struct cppc_cpudata { 133 struct list_head node; 134 struct cppc_perf_caps perf_caps; 135 struct cppc_perf_ctrls perf_ctrls; 136 struct cppc_perf_fb_ctrs perf_fb_ctrs; 137 unsigned int shared_type; 138 cpumask_var_t shared_cpu_map; 139 }; 140 141 #ifdef CONFIG_ACPI_CPPC_LIB 142 extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); 143 extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); 144 extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf); 145 extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); 146 extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); 147 extern int cppc_set_enable(int cpu, bool enable); 148 extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); 149 extern bool cppc_perf_ctrs_in_pcc(void); 150 extern unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf); 151 extern unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq); 152 extern bool acpi_cpc_valid(void); 153 extern bool cppc_allow_fast_switch(void); 154 extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); 155 extern unsigned int cppc_get_transition_latency(int cpu); 156 extern bool cpc_ffh_supported(void); 157 extern bool cpc_supported_by_cpu(void); 158 extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); 159 extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); 160 extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf); 161 extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable); 162 extern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps); 163 extern int cppc_set_auto_sel(int cpu, bool enable); 164 #else /* !CONFIG_ACPI_CPPC_LIB */ 165 static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf) 166 { 167 return -ENOTSUPP; 168 } 169 static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) 170 { 171 return -ENOTSUPP; 172 } 173 static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf) 174 { 175 return -ENOTSUPP; 176 } 177 static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) 178 { 179 return -ENOTSUPP; 180 } 181 static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) 182 { 183 return -ENOTSUPP; 184 } 185 static inline int cppc_set_enable(int cpu, bool enable) 186 { 187 return -ENOTSUPP; 188 } 189 static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps) 190 { 191 return -ENOTSUPP; 192 } 193 static inline bool cppc_perf_ctrs_in_pcc(void) 194 { 195 return false; 196 } 197 static inline bool acpi_cpc_valid(void) 198 { 199 return false; 200 } 201 static inline bool cppc_allow_fast_switch(void) 202 { 203 return false; 204 } 205 static inline unsigned int cppc_get_transition_latency(int cpu) 206 { 207 return CPUFREQ_ETERNAL; 208 } 209 static inline bool cpc_ffh_supported(void) 210 { 211 return false; 212 } 213 static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) 214 { 215 return -ENOTSUPP; 216 } 217 static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) 218 { 219 return -ENOTSUPP; 220 } 221 static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable) 222 { 223 return -ENOTSUPP; 224 } 225 static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf) 226 { 227 return -ENOTSUPP; 228 } 229 static inline int cppc_set_auto_sel(int cpu, bool enable) 230 { 231 return -ENOTSUPP; 232 } 233 static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps) 234 { 235 return -ENOTSUPP; 236 } 237 #endif /* !CONFIG_ACPI_CPPC_LIB */ 238 239 #endif /* _CPPC_ACPI_H*/ 240