summaryrefslogtreecommitdiff
path: root/chip/mec1322/lpc.c
diff options
context:
space:
mode:
authorDivya Jyothi <divya.jyothi@intel.com>2014-10-27 09:48:38 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-06 09:26:21 +0000
commit75ced738383d4b3bdf4e95b31c193cb0366e69cf (patch)
tree304e1fef1e803c3fb0af2241b9fd60c1c4815f5e /chip/mec1322/lpc.c
parent41cde665166da1aced2ece17f7b503c78cdb5c8f (diff)
downloadchrome-ec-75ced738383d4b3bdf4e95b31c193cb0366e69cf.tar.gz
Strago: Initial Version of Strago Board added.
Modules that are enabled are listed below: - Power Sequencing - Keyboard Scan and Protocol - LPC to support Keyboard - Power Button Task ec.spi.bin has to be generated manualy using pack_ec.py BUG=None BRANCH=None TEST=Tested on Stargo-Proto board Change-Id: Ic5d504c3d6e9c7c5f3482fb7e9e37800b6274824 Signed-off-by: Divya Jyothi <divya.jyothi@intel.com> Reviewed-on: https://chromium-review.googlesource.com/226303 Reviewed-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'chip/mec1322/lpc.c')
-rw-r--r--chip/mec1322/lpc.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c
index 265b7598e9..07e75f2a09 100644
--- a/chip/mec1322/lpc.c
+++ b/chip/mec1322/lpc.c
@@ -18,6 +18,10 @@
#include "timer.h"
#include "util.h"
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_LPC, outstr)
+#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
+
static uint8_t mem_mapped[0x200] __attribute__((section(".bss.big_align")));
static uint32_t host_events; /* Currently pending SCI/SMI events */
@@ -32,6 +36,34 @@ static int init_done;
static struct ec_lpc_host_args * const lpc_host_args =
(struct ec_lpc_host_args *)mem_mapped;
+
+#ifdef CONFIG_KEYBOARD_IRQ_GPIO
+static void keyboard_irq_assert(void)
+{
+ /*
+ * Enforce signal-high for long enough for the signal to be pulled high
+ * by the external pullup resistor. This ensures the host will see the
+ * following falling edge, regardless of the line state before this
+ * function call.
+ */
+ gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
+ udelay(4);
+ /* Generate a falling edge */
+ gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 0);
+ udelay(4);
+
+ /* Set signal high, now that we've generated the edge */
+ gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
+}
+#else
+static void keyboard_irq_assert(void)
+{
+ /*
+ * TODO(crosbug.com/p/24107): Implement SER_IRQ
+ */
+}
+#endif
+
/**
* Generate SMI pulse to the host chipset via GPIO.
*
@@ -158,14 +190,14 @@ static void lpc_send_response_packet(struct host_packet *pkt)
*/
static void setup_lpc(void)
{
- uintptr_t ptr = (uintptr_t)mem_mapped;
-
- /* EMI module only takes alias memory address */
- if (ptr < 0x120000)
- ptr = ptr - 0x118000 + 0x20000000;
-
gpio_config_module(MODULE_LPC, 1);
+ /* Set up interrupt on LRESET# deassert */
+ MEC1322_INT_SOURCE(19) |= 1 << 1;
+ MEC1322_INT_ENABLE(19) |= 1 << 1;
+ MEC1322_INT_BLK_EN |= 1 << 19;
+ task_enable_irq(MEC1322_IRQ_GIRQ19);
+
/* Set up ACPI0 for 0x62/0x66 */
MEC1322_LPC_ACPI_EC0_BAR = 0x00628034;
MEC1322_INT_ENABLE(15) |= 1 << 6;
@@ -181,18 +213,15 @@ static void setup_lpc(void)
/* Set up 8042 interface at 0x60/0x64 */
MEC1322_LPC_8042_BAR = 0x00608104;
MEC1322_8042_ACT |= 1;
- MEC1322_INT_ENABLE(15) |= 1 << 14;
+ MEC1322_INT_ENABLE(15) |= ((1 << 13) | (1 << 14));
MEC1322_INT_BLK_EN |= 1 << 15;
task_enable_irq(MEC1322_IRQ_8042EM_IBF);
+ task_enable_irq(MEC1322_IRQ_8042EM_OBF);
/* TODO(crosbug.com/p/24107): Route KIRQ to SER_IRQ1 */
/* Set up EMI module for memory mapped region and port 80 */
MEC1322_LPC_EMI_BAR = 0x0080800f;
- MEC1322_EMI_MBA0 = ptr;
- MEC1322_EMI_MRL0 = 0x200;
- MEC1322_EMI_MWL0 = 0x100;
-
MEC1322_INT_ENABLE(15) |= 1 << 2;
MEC1322_INT_BLK_EN |= 1 << 15;
task_enable_irq(MEC1322_IRQ_EMI);
@@ -225,6 +254,27 @@ static void lpc_init(void)
*/
DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC);
+void girq19_interrupt(void)
+{
+ /* Check interrupt result for LRESET# trigger */
+ if (MEC1322_INT_RESULT(19) & (1 << 1)) {
+ /* Initialize LPC module when LRESET# is deasserted */
+ if (!lpc_get_pltrst_asserted()) {
+ setup_lpc();
+ } else {
+ /* Store port 80 reset event */
+ port_80_write(PORT_80_EVENT_RESET);
+ }
+
+ CPRINTS("LPC RESET# %sasserted",
+ lpc_get_pltrst_asserted() ? "" : "de");
+
+ /* Clear interrupt source */
+ MEC1322_INT_SOURCE(19) |= 1 << 1;
+ }
+}
+DECLARE_IRQ(MEC1322_IRQ_GIRQ19, girq19_interrupt, 1);
+
void emi_interrupt(void)
{
port_80_write(MEC1322_EMI_H2E_MBX);
@@ -313,6 +363,12 @@ void kb_ibf_interrupt(void)
task_wake(TASK_ID_KEYPROTO);
}
DECLARE_IRQ(MEC1322_IRQ_8042EM_IBF, kb_ibf_interrupt, 1);
+
+void kb_obf_interrupt(void)
+{
+ task_wake(TASK_ID_KEYPROTO);
+}
+DECLARE_IRQ(MEC1322_IRQ_8042EM_OBF, kb_obf_interrupt, 1);
#endif
int lpc_keyboard_has_char(void)
@@ -328,21 +384,21 @@ int lpc_keyboard_input_pending(void)
void lpc_keyboard_put_char(uint8_t chr, int send_irq)
{
MEC1322_8042_E2H = chr;
- /*
- * TODO(crosbug.com/p/24107): Implement SER_IRQ and handle
- * send_irq.
- */
+ if (send_irq)
+ keyboard_irq_assert();
}
void lpc_keyboard_clear_buffer(void)
{
volatile char dummy __attribute__((unused));
+
dummy = MEC1322_8042_OBF_CLR;
}
void lpc_keyboard_resume_irq(void)
{
- /* TODO(crosbug.com/p/24107): Implement SER_IRQ */
+ if (lpc_keyboard_has_char())
+ keyboard_irq_assert();
}
void lpc_set_host_event_state(uint32_t mask)
@@ -393,6 +449,11 @@ uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
return event_mask[type];
}
+int lpc_get_pltrst_asserted(void)
+{
+ return (MEC1322_LPC_BUS_MONITOR & (1<<1)) ? 1 : 0;
+}
+
/* On boards without a host, this command is used to set up LPC */
static int lpc_command_init(int argc, char **argv)
{