| /* |
| * 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 */ |