1 /*
2  *  xen/include/acpi/cpufreq/cpufreq.h
3  *
4  *  Copyright (C) 2001 Russell King
5  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6  *
7  * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 #ifndef __XEN_CPUFREQ_PM_H__
15 #define __XEN_CPUFREQ_PM_H__
16 
17 #include <xen/types.h>
18 #include <xen/list.h>
19 #include <xen/cpumask.h>
20 
21 #include "processor_perf.h"
22 
23 DECLARE_PER_CPU(spinlock_t, cpufreq_statistic_lock);
24 
25 extern bool_t cpufreq_verbose;
26 
27 struct cpufreq_governor;
28 
29 struct acpi_cpufreq_data {
30     struct processor_performance *acpi_data;
31     struct cpufreq_frequency_table *freq_table;
32     unsigned int arch_cpu_flags;
33 };
34 
35 extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS];
36 
37 struct cpufreq_cpuinfo {
38     unsigned int        max_freq;
39     unsigned int        second_max_freq;    /* P1 if Turbo Mode is on */
40     unsigned int        min_freq;
41     unsigned int        transition_latency; /* in 10^(-9) s = nanoseconds */
42 };
43 
44 struct perf_limits {
45     bool_t no_turbo;
46     bool_t turbo_disabled;
47     uint32_t turbo_pct;
48     uint32_t max_perf_pct; /* max performance in percentage */
49     uint32_t min_perf_pct; /* min performance in percentage */
50     uint32_t max_perf;
51     uint32_t min_perf;
52     uint32_t max_policy_pct;
53     uint32_t min_policy_pct;
54 };
55 
56 struct cpufreq_policy {
57     cpumask_var_t       cpus;          /* affected CPUs */
58     unsigned int        shared_type;   /* ANY or ALL affected CPUs
59                                           should set cpufreq */
60     unsigned int        cpu;           /* cpu nr of registered CPU */
61     struct cpufreq_cpuinfo    cpuinfo;
62 
63     unsigned int        min;    /* in kHz */
64     unsigned int        max;    /* in kHz */
65     unsigned int        cur;    /* in kHz, only needed if cpufreq
66                                  * governors are used */
67     struct perf_limits  limits;
68     struct cpufreq_governor     *governor;
69 
70     bool_t              resume; /* flag for cpufreq 1st run
71                                  * S3 wakeup, hotplug cpu, etc */
72     s8                  turbo;  /* tristate flag: 0 for unsupported
73                                  * -1 for disable, 1 for enabled
74                                  * See CPUFREQ_TURBO_* below for defines */
75     bool_t              aperf_mperf; /* CPU has APERF/MPERF MSRs */
76 };
77 DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
78 
79 extern int __cpufreq_set_policy(struct cpufreq_policy *data,
80                                 struct cpufreq_policy *policy);
81 
82 #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
83 #define CPUFREQ_SHARED_TYPE_HW   (1) /* HW does needed coordination */
84 #define CPUFREQ_SHARED_TYPE_ALL  (2) /* All dependent CPUs should set freq */
85 #define CPUFREQ_SHARED_TYPE_ANY  (3) /* Freq can be set from any dependent CPU*/
86 
87 /******************** cpufreq transition notifiers *******************/
88 
89 struct cpufreq_freqs {
90     unsigned int cpu;    /* cpu nr */
91     unsigned int old;
92     unsigned int new;
93     u8 flags;            /* flags of cpufreq_driver, see below. */
94 };
95 
96 
97 /*********************************************************************
98  *                          CPUFREQ GOVERNORS                        *
99  *********************************************************************/
100 
101 #define CPUFREQ_GOV_START  1
102 #define CPUFREQ_GOV_STOP   2
103 #define CPUFREQ_GOV_LIMITS 3
104 
105 struct cpufreq_governor {
106     char    name[CPUFREQ_NAME_LEN];
107     int     (*governor)(struct cpufreq_policy *policy,
108                         unsigned int event);
109     bool_t  (*handle_option)(const char *name, const char *value);
110     struct list_head governor_list;
111 };
112 
113 extern struct cpufreq_governor *cpufreq_opt_governor;
114 extern struct cpufreq_governor cpufreq_gov_dbs;
115 extern struct cpufreq_governor cpufreq_gov_userspace;
116 extern struct cpufreq_governor cpufreq_gov_performance;
117 extern struct cpufreq_governor cpufreq_gov_powersave;
118 
119 extern struct list_head cpufreq_governor_list;
120 
121 extern int cpufreq_register_governor(struct cpufreq_governor *governor);
122 extern struct cpufreq_governor *__find_governor(const char *governor);
123 #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
124 
125 /* pass a target to the cpufreq driver */
126 extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
127                                    unsigned int target_freq,
128                                    unsigned int relation);
129 
130 #define GOV_GETAVG     1
131 #define USR_GETAVG     2
132 extern int cpufreq_driver_getavg(unsigned int cpu, unsigned int flag);
133 
134 #define CPUFREQ_TURBO_DISABLED      -1
135 #define CPUFREQ_TURBO_UNSUPPORTED   0
136 #define CPUFREQ_TURBO_ENABLED       1
137 
138 extern int cpufreq_update_turbo(int cpuid, int new_state);
139 extern int cpufreq_get_turbo_status(int cpuid);
140 
141 static __inline__ int
__cpufreq_governor(struct cpufreq_policy * policy,unsigned int event)142 __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
143 {
144     return policy->governor->governor(policy, event);
145 }
146 
147 
148 /*********************************************************************
149  *                      CPUFREQ DRIVER INTERFACE                     *
150  *********************************************************************/
151 
152 #define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
153 #define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
154 
155 struct cpufreq_driver {
156     const char *name;
157     int    (*init)(struct cpufreq_policy *policy);
158     int    (*verify)(struct cpufreq_policy *policy);
159     int    (*setpolicy)(struct cpufreq_policy *policy);
160     int    (*update)(int cpuid, struct cpufreq_policy *policy);
161     int    (*target)(struct cpufreq_policy *policy,
162                      unsigned int target_freq,
163                      unsigned int relation);
164     unsigned int    (*get)(unsigned int cpu);
165     unsigned int    (*getavg)(unsigned int cpu, unsigned int flag);
166     int    (*exit)(struct cpufreq_policy *policy);
167 };
168 
169 extern struct cpufreq_driver cpufreq_driver;
170 
171 int cpufreq_register_driver(const struct cpufreq_driver *);
172 
173 static __inline__
cpufreq_verify_within_limits(struct cpufreq_policy * policy,unsigned int min,unsigned int max)174 void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
175                                   unsigned int min, unsigned int max)
176 {
177     if (policy->min < min)
178         policy->min = min;
179     if (policy->max < min)
180         policy->max = min;
181     if (policy->min > max)
182         policy->min = max;
183     if (policy->max > max)
184         policy->max = max;
185     if (policy->min > policy->max)
186         policy->min = policy->max;
187     return;
188 }
189 
190 
191 /*********************************************************************
192  *                     FREQUENCY TABLE HELPERS                       *
193  *********************************************************************/
194 
195 #define CPUFREQ_ENTRY_INVALID ~0
196 #define CPUFREQ_TABLE_END     ~1
197 
198 struct cpufreq_frequency_table {
199     unsigned int    index;     /* any */
200     unsigned int    frequency; /* kHz - doesn't need to be in ascending
201                                 * order */
202 };
203 
204 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
205                    struct cpufreq_frequency_table *table);
206 
207 int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
208                    struct cpufreq_frequency_table *table);
209 
210 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
211                    struct cpufreq_frequency_table *table,
212                    unsigned int target_freq,
213                    unsigned int relation,
214                    unsigned int *index);
215 
216 
217 /*********************************************************************
218  *                     UNIFIED DEBUG HELPERS                         *
219  *********************************************************************/
220 
221 struct cpu_dbs_info_s {
222     uint64_t prev_cpu_idle;
223     uint64_t prev_cpu_wall;
224     struct cpufreq_policy *cur_policy;
225     struct cpufreq_frequency_table *freq_table;
226     int cpu;
227     unsigned int enable:1;
228     unsigned int turbo_enabled:1;
229     int8_t stoppable;
230 };
231 
232 int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
233 int get_cpufreq_ondemand_para(uint32_t *sampling_rate_max,
234                               uint32_t *sampling_rate_min,
235                               uint32_t *sampling_rate,
236                               uint32_t *up_threshold);
237 int write_ondemand_sampling_rate(unsigned int sampling_rate);
238 int write_ondemand_up_threshold(unsigned int up_threshold);
239 
240 int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
241 
242 void cpufreq_dbs_timer_suspend(void);
243 void cpufreq_dbs_timer_resume(void);
244 
245 #endif /* __XEN_CPUFREQ_PM_H__ */
246