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  	raw_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  extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
165  extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
166  extern int amd_detect_prefcore(bool *detected);
167  #else /* !CONFIG_ACPI_CPPC_LIB */
cppc_get_desired_perf(int cpunum,u64 * desired_perf)168  static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
169  {
170  	return -EOPNOTSUPP;
171  }
cppc_get_nominal_perf(int cpunum,u64 * nominal_perf)172  static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
173  {
174  	return -EOPNOTSUPP;
175  }
cppc_get_highest_perf(int cpunum,u64 * highest_perf)176  static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
177  {
178  	return -EOPNOTSUPP;
179  }
cppc_get_perf_ctrs(int cpu,struct cppc_perf_fb_ctrs * perf_fb_ctrs)180  static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
181  {
182  	return -EOPNOTSUPP;
183  }
cppc_set_perf(int cpu,struct cppc_perf_ctrls * perf_ctrls)184  static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
185  {
186  	return -EOPNOTSUPP;
187  }
cppc_set_enable(int cpu,bool enable)188  static inline int cppc_set_enable(int cpu, bool enable)
189  {
190  	return -EOPNOTSUPP;
191  }
cppc_get_perf_caps(int cpu,struct cppc_perf_caps * caps)192  static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
193  {
194  	return -EOPNOTSUPP;
195  }
cppc_perf_ctrs_in_pcc(void)196  static inline bool cppc_perf_ctrs_in_pcc(void)
197  {
198  	return false;
199  }
acpi_cpc_valid(void)200  static inline bool acpi_cpc_valid(void)
201  {
202  	return false;
203  }
cppc_allow_fast_switch(void)204  static inline bool cppc_allow_fast_switch(void)
205  {
206  	return false;
207  }
cppc_get_transition_latency(int cpu)208  static inline unsigned int cppc_get_transition_latency(int cpu)
209  {
210  	return CPUFREQ_ETERNAL;
211  }
cpc_ffh_supported(void)212  static inline bool cpc_ffh_supported(void)
213  {
214  	return false;
215  }
cpc_read_ffh(int cpunum,struct cpc_reg * reg,u64 * val)216  static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
217  {
218  	return -EOPNOTSUPP;
219  }
cpc_write_ffh(int cpunum,struct cpc_reg * reg,u64 val)220  static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
221  {
222  	return -EOPNOTSUPP;
223  }
cppc_set_epp_perf(int cpu,struct cppc_perf_ctrls * perf_ctrls,bool enable)224  static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
225  {
226  	return -EOPNOTSUPP;
227  }
cppc_get_epp_perf(int cpunum,u64 * epp_perf)228  static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
229  {
230  	return -EOPNOTSUPP;
231  }
cppc_set_auto_sel(int cpu,bool enable)232  static inline int cppc_set_auto_sel(int cpu, bool enable)
233  {
234  	return -EOPNOTSUPP;
235  }
cppc_get_auto_sel_caps(int cpunum,struct cppc_perf_caps * perf_caps)236  static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps)
237  {
238  	return -EOPNOTSUPP;
239  }
amd_get_highest_perf(unsigned int cpu,u32 * highest_perf)240  static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf)
241  {
242  	return -ENODEV;
243  }
amd_get_boost_ratio_numerator(unsigned int cpu,u64 * numerator)244  static inline int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
245  {
246  	return -EOPNOTSUPP;
247  }
amd_detect_prefcore(bool * detected)248  static inline int amd_detect_prefcore(bool *detected)
249  {
250  	return -ENODEV;
251  }
252  #endif /* !CONFIG_ACPI_CPPC_LIB */
253  
254  #endif /* _CPPC_ACPI_H*/
255