From 84e2dbbde485fb1babe55192df5ea9c77f12eab0 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 30 Jul 2024 14:44:18 -0600 Subject: [PATCH] Move fan-specific PWM logic to fan module Better define the scope of the tachometer variables by moving them to the fan module. `fan_update_duty` is renamed to `fan_event` to reflect that it handles more than just updating the PWM duties. Signed-off-by: Tim Crawford --- src/board/system76/common/acpi.c | 5 ++- src/board/system76/common/fan.c | 41 ++++++++++++++++--- src/board/system76/common/include/board/fan.h | 7 +++- src/board/system76/common/include/board/pwm.h | 9 ---- src/board/system76/common/main.c | 8 +--- src/board/system76/common/pwm.c | 31 +------------- 6 files changed, 46 insertions(+), 55 deletions(-) diff --git a/src/board/system76/common/acpi.c b/src/board/system76/common/acpi.c index 8deb7afca..c33f1c33e 100644 --- a/src/board/system76/common/acpi.c +++ b/src/board/system76/common/acpi.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -162,13 +163,13 @@ uint8_t acpi_read(uint8_t addr) { ACPI_8(0xCC, sci_extra); ACPI_8(0xCE, FAN1_PWM); - ACPI_16(0xD0, pwm_tach0_rpm); + ACPI_16(0xD0, fan1_rpm); #if CONFIG_HAVE_DGPU ACPI_8(0xCD, dgpu_temp); #endif // CONFIG_HAVE_DGPU #ifdef FAN2_PWM ACPI_8(0xCF, FAN2_PWM); - ACPI_16(0xD2, pwm_tach1_rpm); + ACPI_16(0xD2, fan2_rpm); #endif // FAN2_PWM #if HAVE_LED_AIRPLANE_N diff --git a/src/board/system76/common/fan.c b/src/board/system76/common/fan.c index 7d9569dc0..023320666 100644 --- a/src/board/system76/common/fan.c +++ b/src/board/system76/common/fan.c @@ -13,6 +13,18 @@ bool fan_max = false; static uint8_t last_fan1_duty = 0; static uint8_t last_fan2_duty = 0; +uint16_t fan1_rpm = 0; +uint16_t fan2_rpm = 0; + +#define TACH_FREQ (CONFIG_CLOCK_FREQ_KHZ * 1000UL) + +// Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnRLRR} * P) +// - n: 1 or 2 +// - P: the numbers of square pulses per revolution +// - fs: sample rate (FreqEC / 128) +// - {FnTMRR, FnTLRR} = 0000h: Fan Speed is zero +#define TACH_TO_RPM(x) (60UL * TACH_FREQ / 128UL / 2UL / (x)) + #define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) } #if SMOOTH_FANS != 0 @@ -219,33 +231,50 @@ static uint8_t fan_get_duty(const struct Fan *const fan, int16_t temp) { return duty; } -void fan_update_duty(void) { +static uint16_t fan_get_tach0_rpm(void) { + uint16_t rpm = (F1TMRR << 8) | F1TLRR; + + if (rpm) + rpm = TACH_TO_RPM(rpm); + + return rpm; +} + +static uint16_t fan_get_tach1_rpm(void) { + uint16_t rpm = (F2TMRR << 8) | F2TLRR; + + if (rpm) + rpm = TACH_TO_RPM(rpm); + + return rpm; +} + +void fan_event(void) { #if CONFIG_HAVE_DGPU int16_t sys_temp = MAX(peci_temp, dgpu_temp); #else int16_t sys_temp = peci_temp; #endif - uint8_t fan1_duty = fan_get_duty(&FAN1, sys_temp); -#ifdef FAN2_PWM - uint8_t fan2_duty = fan_get_duty(&FAN2, sys_temp); -#endif // FAN2_PWM - // set FAN1 duty + uint8_t fan1_duty = fan_get_duty(&FAN1, sys_temp); if (fan1_duty != FAN1_PWM) { TRACE("FAN1 fan_duty_raw=%d\n", fan1_duty); last_fan1_duty = fan1_duty = fan_smooth(last_fan1_duty, fan1_duty); FAN1_PWM = fan_max ? MAX_FAN_SPEED : fan1_duty; TRACE("FAN1 fan_duty_smoothed=%d\n", fan1_duty); } + fan1_rpm = fan_get_tach0_rpm(); #ifdef FAN2_PWM // set FAN2 duty + uint8_t fan2_duty = fan_get_duty(&FAN2, sys_temp); if (fan2_duty != FAN2_PWM) { TRACE("FAN2 fan_duty_raw=%d\n", fan2_duty); last_fan2_duty = fan2_duty = fan_smooth(last_fan2_duty, fan2_duty); FAN2_PWM = fan_max ? MAX_FAN_SPEED : fan2_duty; TRACE("FAN2 fan_duty_smoothed=%d\n", fan2_duty); } + fan2_rpm = fan_get_tach1_rpm(); #endif } diff --git a/src/board/system76/common/include/board/fan.h b/src/board/system76/common/include/board/fan.h index 53360f660..ae12ef741 100644 --- a/src/board/system76/common/include/board/fan.h +++ b/src/board/system76/common/include/board/fan.h @@ -44,7 +44,12 @@ struct Fan { extern bool fan_max; +// NOTE: These are used instead of the functions directly for ACPI to prevent +// double reads of the tachometer values. +extern uint16_t fan1_rpm; +extern uint16_t fan2_rpm; + void fan_reset(void); -void fan_update_duty(void); +void fan_event(void); #endif // _BOARD_FAN_H diff --git a/src/board/system76/common/include/board/pwm.h b/src/board/system76/common/include/board/pwm.h index 7c6a499a5..1be5b816a 100644 --- a/src/board/system76/common/include/board/pwm.h +++ b/src/board/system76/common/include/board/pwm.h @@ -3,15 +3,6 @@ #ifndef _BOARD_PWM_H #define _BOARD_PWM_H -#include - -// NOTE: These are used instead of the functions directly for ACPI to prevent -// double reads of the tachometer values. -extern int16_t pwm_tach0_rpm; -extern int16_t pwm_tach1_rpm; - void pwm_init(void); -int16_t pwm_get_tach0_rpm(void); -int16_t pwm_get_tach1_rpm(void); #endif // _BOARD_PWM_H diff --git a/src/board/system76/common/main.c b/src/board/system76/common/main.c index c5b0194ca..2eade4af8 100644 --- a/src/board/system76/common/main.c +++ b/src/board/system76/common/main.c @@ -137,13 +137,7 @@ void main(void) { peci_read_temp(); dgpu_read_temp(); - // Update fan speeds - fan_update_duty(); - - // NOTE: These values are reported to ACPI. Update them at the - // same interval as the fan duties. - pwm_tach0_rpm = pwm_get_tach0_rpm(); - pwm_tach1_rpm = pwm_get_tach1_rpm(); + fan_event(); } // Only run the following once per interval diff --git a/src/board/system76/common/pwm.c b/src/board/system76/common/pwm.c index e972aaafd..684f28f04 100644 --- a/src/board/system76/common/pwm.c +++ b/src/board/system76/common/pwm.c @@ -1,20 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only #include +#include #include -#define TACH_FREQ (CONFIG_CLOCK_FREQ_KHZ * 1000UL) - -// Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnRLRR} * P) -// - n: 1 or 2 -// - P: the numbers of square pulses per revolution -// - fs: sample rate (FreqEC / 128) -// - {FnTMRR, FnTLRR} = 0000h: Fan Speed is zero -#define TACH_TO_RPM(x) (60UL * TACH_FREQ / 128UL / 2UL / (x)) - -int16_t pwm_tach0_rpm = -1; -int16_t pwm_tach1_rpm = -1; - void pwm_init(void) { // Set T0CHSEL to TACH0A and T1CHSEL to TACH1A TSWCTLR = 0; @@ -49,21 +38,3 @@ void pwm_init(void) { // Enable PWM ZTIER = BIT(1); } - -int16_t pwm_get_tach0_rpm(void) { - uint16_t rpm = (F1TMRR << 8) | F1TLRR; - - if (rpm) - rpm = TACH_TO_RPM(rpm); - - return rpm; -} - -int16_t pwm_get_tach1_rpm(void) { - uint16_t rpm = (F2TMRR << 8) | F2TLRR; - - if (rpm) - rpm = TACH_TO_RPM(rpm); - - return rpm; -}