From 8af84e0e76f68e463af9f0087c6f36fe813e54ed Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 2 May 2024 12:54:09 -0600 Subject: [PATCH] acpi: Report RPM values instead of raw tachometer values Ref: IT5570E V0.3.2 datasheet; 7.12.3.2 Manual Fan Control Mode Signed-off-by: Tim Crawford --- src/board/system76/common/acpi.c | 10 +++---- src/board/system76/common/include/board/pwm.h | 7 +++++ src/board/system76/common/main.c | 5 ++++ src/board/system76/common/pwm.c | 30 +++++++++++++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/board/system76/common/acpi.c b/src/board/system76/common/acpi.c index 7486d75b7..1df98aa9e 100644 --- a/src/board/system76/common/acpi.c +++ b/src/board/system76/common/acpi.c @@ -7,9 +7,9 @@ #include #include #include -#include +#include #include -#include +#include #ifndef HAVE_LED_AIRPLANE_N #define HAVE_LED_AIRPLANE_N 1 @@ -162,13 +162,11 @@ uint8_t acpi_read(uint8_t addr) { ACPI_8(0xCC, sci_extra); ACPI_8(0xCE, DCR2); - ACPI_8(0xD0, F1TLRR); - ACPI_8(0xD1, F1TMRR); + ACPI_16(0xD0, pwm_tach0_rpm); #if CONFIG_HAVE_DGPU ACPI_8(0xCD, dgpu_temp); ACPI_8(0xCF, DCR4); - ACPI_8(0xD2, F2TLRR); - ACPI_8(0xD3, F2TMRR); + ACPI_16(0xD2, pwm_tach1_rpm); #endif // CONFIG_HAVE_DGPU #if HAVE_LED_AIRPLANE_N diff --git a/src/board/system76/common/include/board/pwm.h b/src/board/system76/common/include/board/pwm.h index 64553106d..7c6a499a5 100644 --- a/src/board/system76/common/include/board/pwm.h +++ b/src/board/system76/common/include/board/pwm.h @@ -5,6 +5,13 @@ #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 f1d0e9a84..b8f5f1001 100644 --- a/src/board/system76/common/main.c +++ b/src/board/system76/common/main.c @@ -135,6 +135,11 @@ void main(void) { // Update fan speeds fan_duty_set(peci_get_fan_duty(), dgpu_get_fan_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(); } // Only run the following once per interval diff --git a/src/board/system76/common/pwm.c b/src/board/system76/common/pwm.c index 6ad6d1b3e..330cad9e4 100644 --- a/src/board/system76/common/pwm.c +++ b/src/board/system76/common/pwm.c @@ -3,6 +3,18 @@ #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; @@ -37,3 +49,21 @@ 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; +}