summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cyan/board.h2
-rw-r--r--board/cyan/ec.tasklist1
-rw-r--r--board/glower/board.h1
-rw-r--r--board/glower/ec.tasklist1
-rw-r--r--board/strago/board.h2
-rw-r--r--board/strago/ec.tasklist1
-rw-r--r--chip/mec1322/lpc.c27
-rw-r--r--chip/mec1322/registers.h4
-rw-r--r--common/port80.c47
-rw-r--r--include/config.h8
-rw-r--r--include/port80.h11
11 files changed, 105 insertions, 0 deletions
diff --git a/board/cyan/board.h b/board/cyan/board.h
index 8ec396036d..98b8910f7b 100644
--- a/board/cyan/board.h
+++ b/board/cyan/board.h
@@ -27,6 +27,8 @@
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_I2C
+#define CONFIG_PORT80_TASK_EN
+
#define CONFIG_CHARGER
#define CONFIG_BATTERY_SMART
#define CONFIG_CHARGER_V2
diff --git a/board/cyan/ec.tasklist b/board/cyan/ec.tasklist
index 73f54cca53..2fc581d310 100644
--- a/board/cyan/ec.tasklist
+++ b/board/cyan/ec.tasklist
@@ -23,6 +23,7 @@
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
+ TASK_NOTEST(PORT80, port80_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(POWERBTN, power_button_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
diff --git a/board/glower/board.h b/board/glower/board.h
index a6a120332f..387c582992 100644
--- a/board/glower/board.h
+++ b/board/glower/board.h
@@ -12,6 +12,7 @@
/* #define CONFIG_BACKLIGHT_LID */
/* #define CONFIG_BATTERY_SMART */
#define CONFIG_BOARD_VERSION
+#define CONFIG_PORT80_TASK_EN
#if 0
#define CONFIG_CHARGER
diff --git a/board/glower/ec.tasklist b/board/glower/ec.tasklist
index b199809ac9..4067403bee 100644
--- a/board/glower/ec.tasklist
+++ b/board/glower/ec.tasklist
@@ -23,5 +23,6 @@
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
+ TASK_NOTEST(PORT80, port80_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(POWERBTN, power_button_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
diff --git a/board/strago/board.h b/board/strago/board.h
index 8b39fd4b6d..d3a8002043 100644
--- a/board/strago/board.h
+++ b/board/strago/board.h
@@ -26,6 +26,8 @@
#define CONFIG_POWER_COMMON
#define CONFIG_EXTPOWER_GPIO
+#define CONFIG_PORT80_TASK_EN
+
#define CONFIG_SPI_PORT 1
#define CONFIG_SPI_CS_GPIO GPIO_PVT_CS0
#define CONFIG_SPI_FLASH
diff --git a/board/strago/ec.tasklist b/board/strago/ec.tasklist
index bc15569efd..370444648e 100644
--- a/board/strago/ec.tasklist
+++ b/board/strago/ec.tasklist
@@ -24,5 +24,6 @@
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
+ TASK_NOTEST(PORT80, port80_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(POWERBTN, power_button_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c
index 635e2e64de..4486ef9f7a 100644
--- a/chip/mec1322/lpc.c
+++ b/chip/mec1322/lpc.c
@@ -239,6 +239,10 @@ static void setup_lpc(void)
MEC1322_EMI_MRL0 = 0x200;
MEC1322_EMI_MWL0 = 0x100;
+ /* Set up Mailbox for Port80 trapping */
+ MEC1322_MBX_INDEX = 0xff;
+ MEC1322_LPC_MAILBOX_BAR = 0x00808901;
+
/* We support LPC args and version 3 protocol */
*(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) =
EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
@@ -294,6 +298,29 @@ void emi_interrupt(void)
}
DECLARE_IRQ(MEC1322_IRQ_EMI, emi_interrupt, 1);
+#ifdef HAS_TASK_PORT80
+/*
+ * Port80 POST code polling limitation:
+ * - POST code 0xFF is ignored.
+ */
+int port_80_read(void)
+{
+ int data;
+
+ /* read MBX_INDEX for POST code */
+ data = MEC1322_MBX_INDEX;
+
+ /* clear MBX_INDEX for next POST code*/
+ MEC1322_MBX_INDEX = 0xff;
+
+ /* mark POST code 0xff as invalid */
+ if (data == 0xff)
+ data = PORT_80_IGNORE;
+
+ return data;
+}
+#endif
+
void acpi_0_interrupt(void)
{
uint8_t value, result, is_cmd;
diff --git a/chip/mec1322/registers.h b/chip/mec1322/registers.h
index af89609dc9..88b055eaa5 100644
--- a/chip/mec1322/registers.h
+++ b/chip/mec1322/registers.h
@@ -175,6 +175,10 @@ static inline uintptr_t gpio_port_base(int port_id)
/* Mailbox */
+#define MEC1322_MBX_RT_BASE 0x400f2400
+#define MEC1322_MBX_INDEX REG8(MEC1322_MBX_RT_BASE + 0x0)
+#define MEC1322_MBX_DATA REG8(MEC1322_MBX_RT_BASE + 0x1)
+
#define MEC1322_MBX_BASE 0x400f2500
#define MEC1322_MBX_H2E_MBX REG8(MEC1322_MBX_BASE + 0x0)
#define MEC1322_MBX_E2H_MBX REG8(MEC1322_MBX_BASE + 0x4)
diff --git a/common/port80.c b/common/port80.c
index 9f6136cf5d..f857540727 100644
--- a/common/port80.c
+++ b/common/port80.c
@@ -9,17 +9,24 @@
#include "console.h"
#include "host_command.h"
#include "port80.h"
+#include "task.h"
+#include "timer.h"
#include "util.h"
#define CPRINTF(format, args...) cprintf(CC_PORT80, format, ## args)
#define HISTORY_LEN 256
+#define PORT80_POLL_PERIOD MSEC
static uint16_t history[HISTORY_LEN];
static int writes; /* Number of port 80 writes so far */
static int last_boot; /* Last code from previous boot */
static int scroll;
static int print_in_int = 1;
+#ifdef HAS_TASK_PORT80
+static int task_en; /* Port 80 task control */
+static int task_timeout = -1;
+#endif
void port_80_write(int data)
{
@@ -43,6 +50,30 @@ void port_80_write(int data)
writes++;
}
+#ifdef HAS_TASK_PORT80
+/*
+ * Port80 POST code polling limitation:
+ * - POST code 0xFF is ignored.
+ * - POST code frequency is greater than 1 msec.
+ */
+void port80_task(void)
+{
+#ifdef CONFIG_PORT80_TASK_EN
+ task_en = 1;
+ task_timeout = PORT80_POLL_PERIOD;
+#endif
+
+ while (1) {
+ int data = port_80_read();
+
+ if (data != PORT_80_IGNORE)
+ port_80_write(data);
+
+ task_wait_event(task_timeout);
+ }
+}
+#endif
+
/*****************************************************************************/
/* Console commands */
@@ -69,6 +100,22 @@ static int command_port80(int argc, char **argv)
} else if (!strcasecmp(argv[1], "flush")) {
writes = 0;
return EC_SUCCESS;
+#ifdef HAS_TASK_PORT80
+ } else if (!strcasecmp(argv[1], "task")) {
+ task_en = !task_en;
+ ccprintf("task %sabled\n", task_en ? "en" : "dis");
+ if (task_en) {
+ task_timeout = PORT80_POLL_PERIOD;
+ task_wake(TASK_ID_PORT80);
+ } else
+ task_timeout = -1;
+ return EC_SUCCESS;
+ } else if (!strcasecmp(argv[1], "poll")) {
+ i = port_80_read();
+ if (i != PORT_80_IGNORE)
+ port_80_write(i);
+ /* continue on to print the port 80 history */
+#endif
} else {
return EC_ERROR_PARAM1;
}
diff --git a/include/config.h b/include/config.h
index cb6be599a9..c5bfde79f6 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1005,6 +1005,14 @@
/*****************************************************************************/
+/*
+ * Enable polling at boot by port 80 task.
+ * Ignored if port 80 is handled by interrupt
+ */
+#undef CONFIG_PORT80_TASK_EN
+
+/*****************************************************************************/
+
/* Compile common code to support power button debouncing */
#undef CONFIG_POWER_BUTTON
diff --git a/include/port80.h b/include/port80.h
index 28966750c6..470b01cc4b 100644
--- a/include/port80.h
+++ b/include/port80.h
@@ -13,6 +13,7 @@
enum port_80_event {
PORT_80_EVENT_RESUME = 0x1001, /* S3->S0 transition */
PORT_80_EVENT_RESET = 0x1002, /* RESET transition */
+ PORT_80_IGNORE = 0xffff, /* Invalid POST CODE */
};
/**
@@ -22,4 +23,14 @@ enum port_80_event {
*/
void port_80_write(int data);
+#ifdef HAS_TASK_PORT80
+/**
+ * Chip specific function to read from port 80.
+ *
+ * @return data from the last LPC write to port 80,
+ * or PORT_80_IGNORE if no data is available.
+ */
+int port_80_read(void);
+#endif
+
#endif /* __CROS_EC_PORT80_H */