summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Sanders <nsanders@chromium.org>2017-05-15 17:42:41 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-05-25 00:14:07 -0700
commit81b2654dc92b04750c2aa25e3ed9fed143c8d396 (patch)
treeba9c756f7c1a550f0528168da958d49bca9227a6
parentc78562ff602bd3026c02267650c020d61c87cee2 (diff)
downloadchrome-ec-81b2654dc92b04750c2aa25e3ed9fed143c8d396.tar.gz
mn50: socket controls
Add console and usb_spi commands to enable or disable IOs to the socket, so that it will not be powered if a chip is inserted, and control reset and boot_cfg. BUG=b:36910757 BRANCH=None TEST=Check no voltage when socket is disabled. Full spiflash compatibility. Change-Id: Ie4ce0613a868030833abfdccd827acce2753dc6f Reviewed-on: https://chromium-review.googlesource.com/509072 Commit-Ready: Nick Sanders <nsanders@chromium.org> Tested-by: Nick Sanders <nsanders@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/mn50/board.c110
-rw-r--r--board/mn50/board.h4
-rw-r--r--board/mn50/gpio.inc18
-rw-r--r--board/mn50/usb_spi.c29
-rw-r--r--chip/g/usb_spi.h3
5 files changed, 144 insertions, 20 deletions
diff --git a/board/mn50/board.c b/board/mn50/board.c
index 9833b48e62..0981a516ce 100644
--- a/board/mn50/board.c
+++ b/board/mn50/board.c
@@ -54,9 +54,11 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+/* Recall whether we have enable socket power. */
+static int socket_set_enabled;
/*****************************************************************************/
-/* */
+
#include "gpio.wrap"
static void init_interrupts(void)
@@ -119,6 +121,9 @@ static void board_init(void)
/* Initialize the persistent storage. */
initvars();
+ /* Disable all power to socket, for hot swapping. */
+ disable_socket();
+
/* Indication that firmware is running, for debug purposes. */
GREG32(PMU, PWRDN_SCRATCH16) = 0xCAFECAFE;
@@ -199,6 +204,107 @@ int flash_regions_to_enable(struct g_flash_region *regions,
return 3;
}
+/* Check if socket has been anabled and power is OK. */
+int is_socket_enabled(void)
+{
+ /* TODO: check voltage rails within approved bands. */
+ return (gpio_get_level(GPIO_DUT_PWRGOOD) && socket_set_enabled);
+}
+
+/* Determine whether the socket has no voltage. TODO: check GPIOS? */
+int is_socket_off(void)
+{
+ /* Check 3.3v = 0. */
+ if (ina2xx_get_voltage(1) > 10)
+ return 0;
+ /* Check 2.6v = 0. */
+ if (ina2xx_get_voltage(4) > 10)
+ return 0;
+ return 1;
+}
+
+void enable_socket(void)
+{
+ /* Power up. */
+ gpio_set_level(GPIO_DUT_PWR_EN, 1);
+
+ /* Indicate socket powered with red LED. */
+ gpio_set_level(GPIO_LED_L, 0);
+
+ /* GPIOs as ioutputs. */
+ gpio_set_flags(GPIO_DUT_RST_L, GPIO_OUT_LOW);
+ gpio_set_flags(GPIO_DUT_BOOT_CFG, GPIO_OUT_LOW);
+ gpio_set_flags(GPIO_SPI_CS_ALT_L, GPIO_OUT_HIGH);
+
+ /* Connect DIO A4, A8 to the SPI peripheral */
+ GWRITE(PINMUX, DIOA4_SEL, 0); /* SPI_MOSI */
+ GWRITE(PINMUX, DIOA8_SEL, 0); /* SPI_CLK */
+ GWRITE(PINMUX, DIOA5_SEL, GC_PINMUX_GPIO0_GPIO10_SEL);
+
+ /* UART */
+ GWRITE(PINMUX, DIOA7_SEL, GC_PINMUX_UART1_TX_SEL);
+
+ /* Chip select. */
+ GWRITE_FIELD(PINMUX, DIOA5_CTL, PU, 1);
+
+ socket_set_enabled = 1;
+}
+
+void disable_socket(void)
+{
+ /* Disable CS pin. */
+ GWRITE_FIELD(PINMUX, DIOA5_CTL, PU, 0);
+
+ /* TODO: Implement way to get the gpio */
+ ASSERT(GREAD(PINMUX, GPIO0_GPIO7_SEL) == GC_PINMUX_DIOA4_SEL);
+ ASSERT(GREAD(PINMUX, GPIO0_GPIO8_SEL) == GC_PINMUX_DIOA8_SEL);
+ ASSERT(GREAD(PINMUX, GPIO0_GPIO10_SEL) == GC_PINMUX_DIOA5_SEL);
+
+ /* Set SPI MOSI, CLK, and CS_L as inputs */
+ GWRITE(PINMUX, DIOA4_SEL, GC_PINMUX_GPIO0_GPIO7_SEL);
+ GWRITE(PINMUX, DIOA8_SEL, GC_PINMUX_GPIO0_GPIO8_SEL);
+ GWRITE(PINMUX, DIOA5_SEL, GC_PINMUX_GPIO0_GPIO10_SEL);
+
+ /* UART */
+ GWRITE(PINMUX, DIOA7_SEL, 0);
+
+ /* GPIOs as inputs. */
+ gpio_set_flags(GPIO_DUT_BOOT_CFG, GPIO_INPUT);
+ gpio_set_flags(GPIO_DUT_RST_L, GPIO_INPUT);
+ gpio_set_flags(GPIO_SPI_CS_ALT_L, GPIO_INPUT);
+
+ /* Turn off socket power. */
+ gpio_set_level(GPIO_DUT_PWR_EN, 0);
+
+ /* Indicate socket unpowered with no red LED. */
+ gpio_set_level(GPIO_LED_L, 1);
+ socket_set_enabled = 0;
+}
+
+static int command_socket(int argc, char **argv)
+{
+ if (argc > 1) {
+ if (!strcasecmp("enable", argv[1]))
+ enable_socket();
+ else if (!strcasecmp("disable", argv[1]))
+ disable_socket();
+ else
+ return EC_ERROR_PARAM1;
+
+ /* Let power settle. */
+ msleep(5);
+ }
+
+ ccprintf("Socket enabled: %s, powered: %s\n",
+ is_socket_enabled() ? "yes" : "no",
+ is_socket_off() ? "off" : "on");
+ return EC_SUCCESS;
+}
+DECLARE_SAFE_CONSOLE_COMMAND(socket, command_socket,
+ "[enable|disable]",
+ "Activate and deactivate socket");
+
+
/* Determine key type based on the key ID. */
static const char *key_type(uint32_t key_id)
@@ -227,7 +333,7 @@ static int command_sysinfo(int argc, char **argv)
system_print_reset_flags();
ccprintf(")\n");
- ccprintf("Chip: %s %s %s\n", system_get_chip_vendor(),
+ ccprintf("Chip: %s %s %s\n", system_get_chip_vendor(),
system_get_chip_name(), system_get_chip_revision());
active = system_get_ro_image_copy();
diff --git a/board/mn50/board.h b/board/mn50/board.h
index 92b92c877b..2037fd8e5b 100644
--- a/board/mn50/board.h
+++ b/board/mn50/board.h
@@ -127,6 +127,10 @@ enum usb_strings {
void post_reboot_request(void);
void ccd_force_enable(void);
+void disable_socket(void);
+void enable_socket(void);
+int is_socket_enabled(void);
+int is_socket_off(void);
#endif /* !__ASSEMBLER__ */
diff --git a/board/mn50/gpio.inc b/board/mn50/gpio.inc
index fd40d34026..069d57bcfb 100644
--- a/board/mn50/gpio.inc
+++ b/board/mn50/gpio.inc
@@ -46,10 +46,11 @@
/* Use these to reset/flash the DUT haven */
-GPIO(DUT_BOOT_CFG, PIN(0, 0), GPIO_OUT_LOW) /* DIOB2 */
-GPIO(DUT_RST_L, PIN(0, 1), GPIO_ODR_LOW) /* DIOB3 */
GPIO(DUT_PWR_EN, PIN(0, 2), GPIO_OUT_LOW) /* DIOB5 */
GPIO(DUT_PWRGOOD, PIN(0, 3), GPIO_INPUT) /* DIOB7 */
+/* These GPIOS are switched between input/output by socket enable. */
+GPIO(DUT_BOOT_CFG, PIN(0, 0), GPIO_OUT_LOW) /* DIOB2 */
+GPIO(DUT_RST_L, PIN(0, 1), GPIO_OUT_LOW) /* DIOB3 */
GPIO(LED_B_L, PIN(0, 4), GPIO_ODR_HIGH) /* DIOA9 */
GPIO(LED_R_L, PIN(0, 5), GPIO_ODR_HIGH) /* DIOA13 */
@@ -60,7 +61,7 @@ GPIO(LED_L, PIN(0, 11), GPIO_ODR_HIGH) /* DIOB6 */
GPIO(SPI_MOSI, PIN(0, 7), GPIO_INPUT) /* DIOA4 */
GPIO(SPI_CLK, PIN(0, 8), GPIO_INPUT) /* DIOA8 */
GPIO(SPI_CS_L, PIN(0, 9), GPIO_INPUT) /* DIOA14 */
-GPIO(SPI_CS_ALT_L, PIN(0, 10), GPIO_OUT_HIGH) /* DIOA5 */
+GPIO(SPI_CS_ALT_L, PIN(0, 10), GPIO_INPUT) /* DIOA5 */
/* Unimplemented signals which we need to emulate for now */
/* TODO(wfrichar): Half the boards don't use this signal. Take it out. */
@@ -90,7 +91,14 @@ PINMUX(GPIO(LED_L), B6, DIO_INPUT)
PINMUX(FUNC(UART0_TX), A0, DIO_OUTPUT) /* Cr50 console */
PINMUX(FUNC(UART0_RX), A1, DIO_INPUT | DIO_WAKE_LOW)
-PINMUX(FUNC(UART1_TX), A7, DIO_OUTPUT) /* DUT console */
+/*
+ * UART1_TX will be enabled when the socket power is enabled,
+ * to prevent backpowering.
+ *
+ * PINMUX(FUNC(UART1_TX), A7, DIO_OUTPUT)
+ */
+
+/* DUT console */
PINMUX(FUNC(UART1_RX), A3, DIO_INPUT)
/* I2C setup */
@@ -111,6 +119,6 @@ PINMUX(FUNC(I2C0_SDA), B1, DIO_INPUT | DIO_OUTPUT)
*/
PINMUX(GPIO(SPI_MOSI), A4, DIO_OUTPUT)
PINMUX(GPIO(SPI_CLK), A8, DIO_OUTPUT)
-PINMUX(GPIO(SPI_CS_ALT_L), A5, DIO_INPUT)
+PINMUX(GPIO(SPI_CS_ALT_L), A5, DIO_OUTPUT)
#undef PINMUX
diff --git a/board/mn50/usb_spi.c b/board/mn50/usb_spi.c
index 48f4728a34..9dffeeae99 100644
--- a/board/mn50/usb_spi.c
+++ b/board/mn50/usb_spi.c
@@ -16,10 +16,6 @@
int usb_spi_board_enable(struct usb_spi_config const *config)
{
- /* Connect DIO A4, A8, and A14 to the SPI peripheral */
- GWRITE(PINMUX, DIOA4_SEL, 0); /* SPI_MOSI */
- GWRITE(PINMUX, DIOA8_SEL, 0); /* SPI_CLK */
-
spi_enable(CONFIG_SPI_FLASH_PORT, 1);
/* Enable SPI framing for H1 bootloader */
@@ -34,14 +30,6 @@ void usb_spi_board_disable(struct usb_spi_config const *config)
gpio_set_level(GPIO_SPI_CS_ALT_L, 1);
spi_enable(CONFIG_SPI_FLASH_PORT, 0);
-
- /* Disconnect SPI peripheral to tri-state pads */
- ASSERT(GREAD(PINMUX, GPIO0_GPIO7_SEL) == GC_PINMUX_DIOA4_SEL);
- ASSERT(GREAD(PINMUX, GPIO0_GPIO8_SEL) == GC_PINMUX_DIOA8_SEL);
-
- /* Set SPI MOSI, CLK as inputs */
- GWRITE(PINMUX, DIOA4_SEL, GC_PINMUX_GPIO0_GPIO7_SEL);
- GWRITE(PINMUX, DIOA8_SEL, GC_PINMUX_GPIO0_GPIO8_SEL);
}
int usb_spi_interface(struct usb_spi_config const *config,
@@ -52,7 +40,7 @@ int usb_spi_interface(struct usb_spi_config const *config,
USB_RECIP_INTERFACE))
return 1;
- if (req->wValue != 0 ||
+ if ((req->wValue != 0 && req->wValue != 1) ||
req->wIndex != config->interface ||
req->wLength != 0)
return 1;
@@ -64,6 +52,21 @@ int usb_spi_interface(struct usb_spi_config const *config,
case USB_SPI_REQ_ENABLE_H1:
config->state->enabled_host = USB_SPI_H1;
break;
+
+ /* Set reset and DFU pins. Both active high. */
+ case USB_SPI_REQ_RESET:
+ gpio_set_level(GPIO_DUT_RST_L, !req->wValue);
+ break;
+ case USB_SPI_REQ_BOOT_CFG:
+ gpio_set_level(GPIO_DUT_BOOT_CFG, req->wValue);
+ break;
+ /* Set socket power. */
+ case USB_SPI_REQ_SOCKET:
+ if (req->wValue)
+ enable_socket();
+ else
+ disable_socket();
+ break;
case USB_SPI_REQ_ENABLE_AP:
case USB_SPI_REQ_ENABLE:
CPRINTS("ERROR: Must specify target");
diff --git a/chip/g/usb_spi.h b/chip/g/usb_spi.h
index bdd4fbcd24..2240999950 100644
--- a/chip/g/usb_spi.h
+++ b/chip/g/usb_spi.h
@@ -67,6 +67,9 @@ enum usb_spi_request {
USB_SPI_REQ_ENABLE_AP = 0x0002,
USB_SPI_REQ_ENABLE_EC = 0x0003,
USB_SPI_REQ_ENABLE_H1 = 0x0004,
+ USB_SPI_REQ_RESET = 0x0005,
+ USB_SPI_REQ_BOOT_CFG = 0x0006,
+ USB_SPI_REQ_SOCKET = 0x0007,
};
/* USB SPI device indexes */