summaryrefslogtreecommitdiff
path: root/src/superio/fintek/common/fan_control.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/superio/fintek/common/fan_control.h')
-rw-r--r--src/superio/fintek/common/fan_control.h199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/superio/fintek/common/fan_control.h b/src/superio/fintek/common/fan_control.h
new file mode 100644
index 0000000000..fbe784bfa1
--- /dev/null
+++ b/src/superio/fintek/common/fan_control.h
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2019 Richard Spiegel <richard.spiegel@silverbackltd.com>
+ * Copyright (C) 2019 Silverback ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SUPERIO_FINTEK_FAN_CONTROL_H
+#define SUPERIO_FINTEK_FAN_CONTROL_H
+
+#include <stdint.h>
+#include <arch/io.h>
+
+typedef enum {
+ IGNORE_SENSOR = 0,
+ EXTERNAL_SENSOR1,
+ EXTERNAL_SENSOR2,
+ EXTERNAL_SENSOR3,
+ EXTERNAL_SENSOR4
+} external_sensor;
+
+typedef enum {
+ TEMP_SENSOR_THERMISTOR = 0,
+ TEMP_SENSOR_BJT,
+ TEMP_SENSOR_DEFAULT
+} temp_sensor_type;
+
+typedef enum {
+ FAN_TYPE_PWM_PUSH_PULL = 0,
+ FAN_TYPE_DAC_POWER,
+ FAN_TYPE_PWM_OPEN_DRAIN,
+ FAN_TYPE_RESERVED
+} fan_type;
+#define FAN_TYPE_PWM_CHECK 1 /* bit 0 must be 0 for PWM */
+
+typedef enum {
+ FAN_MODE_AUTO_RPM = 0,
+ FAN_MODE_AUTO_PWM_DAC,
+ FAN_MODE_MANUAL_RPM,
+ FAN_MODE_MANUAL_PWM_DAC,
+ FAN_MODE_DEFAULT
+} fan_mode;
+
+typedef enum {
+ FAN_PWM_FREQ_23500 = 0,
+ FAN_PWM_FREQ_11750,
+ FAN_PWM_FREQ_5875,
+ FAN_PWM_FREQ_220
+} fan_pwm_freq;
+
+typedef enum {
+ FAN_TEMP_PECI = 0,
+ FAN_TEMP_EXTERNAL_1,
+ FAN_TEMP_EXTERNAL_2,
+ FAN_TEMP_TSI = 4,
+ FAN_TEMP_MXM,
+} fan_temp_source;
+
+typedef enum {
+ FAN_UP_RATE_2HZ = 0,
+ FAN_UP_RATE_5HZ,
+ FAN_UP_RATE_10HZ,
+ FAN_UP_RATE_20HZ,
+ FAN_UP_RATE_DEFAULT,
+ FAN_UP_RATE_JUMP = 8
+} fan_rate_up;
+
+typedef enum {
+ FAN_DOWN_RATE_2HZ = 0,
+ FAN_DOWN_RATE_5HZ,
+ FAN_DOWN_RATE_10HZ,
+ FAN_DOWN_RATE_20HZ,
+ FAN_DOWN_RATE_DEFAULT,
+ FAN_DOWN_RATE_SAME_AS_UP,
+ FAN_DOWN_RATE_JUMP = 8
+} fan_rate_down;
+
+typedef enum {
+ FAN_FOLLOW_STEP = 0,
+ FAN_FOLLOW_INTERPOLATION
+} fan_follow;
+
+struct fintek_fan {
+ uint8_t fan;
+ external_sensor sensor;
+ temp_sensor_type stype;
+ fan_temp_source temp_source;
+ fan_type ftype;
+ fan_mode fmode;
+ fan_pwm_freq fan_freq;
+ fan_rate_up rate_up;
+ fan_rate_down rate_down;
+ fan_follow follow;
+ uint8_t *boundaries;
+ uint8_t *sections;
+};
+
+#define HWM_STATUS_SUCCESS 0
+#define HWM_STATUS_INVALID_FAN -1
+#define HWM_STATUS_INVALID_TEMP_SOURCE -2
+#define HWM_STATUS_INVALID_TYPE -3
+#define HWM_STATUS_INVALID_MODE -4
+#define HWM_STATUS_INVALID_RATE -5
+#define HWM_STATUS_INVALID_FREQUENCY -6
+#define HWM_STATUS_INVALID_TEMP_SENSOR -7
+#define HWM_STATUS_INVALID_BOUNDARY_VALUE -8
+#define HWM_STATUS_INVALID_SECTION_VALUE -9
+#define HWM_STATUS_BOUNDARY_WRONG_ORDER -10
+#define HWM_STATUS_SECTIONS_WRONG_ORDER -11
+#define HWM_STATUS_WARNING_SENSOR_DISCONECTED 1
+#define HWM_STATUS_WARNING_FAN_NOT_PWM 2
+
+#define CPU_DAMAGE_TEMP 110
+
+/*
+ * Boundaries order is from highest temp. to lowest. Values from 0 to 127.
+ * Boundaries should be defined as u8 boundaries[FINTEK_BOUNDARIES_SIZE].
+ */
+#define FINTEK_BOUNDARIES_SIZE 4
+/*
+ * Section defines the duty_cycle/voltage to be used based on where the
+ * temperature lies with respect to the boundaries. There are 5 sections
+ * (4 boundaries) and the order must be from highest to lowest. Values
+ * from 0% to 100%, will be converted internally to percent of 255.
+ * Sections should be defined as u8 sections[FINTEK_SECTIONS_SIZE].
+ */
+#define FINTEK_SECTIONS_SIZE 5
+
+/*
+ * When using external sensor, its type must be defined. When using PECI,
+ * TSI or MXM use IGNORE_SENSOR to indicate so.
+ */
+int set_sensor_type(u16 base_address, external_sensor sensor,
+ temp_sensor_type type);
+
+/*
+ * Define the temperature source used to control a fan.
+ */
+int set_fan_temperature_source(u16 base_address, u8 fan,
+ fan_temp_source source);
+
+/*
+ * Define if fan is controlled through PWM or absolute voltage powering it
+ * (DAC). Then, under mode, define if control is automatic (SIO) or manual
+ * (CPU, through ACPI). Notice there needs to be a match between type and
+ * mode (PWM with PWM or DAC with DAC).
+ */
+int set_fan_type_mode(u16 base_address, u8 fan, fan_type type, fan_mode mode);
+
+/*
+ * For fans controlled through pulse width, define the base frequency used.
+ */
+int set_pwm_frequency(u16 base_address, u8 fan, fan_pwm_freq frequency);
+
+/*
+ * For fintek SIO HWM there are 4 (temperature) boundaries points, defining
+ * 5 sections (1 fan speed per section). Start with the highest temperature/
+ * speed. Temperature is in Celsius, speed is in percentile of max speed. The
+ * highest speed should be 100%, no requirements for minimum speed, could be
+ * 0 or above 0.
+ */
+int set_sections(u16 base_address, u8 fan, u8 *boundaries, u8 *sections);
+
+/*
+ * Define how often temperature is measured to change fan speed.
+ */
+int set_fan_speed_change_rate(u16 base_address, u8 fan, fan_rate_up rate_up,
+ fan_rate_down rate_down);
+
+/*
+ * There a 2 ways a fan can be controlled: A single speed per section, or
+ * interpolation. Under interpolation, the section speed is the speed at the
+ * lowest temperature of the section (0 Celsius for the lowest section), and
+ * it's the speed of the next section at the boundary to the next section.
+ * In between these 2 points, it's a linear function. For example, midway
+ * between temperature points it'll have a speed that is midway between the
+ * section speed and next section speed. Obviously, there's no variation for
+ * the highest section, reason why it must be 100% max speed.
+ */
+int set_fan_follow(u16 base_address, u8 fan, fan_follow follow);
+
+/*
+ * This is an upper level API which calls all the above APIs in the
+ * appropriate order. Any API failure will be displayed. Alerts will
+ * also be displayed, but will not interrupt the sequence, while errors
+ * will interrupt the sequence.
+ */
+int set_fan(struct fintek_fan *fan_init);
+
+#endif /* SUPERIO_FINTEK_FAN_CONTROL_H */