diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-02-10 14:09:42 -0800 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-02-10 14:09:42 -0800 |
commit | 6063ad473c9921420145f6d0fa51873ba2d05062 (patch) | |
tree | acc0701717c8b47c5096eb9800f5466ee0f1dc34 /chip | |
parent | 186c81dcac9ae96a1ace3ad5bf147fbf8fd35c50 (diff) | |
download | chrome-ec-6063ad473c9921420145f6d0fa51873ba2d05062.tar.gz |
Add PECI module and CPU temperature monitoring
Signed-off-by: Randall Spangler <rspangler@chromium.org>
BUG=chrome-os-partner:7493
TEST='powerbtn' to boot main processor, then 'temps' and 'pecitemp'
Change-Id: Id57526ebb37c8aecb05ecebccc2824f462b9de1a
Diffstat (limited to 'chip')
-rw-r--r-- | chip/lm4/build.mk | 1 | ||||
-rw-r--r-- | chip/lm4/config.h | 1 | ||||
-rw-r--r-- | chip/lm4/peci.c | 106 | ||||
-rw-r--r-- | chip/lm4/registers.h | 24 |
4 files changed, 132 insertions, 0 deletions
diff --git a/chip/lm4/build.mk b/chip/lm4/build.mk index 028eeecc3f..63d0376102 100644 --- a/chip/lm4/build.mk +++ b/chip/lm4/build.mk @@ -13,6 +13,7 @@ chip-y+=clock.o gpio.o system.o uart.o power_button.o chip-y+=watchdog.o eeprom.o hwtimer.o chip-$(CONFIG_FLASH)+=flash.o chip-$(CONFIG_LPC)+=lpc.o +chip-$(CONFIG_PECI)+=peci.o chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_TEMP_SENSOR)+=chip_temp_sensor.o chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o diff --git a/chip/lm4/config.h b/chip/lm4/config.h index f2224f8226..033810c682 100644 --- a/chip/lm4/config.h +++ b/chip/lm4/config.h @@ -37,6 +37,7 @@ #define CONFIG_PWM #define CONFIG_TEMP_SENSOR #define CONFIG_CHARGER +#define CONFIG_PECI /* Compile for running from RAM instead of flash */ /* #define COMPILE_FOR_RAM */ diff --git a/chip/lm4/peci.c b/chip/lm4/peci.c new file mode 100644 index 0000000000..fc0d09f71d --- /dev/null +++ b/chip/lm4/peci.c @@ -0,0 +1,106 @@ +/* Copyright (c) 2012 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. + */ + +/* PECI interface for Chrome EC */ + +#include "board.h" +#include "console.h" +#include "gpio.h" +#include "peci.h" +#include "registers.h" +#include "uart.h" +#include "util.h" + +/* Max junction temperature for processor in degrees C */ +/* TODO: read TjMax from processor via PECI */ +#define PECI_TJMAX 105 + +/* Initial PECI baud rate */ +#define PECI_BAUD_RATE 150000 + +/* Polling interval for PECI, in ms */ +#define PECI_POLL_INTERVAL_MS 200 + +/* Internal and external path delays, in ns */ +#define PECI_TD_FET_NS 25 /* Guess; TODO: what is real delay */ +#define PECI_TD_INT_NS 80 + + +/* Configures the GPIOs for the PECI module. */ +static void configure_gpios(void) +{ + /* PJ6 alternate function 1 = PECI Tx */ + gpio_set_alternate_function(LM4_GPIO_J, 0x40, 1); + + /* PJ7 analog input = PECI Rx (comparator) */ + LM4_GPIO_DEN(LM4_GPIO_J) &= ~0x80; +} + + +int peci_get_cpu_temp(void) +{ + int v = LM4_PECI_M0D0 & 0xffff; + + if (v >= 0x8000 && v <= 0x8fff) + return -1; + + return v >> 6; +} + + +int peci_temp_sensor_read(const struct temp_sensor_t* sensor) +{ + if (sensor->id != TEMP_SENSOR_CPU_PECI) + return EC_ERROR_INVAL; + + return peci_get_cpu_temp(); +} + +/*****************************************************************************/ +/* Console commands */ + +static int command_peci_temp(int argc, char **argv) +{ + int t = peci_get_cpu_temp(); + if (t == -1) { + uart_puts("Error reading CPU temperature via PECI\n"); + uart_printf("Error code = 0x%04x\n", LM4_PECI_M0D0 & 0xffff); + return EC_ERROR_UNKNOWN; + } + uart_printf("Current CPU temperature = %d K = %d C\n", t, t - 273); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(pecitemp, command_peci_temp); + +/*****************************************************************************/ +/* Initialization */ + +int peci_init(void) +{ + volatile uint32_t scratch __attribute__((unused)); + int baud; + + /* Enable the PECI module and delay a few clocks */ + LM4_SYSTEM_RCGCPECI = 1; + scratch = LM4_SYSTEM_RCGCPECI; + + /* Configure GPIOs */ + configure_gpios(); + + /* Calculate baud setting from desired rate, compensating for internal + * and external delays. */ + baud = CPU_CLOCK / (4 * PECI_BAUD_RATE) - 2; + baud -= (CPU_CLOCK / 1000000) * (PECI_TD_FET_NS + PECI_TD_INT_NS) + / 1000; + + /* Set baud rate and polling rate */ + LM4_PECI_DIV = (baud << 16) | + (PECI_POLL_INTERVAL_MS * (CPU_CLOCK / 1000 / 4096)); + + /* Set up temperature monitoring to report in degrees K */ + LM4_PECI_CTL = ((PECI_TJMAX + 273) << 22) | 0x2001; + + return EC_SUCCESS; +} diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h index a379be16d8..05e6db3ad7 100644 --- a/chip/lm4/registers.h +++ b/chip/lm4/registers.h @@ -124,6 +124,29 @@ static inline int lm4_fan_addr(int ch, int offset) #define LM4_EEPROM_EEINT LM4REG(0x400af040) #define LM4_EEPROM_EEHIDE LM4REG(0x400af050) +#define LM4_PECI_CTL LM4REG(0x400b0000) +#define LM4_PECI_DIV LM4REG(0x400b0004) +#define LM4_PECI_CMP LM4REG(0x400b0008) +#define LM4_PECI_M0D0C LM4REG(0x400b0010) +#define LM4_PECI_M0D1C LM4REG(0x400b0014) +#define LM4_PECI_M1D0C LM4REG(0x400b0018) +#define LM4_PECI_M1D1C LM4REG(0x400b001c) +#define LM4_PECI_M0D0 LM4REG(0x400b0040) +#define LM4_PECI_M0D1 LM4REG(0x400b0044) +#define LM4_PECI_M1D0 LM4REG(0x400b0048) +#define LM4_PECI_M1D1 LM4REG(0x400b004c) +#define LM4_PECI_IM LM4REG(0x400b0080) +#define LM4_PECI_RIS LM4REG(0x400b0084) +#define LM4_PECI_MIS LM4REG(0x400b0088) +#define LM4_PECI_IC LM4REG(0x400b008c) +#define LM4_PECI_ACADDR LM4REG(0x400b0100) +#define LM4_PECI_ACARG LM4REG(0x400b0104) +#define LM4_PECI_ACRDWR0 LM4REG(0x400b0108) +#define LM4_PECI_ACRDWR1 LM4REG(0x400b010c) +#define LM4_PECI_ACCMD LM4REG(0x400b0110) +#define LM4_PECI_ACCODE LM4REG(0x400b0114) + + #define LM4_HIBERNATE_HIBRTCC LM4REG(0x400fc000) #define LM4_HIBERNATE_HIBRTCM0 LM4REG(0x400fc004) #define LM4_HIBERNATE_HIBRTCLD LM4REG(0x400fc00c) @@ -172,6 +195,7 @@ static inline int lm4_fan_addr(int ch, int offset) #define LM4_SYSTEM_RCGCI2C LM4REG(0x400fe620) #define LM4_SYSTEM_RCGCADC LM4REG(0x400fe638) #define LM4_SYSTEM_RCGCLPC LM4REG(0x400fe648) +#define LM4_SYSTEM_RCGCPECI LM4REG(0x400fe650) #define LM4_SYSTEM_RCGCFAN LM4REG(0x400fe654) #define LM4_SYSTEM_RCGCEEPROM LM4REG(0x400fe658) #define LM4_SYSTEM_RCGCWTIMER LM4REG(0x400fe65c) |