summaryrefslogtreecommitdiff
path: root/chip/lm4/peci.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/lm4/peci.c')
-rw-r--r--chip/lm4/peci.c106
1 files changed, 106 insertions, 0 deletions
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;
+}