summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-02-23 17:37:17 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-02-27 00:38:19 -0800
commitb47c1fed2027c45f3062705e0ee9943601bdeba7 (patch)
treebba7dff9db8a49f92bdddf5881e960d49ab370e7
parent30585eb36ba41822d59c838eb721826473cbd443 (diff)
downloadchrome-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>
-rw-r--r--chip/g/gpio.c151
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);