xref: /aosp_15_r20/external/coreboot/src/superio/fintek/common/fan_control.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef SUPERIO_FINTEK_FAN_CONTROL_H
4 #define SUPERIO_FINTEK_FAN_CONTROL_H
5 
6 #include <stdint.h>
7 
8 typedef enum {
9 	IGNORE_SENSOR = 0,
10 	EXTERNAL_SENSOR1,
11 	EXTERNAL_SENSOR2,
12 	EXTERNAL_SENSOR3,
13 	EXTERNAL_SENSOR4
14 } external_sensor;
15 
16 typedef enum {
17 	TEMP_SENSOR_THERMISTOR = 0,
18 	TEMP_SENSOR_BJT,
19 	TEMP_SENSOR_DEFAULT
20 } temp_sensor_type;
21 
22 typedef enum {
23 	FAN_TYPE_PWM_PUSH_PULL = 0,
24 	FAN_TYPE_DAC_POWER,
25 	FAN_TYPE_PWM_OPEN_DRAIN,
26 	FAN_TYPE_RESERVED
27 } fan_type;
28 #define FAN_TYPE_PWM_CHECK			1 /* bit 0 must be 0 for PWM */
29 
30 typedef enum {
31 	FAN_MODE_AUTO_RPM = 0,
32 	FAN_MODE_AUTO_PWM_DAC,
33 	FAN_MODE_MANUAL_RPM,
34 	FAN_MODE_MANUAL_PWM_DAC,
35 	FAN_MODE_DEFAULT
36 } fan_mode;
37 
38 typedef enum {
39 	FAN_PWM_FREQ_23500 = 0,
40 	FAN_PWM_FREQ_11750,
41 	FAN_PWM_FREQ_5875,
42 	FAN_PWM_FREQ_220
43 } fan_pwm_freq;
44 
45 typedef enum {
46 	FAN_TEMP_PECI = 0,
47 	FAN_TEMP_EXTERNAL_1,
48 	FAN_TEMP_EXTERNAL_2,
49 	FAN_TEMP_TSI = 4,
50 	FAN_TEMP_MXM,
51 } fan_temp_source;
52 
53 typedef enum {
54 	FAN_UP_RATE_2HZ = 0,
55 	FAN_UP_RATE_5HZ,
56 	FAN_UP_RATE_10HZ,
57 	FAN_UP_RATE_20HZ,
58 	FAN_UP_RATE_DEFAULT,
59 	FAN_UP_RATE_JUMP = 8
60 } fan_rate_up;
61 
62 typedef enum {
63 	FAN_DOWN_RATE_2HZ = 0,
64 	FAN_DOWN_RATE_5HZ,
65 	FAN_DOWN_RATE_10HZ,
66 	FAN_DOWN_RATE_20HZ,
67 	FAN_DOWN_RATE_DEFAULT,
68 	FAN_DOWN_RATE_SAME_AS_UP,
69 	FAN_DOWN_RATE_JUMP = 8
70 } fan_rate_down;
71 
72 typedef enum {
73 	FAN_FOLLOW_STEP = 0,
74 	FAN_FOLLOW_INTERPOLATION
75 } fan_follow;
76 
77 struct fintek_fan {
78 	uint8_t fan;
79 	external_sensor sensor;
80 	temp_sensor_type stype;
81 	fan_temp_source temp_source;
82 	fan_type ftype;
83 	fan_mode fmode;
84 	fan_pwm_freq fan_freq;
85 	fan_rate_up rate_up;
86 	fan_rate_down rate_down;
87 	fan_follow follow;
88 	uint8_t *boundaries;
89 	uint8_t *sections;
90 };
91 
92 #define HWM_STATUS_SUCCESS			0
93 #define HWM_STATUS_INVALID_FAN			-1
94 #define HWM_STATUS_INVALID_TEMP_SOURCE		-2
95 #define HWM_STATUS_INVALID_TYPE			-3
96 #define HWM_STATUS_INVALID_MODE			-4
97 #define HWM_STATUS_INVALID_RATE			-5
98 #define HWM_STATUS_INVALID_FREQUENCY		-6
99 #define HWM_STATUS_INVALID_TEMP_SENSOR		-7
100 #define HWM_STATUS_INVALID_BOUNDARY_VALUE	-8
101 #define HWM_STATUS_INVALID_SECTION_VALUE	-9
102 #define HWM_STATUS_BOUNDARY_WRONG_ORDER		-10
103 #define HWM_STATUS_SECTIONS_WRONG_ORDER		-11
104 #define HWM_STATUS_WARNING_SENSOR_DISCONNECTED	1
105 #define HWM_STATUS_WARNING_FAN_NOT_PWM		2
106 
107 #define CPU_DAMAGE_TEMP				110
108 
109 /*
110  * Boundaries order is from highest temp. to lowest. Values from 0 to 127.
111  * Boundaries should be defined as u8 boundaries[FINTEK_BOUNDARIES_SIZE].
112  */
113 #define FINTEK_BOUNDARIES_SIZE			4
114 /*
115  * Section defines the duty_cycle/voltage to be used based on where the
116  * temperature lies with respect to the boundaries. There are 5 sections
117  * (4 boundaries) and the order must be from highest to lowest. Values
118  * from 0% to 100%, will be converted internally to percent of 255.
119  * Sections should be defined as u8 sections[FINTEK_SECTIONS_SIZE].
120  */
121 #define FINTEK_SECTIONS_SIZE			5
122 
123 /*
124  * When using external sensor, its type must be defined. When using PECI,
125  * TSI or MXM use IGNORE_SENSOR to indicate so.
126  */
127 int set_sensor_type(u16 base_address, external_sensor sensor,
128 						temp_sensor_type type);
129 
130 /*
131  * Define the temperature source used to control a fan.
132  */
133 int set_fan_temperature_source(u16 base_address, u8 fan,
134 						fan_temp_source source);
135 
136 /*
137  * Define if fan is controlled through PWM or absolute voltage powering it
138  * (DAC). Then, under mode, define if control is automatic (SIO) or manual
139  * (CPU, through ACPI). Notice there needs to be a match between type and
140  * mode (PWM with PWM or DAC with DAC).
141  */
142 int set_fan_type_mode(u16 base_address, u8 fan, fan_type type, fan_mode mode);
143 
144 /*
145  * For fans controlled through pulse width, define the base frequency used.
146  */
147 int set_pwm_frequency(u16 base_address, u8 fan, fan_pwm_freq frequency);
148 
149 /*
150  * For fintek SIO HWM there are 4 (temperature) boundaries points, defining
151  * 5 sections (1 fan speed per section). Start with the highest temperature/
152  * speed. Temperature is in Celsius, speed is in percentile of max speed. The
153  * highest speed should be 100%, no requirements for minimum speed, could be
154  * 0 or above 0.
155  */
156 int set_sections(u16 base_address, u8 fan, u8 *boundaries, u8 *sections);
157 
158 /*
159  * Define how often temperature is measured to change fan speed.
160  */
161 int set_fan_speed_change_rate(u16 base_address, u8 fan, fan_rate_up rate_up,
162 						fan_rate_down rate_down);
163 
164 /*
165  * There a 2 ways a fan can be controlled: A single speed per section, or
166  * interpolation. Under interpolation, the section speed is the speed at the
167  * lowest temperature of the section (0 Celsius for the lowest section), and
168  * it's the speed of the next section at the boundary to the next section.
169  * In between these 2 points, it's a linear function. For example, midway
170  * between temperature points it'll have a speed that is midway between the
171  * section speed and next section speed. Obviously, there's no variation for
172  * the highest section, reason why it must be 100% max speed.
173  */
174 int set_fan_follow(u16 base_address, u8 fan, fan_follow follow);
175 
176 /*
177  * This is an upper level API which calls all the above APIs in the
178  * appropriate order. Any API failure will be displayed. Alerts will
179  * also be displayed, but will not interrupt the sequence, while errors
180  * will interrupt the sequence.
181  */
182 int set_fan(struct fintek_fan *fan_init);
183 
184 #endif /* SUPERIO_FINTEK_FAN_CONTROL_H */
185