mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
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
This commit is contained in:
@@ -159,8 +159,10 @@ enum temp_sensor_id {
|
||||
TEMP_SENSOR_I2C_DIE_NEAR_CHARGER,
|
||||
/* EC internal temperature sensor */
|
||||
TEMP_SENSOR_EC_INTERNAL,
|
||||
/* CPU die temperature via PECI */
|
||||
TEMP_SENSOR_CPU_PECI,
|
||||
|
||||
/* TODO: I2C temperature sensors. */
|
||||
/* TODO: I2C remote temperature sensors. */
|
||||
|
||||
TEMP_SENSOR_COUNT
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "chip_temp_sensor.h"
|
||||
#include "board.h"
|
||||
#include "i2c.h"
|
||||
#include "peci.h"
|
||||
|
||||
#define TEMP_CPU_REG_ADDR ((0x40 << 1) | I2C_FLAG_BIG_ENDIAN)
|
||||
#define TEMP_PCH_REG_ADDR ((0x41 << 1) | I2C_FLAG_BIG_ENDIAN)
|
||||
@@ -24,14 +25,16 @@
|
||||
* temp_sensor_id.
|
||||
*/
|
||||
const struct temp_sensor_t temp_sensors[TEMP_SENSOR_COUNT] = {
|
||||
{"CPU", TEMP_SENSOR_I2C_DIE_NEAR_CPU, TEMP_CPU_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"PCH", TEMP_SENSOR_I2C_DIE_NEAR_PCH, TEMP_PCH_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"DDR", TEMP_SENSOR_I2C_DIE_NEAR_DDR, TEMP_DDR_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"Charger", TEMP_SENSOR_I2C_DIE_NEAR_CHARGER, TEMP_CHARGER_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"I2C_CPU", TEMP_SENSOR_I2C_DIE_NEAR_CPU, TEMP_CPU_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"I2C_PCH", TEMP_SENSOR_I2C_DIE_NEAR_PCH, TEMP_PCH_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"I2C_DDR", TEMP_SENSOR_I2C_DIE_NEAR_DDR, TEMP_DDR_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"I2C_Charger", TEMP_SENSOR_I2C_DIE_NEAR_CHARGER, TEMP_CHARGER_ADDR,
|
||||
temp_sensor_tmp006_read_die_temp, temp_sensor_tmp006_print},
|
||||
{"ECInternal", TEMP_SENSOR_EC_INTERNAL, TEMP_SENSOR_NO_ADDR,
|
||||
chip_temp_sensor_read, TEMP_SENSOR_NO_PRINT},
|
||||
chip_temp_sensor_read, TEMP_SENSOR_NO_PRINT},
|
||||
{"PECI", TEMP_SENSOR_CPU_PECI, TEMP_SENSOR_NO_ADDR,
|
||||
peci_temp_sensor_read, TEMP_SENSOR_NO_PRINT},
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
106
chip/lm4/peci.c
Normal file
106
chip/lm4/peci.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
*/
|
||||
|
||||
#include "adc.h"
|
||||
#include "config.h"
|
||||
#include "charger.h"
|
||||
#include "chip_temp_sensor.h"
|
||||
#include "clock.h"
|
||||
#include "config.h"
|
||||
#include "console.h"
|
||||
#include "eeprom.h"
|
||||
#include "flash.h"
|
||||
@@ -18,6 +20,7 @@
|
||||
#include "keyboard.h"
|
||||
#include "lpc.h"
|
||||
#include "memory_commands.h"
|
||||
#include "peci.h"
|
||||
#include "port80.h"
|
||||
#include "power_button.h"
|
||||
#include "powerdemo.h"
|
||||
@@ -25,16 +28,12 @@
|
||||
#include "pwm_commands.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#ifdef CONFIG_TEMP_SENSOR
|
||||
#include "temp_sensor.h"
|
||||
#endif
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "usb_charge.h"
|
||||
#include "vboot.h"
|
||||
#include "watchdog.h"
|
||||
#include "usb_charge.h"
|
||||
#include "chip_temp_sensor.h"
|
||||
#include "charger.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -87,6 +86,10 @@ int main(void)
|
||||
charger_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PECI
|
||||
peci_init();
|
||||
#endif
|
||||
|
||||
/* Print the reset cause */
|
||||
uart_printf("\n\n--- Chrome EC initialized! ---\n");
|
||||
uart_printf("(image: %s, version: %s, last reset: %s)\n",
|
||||
|
||||
28
include/peci.h
Normal file
28
include/peci.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* 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 module for Chrome EC */
|
||||
|
||||
#ifndef __CROS_EC_PECI_H
|
||||
#define __CROS_EC_PECI_H
|
||||
|
||||
#include "common.h"
|
||||
#include "temp_sensor.h"
|
||||
|
||||
/* Initializes the module. */
|
||||
int peci_init(void);
|
||||
|
||||
/* Returns the current CPU temperature in degrees K, or -1 if error.
|
||||
*
|
||||
* Note that the PECI interface is currently a little flaky; if you get an
|
||||
* error, retry a bit later. */
|
||||
int peci_get_cpu_temp(void);
|
||||
|
||||
/* Reads the CPU temperature sensor via PECI. This interface is for the
|
||||
* temperature sensor module. Returns the temperature in degrees K, or -1 if
|
||||
* error. */
|
||||
int peci_temp_sensor_read(const struct temp_sensor_t *sensor);
|
||||
|
||||
#endif /* __CROS_EC_PECI_H */
|
||||
Reference in New Issue
Block a user