Refactor reading thermals, updating fan duty
Move the fan-related logic from the PECI and dGPU modules to the fan module. The PECI and dGPU modules are now only responsible for reading the thermal data, and the fan module handles calculating and updating the fans duties based on that data.
This commit is contained in:
committed by
Tim Crawford
parent
e01536005a
commit
ceba69d7fa
@ -1,59 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <board/dgpu.h>
|
||||
#include <board/fan.h>
|
||||
#include <board/gpio.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/macro.h>
|
||||
#include <ec/i2c.h>
|
||||
#include <ec/pwm.h>
|
||||
|
||||
// Fan speed is the lowest requested over HEATUP seconds
|
||||
#ifndef BOARD_DGPU_HEATUP
|
||||
#define BOARD_DGPU_HEATUP 4
|
||||
#endif
|
||||
|
||||
static uint8_t FAN_HEATUP[BOARD_DGPU_HEATUP] = { 0 };
|
||||
|
||||
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
|
||||
#ifndef BOARD_DGPU_COOLDOWN
|
||||
#define BOARD_DGPU_COOLDOWN 10
|
||||
#endif
|
||||
|
||||
static uint8_t FAN_COOLDOWN[BOARD_DGPU_COOLDOWN] = { 0 };
|
||||
|
||||
int16_t dgpu_temp = 0;
|
||||
|
||||
#define DGPU_TEMP(X) ((int16_t)(X))
|
||||
|
||||
#define FAN_POINT(T, D) \
|
||||
{ .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) }
|
||||
|
||||
// Fan curve with temperature in degrees C, duty cycle in percent
|
||||
static struct FanPoint __code FAN_POINTS[] = {
|
||||
#ifdef BOARD_DGPU_FAN_POINTS
|
||||
BOARD_DGPU_FAN_POINTS
|
||||
#else
|
||||
FAN_POINT(70, 40),
|
||||
FAN_POINT(75, 50),
|
||||
FAN_POINT(80, 60),
|
||||
FAN_POINT(85, 65),
|
||||
FAN_POINT(90, 65)
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct Fan __code FAN = {
|
||||
.points = FAN_POINTS,
|
||||
.points_size = ARRAY_SIZE(FAN_POINTS),
|
||||
.heatup = FAN_HEATUP,
|
||||
.heatup_size = ARRAY_SIZE(FAN_HEATUP),
|
||||
.cooldown = FAN_COOLDOWN,
|
||||
.cooldown_size = ARRAY_SIZE(FAN_COOLDOWN),
|
||||
.interpolate = SMOOTH_FANS != 0,
|
||||
};
|
||||
|
||||
void dgpu_init(void) {
|
||||
// Set up for i2c usage
|
||||
i2c_reset(&I2C_DGPU, true);
|
||||
@ -77,28 +32,12 @@ bool dgpu_get_temp(int16_t *const data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t dgpu_get_fan_duty(void) {
|
||||
uint8_t duty;
|
||||
void dgpu_read_temp(void) {
|
||||
if (power_state == POWER_STATE_S0) {
|
||||
if (dgpu_get_temp(&dgpu_temp)) {
|
||||
duty = fan_duty(&FAN, dgpu_temp);
|
||||
} else {
|
||||
duty = PWM_DUTY(50);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dgpu_temp = 0;
|
||||
duty = PWM_DUTY(0);
|
||||
}
|
||||
|
||||
if (peci_on && fan_max) {
|
||||
// Override duty if fans are manually set to maximum
|
||||
duty = PWM_DUTY(100);
|
||||
} else {
|
||||
// Apply heatup and cooldown filters to duty
|
||||
duty = fan_heatup(&FAN, duty);
|
||||
duty = fan_cooldown(&FAN, duty);
|
||||
}
|
||||
|
||||
TRACE("DGPU temp=%d\n", dgpu_temp);
|
||||
return duty;
|
||||
dgpu_temp = 0;
|
||||
}
|
||||
|
@ -1,9 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <board/fan.h>
|
||||
#include <board/dgpu.h>
|
||||
#include <board/peci.h>
|
||||
#include <board/power.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/macro.h>
|
||||
#include <ec/pwm.h>
|
||||
|
||||
bool fan_max = false;
|
||||
|
||||
static uint8_t last_duty_dgpu = 0;
|
||||
static uint8_t last_duty_peci = 0;
|
||||
|
||||
#define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) }
|
||||
|
||||
#if SMOOTH_FANS != 0
|
||||
#define MAX_JUMP_UP ((MAX_FAN_SPEED - MIN_FAN_SPEED) / (uint8_t)SMOOTH_FANS_UP)
|
||||
#define MAX_JUMP_DOWN ((MAX_FAN_SPEED - MIN_FAN_SPEED) / (uint8_t)SMOOTH_FANS_DOWN)
|
||||
@ -14,9 +25,83 @@
|
||||
|
||||
#define MIN_SPEED_TO_SMOOTH PWM_DUTY(SMOOTH_FANS_MIN)
|
||||
|
||||
bool fan_max = false;
|
||||
uint8_t last_duty_dgpu = 0;
|
||||
uint8_t last_duty_peci = 0;
|
||||
// Fan speed is the lowest requested over HEATUP seconds
|
||||
#ifndef BOARD_HEATUP
|
||||
#define BOARD_HEATUP 4
|
||||
#endif
|
||||
|
||||
static uint8_t FAN1_HEATUP[BOARD_HEATUP] = { 0 };
|
||||
|
||||
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
|
||||
#ifndef BOARD_COOLDOWN
|
||||
#define BOARD_COOLDOWN 10
|
||||
#endif
|
||||
|
||||
static uint8_t FAN1_COOLDOWN[BOARD_COOLDOWN] = { 0 };
|
||||
|
||||
// Fan curve with temperature in degrees C, duty cycle in percent
|
||||
static struct FanPoint __code FAN1_POINTS[] = {
|
||||
#ifdef BOARD_FAN_POINTS
|
||||
BOARD_FAN_POINTS
|
||||
#else
|
||||
FAN_POINT(70, 40),
|
||||
FAN_POINT(75, 50),
|
||||
FAN_POINT(80, 60),
|
||||
FAN_POINT(85, 65),
|
||||
FAN_POINT(90, 65)
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct Fan __code FAN1 = {
|
||||
.points = FAN1_POINTS,
|
||||
.points_size = ARRAY_SIZE(FAN1_POINTS),
|
||||
.heatup = FAN1_HEATUP,
|
||||
.heatup_size = ARRAY_SIZE(FAN1_HEATUP),
|
||||
.cooldown = FAN1_COOLDOWN,
|
||||
.cooldown_size = ARRAY_SIZE(FAN1_COOLDOWN),
|
||||
.interpolate = SMOOTH_FANS != 0,
|
||||
};
|
||||
|
||||
#if CONFIG_HAVE_DGPU
|
||||
|
||||
// Fan speed is the lowest requested over HEATUP seconds
|
||||
#ifndef BOARD_DGPU_HEATUP
|
||||
#define BOARD_DGPU_HEATUP 4
|
||||
#endif
|
||||
|
||||
static uint8_t FAN2_HEATUP[BOARD_DGPU_HEATUP] = { 0 };
|
||||
|
||||
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
|
||||
#ifndef BOARD_DGPU_COOLDOWN
|
||||
#define BOARD_DGPU_COOLDOWN 10
|
||||
#endif
|
||||
|
||||
static uint8_t FAN2_COOLDOWN[BOARD_DGPU_COOLDOWN] = { 0 };
|
||||
|
||||
// Fan curve with temperature in degrees C, duty cycle in percent
|
||||
static struct FanPoint __code FAN2_POINTS[] = {
|
||||
#ifdef BOARD_DGPU_FAN_POINTS
|
||||
BOARD_DGPU_FAN_POINTS
|
||||
#else
|
||||
FAN_POINT(70, 40),
|
||||
FAN_POINT(75, 50),
|
||||
FAN_POINT(80, 60),
|
||||
FAN_POINT(85, 65),
|
||||
FAN_POINT(90, 65)
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct Fan __code FAN2 = {
|
||||
.points = FAN2_POINTS,
|
||||
.points_size = ARRAY_SIZE(FAN2_POINTS),
|
||||
.heatup = FAN2_HEATUP,
|
||||
.heatup_size = ARRAY_SIZE(FAN2_HEATUP),
|
||||
.cooldown = FAN2_COOLDOWN,
|
||||
.cooldown_size = ARRAY_SIZE(FAN2_COOLDOWN),
|
||||
.interpolate = SMOOTH_FANS != 0,
|
||||
};
|
||||
|
||||
#endif // CONFIG_HAVE_DGPU
|
||||
|
||||
void fan_reset(void) {
|
||||
// Do not manually set fans to maximum speed
|
||||
@ -25,7 +110,7 @@ void fan_reset(void) {
|
||||
|
||||
// Get duty cycle based on temperature, adapted from
|
||||
// https://github.com/pop-os/system76-power/blob/master/src/fan.rs
|
||||
uint8_t fan_duty(const struct Fan *const fan, int16_t temp) __reentrant {
|
||||
static uint8_t fan_duty(const struct Fan *const fan, int16_t temp) __reentrant {
|
||||
for (uint8_t i = 0; i < fan->points_size; i++) {
|
||||
const struct FanPoint *cur = &fan->points[i];
|
||||
|
||||
@ -60,66 +145,7 @@ uint8_t fan_duty(const struct Fan *const fan, int16_t temp) __reentrant {
|
||||
return MAX_FAN_SPEED;
|
||||
}
|
||||
|
||||
void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant {
|
||||
#if SYNC_FANS != 0
|
||||
peci_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
|
||||
dgpu_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
|
||||
#endif
|
||||
|
||||
// set PECI fan duty
|
||||
if (peci_fan_duty != DCR2) {
|
||||
TRACE("PECI fan_duty_raw=%d\n", peci_fan_duty);
|
||||
last_duty_peci = peci_fan_duty = fan_smooth(last_duty_peci, peci_fan_duty);
|
||||
DCR2 = fan_max ? MAX_FAN_SPEED : peci_fan_duty;
|
||||
#if HAVE_CPU_FAN2
|
||||
// FIXME: Handle better
|
||||
DCR3 = fan_max ? MAX_FAN_SPEED : peci_fan_duty;
|
||||
#endif
|
||||
TRACE("PECI fan_duty_smoothed=%d\n", peci_fan_duty);
|
||||
}
|
||||
|
||||
// set dGPU fan duty
|
||||
if (dgpu_fan_duty != DCR4) {
|
||||
TRACE("DGPU fan_duty_raw=%d\n", dgpu_fan_duty);
|
||||
last_duty_dgpu = dgpu_fan_duty = fan_smooth(last_duty_dgpu, dgpu_fan_duty);
|
||||
DCR4 = fan_max ? MAX_FAN_SPEED : dgpu_fan_duty;
|
||||
TRACE("DGPU fan_duty_smoothed=%d\n", dgpu_fan_duty);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t fan_heatup(const struct Fan *const fan, uint8_t duty) __reentrant {
|
||||
uint8_t lowest = duty;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; (i + 1) < fan->heatup_size; i++) {
|
||||
uint8_t value = fan->heatup[i + 1];
|
||||
if (value < lowest) {
|
||||
lowest = value;
|
||||
}
|
||||
fan->heatup[i] = value;
|
||||
}
|
||||
fan->heatup[i] = duty;
|
||||
|
||||
return lowest;
|
||||
}
|
||||
|
||||
uint8_t fan_cooldown(const struct Fan *const fan, uint8_t duty) __reentrant {
|
||||
uint8_t highest = duty;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; (i + 1) < fan->cooldown_size; i++) {
|
||||
uint8_t value = fan->cooldown[i + 1];
|
||||
if (value > highest) {
|
||||
highest = value;
|
||||
}
|
||||
fan->cooldown[i] = value;
|
||||
}
|
||||
fan->cooldown[i] = duty;
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
||||
uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant {
|
||||
static uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant {
|
||||
uint8_t next_duty = duty;
|
||||
|
||||
// ramping down
|
||||
@ -150,3 +176,110 @@ uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant {
|
||||
|
||||
return next_duty;
|
||||
}
|
||||
|
||||
static uint8_t fan_heatup(const struct Fan *const fan, uint8_t duty) __reentrant {
|
||||
uint8_t lowest = duty;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; (i + 1) < fan->heatup_size; i++) {
|
||||
uint8_t value = fan->heatup[i + 1];
|
||||
if (value < lowest) {
|
||||
lowest = value;
|
||||
}
|
||||
fan->heatup[i] = value;
|
||||
}
|
||||
fan->heatup[i] = duty;
|
||||
|
||||
return lowest;
|
||||
}
|
||||
|
||||
static uint8_t fan_cooldown(const struct Fan *const fan, uint8_t duty) __reentrant {
|
||||
uint8_t highest = duty;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; (i + 1) < fan->cooldown_size; i++) {
|
||||
uint8_t value = fan->cooldown[i + 1];
|
||||
if (value > highest) {
|
||||
highest = value;
|
||||
}
|
||||
fan->cooldown[i] = value;
|
||||
}
|
||||
fan->cooldown[i] = duty;
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
||||
static uint8_t peci_get_fan_duty(void) {
|
||||
uint8_t duty;
|
||||
|
||||
if (power_state == POWER_STATE_S0) {
|
||||
duty = fan_duty(&FAN1, peci_temp);
|
||||
if (fan_max) {
|
||||
duty = PWM_DUTY(100);
|
||||
} else {
|
||||
duty = fan_heatup(&FAN1, duty);
|
||||
duty = fan_cooldown(&FAN1, duty);
|
||||
}
|
||||
} else {
|
||||
duty = PWM_DUTY(0);
|
||||
}
|
||||
|
||||
return duty;
|
||||
}
|
||||
|
||||
#if CONFIG_HAVE_DGPU
|
||||
static uint8_t dgpu_get_fan_duty(void) {
|
||||
uint8_t duty;
|
||||
|
||||
if (power_state == POWER_STATE_S0) {
|
||||
duty = fan_duty(&FAN2, dgpu_temp);
|
||||
if (fan_max) {
|
||||
duty = PWM_DUTY(100);
|
||||
} else {
|
||||
duty = fan_heatup(&FAN2, duty);
|
||||
duty = fan_cooldown(&FAN2, duty);
|
||||
}
|
||||
} else {
|
||||
duty = PWM_DUTY(0);
|
||||
}
|
||||
|
||||
return duty;
|
||||
}
|
||||
#else
|
||||
static uint8_t dgpu_get_fan_duty(void) {
|
||||
return PWM_DUTY(0);
|
||||
}
|
||||
#endif // CONFIG_HAVE_DGPU
|
||||
|
||||
static void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant {
|
||||
#if SYNC_FANS != 0
|
||||
peci_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
|
||||
dgpu_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
|
||||
#endif
|
||||
|
||||
// set PECI fan duty
|
||||
if (peci_fan_duty != DCR2) {
|
||||
TRACE("PECI fan_duty_raw=%d\n", peci_fan_duty);
|
||||
last_duty_peci = peci_fan_duty = fan_smooth(last_duty_peci, peci_fan_duty);
|
||||
DCR2 = fan_max ? MAX_FAN_SPEED : peci_fan_duty;
|
||||
#if HAVE_CPU_FAN2
|
||||
// FIXME: Handle better
|
||||
DCR3 = fan_max ? MAX_FAN_SPEED : peci_fan_duty;
|
||||
#endif
|
||||
TRACE("PECI fan_duty_smoothed=%d\n", peci_fan_duty);
|
||||
}
|
||||
|
||||
// set dGPU fan duty
|
||||
if (dgpu_fan_duty != DCR4) {
|
||||
TRACE("DGPU fan_duty_raw=%d\n", dgpu_fan_duty);
|
||||
last_duty_dgpu = dgpu_fan_duty = fan_smooth(last_duty_dgpu, dgpu_fan_duty);
|
||||
DCR4 = fan_max ? MAX_FAN_SPEED : dgpu_fan_duty;
|
||||
TRACE("DGPU fan_duty_smoothed=%d\n", dgpu_fan_duty);
|
||||
}
|
||||
}
|
||||
|
||||
void fan_update_duty(void) {
|
||||
uint8_t fan1_duty = peci_get_fan_duty();
|
||||
uint8_t fan2_duty = dgpu_get_fan_duty();
|
||||
fan_duty_set(fan1_duty, fan2_duty);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ extern int16_t dgpu_temp;
|
||||
|
||||
void dgpu_init(void);
|
||||
bool dgpu_get_temp(int16_t *const data);
|
||||
uint8_t dgpu_get_fan_duty(void);
|
||||
void dgpu_read_temp(void);
|
||||
|
||||
#else
|
||||
|
||||
@ -23,9 +23,7 @@ static inline bool dgpu_get_temp(int16_t *const data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline uint8_t dgpu_get_fan_duty(void) {
|
||||
return 0;
|
||||
}
|
||||
static inline void dgpu_read_temp(void) {}
|
||||
|
||||
#endif // CONFIG_HAVE_DGPU
|
||||
|
||||
|
@ -49,11 +49,6 @@ struct Fan {
|
||||
extern bool fan_max;
|
||||
|
||||
void fan_reset(void);
|
||||
|
||||
uint8_t fan_duty(const struct Fan *const fan, int16_t temp) __reentrant;
|
||||
void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant;
|
||||
uint8_t fan_heatup(const struct Fan *const fan, uint8_t duty) __reentrant;
|
||||
uint8_t fan_cooldown(const struct Fan *const fan, uint8_t duty) __reentrant;
|
||||
uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant;
|
||||
void fan_update_duty(void);
|
||||
|
||||
#endif // _BOARD_FAN_H
|
||||
|
@ -13,6 +13,6 @@ extern int16_t peci_temp;
|
||||
void peci_init(void);
|
||||
bool peci_available(void);
|
||||
int16_t peci_wr_pkg_config(uint8_t index, uint16_t param, uint32_t data);
|
||||
uint8_t peci_get_fan_duty(void);
|
||||
void peci_read_temp(void);
|
||||
|
||||
#endif // _BOARD_PECI_H
|
||||
|
@ -133,8 +133,12 @@ void main(void) {
|
||||
if ((time - last_time_fan) >= fan_interval) {
|
||||
last_time_fan = time;
|
||||
|
||||
// Read thermal data
|
||||
peci_read_temp();
|
||||
dgpu_read_temp();
|
||||
|
||||
// Update fan speeds
|
||||
fan_duty_set(peci_get_fan_duty(), dgpu_get_fan_duty());
|
||||
fan_update_duty();
|
||||
|
||||
// NOTE: These values are reported to ACPI. Update them at the
|
||||
// same interval as the fan duties.
|
||||
|
@ -1,5 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// PECI information can be found here:
|
||||
// https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf
|
||||
|
||||
#include <arch/time.h>
|
||||
#include <board/espi.h>
|
||||
#include <board/fan.h>
|
||||
@ -11,56 +14,15 @@
|
||||
#include <ec/gpio.h>
|
||||
#include <ec/pwm.h>
|
||||
|
||||
// Fan speed is the lowest requested over HEATUP seconds
|
||||
#ifndef BOARD_HEATUP
|
||||
#define BOARD_HEATUP 4
|
||||
#endif
|
||||
|
||||
static uint8_t FAN_HEATUP[BOARD_HEATUP] = { 0 };
|
||||
|
||||
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
|
||||
#ifndef BOARD_COOLDOWN
|
||||
#define BOARD_COOLDOWN 10
|
||||
#endif
|
||||
|
||||
static uint8_t FAN_COOLDOWN[BOARD_COOLDOWN] = { 0 };
|
||||
|
||||
bool peci_on = false;
|
||||
int16_t peci_temp = 0;
|
||||
|
||||
#define PECI_TEMP(X) ((int16_t)(X))
|
||||
|
||||
// Tjunction = 100C for i7-8565U (and probably the same for all WHL-U)
|
||||
#define T_JUNCTION PECI_TEMP(100)
|
||||
#define T_JUNCTION ((int16_t)100)
|
||||
|
||||
// Maximum OOB channel response time in ms
|
||||
#define PECI_ESPI_TIMEOUT 10
|
||||
|
||||
#define FAN_POINT(T, D) { .temp = PECI_TEMP(T), .duty = PWM_DUTY(D) }
|
||||
|
||||
// Fan curve with temperature in degrees C, duty cycle in percent
|
||||
static struct FanPoint __code FAN_POINTS[] = {
|
||||
#ifdef BOARD_FAN_POINTS
|
||||
BOARD_FAN_POINTS
|
||||
#else
|
||||
FAN_POINT(70, 40),
|
||||
FAN_POINT(75, 50),
|
||||
FAN_POINT(80, 60),
|
||||
FAN_POINT(85, 65),
|
||||
FAN_POINT(90, 65)
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct Fan __code FAN = {
|
||||
.points = FAN_POINTS,
|
||||
.points_size = ARRAY_SIZE(FAN_POINTS),
|
||||
.heatup = FAN_HEATUP,
|
||||
.heatup_size = ARRAY_SIZE(FAN_HEATUP),
|
||||
.cooldown = FAN_COOLDOWN,
|
||||
.cooldown_size = ARRAY_SIZE(FAN_COOLDOWN),
|
||||
.interpolate = SMOOTH_FANS != 0,
|
||||
};
|
||||
|
||||
// Returns true if peci is available
|
||||
bool peci_available(void) {
|
||||
// Ensure power state is up to date
|
||||
@ -419,36 +381,13 @@ int16_t peci_wr_pkg_config(uint8_t index, uint16_t param, uint32_t data) {
|
||||
|
||||
#endif // CONFIG_PECI_OVER_ESPI
|
||||
|
||||
// PECI information can be found here:
|
||||
// https://www.intel.com/content/dam/www/public/us/en/documents/design-guides/core-i7-lga-2011-guide.pdf
|
||||
uint8_t peci_get_fan_duty(void) {
|
||||
uint8_t duty;
|
||||
|
||||
void peci_read_temp(void) {
|
||||
peci_on = peci_available();
|
||||
if (peci_on) {
|
||||
if (peci_get_temp(&peci_temp)) {
|
||||
// Use result if finished successfully
|
||||
duty = fan_duty(&FAN, peci_temp);
|
||||
} else {
|
||||
// Default to 50% if there is an error
|
||||
peci_temp = 0;
|
||||
duty = PWM_DUTY(50);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Turn fan off if not in S0 state
|
||||
peci_temp = 0;
|
||||
duty = PWM_DUTY(0);
|
||||
}
|
||||
|
||||
if (peci_on && fan_max) {
|
||||
// Override duty if fans are manually set to maximum
|
||||
duty = PWM_DUTY(100);
|
||||
} else {
|
||||
// Apply heatup and cooldown filters to duty
|
||||
duty = fan_heatup(&FAN, duty);
|
||||
duty = fan_cooldown(&FAN, duty);
|
||||
}
|
||||
|
||||
TRACE("PECI temp=%d\n", peci_temp);
|
||||
return duty;
|
||||
peci_temp = 0;
|
||||
}
|
||||
|
@ -35,11 +35,14 @@ void pwm_init(void) {
|
||||
// Set cycle time to 255 + 1
|
||||
CTR0 = 255;
|
||||
|
||||
// Turn off CPU fan (temperature control in peci_get_fan_duty)
|
||||
// Turn off fans
|
||||
DCR2 = 0;
|
||||
#if HAVE_CPU_FAN2
|
||||
DCR3 = 0;
|
||||
#endif
|
||||
#if CONFIG_HAVE_DGPU
|
||||
DCR4 = 0;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EC_ITE_IT5570E || CONFIG_EC_ITE_IT5571E
|
||||
// Reload counters when they reach 0 instead of immediately
|
||||
|
Reference in New Issue
Block a user