xref: /freebsd/sys/sys/cpu.h (revision 5fffaf16)
1a07c3820SNate Lawson /*-
2a07c3820SNate Lawson  * Copyright (c) 2005 Nate Lawson (SDG)
3a07c3820SNate Lawson  * All rights reserved.
4a07c3820SNate Lawson  *
5a07c3820SNate Lawson  * Redistribution and use in source and binary forms, with or without
6a07c3820SNate Lawson  * modification, are permitted provided that the following conditions
7a07c3820SNate Lawson  * are met:
8a07c3820SNate Lawson  * 1. Redistributions of source code must retain the above copyright
9a07c3820SNate Lawson  *    notice, this list of conditions and the following disclaimer.
10a07c3820SNate Lawson  * 2. Redistributions in binary form must reproduce the above copyright
11a07c3820SNate Lawson  *    notice, this list of conditions and the following disclaimer in the
12a07c3820SNate Lawson  *    documentation and/or other materials provided with the distribution.
13a07c3820SNate Lawson  *
14a07c3820SNate Lawson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15a07c3820SNate Lawson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16a07c3820SNate Lawson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17a07c3820SNate Lawson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18a07c3820SNate Lawson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19a07c3820SNate Lawson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20a07c3820SNate Lawson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21a07c3820SNate Lawson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22a07c3820SNate Lawson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23a07c3820SNate Lawson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24a07c3820SNate Lawson  * SUCH DAMAGE.
25a07c3820SNate Lawson  *
26a07c3820SNate Lawson  * $FreeBSD$
27a07c3820SNate Lawson  */
28a07c3820SNate Lawson 
29a07c3820SNate Lawson #ifndef _SYS_CPU_H_
30a07c3820SNate Lawson #define _SYS_CPU_H_
31a07c3820SNate Lawson 
32a07c3820SNate Lawson /*
33a07c3820SNate Lawson  * CPU device support.
34a07c3820SNate Lawson  */
35a07c3820SNate Lawson 
36a07c3820SNate Lawson #define CPU_IVAR_PCPU		1
37a07c3820SNate Lawson 
38a07c3820SNate Lawson static __inline struct pcpu *cpu_get_pcpu(device_t dev)
39a07c3820SNate Lawson {
40a07c3820SNate Lawson 	uintptr_t v = 0;
41a07c3820SNate Lawson 	BUS_READ_IVAR(device_get_parent(dev), dev, CPU_IVAR_PCPU, &v);
42a07c3820SNate Lawson 	return ((struct pcpu *)v);
43a07c3820SNate Lawson }
44a07c3820SNate Lawson 
45a07c3820SNate Lawson /*
46a07c3820SNate Lawson  * CPU frequency control interface.
47a07c3820SNate Lawson  */
48a07c3820SNate Lawson 
49a07c3820SNate Lawson /* Each driver's CPU frequency setting is exported in this format. */
50a07c3820SNate Lawson struct cf_setting {
515fffaf16SNate Lawson 	int	freq;	/* CPU clock in Mhz or 100ths of a percent. */
52a07c3820SNate Lawson 	int	volts;	/* Voltage in mV. */
53a07c3820SNate Lawson 	int	power;	/* Power consumed in mW. */
54a07c3820SNate Lawson 	int	lat;	/* Transition latency in us. */
55a07c3820SNate Lawson 	device_t dev;	/* Driver providing this setting. */
56a07c3820SNate Lawson };
57a07c3820SNate Lawson 
58a07c3820SNate Lawson /* Maximum number of settings a given driver can have. */
59a07c3820SNate Lawson #define MAX_SETTINGS		24
60a07c3820SNate Lawson 
61a07c3820SNate Lawson /* A combination of settings is a level. */
62a07c3820SNate Lawson struct cf_level {
63a07c3820SNate Lawson 	struct cf_setting	total_set;
64a07c3820SNate Lawson 	struct cf_setting	abs_set;
65a07c3820SNate Lawson 	struct cf_setting	rel_set[MAX_SETTINGS];
66a07c3820SNate Lawson 	int			rel_count;
67a07c3820SNate Lawson 	TAILQ_ENTRY(cf_level)	link;
68a07c3820SNate Lawson };
69a07c3820SNate Lawson 
70a07c3820SNate Lawson TAILQ_HEAD(cf_level_lst, cf_level);
71a07c3820SNate Lawson 
72a07c3820SNate Lawson /* Drivers should set all unknown values to this. */
73a07c3820SNate Lawson #define CPUFREQ_VAL_UNKNOWN	(-1)
74a07c3820SNate Lawson 
75a07c3820SNate Lawson /*
76a07c3820SNate Lawson  * Every driver offers a type of CPU control.  Absolute levels are mutually
77a07c3820SNate Lawson  * exclusive while relative levels modify the current absolute level.  There
78a07c3820SNate Lawson  * may be multiple absolute and relative drivers available on a given
79a07c3820SNate Lawson  * system.
80a07c3820SNate Lawson  *
81a07c3820SNate Lawson  * For example, consider a system with two absolute drivers that provide
82a07c3820SNate Lawson  * frequency settings of 100, 200 and 300, 400 and a relative driver that
83a07c3820SNate Lawson  * provides settings of 50%, 100%.  The cpufreq core would export frequency
84a07c3820SNate Lawson  * levels of 50, 100, 150, 200, 300, 400.
855fffaf16SNate Lawson  *
865fffaf16SNate Lawson  * The "info only" flag signifies that settings returned by
875fffaf16SNate Lawson  * CPUFREQ_DRV_SETTINGS cannot be passed to the CPUFREQ_DRV_SET method and
885fffaf16SNate Lawson  * are only informational.  This is for some drivers that can return
895fffaf16SNate Lawson  * information about settings but rely on another machine-dependent driver
905fffaf16SNate Lawson  * for actually performing the frequency transition (e.g., ACPI performance
915fffaf16SNate Lawson  * states of type "functional fixed hardware.")
92a07c3820SNate Lawson  */
935fffaf16SNate Lawson #define CPUFREQ_TYPE_MASK	0xffff
94a07c3820SNate Lawson #define CPUFREQ_TYPE_RELATIVE	(1<<0)
95a07c3820SNate Lawson #define CPUFREQ_TYPE_ABSOLUTE	(1<<1)
965fffaf16SNate Lawson #define CPUFREQ_FLAG_INFO_ONLY	(1<<16)
97a07c3820SNate Lawson 
98a07c3820SNate Lawson /*
99a07c3820SNate Lawson  * When setting a level, the caller indicates the priority of this request.
100a07c3820SNate Lawson  * Priorities determine, among other things, whether a level can be
101a07c3820SNate Lawson  * overridden by other callers.  For example, if the user sets a level but
102a07c3820SNate Lawson  * the system thermal driver needs to override it for emergency cooling,
103a07c3820SNate Lawson  * the driver would use a higher priority.  Once the event has passed, the
104a07c3820SNate Lawson  * driver would call cpufreq to resume any previous level.
105a07c3820SNate Lawson  */
106a07c3820SNate Lawson #define CPUFREQ_PRIO_HIGHEST	1000000
107a07c3820SNate Lawson #define CPUFREQ_PRIO_KERN	1000
108a07c3820SNate Lawson #define CPUFREQ_PRIO_USER	100
109a07c3820SNate Lawson #define CPUFREQ_PRIO_LOWEST	0
110a07c3820SNate Lawson 
111a07c3820SNate Lawson /*
112a07c3820SNate Lawson  * Register and unregister a driver with the cpufreq core.  Once a driver
113a07c3820SNate Lawson  * is registered, it must support calls to its CPUFREQ_GET, CPUFREQ_GET_LEVEL,
114a07c3820SNate Lawson  * and CPUFREQ_SET methods.  It must also unregister before returning from
115a07c3820SNate Lawson  * its DEVICE_DETACH method.
116a07c3820SNate Lawson  */
117a07c3820SNate Lawson int	cpufreq_register(device_t dev);
118a07c3820SNate Lawson int	cpufreq_unregister(device_t dev);
119a07c3820SNate Lawson 
120a07c3820SNate Lawson /* Allow values to be +/- a bit since sometimes we have to estimate. */
121a07c3820SNate Lawson #define CPUFREQ_CMP(x, y)	(abs((x) - (y)) < 25)
122a07c3820SNate Lawson 
123a07c3820SNate Lawson /*
124a07c3820SNate Lawson  * Machine-dependent functions.
125a07c3820SNate Lawson  */
126a07c3820SNate Lawson 
127a07c3820SNate Lawson /* Estimate the current clock rate for the given CPU id. */
128a07c3820SNate Lawson int	cpu_est_clockrate(int cpu_id, uint64_t *rate);
129a07c3820SNate Lawson 
130a07c3820SNate Lawson #endif /* !_SYS_CPU_H_ */
131