summaryrefslogtreecommitdiff
path: root/chip/it83xx/fan.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /chip/it83xx/fan.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14411.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'chip/it83xx/fan.c')
-rw-r--r--chip/it83xx/fan.c478
1 files changed, 0 insertions, 478 deletions
diff --git a/chip/it83xx/fan.c b/chip/it83xx/fan.c
deleted file mode 100644
index adb3985025..0000000000
--- a/chip/it83xx/fan.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/* Copyright 2015 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Fan control module. */
-
-#include "clock.h"
-#include "fan.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "hwtimer_chip.h"
-#include "math_util.h"
-#include "pwm.h"
-#include "pwm_chip.h"
-#include "registers.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-
-#define TACH_EC_FREQ 8000000
-#define FAN_CTRL_BASED_MS 10
-#define FAN_CTRL_INTERVAL_MAX_MS 60
-
-/* The sampling rate (fs) is FreqEC / 128 */
-#define TACH_DATA_VALID_TIMEOUT_MS (0xFFFF * 128 / (TACH_EC_FREQ / 1000))
-
-/*
- * Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnTLRR} * P)
- * n denotes 1 or 2.
- * P denotes the numbers of square pulses per revolution.
- * And {FnTMRR, FnTLRR} = 0000h denotes Fan Speed is zero.
- * The sampling rate (fs) is FreqEC / 128.
- */
-/* pulse, the numbers of square pulses per revolution. */
-#define TACH0_TO_RPM(pulse, raw) (60 * TACH_EC_FREQ / 128 / pulse / raw)
-#define TACH1_TO_RPM(pulse, raw) (raw * 120 / (pulse * 2))
-
-enum fan_output_s {
- FAN_DUTY_I = 0x01,
- FAN_DUTY_R = 0x02,
- FAN_DUTY_OV = 0x03,
- FAN_DUTY_DONE = 0x04,
-};
-
-struct fan_info {
- unsigned int flags;
- int fan_mode;
- int fan_p;
- int rpm_target;
- int rpm_actual;
- int tach_valid_ms;
- int rpm_re;
- int fan_ms;
- int fan_ms_idx;
- int startup_duty;
- enum fan_status fan_sts;
- int enabled;
-};
-static struct fan_info fan_info_data[TACH_CH_COUNT];
-
-static enum tach_ch_sel tach_bind(int ch)
-{
- return fan_tach[pwm_channels[ch].channel].ch_tach;
-}
-
-static void fan_set_interval(int ch)
-{
- int diff, fan_ms;
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- diff = ABS(fan_info_data[tach_ch].rpm_target -
- fan_info_data[tach_ch].rpm_actual) / 100;
-
- fan_ms = FAN_CTRL_INTERVAL_MAX_MS;
-
- fan_ms -= diff;
- if (fan_ms < FAN_CTRL_BASED_MS)
- fan_ms = FAN_CTRL_BASED_MS;
-
- fan_info_data[tach_ch].fan_ms = fan_ms;
-}
-
-static void fan_init_start(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- fan_set_duty(ch, fan_info_data[tach_ch].startup_duty);
-}
-
-static int fan_all_disabled(void)
-{
- int fan, all_disabled = 0;
-
- for (fan = 0; fan < fan_get_count(); fan++) {
- if (!fan_get_enabled(FAN_CH(fan)))
- all_disabled++;
- }
-
- if (all_disabled >= fan_get_count())
- return 1;
-
- return 0;
-}
-
-void fan_set_enabled(int ch, int enabled)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- /* enable */
- if (enabled) {
- if (tach_ch < TACH_CH_COUNT)
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_CHANGING;
-
- disable_sleep(SLEEP_MASK_FAN);
- /* enable timer interrupt for fan control */
- ext_timer_start(FAN_CTRL_EXT_TIMER, 1);
- /* disable */
- } else {
- fan_set_duty(ch, 0);
-
- if (tach_ch < TACH_CH_COUNT) {
- fan_info_data[tach_ch].rpm_actual = 0;
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_STOPPED;
- }
- }
-
- /* on/off */
- if (tach_ch < TACH_CH_COUNT) {
- fan_info_data[tach_ch].enabled = enabled;
- fan_info_data[tach_ch].tach_valid_ms = 0;
- }
-
- pwm_enable(ch, enabled);
-
- if (!enabled) {
- /* disable timer interrupt if all fan off. */
- if (fan_all_disabled()) {
- ext_timer_stop(FAN_CTRL_EXT_TIMER, 1);
- enable_sleep(SLEEP_MASK_FAN);
- }
- }
-}
-
-int fan_get_enabled(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- return pwm_get_enabled(ch) && fan_info_data[tach_ch].enabled;
- else
- return 0;
-}
-
-void fan_set_duty(int ch, int percent)
-{
- pwm_set_duty(ch, percent);
-}
-
-int fan_get_duty(int ch)
-{
- return pwm_get_duty(ch);
-}
-
-int fan_get_rpm_mode(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- return fan_info_data[tach_ch].fan_mode;
- else
- return EC_ERROR_UNKNOWN;
-}
-
-void fan_set_rpm_mode(int ch, int rpm_mode)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- fan_info_data[tach_ch].fan_mode = rpm_mode;
-}
-
-int fan_get_rpm_actual(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- return fan_info_data[tach_ch].rpm_actual;
- else
- return EC_ERROR_UNKNOWN;
-}
-
-int fan_get_rpm_target(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- return fan_info_data[tach_ch].rpm_target;
- else
- return EC_ERROR_UNKNOWN;
-}
-
-test_mockable void fan_set_rpm_target(int ch, int rpm)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- fan_info_data[tach_ch].rpm_target = rpm;
-}
-
-enum fan_status fan_get_status(int ch)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- return fan_info_data[tach_ch].fan_sts;
- else
- return FAN_STATUS_STOPPED;
-}
-
-/**
- * Return non-zero if fan is enabled but stalled.
- */
-int fan_is_stalled(int ch)
-{
- /* Must be enabled with non-zero target to stall */
- if (!fan_get_enabled(ch) ||
- fan_get_rpm_target(ch) == 0 ||
- !fan_get_duty(ch))
- return 0;
-
- /* Check for stall condition */
- return fan_get_status(ch) == FAN_STATUS_STOPPED;
-}
-
-void fan_channel_setup(int ch, unsigned int flags)
-{
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- if (tach_ch < TACH_CH_COUNT)
- fan_info_data[tach_ch].flags = flags;
-}
-
-static void fan_ctrl(int ch)
-{
- int status = -1, adjust = 0;
- int rpm_actual, rpm_target, rpm_re, duty;
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- fan_info_data[tach_ch].fan_ms_idx += FAN_CTRL_BASED_MS;
- if (fan_info_data[tach_ch].fan_ms_idx >
- fan_info_data[tach_ch].fan_ms) {
- fan_info_data[tach_ch].fan_ms_idx = 0x00;
- adjust = 1;
- }
-
- if (adjust) {
- /* get current pwm output duty */
- duty = fan_get_duty(ch);
-
- /* rpm mode */
- if (fan_info_data[tach_ch].fan_mode) {
- rpm_actual = fan_info_data[tach_ch].rpm_actual;
- rpm_target = fan_info_data[tach_ch].rpm_target;
- rpm_re = fan_info_data[tach_ch].rpm_re;
-
- if (rpm_actual < (rpm_target - rpm_re)) {
- if (duty == 100) {
- status = FAN_DUTY_OV;
- } else {
- if (duty == 0)
- fan_init_start(ch);
-
- pwm_duty_inc(ch);
- status = FAN_DUTY_I;
- }
- } else if (rpm_actual > (rpm_target + rpm_re)) {
- if (duty == 0) {
- status = FAN_DUTY_OV;
- } else {
- pwm_duty_reduce(ch);
- status = FAN_DUTY_R;
- }
- } else {
- status = FAN_DUTY_DONE;
- }
- } else {
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_LOCKED;
- }
-
- if (status == FAN_DUTY_DONE) {
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_LOCKED;
- } else if ((status == FAN_DUTY_I) || (status == FAN_DUTY_R)) {
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_CHANGING;
- } else if (status == FAN_DUTY_OV) {
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_FRUSTRATED;
-
- if (!fan_info_data[tach_ch].rpm_actual && duty)
- fan_info_data[tach_ch].fan_sts =
- FAN_STATUS_STOPPED;
- }
- }
-}
-
-static int tach_ch_valid(enum tach_ch_sel tach_ch)
-{
- int valid = 0;
-
- switch (tach_ch) {
- case TACH_CH_TACH0A:
- if ((IT83XX_PWM_TSWCTRL & 0x0C) == 0x08)
- valid = 1;
- break;
- case TACH_CH_TACH1A:
- if ((IT83XX_PWM_TSWCTRL & 0x03) == 0x02)
- valid = 1;
- break;
- case TACH_CH_TACH0B:
- if ((IT83XX_PWM_TSWCTRL & 0x0C) == 0x0C)
- valid = 1;
- break;
- case TACH_CH_TACH1B:
- if ((IT83XX_PWM_TSWCTRL & 0x03) == 0x03)
- valid = 1;
- break;
- default:
- break;
- }
-
- return valid;
-}
-
-static int get_tach0_rpm(int fan_p)
-{
- uint16_t rpm;
-
- /* TACH0A / TACH0B data is valid */
- if (IT83XX_PWM_TSWCTRL & 0x08) {
- rpm = (IT83XX_PWM_F1TMRR << 8) | IT83XX_PWM_F1TLRR;
-
- if (rpm)
- rpm = TACH0_TO_RPM(fan_p, rpm);
-
- /* W/C */
- IT83XX_PWM_TSWCTRL |= 0x08;
- return rpm;
- }
- return -1;
-}
-
-static int get_tach1_rpm(int fan_p)
-{
- uint16_t rpm;
-
- /* TACH1A / TACH1B data is valid */
- if (IT83XX_PWM_TSWCTRL & 0x02) {
- rpm = (IT83XX_PWM_F2TMRR << 8) | IT83XX_PWM_F2TLRR;
-
- if (rpm)
- rpm = TACH1_TO_RPM(fan_p, rpm);
-
- /* W/C */
- IT83XX_PWM_TSWCTRL |= 0x02;
- return rpm;
- }
- return -1;
-}
-
-static void proc_tach(int ch)
-{
- int t_rpm;
- enum tach_ch_sel tach_ch;
-
- tach_ch = tach_bind(ch);
-
- /* tachometer data valid */
- if (tach_ch_valid(tach_ch)) {
- if ((tach_ch == TACH_CH_TACH0A) || (tach_ch == TACH_CH_TACH0B))
- t_rpm = get_tach0_rpm(fan_info_data[tach_ch].fan_p);
- else
- t_rpm = get_tach1_rpm(fan_info_data[tach_ch].fan_p);
-
- fan_info_data[tach_ch].rpm_actual = t_rpm;
- fan_set_interval(ch);
- fan_info_data[tach_ch].tach_valid_ms = 0;
- } else {
- fan_info_data[tach_ch].tach_valid_ms += FAN_CTRL_BASED_MS;
- if (fan_info_data[tach_ch].tach_valid_ms >
- TACH_DATA_VALID_TIMEOUT_MS)
- fan_info_data[tach_ch].rpm_actual = 0;
- }
-}
-
-void fan_ext_timer_interrupt(void)
-{
- int fan;
-
- task_clear_pending_irq(et_ctrl_regs[FAN_CTRL_EXT_TIMER].irq);
-
- for (fan = 0; fan < fan_get_count(); fan++) {
- if (fan_get_enabled(FAN_CH(fan))) {
- proc_tach(FAN_CH(fan));
- fan_ctrl(FAN_CH(fan));
- }
- }
-}
-
-static void fan_init(void)
-{
- int ch, rpm_re, fan_p, s_duty;
- enum tach_ch_sel tach_ch;
-
- for (ch = 0; ch < fan_get_count(); ch++) {
-
- rpm_re = fan_tach[pwm_channels[FAN_CH(ch)].channel].rpm_re;
- fan_p = fan_tach[pwm_channels[FAN_CH(ch)].channel].fan_p;
- s_duty = fan_tach[pwm_channels[FAN_CH(ch)].channel].s_duty;
- tach_ch = tach_bind(FAN_CH(ch));
-
- if (tach_ch < TACH_CH_COUNT) {
-
- if (tach_ch == TACH_CH_TACH0B) {
- /* GPJ2 will select TACH0B as its alt. */
- IT83XX_GPIO_GRC5 |= 0x01;
- /* bit2, to select TACH0B */
- IT83XX_PWM_TSWCTRL |= 0x04;
- } else if (tach_ch == TACH_CH_TACH1B) {
- /* GPJ3 will select TACH1B as its alt. */
- IT83XX_GPIO_GRC5 |= 0x02;
- /* bit0, to select TACH1B */
- IT83XX_PWM_TSWCTRL |= 0x01;
- }
-
- fan_info_data[tach_ch].flags = 0;
- fan_info_data[tach_ch].fan_mode = 0;
- fan_info_data[tach_ch].rpm_target = 0;
- fan_info_data[tach_ch].rpm_actual = 0;
- fan_info_data[tach_ch].tach_valid_ms = 0;
- fan_info_data[tach_ch].fan_ms_idx = 0;
- fan_info_data[tach_ch].enabled = 0;
- fan_info_data[tach_ch].fan_p = fan_p;
- fan_info_data[tach_ch].rpm_re = rpm_re;
- fan_info_data[tach_ch].fan_ms = FAN_CTRL_BASED_MS;
- fan_info_data[tach_ch].fan_sts = FAN_STATUS_STOPPED;
- fan_info_data[tach_ch].startup_duty = s_duty;
- }
- }
-
- /* init external timer for fan control */
- ext_timer_ms(FAN_CTRL_EXT_TIMER, EXT_PSR_32P768K_HZ, 0, 0,
- FAN_CTRL_BASED_MS, 1, 0);
-}
-DECLARE_HOOK(HOOK_INIT, fan_init, HOOK_PRIO_INIT_FAN);