Skip to content

Commit

Permalink
Move fan-specific PWM logic to fan module
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
crawfxrd committed Aug 6, 2024
1 parent 6f836fd commit 84e2dbb
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 55 deletions.
5 changes: 3 additions & 2 deletions src/board/system76/common/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <board/acpi.h>
#include <board/battery.h>
#include <board/dgpu.h>
#include <board/fan.h>
#include <board/gpio.h>
#include <board/kbled.h>
#include <board/lid.h>
Expand Down Expand Up @@ -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
Expand Down
41 changes: 35 additions & 6 deletions src/board/system76/common/fan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
7 changes: 6 additions & 1 deletion src/board/system76/common/include/board/fan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 0 additions & 9 deletions src/board/system76/common/include/board/pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
#ifndef _BOARD_PWM_H
#define _BOARD_PWM_H

#include <ec/pwm.h>

// 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
8 changes: 1 addition & 7 deletions src/board/system76/common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 1 addition & 30 deletions src/board/system76/common/pwm.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only

#include <board/pwm.h>
#include <ec/pwm.h>
#include <common/macro.h>

#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;
Expand Down Expand Up @@ -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;
}

0 comments on commit 84e2dbb

Please sign in to comment.