summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-04-01 17:09:01 -0700
committerBill Richardson <wfrichar@chromium.org>2016-04-05 16:54:03 +0000
commit5aec786f4c698f264c868cef000d88b4d2e43100 (patch)
treef8fdd7224a5ee7774c91afdabafcf9dcbfdfdc2a
parent76850c555626c7b6efb13b02dac10f4635fe5bce (diff)
downloadchrome-ec-5aec786f4c698f264c868cef000d88b4d2e43100.tar.gz
Cr50: Specify pinmux wake sources in gpio.inc
This adds (and uses) some additional flags for gpio.inc's PINMUX() macro, to configure specific pads as wake sources when the SoC is sleeping. BUG=chrome-os-partner:49955 BRANCH=none TEST=make buildall; test on Cr50 The sleep/deep sleep behavior is unchanged. This just replaces hard-coded wake sources with pads configured in gpio.inc and the chip/g/sps.c module. Tests from previous CLs still pass. Change-Id: I6608dc959524f42fd589feb804fa06f29cfd9b9c Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/336838 Reviewed-by: Dominic Rizzo <domrizzo@google.com>
-rw-r--r--board/cr50/gpio.inc2
-rw-r--r--chip/g/gpio.c29
-rw-r--r--chip/g/idle.c18
-rw-r--r--chip/g/jtag.c1
-rw-r--r--chip/g/registers.h15
-rw-r--r--chip/g/sps.c15
6 files changed, 51 insertions, 29 deletions
diff --git a/board/cr50/gpio.inc b/board/cr50/gpio.inc
index 9ad8d64774..0dda8ecb2f 100644
--- a/board/cr50/gpio.inc
+++ b/board/cr50/gpio.inc
@@ -52,7 +52,7 @@ PINMUX(GPIO(BATT_PRES), M2, 0)
/* UARTs */
PINMUX(FUNC(UART0_TX), A0, DIO_OUTPUT) /* Cr50 console */
-PINMUX(FUNC(UART0_RX), A1, DIO_INPUT)
+PINMUX(FUNC(UART0_RX), A1, DIO_INPUT | DIO_WAKE_LOW)
PINMUX(FUNC(UART1_TX), A3, DIO_INPUT) /* AP console */
PINMUX(FUNC(UART1_RX), A7, DIO_INPUT)
PINMUX(FUNC(UART2_TX), B5, DIO_INPUT) /* EC console */
diff --git a/chip/g/gpio.c b/chip/g/gpio.c
index 6caf0669dd..64c441bcbd 100644
--- a/chip/g/gpio.c
+++ b/chip/g/gpio.c
@@ -187,13 +187,38 @@ static int connect_dio_to_gpio(struct pinmux const *p)
static void connect_pinmux(struct pinmux const *p)
{
+ uint32_t bitmask;
+
+ /* Connect the pinmux DIO to the right thing */
if ((p->flags & DIO_ENABLE_DIRECT_INPUT) ||
((p->flags & DIO_TO_PERIPHERAL) ?
connect_dio_to_peripheral(p) :
connect_dio_to_gpio(p)))
+ /* and maybe enable the pin as an input */
REG_WRITE_MLV(DIO_CTL_REG(p->dio.offset),
DIO_CTL_IE_MASK,
DIO_CTL_IE_LSB, 1);
+
+ /* Enable any wake pins needed to exit low-power modes */
+ if ((p->flags & DIO_WAKE_EN0) &&
+ (p->dio.offset <= GC_PINMUX_DIOB7_SEL_OFFSET)) { /* not VIOn ! */
+ bitmask = (1 << (p->dio.offset / 8));
+
+ /* enable pad as wake source */
+ GREG32(PINMUX, EXITEN0) |= bitmask;
+
+ /* level (0) or edge sensitive (1) */
+ if (p->flags & DIO_WAKE_EDGE0)
+ GREG32(PINMUX, EXITEDGE0) |= bitmask;
+ else
+ GREG32(PINMUX, EXITEDGE0) &= ~bitmask;
+
+ /* high/rising (0) or low/falling (1) */
+ if (p->flags & DIO_WAKE_INV0)
+ GREG32(PINMUX, EXITINV0) |= bitmask;
+ else
+ GREG32(PINMUX, EXITINV0) &= ~bitmask;
+ }
}
int gpio_enable_interrupt(enum gpio_signal signal)
@@ -294,7 +319,7 @@ static void show_pinmux(const char *name, int i, int ofs)
if (sel == 0 && (ctl & (0xf << 2)) == 0)
return;
- ccprintf("%08x: %s%d %2d %s%s%s%s",
+ ccprintf("%08x: %s%-2d %2d %s%s%s%s",
GC_PINMUX_BASE_ADDR + i * 8 + ofs,
name, i, sel,
(ctl & (1<<2)) ? " IN" : "",
@@ -333,7 +358,7 @@ static void show_pinmux_gpio(const char *name, int i, int ofs)
if (sel == 0)
return;
- ccprintf("%08x: %s%d %2d",
+ ccprintf("%08x: %s%-2d %2d",
GC_PINMUX_BASE_ADDR + i * 4 + ofs,
name, i, sel);
print_dio_str(sel);
diff --git a/chip/g/idle.c b/chip/g/idle.c
index 4c7afe86b1..dc003d3eef 100644
--- a/chip/g/idle.c
+++ b/chip/g/idle.c
@@ -5,7 +5,7 @@
#include "common.h"
#include "console.h"
-#include "pmu.h"
+#include "registers.h"
#include "system.h"
#include "task.h"
#include "util.h"
@@ -52,22 +52,6 @@ static void prepare_to_sleep(void)
/* No task switching! */
interrupt_disable();
- /*
- * Specify the PINMUX pads that can wake us.
- * A1 is UART RX. Idle is high, so wake on low level
- * A12 is SPS_CS_L. Also wake on low.
- * HEY: Use something in gpio.inc to identify these!
- */
- GREG32(PINMUX, EXITEN0) =
- GC_PINMUX_EXITEN0_DIOA1_MASK |
- GC_PINMUX_EXITEN0_DIOA12_MASK;
-
- GREG32(PINMUX, EXITEDGE0) = 0; /* level sensitive */
-
- GREG32(PINMUX, EXITINV0) = /* low or falling */
- GC_PINMUX_EXITINV0_DIOA1_MASK |
- GC_PINMUX_EXITINV0_DIOA12_MASK;
-
/* Enable all possible internal wake sources */
GR_PMU_EXITPD_MASK =
GC_PMU_EXITPD_MASK_PIN_PD_EXIT_MASK |
diff --git a/chip/g/jtag.c b/chip/g/jtag.c
index c835e743d8..7632252e40 100644
--- a/chip/g/jtag.c
+++ b/chip/g/jtag.c
@@ -27,6 +27,5 @@ void jtag_pre_init(void)
GWRITE_FIELD(USB, PCGCCTL, PWRCLMP, 0);
/* Unfreeze the PINMUX */
- GREG32(PINMUX, EXITEN0) = 0;
GREG32(PINMUX, HOLD) = 0;
}
diff --git a/chip/g/registers.h b/chip/g/registers.h
index 0d8d8a097e..8841da9ba6 100644
--- a/chip/g/registers.h
+++ b/chip/g/registers.h
@@ -176,10 +176,19 @@ static inline int x_uart_addr(int ch, int offset)
*/
/* Flags to indicate the direction and type of the signal-to-pin connection */
-#define DIO_INPUT 0x0001
-#define DIO_OUTPUT 0x0002
+#define DIO_INPUT 0x0001
+#define DIO_OUTPUT 0x0002
#define DIO_ENABLE_DIRECT_INPUT 0x0004
-#define DIO_TO_PERIPHERAL 0x0008
+#define DIO_TO_PERIPHERAL 0x0008
+/* Bits to indicate pinmux wake-from-sleep controls */
+#define DIO_WAKE_EN0 0x0040
+#define DIO_WAKE_EDGE0 0x0020
+#define DIO_WAKE_INV0 0x0010
+/* Use these combinations in gpio.inc for clarity */
+#define DIO_WAKE_HIGH (DIO_WAKE_EN0)
+#define DIO_WAKE_LOW (DIO_WAKE_EN0 | DIO_WAKE_INV0)
+#define DIO_WAKE_RISING (DIO_WAKE_EN0 | DIO_WAKE_EDG0)
+#define DIO_WAKE_FALLING (DIO_WAKE_EN0 | DIO_WAKE_EDG0 | DIO_WAKE_INV0)
/* Generate the MUX selector register address for the DIO */
#define DIO_SEL_REG(offset) REG32(GC_PINMUX_BASE_ADDR + offset)
diff --git a/chip/g/sps.c b/chip/g/sps.c
index 100f73c904..39aebeb5c7 100644
--- a/chip/g/sps.c
+++ b/chip/g/sps.c
@@ -240,11 +240,16 @@ static void sps_init(void)
{
pmu_clock_en(PERIPH_SPS);
- GWRITE_FIELD(PINMUX, DIOA2_CTL, IE, 1);
- GWRITE_FIELD(PINMUX, DIOA6_CTL, IE, 1);
- GWRITE_FIELD(PINMUX, DIOA12_CTL, IE, 1);
- GWRITE_FIELD(PINMUX, DIOA10_CTL, IE, 0);
-
+ /* The pinmux connections are preset, but we have to set IN/OUT */
+ GWRITE_FIELD(PINMUX, DIOA2_CTL, IE, 1); /* SPS_MOSI */
+ GWRITE_FIELD(PINMUX, DIOA6_CTL, IE, 1); /* SPS_CLK */
+ GWRITE_FIELD(PINMUX, DIOA10_CTL, IE, 0); /* SPS_MISO */
+ GWRITE_FIELD(PINMUX, DIOA12_CTL, IE, 1); /* SPS_CS_L */
+
+ /* Allow SPS_CS_L to wake from sleep */
+ GWRITE_FIELD(PINMUX, EXITEN0, DIOA12, 1); /* enable powerdown exit */
+ GWRITE_FIELD(PINMUX, EXITEDGE0, DIOA12, 0); /* level sensitive */
+ GWRITE_FIELD(PINMUX, EXITINV0, DIOA12, 1); /* wake on low */
}
DECLARE_HOOK(HOOK_INIT, sps_init, HOOK_PRIO_DEFAULT);