diff options
author | Vijay Hiremath <vijay.p.hiremath@intel.com> | 2019-03-08 17:29:45 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-28 10:44:36 -0700 |
commit | 148145c4457e70b0da517b4b9f961338fc21bd46 (patch) | |
tree | 08c8a5d7d2ccee44919d3d586f961d5cf4cfe41e /chip/it83xx/peci.c | |
parent | 68763771658af368ceaa07803e8dfb5b841c9cf6 (diff) | |
download | chrome-ec-148145c4457e70b0da517b4b9f961338fc21bd46.tar.gz |
PECI: Move non-chipset specific PECI code to common folder
The Platform Environment Control Interface (PECI) is a thermal management
standard with one-wire bus interface that provides a communication channel
between Intel processor and chipset components to external monitoring or
control devices.
As we can read the CPU temperature over PECI more accurately than the
thermistors, we can eliminate usage of thermistors for reading CPU
temperature.
BUG=b:128666114
BRANCH=none
TEST=Manually tested on Dragonegg, able read CPU temperature.
Change-Id: Ie0845ca776e6a7e14511dc9315d6d83cdd5f09a6
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/1622740
Commit-Ready: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'chip/it83xx/peci.c')
-rw-r--r-- | chip/it83xx/peci.c | 246 |
1 files changed, 21 insertions, 225 deletions
diff --git a/chip/it83xx/peci.c b/chip/it83xx/peci.c index b8e0b7c451..07336eaaf6 100644 --- a/chip/it83xx/peci.c +++ b/chip/it83xx/peci.c @@ -5,46 +5,14 @@ /* PECI interface for Chrome EC */ -#include "chipset.h" #include "clock.h" -#include "common.h" -#include "console.h" -#include "gpio.h" #include "hooks.h" #include "peci.h" #include "registers.h" -#include "temp_sensor.h" #include "util.h" #include "timer.h" #include "task.h" -#define TEMP_AVG_LENGTH 4 /* Should be power of 2 */ -static int temp_vals[TEMP_AVG_LENGTH]; -static int temp_idx; - -#define PECI_TARGET_ADDRESS 0x30 -#define PECI_WRITE_DATA_FIFO_SIZE 15 -#define PECI_READ_DATA_FIFO_SIZE 16 - -#define PECI_GET_TEMP_READ_LENGTH 2 -#define PECI_GET_TEMP_WRITE_LENGTH 0 -#define PECI_GET_TEMP_TIMEOUT_US 200 - -/* PECI Command Code */ -enum peci_command_code { - PECI_CMD_PING = 0x00, - PECI_CMD_GET_DIB = 0xF7, - PECI_CMD_GET_TEMP = 0x01, - PECI_CMD_RD_PKG_CFG = 0xA1, - PECI_CMD_WR_PKG_CFG = 0xA5, - PECI_CMD_RD_IAMSR = 0xB1, - PECI_CMD_WR_IAMSR = 0xB5, - PECI_CMD_RD_PCI_CFG = 0x61, - PECI_CMD_WR_PCI_CFG = 0x65, - PECI_CMD_RD_PCI_CFG_LOCAL = 0xE1, - PECI_CMD_WR_PCI_CFG_LOCAL = 0xE5, -}; - enum peci_status { PECI_STATUS_NO_ERR = 0x00, PECI_STATUS_HOBY = 0x01, @@ -103,23 +71,11 @@ static void peci_reset(void) /** * Start a PECI transaction * - * @param addr client address - * @param w_len write length (no include [Cmd Code] and [AW FCS]) - * @param r_len read length (no include [FCS]) - * @param cmd_code command code - * @param *w_buf How buffer pointer of write data - * @param *r_buf How buffer pointer of read data - * @param timeout_us transaction timeout unit:us + * @param peci transaction data * * @return zero if successful, non-zero if error */ -static enum peci_status peci_transaction(uint8_t addr, - uint8_t w_len, - uint8_t r_len, - enum peci_command_code cmd_code, - uint8_t *w_buf, - uint8_t *r_buf, - int timeout_us) +int peci_transaction(struct peci_data *peci) { uint8_t status; int index; @@ -140,22 +96,22 @@ static enum peci_status peci_transaction(uint8_t addr, IT83XX_PECI_HOCTLR |= 0x34; /* This register is the target address field of the PECI protocol. */ - IT83XX_PECI_HOTRADDR = addr; + IT83XX_PECI_HOTRADDR = peci->addr; /* This register is the write length field of the PECI protocol. */ - ASSERT(w_len <= PECI_WRITE_DATA_FIFO_SIZE); + ASSERT(peci->w_len <= PECI_WRITE_DATA_FIFO_SIZE); - if (cmd_code == PECI_CMD_PING) { + if (peci->cmd_code == PECI_CMD_PING) { /* write length is 0 */ IT83XX_PECI_HOWRLR = 0x00; } else { - if ((cmd_code == PECI_CMD_WR_PKG_CFG) || - (cmd_code == PECI_CMD_WR_IAMSR) || - (cmd_code == PECI_CMD_WR_PCI_CFG) || - (cmd_code == PECI_CMD_WR_PCI_CFG_LOCAL)) { + if ((peci->cmd_code == PECI_CMD_WR_PKG_CFG) || + (peci->cmd_code == PECI_CMD_WR_IAMSR) || + (peci->cmd_code == PECI_CMD_WR_PCI_CFG) || + (peci->cmd_code == PECI_CMD_WR_PCI_CFG_LOCAL)) { /* write length include Cmd Code + AW FCS */ - IT83XX_PECI_HOWRLR = w_len + 2; + IT83XX_PECI_HOWRLR = peci->w_len + 2; /* bit1, The bit enables the AW_FCS hardwired mechanism * based on the PECI command. This bit is functional @@ -167,22 +123,22 @@ static enum peci_status peci_transaction(uint8_t addr, IT83XX_PECI_HOCTLR |= 0x02; } else { /* write length include Cmd Code */ - IT83XX_PECI_HOWRLR = w_len + 1; + IT83XX_PECI_HOWRLR = peci->w_len + 1; IT83XX_PECI_HOCTLR &= ~0x02; } } /* This register is the read length field of the PECI protocol. */ - ASSERT(r_len <= PECI_READ_DATA_FIFO_SIZE); - IT83XX_PECI_HORDLR = r_len; + ASSERT(peci->r_len <= PECI_READ_DATA_FIFO_SIZE); + IT83XX_PECI_HORDLR = peci->r_len; /* This register is the command field of the PECI protocol. */ - IT83XX_PECI_HOCMDR = cmd_code; + IT83XX_PECI_HOCMDR = peci->cmd_code; /* The write data field of the PECI protocol. */ - for (index = 0x00; index < w_len; index++) - IT83XX_PECI_HOWRDR = w_buf[index]; + for (index = 0x00; index < peci->w_len; index++) + IT83XX_PECI_HOWRDR = peci->w_buf[index]; peci_current_task = task_get_current(); task_clear_pending_irq(IT83XX_IRQ_PECI); @@ -192,15 +148,15 @@ static enum peci_status peci_transaction(uint8_t addr, IT83XX_PECI_HOCTLR |= 0x01; /* pre-set timeout */ - index = timeout_us; - if (task_wait_event(timeout_us) != TASK_EVENT_TIMER) + index = peci->timeout_us; + if (task_wait_event(peci->timeout_us) != TASK_EVENT_TIMER) index = 0; task_disable_irq(IT83XX_IRQ_PECI); peci_current_task = TASK_ID_INVALID; - if (index < timeout_us) { + if (index < peci->timeout_us) { status = IT83XX_PECI_HOSTAR; @@ -213,8 +169,8 @@ static enum peci_status peci_transaction(uint8_t addr, } else if (IT83XX_PECI_HOSTAR & PECI_STATUS_FINISH) { /* The read data field of the PECI protocol. */ - for (index = 0x00; index < r_len; index++) - r_buf[index] = IT83XX_PECI_HORDDR; + for (index = 0x00; index < peci->r_len; index++) + peci->r_buf[index] = IT83XX_PECI_HORDDR; /* W/C */ IT83XX_PECI_HOSTAR = PECI_STATUS_FINISH; @@ -237,72 +193,6 @@ static enum peci_status peci_transaction(uint8_t addr, return status; } -int peci_get_cpu_temp(void) -{ - uint8_t r_buf[PECI_GET_TEMP_READ_LENGTH] = {0}; - int cpu_temp = -1; - - if (peci_transaction(PECI_TARGET_ADDRESS, - PECI_GET_TEMP_WRITE_LENGTH, - PECI_GET_TEMP_READ_LENGTH, - PECI_CMD_GET_TEMP, - NULL, - r_buf, - PECI_GET_TEMP_TIMEOUT_US) == - PECI_STATUS_NO_ERR) { - - /* Get relative raw data of temperature. */ - cpu_temp = (r_buf[1] << 8) | r_buf[0]; - -#ifdef CONFIG_PECI_TJMAX - /* Convert relative raw data to degrees C. */ - cpu_temp = ((cpu_temp ^ 0xFFFF) + 1) >> 6; - /* temperature in K */ - cpu_temp = (CONFIG_PECI_TJMAX - cpu_temp) + 273; -#endif - } - - return cpu_temp; -} - -int peci_temp_sensor_get_val(int idx, int *temp_ptr) -{ - int sum = 0; - int success_cnt = 0; - int i; - - if (!chipset_in_state(CHIPSET_STATE_ON)) - return EC_ERROR_NOT_POWERED; - - for (i = 0; i < TEMP_AVG_LENGTH; ++i) { - if (temp_vals[i] >= 0) { - success_cnt++; - sum += temp_vals[i]; - } - } - - /* - * Require at least two valid samples. When the AP transitions into S0, - * it is possible, depending on the timing of the PECI sample, to read - * an invalid temperature. This is very rare, but when it does happen - * the temperature returned is CONFIG_PECI_TJMAX. Requiring two valid - * samples here assures us that one bad maximum temperature reading - * when entering S0 won't cause us to trigger an over temperature. - */ - if (success_cnt < 2) - return EC_ERROR_UNKNOWN; - - *temp_ptr = sum / success_cnt; - return EC_SUCCESS; -} - -static void peci_temp_sensor_poll(void) -{ - temp_vals[temp_idx] = peci_get_cpu_temp(); - temp_idx = (temp_idx + 1) & (TEMP_AVG_LENGTH - 1); -} -DECLARE_HOOK(HOOK_TICK, peci_temp_sensor_poll, HOOK_PRIO_TEMP_SENSOR); - void peci_interrupt(void) { task_clear_pending_irq(IT83XX_IRQ_PECI); @@ -314,8 +204,6 @@ void peci_interrupt(void) static void peci_init(void) { - int i; - clock_enable_peripheral(CGC_OFFSET_PECI, 0, 0); peci_init_vtt_freq(); @@ -324,97 +212,5 @@ static void peci_init(void) /* bit4, PECI enable */ IT83XX_GPIO_GRC2 |= 0x10; - - /* Initialize temperature reading buffer to a sane value. */ - for (i = 0; i < TEMP_AVG_LENGTH; ++i) - temp_vals[i] = 300; /* 27 C */ } DECLARE_HOOK(HOOK_INIT, peci_init, HOOK_PRIO_DEFAULT); - -/*****************************************************************************/ -/* Console commands */ - -static int peci_cmd(int argc, char **argv) -{ - uint8_t r_buf[PECI_READ_DATA_FIFO_SIZE] = {0}; - uint8_t w_buf[PECI_WRITE_DATA_FIFO_SIZE] = {0}; - - int addr, wlen, rlen, cmd, time_us, param; - char *e; - - if ((argc < 6) || (argc > 8)) - return EC_ERROR_PARAM_COUNT; - - addr = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - wlen = strtoi(argv[2], &e, 0); - if (*e) - return EC_ERROR_PARAM2; - - rlen = strtoi(argv[3], &e, 0); - if (*e) - return EC_ERROR_PARAM3; - - cmd = strtoi(argv[4], &e, 0); - if (*e) - return EC_ERROR_PARAM4; - - time_us = strtoi(argv[5], &e, 0); - if (*e) - return EC_ERROR_PARAM5; - - if (argc > 6) { - param = strtoi(argv[6], &e, 0); - if (*e) - return EC_ERROR_PARAM6; - - /* MSB of parameter */ - w_buf[3] = (uint8_t)(param >> 24); - /* LSB of parameter */ - w_buf[2] = (uint8_t)(param >> 16); - /* Index */ - w_buf[1] = (uint8_t)(param >> 8); - /* Host ID[7:1] & Retry[0] */ - w_buf[0] = (uint8_t)(param >> 0); - - if (argc > 7) { - param = strtoi(argv[7], &e, 0); - if (*e) - return EC_ERROR_PARAM7; - - /* Data (1, 2 or 4 bytes) */ - w_buf[7] = (uint8_t)(param >> 24); - w_buf[6] = (uint8_t)(param >> 16); - w_buf[5] = (uint8_t)(param >> 8); - w_buf[4] = (uint8_t)(param >> 0); - } - } else { - wlen = 0x00; - } - - if (peci_transaction(addr, wlen, rlen, cmd, w_buf, r_buf, time_us)) { - ccprintf("PECI transaction error\n"); - return EC_ERROR_UNKNOWN; - } - ccprintf("PECI read data: %.*h\n", rlen, r_buf); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(peci, peci_cmd, - "addr wlen rlen cmd timeout(us)", - "PECI command"); - -static int command_peci_temp(int argc, char **argv) -{ - int t = peci_get_cpu_temp(); - if (t == -1) { - ccprintf("PECI get cpu temp error\n"); - return EC_ERROR_UNKNOWN; - } - ccprintf("CPU temp = %d K = %d C\n", t, K_TO_C(t)); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(pecitemp, command_peci_temp, - NULL, - "Print CPU temperature"); |