diff options
-rw-r--r-- | board/cr50/gpio.inc | 2 | ||||
-rw-r--r-- | chip/g/gpio.c | 29 | ||||
-rw-r--r-- | chip/g/idle.c | 18 | ||||
-rw-r--r-- | chip/g/jtag.c | 1 | ||||
-rw-r--r-- | chip/g/registers.h | 15 | ||||
-rw-r--r-- | chip/g/sps.c | 15 |
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); |