mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
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>
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user