From b82f2922c7fce3ca6b2797a8d9775e9db2817fe9 Mon Sep 17 00:00:00 2001 From: Ryan Lin Date: Mon, 22 Sep 2014 23:29:16 -0700 Subject: [PATCH] superio: ite8772f: Exit extemp busy state It causes fan top speed due to this bug + our board-specific workaround, and causes invalid temperature sensor readings. Therefore, re-configure the register "External Temperature Sensor Host Control Register" to terminate processes when this issue happens. BUG=chromium:402204 TEST=ran suspend_stress_test 500 times Change-Id: I6e71b6a46a31b00e541c304f1ed58c1678c1d42e Signed-off-by: Ryan Lin Reviewed-on: https://chromium-review.googlesource.com/219445 Reviewed-by: Shawn Nematbakhsh --- src/superio/ite/it8772f/it8772f.h | 1 + src/superio/ite/it8772f/superio.c | 36 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/superio/ite/it8772f/it8772f.h b/src/superio/ite/it8772f/it8772f.h index f881d7a92a..fd676d536a 100644 --- a/src/superio/ite/it8772f/it8772f.h +++ b/src/superio/ite/it8772f/it8772f.h @@ -72,6 +72,7 @@ #define IT8772F_FAN_CTL_AUTO_SMOOTHING_DIS (0 << 7) #define IT8772F_FAN_CTL_AUTO_SMOOTHING_EN (1 << 7) #define IT8772F_EXTEMP_STATUS 0x88 +#define IT8772F_EXTEMP_STATUS_HOST_BUSY (1 << 0) #define IT8772F_EXTEMP_ADDRESS 0x89 #define IT8772F_EXTEMP_WRITE_LENGTH 0x8a #define IT8772F_EXTEMP_READ_LENGTH 0x8b diff --git a/src/superio/ite/it8772f/superio.c b/src/superio/ite/it8772f/superio.c index b18d4ab422..10729339ce 100644 --- a/src/superio/ite/it8772f/superio.c +++ b/src/superio/ite/it8772f/superio.c @@ -26,6 +26,7 @@ #include #include "chip.h" #include "it8772f.h" +#include "delay.h" static void pnp_enter_ext_func_mode(device_t dev) { @@ -54,6 +55,34 @@ static inline void it8772f_envc_write(struct resource *res, u8 addr, u8 value) outb(value, res->base + 6); } +static void it8772f_extemp_force_idle_status(struct resource *res) +{ + u8 reg; + int retries = 10; + + /* Wait up to 10ms for non-busy state. */ + while (retries > 0) { + reg = it8772f_envc_read(res, IT8772F_EXTEMP_STATUS); + + if ((reg & IT8772F_EXTEMP_STATUS_HOST_BUSY) == 0x0) + break; + + retries--; + + mdelay(1); + } + + if (retries == 0 && (reg & IT8772F_EXTEMP_STATUS_HOST_BUSY) == 0x1) { + /* + * SIO is busy due to unfinished peci transaction. + * Re-configure Register 0x8E to terminate processes. + */ + it8772f_envc_write(res, IT8772F_EXTEMP_CONTROL, + IT8772F_EXTEMP_CONTROL_AUTO_4HZ | + IT8772F_EXTEMP_CONTROL_AUTO_START); + } +} + /* * Setup External Temperature to read via PECI into TMPINx register */ @@ -156,6 +185,13 @@ static void it8772f_init(device_t dev) it8772f_enable_fan(res, 2); if (conf->fan3_enable) it8772f_enable_fan(res, 3); + + /* + * System may get wrong temperature data when SIO is in + * busy state. Therefore, check the status and terminate + * processes if needed. + */ + it8772f_extemp_force_idle_status(res); break; case IT8772F_GPIO: /* Set GPIO output levels */