diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-02-23 17:37:17 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-02-27 00:38:19 -0800 |
commit | b47c1fed2027c45f3062705e0ee9943601bdeba7 (patch) | |
tree | bba7dff9db8a49f92bdddf5881e960d49ab370e7 /chip | |
parent | 30585eb36ba41822d59c838eb721826473cbd443 (diff) | |
download | chrome-ec-b47c1fed2027c45f3062705e0ee9943601bdeba7.tar.gz |
Cr50: Debug: Add pinmux and gpiocfg commands
This adds two debugging commands to decode the PINMUX and GPIO
routings without having to look at a bunch of hex values.
They can easily be removed to save space, but they're kind of
handy for now.
BUG=chrome-os-partner:49952
BRANCH=none
TEST=make buildall, and test on Cr50
Run the "pinmux" and "gpiocfg" commands. Verify that the output
reflects the desired configs found in gpio.inc
I get this:
> pinmux
40060000: DIOM0 5 IN GPIO0_GPIO4
40060008: DIOM1 6 IN GPIO0_GPIO5
40060010: DIOM2 0 IN PU
40060028: DIOA0 70 UART0_TX
40060030: DIOA1 0 IN
40060038: DIOA2 0 IN
40060040: DIOA3 2 IN GPIO0_GPIO1
40060050: DIOA5 0 IN
40060058: DIOA6 0 IN
40060060: DIOA7 3 IN GPIO0_GPIO2
40060088: DIOA12 0 IN
400600a0: DIOB0 33 IN
400600a8: DIOB1 34 IN
400600b0: DIOB2 0 IN
400600b8: DIOB3 74 UART1_TX
400600c0: DIOB4 0 IN PD
400600c8: DIOB5 78 UART2_TX
400600d0: DIOB6 0 IN
400600d8: DIOB7 1 IN GPIO0_GPIO0
400600f8: GPIO0_GPIO0 3 DIOB7
400600fc: GPIO0_GPIO1 22 DIOA3
40060100: GPIO0_GPIO2 18 DIOA7
40060104: GPIO0_GPIO3 20 DIOA5
40060108: GPIO0_GPIO4 30 DIOM0
4006010c: GPIO0_GPIO5 29 DIOM1
40060110: GPIO0_GPIO6 28 DIOM2
40060208: UART0_RX 24 DIOA1
40060218: UART1_RX 8 DIOB2
40060228: UART2_RX 4 DIOB6
> gpiocfg
GPIO0_GPIO0: read 0 drive 1
GPIO0_GPIO1: read 0 drive 0
GPIO0_GPIO2: read 0 drive 0
GPIO0_GPIO4: read 0 drive 0
GPIO0_GPIO5: read 0 drive 0
>
Note that we skip GPIO0_GPIO3 and GPIO0_GPIO6 because they're
neither outputs nor interrupts. All the GPIOs can do that.
Change-Id: I93b881bfd93dc100096bbd005a6c31b2669eda2f
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/329527
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/gpio.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/chip/g/gpio.c b/chip/g/gpio.c index 90e5c4f1c5..6caf0669dd 100644 --- a/chip/g/gpio.c +++ b/chip/g/gpio.c @@ -4,6 +4,7 @@ */ #include "common.h" +#include "console.h" #include "gpio.h" #include "hooks.h" #include "registers.h" @@ -277,3 +278,153 @@ void _gpio1_interrupt(void) } DECLARE_IRQ(GC_IRQNUM_GPIO0_GPIOCOMBINT, _gpio0_interrupt, 1); DECLARE_IRQ(GC_IRQNUM_GPIO1_GPIOCOMBINT, _gpio1_interrupt, 1); + +static const char * const uart_str[] = { + "0_CTS", "0_RTS", "0_RX", "0_TX", + "1_CTS", "1_RTS", "1_RX", "1_TX", + "2_CTS", "2_RTS", "2_RX", "2_TX", +}; + +static void show_pinmux(const char *name, int i, int ofs) +{ + uint32_t sel = DIO_SEL_REG(i * 8 + ofs); + uint32_t ctl = DIO_CTL_REG(i * 8 + ofs); + + /* skip empty ones (ignoring drive strength bits) */ + if (sel == 0 && (ctl & (0xf << 2)) == 0) + return; + + ccprintf("%08x: %s%d %2d %s%s%s%s", + GC_PINMUX_BASE_ADDR + i * 8 + ofs, + name, i, sel, + (ctl & (1<<2)) ? " IN" : "", + (ctl & (1<<3)) ? " PD" : "", + (ctl & (1<<4)) ? " PU" : "", + (ctl & (1<<5)) ? " INV" : ""); + + if (sel >= 1 && sel <= 16) + ccprintf(" GPIO0_GPIO%d\n", sel - 1); + else if (sel >= 17 && sel <= 32) + ccprintf(" GPIO1_GPIO%d\n", sel - 17); + else if (sel >= 67 && sel <= 78) + ccprintf(" UART%s\n", uart_str[sel - 67]); + else + ccprintf("\n"); +} + +static void print_dio_str(uint32_t sel) +{ + if (sel >= 1 && sel <= 2) + ccprintf(" VIO%d\n", 2 - sel); + else if (sel >= 3 && sel <= 10) + ccprintf(" DIOB%d\n", 10 - sel); + else if (sel >= 11 && sel <= 25) + ccprintf(" DIOA%d\n", 25 - sel); + else if (sel >= 26 && sel <= 30) + ccprintf(" DIOM%d\n", 30 - sel); + else + ccprintf("\n"); +} + +static void show_pinmux_gpio(const char *name, int i, int ofs) +{ + uint32_t sel = DIO_SEL_REG(i * 4 + ofs); + + if (sel == 0) + return; + + ccprintf("%08x: %s%d %2d", + GC_PINMUX_BASE_ADDR + i * 4 + ofs, + name, i, sel); + print_dio_str(sel); +} + +static void show_pinmux_uart(int i) +{ + + uint32_t ofs = GC_PINMUX_UART0_CTS_SEL_OFFSET + i * 4; + uint32_t sel = DIO_SEL_REG(ofs); + + if (sel == 0) + return; + + ccprintf("%08x: UART%s %2d", + GC_PINMUX_BASE_ADDR + ofs, + uart_str[i], sel); + + print_dio_str(sel); +} + +static int command_pinmux(int argc, char **argv) +{ + int i; + + /* Pad sources */ + for (i = 0; i <= 4; i++) + show_pinmux("DIOM", i, 0x00); + for (i = 0; i <= 14; i++) + show_pinmux("DIOA", i, 0x28); + for (i = 0; i <= 7; i++) + show_pinmux("DIOB", i, 0xa0); + + ccprintf("\n"); + + /* GPIO & Peripheral sources */ + for (i = 0; i <= 15; i++) + show_pinmux_gpio("GPIO0_GPIO", i, 0xf8); + for (i = 0; i <= 15; i++) + show_pinmux_gpio("GPIO1_GPIO", i, 0x134); + + for (i = 0; i <= 11; i++) + show_pinmux_uart(i); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(pinmux, command_pinmux, + "", + "Display pinmux info", + NULL); + +static const char * const int_str[] = { + "LOW", "FALLING", "HIGH", "RISING", +}; + +static void show_gpiocfg(int n) +{ + uint32_t din = GR_GPIO_DATAIN(n); + uint32_t dout = GR_GPIO_DOUT(n); + uint32_t outen = GR_GPIO_SETDOUTEN(n); + uint32_t inten = GR_GPIO_SETINTEN(n); + uint32_t intpol = GR_GPIO_SETINTPOL(n); + uint32_t inttype = GR_GPIO_SETINTTYPE(n); + uint32_t mask; + int i, j; + + for (i = 0, mask = 0x1; i < 16; i++, mask <<= 1) { + /* Skip it unless it's an output or an interrupt */ + if (!((outen & mask) || (inten & mask))) + continue; + + ccprintf("GPIO%d_GPIO%d:\tread %d", n, i, !!(din & mask)); + if (outen & mask) + ccprintf(" drive %d", !!(dout & mask)); + if (inten & mask) { + j = ((intpol & mask) ? 2 : 0) + + ((inttype & mask) ? 1 : 0); + ccprintf(" INT_%s", int_str[j]); + } + ccprintf("\n"); + } +} + +static int command_gpiocfg(int argc, char **argv) +{ + show_gpiocfg(0); + show_gpiocfg(1); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(gpiocfg, command_gpiocfg, + "", + "Display GPIO configs", + NULL); |