summaryrefslogtreecommitdiff
path: root/board/c2d2/board.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /board/c2d2/board.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14336.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'board/c2d2/board.c')
-rw-r--r--board/c2d2/board.c1095
1 files changed, 0 insertions, 1095 deletions
diff --git a/board/c2d2/board.c b/board/c2d2/board.c
deleted file mode 100644
index 3327ea43b6..0000000000
--- a/board/c2d2/board.c
+++ /dev/null
@@ -1,1095 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/* C2D2 debug device board configuration */
-
-#include "adc.h"
-#include "common.h"
-#include "console.h"
-#include "ec_version.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "i2c_ite_flash_support.h"
-#include "queue_policies.h"
-#include "registers.h"
-#include "spi.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "update_fw.h"
-#include "usart_rx_dma.h"
-#include "usart_tx_dma.h"
-#include "usart-stm32f0.h"
-#include "usb_hw.h"
-#include "usb_i2c.h"
-#include "usb_spi.h"
-#include "usb-stream.h"
-#include "util.h"
-
-#include "gpio_list.h"
-
-#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
-
-/* Forward declarations */
-static void update_vrefs_and_shifters(void);
-DECLARE_DEFERRED(update_vrefs_and_shifters);
-static bool is_ec_i2c_enabled(void);
-
-/* Global state tracking current pin configuration and operations */
-static struct mutex vref_bus_state_mutex;
-static int vref_monitor_disable;
-#define VREF_MON_DIS_H1_RST_HELD BIT(0)
-#define VREF_MON_DIS_EC_PWR_HELD BIT(1)
-#define VREF_MON_DIS_SPI_MODE BIT(2)
-
-/*
- * Tracks if bus pins are locked by a function like UART holding, I2C,
- * or SPI.
- */
-enum bus_lock {
- BUS_UNLOCKED, /* Normal UART; pins available for other functions */
- BUS_UART_HELD, /* UART locked to pins while holding RX low */
- BUS_SPI, /* SPI locked to pins */
- BUS_I2C, /* I2C bus locked to pins */
-};
-/* A0/A1 (H1 UART or SPI) */
-enum bus_lock h1_pins;
-/* B6/B7 (EC UART, EC I2C, or SPI) */
-enum bus_lock ec_pins;
-/* B10/B11 (AP UART, AUX I2C) */
-enum bus_lock ap_pins;
-
-static const char *lock_to_string(const enum bus_lock val)
-{
- static const char *const names[] = {
- [BUS_UNLOCKED] = "UART",
- [BUS_UART_HELD] = "UART HELD",
- [BUS_SPI] = "SPI",
- [BUS_I2C] = "I2C",
- };
-
- if (val < 0 || val >= ARRAY_SIZE(names))
- return "UNKNOWN";
-
- return names[val];
-}
-
-static int command_bus_status(int argc, char **argv)
-{
- if (argc > 1)
- return EC_ERROR_PARAM_COUNT;
-
- ccprintf("H1 pins: %s\n", lock_to_string(h1_pins));
- ccprintf("EC pins: %s\n", lock_to_string(ec_pins));
- ccprintf("AP pins: %s\n", lock_to_string(ap_pins));
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(bus_status, command_bus_status,
- "",
- "Gets the bus state for swappable pins");
-
-
-/******************************************************************************
- ** Chip-specific board configuration
- */
-void board_config_pre_init(void)
-{
- /* enable SYSCFG & COMP clock */
- STM32_RCC_APB2ENR |= STM32_RCC_SYSCFGEN;
-
- /* enable DAC for comparator input */
- STM32_RCC_APB1ENR |= STM32_RCC_DACEN;
-
- /*
- * the DMA mapping is :
- * Chan 3 : USART3_RX
- * Chan 5 : USART1_RX
- * Chan 6 : SPI2_RX
- * Chan 7 : SPI2_TX
- *
- * i2c : no dma
- * tim16/17: no dma
- */
- STM32_SYSCFG_CFGR1 |= BIT(24); /* Remap SPI2_RX to channel 6 */
- STM32_SYSCFG_CFGR1 |= BIT(26); /* Remap USART3 RX/TX DMA */
- STM32_SYSCFG_CFGR1 |= BIT(10); /* Remap USART1 RX/TX DMA */
-}
-
-
-/******************************************************************************
- ** ADC channels
- */
-const struct adc_t adc_channels[] = {
- /* Sensing the H1's voltage at the DUT side. Converted to mV. */
- [ADC_H1_SPI_VREF] = {
- .name = "H1_VREF",
- .factor_mul = 3300,
- .factor_div = 4096,
- .shift = 0,
- .channel = STM32_AIN(3),
- },
- /* Sensing the EC's voltage at the DUT side. Converted to mV. */
- [ADC_EC_SPI_VREF] = {
- .name = "EC_VREF",
- .factor_mul = 3300,
- .factor_div = 4096,
- .shift = 0,
- .channel = STM32_AIN(4),
- }
-};
-BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
-
-/******************************************************************************
- * Define the strings used in our USB descriptors.
- */
-const void *const usb_strings[] = {
- [USB_STR_DESC] = usb_string_desc,
- [USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."),
- [USB_STR_PRODUCT] = USB_STRING_DESC("C2D2"),
- [USB_STR_SERIALNO] = 0,
- [USB_STR_VERSION] = USB_STRING_DESC(CROS_EC_VERSION32),
- [USB_STR_USART4_STREAM_NAME] = USB_STRING_DESC("CR50"),
- [USB_STR_UPDATE_NAME] = USB_STRING_DESC("Firmware update"),
- [USB_STR_CONSOLE_NAME] = USB_STRING_DESC("C2D2 Shell"),
- [USB_STR_I2C_NAME] = USB_STRING_DESC("I2C"),
- [USB_STR_USART3_STREAM_NAME] = USB_STRING_DESC("CPU"),
- [USB_STR_USART1_STREAM_NAME] = USB_STRING_DESC("EC"),
-};
-
-BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT);
-
-/******************************************************************************
- * Support I2C bridging over USB.
- */
-
-/* I2C ports */
-const struct i2c_port_t i2c_ports[] = {
- {
- .name = "ec",
- .port = I2C_PORT_EC,
- .kbps = 100,
- .scl = GPIO_UART_DBG_TX_EC_RX_SCL,
- .sda = GPIO_UART_EC_TX_DBG_RX_SDA,
- .flags = I2C_PORT_FLAG_DYNAMIC_SPEED,
- },
- {
- .name = "aux",
- .port = I2C_PORT_AUX,
- .kbps = 100,
- .scl = GPIO_UART_DBG_TX_AP_RX_INA_SCL,
- .sda = GPIO_UART_AP_TX_DBG_RX_INA_SDA,
- .flags = I2C_PORT_FLAG_DYNAMIC_SPEED,
- },
-};
-const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
-
-/* Configure ITE flash support module */
-const struct ite_dfu_config_t ite_dfu_config = {
- .i2c_port = I2C_PORT_EC,
- /* PB6/7 are connected to complement outputs of TIM16/17 */
- .use_complement_timer_channel = true,
- .access_allow = &is_ec_i2c_enabled,
- .scl = GPIO_UART_DBG_TX_EC_RX_SCL,
- .sda = GPIO_UART_EC_TX_DBG_RX_SDA,
-};
-
-/*
- * I2C is always enabled, but the i2c pins may not be muxed to DUT. We will
- * let the i2c transactions fail instead of using the USB endpoint disable
- * status.
- */
-int usb_i2c_board_is_enabled(void) { return 1; }
-
-/******************************************************************************
- * Forward UARTs as a USB serial interface.
- */
-
-#define USB_STREAM_RX_SIZE 32
-#define USB_STREAM_TX_SIZE 64
-
-/******************************************************************************
- * Forward USART1 (EC) as a simple USB serial interface.
- */
-
-static struct usart_config const usart1;
-struct usb_stream_config const usart1_usb;
-
-static struct queue const usart1_to_usb = QUEUE_DIRECT(128, uint8_t,
- usart1.producer, usart1_usb.consumer);
-static struct queue const usb_to_usart1 = QUEUE_DIRECT(64, uint8_t,
- usart1_usb.producer, usart1.consumer);
-
-static struct usart_rx_dma const usart1_rx_dma =
- USART_RX_DMA(STM32_DMAC_CH5, 32);
-
-static struct usart_config const usart1 =
- USART_CONFIG(usart1_hw,
- usart1_rx_dma.usart_rx,
- usart_tx_interrupt,
- 115200,
- 0,
- usart1_to_usb,
- usb_to_usart1);
-
-USB_STREAM_CONFIG_USART_IFACE(usart1_usb,
- USB_IFACE_USART1_STREAM,
- USB_STR_USART1_STREAM_NAME,
- USB_EP_USART1_STREAM,
- USB_STREAM_RX_SIZE,
- USB_STREAM_TX_SIZE,
- usb_to_usart1,
- usart1_to_usb,
- usart1)
-
-
-/******************************************************************************
- * Forward USART3 (CPU) as a simple USB serial interface.
- */
-
-static struct usart_config const usart3;
-struct usb_stream_config const usart3_usb;
-
-static struct queue const usart3_to_usb = QUEUE_DIRECT(1024, uint8_t,
- usart3.producer, usart3_usb.consumer);
-static struct queue const usb_to_usart3 = QUEUE_DIRECT(64, uint8_t,
- usart3_usb.producer, usart3.consumer);
-
-static struct usart_rx_dma const usart3_rx_dma =
- USART_RX_DMA(STM32_DMAC_CH3, 32);
-
-static struct usart_config const usart3 =
- USART_CONFIG(usart3_hw,
- usart3_rx_dma.usart_rx,
- usart_tx_interrupt,
- 115200,
- 0,
- usart3_to_usb,
- usb_to_usart3);
-
-USB_STREAM_CONFIG_USART_IFACE(usart3_usb,
- USB_IFACE_USART3_STREAM,
- USB_STR_USART3_STREAM_NAME,
- USB_EP_USART3_STREAM,
- USB_STREAM_RX_SIZE,
- USB_STREAM_TX_SIZE,
- usb_to_usart3,
- usart3_to_usb,
- usart3)
-
-
-/******************************************************************************
- * Forward USART4 (cr50) as a simple USB serial interface.
- *
- * We do not try to share DMA channel 6 with SPI2, so just use interrupts
- */
-
-static struct usart_config const usart4;
-struct usb_stream_config const usart4_usb;
-
-static struct queue const usart4_to_usb = QUEUE_DIRECT(1024, uint8_t,
- usart4.producer, usart4_usb.consumer);
-static struct queue const usb_to_usart4 = QUEUE_DIRECT(64, uint8_t,
- usart4_usb.producer, usart4.consumer);
-
-static struct usart_config const usart4 =
- USART_CONFIG(usart4_hw,
- usart_rx_interrupt,
- usart_tx_interrupt,
- 115200,
- 0,
- usart4_to_usb,
- usb_to_usart4);
-
-USB_STREAM_CONFIG_USART_IFACE(usart4_usb,
- USB_IFACE_USART4_STREAM,
- USB_STR_USART4_STREAM_NAME,
- USB_EP_USART4_STREAM,
- USB_STREAM_RX_SIZE,
- USB_STREAM_TX_SIZE,
- usb_to_usart4,
- usart4_to_usb,
- usart4)
-
-/******************************************************************************
- * Set up SPI over USB
- * Notes DMA Channel 6 is shared and mutually exclusive with USART4 RX
- */
-
-/* SPI devices */
-const struct spi_device_t spi_devices[] = {
- { CONFIG_SPI_FLASH_PORT, 1, GPIO_SPI_CSN},
-};
-const unsigned int spi_devices_used = ARRAY_SIZE(spi_devices);
-
-void usb_spi_board_enable(struct usb_spi_config const *config)
-{
- /* Configure SPI GPIOs */
- gpio_config_module(MODULE_SPI_FLASH, 1);
-
- /* Set all four SPI pins to high speed */
- STM32_GPIO_OSPEEDR(GPIO_B) |= 0xff000000;
-
- /* Enable clocks to SPI2 module */
- STM32_RCC_APB1ENR |= STM32_RCC_PB1_SPI2;
-
- /* Reset SPI2 */
- STM32_RCC_APB1RSTR |= STM32_RCC_PB1_SPI2;
- STM32_RCC_APB1RSTR &= ~STM32_RCC_PB1_SPI2;
-
- spi_enable(&spi_devices[0], 1);
-}
-
-void usb_spi_board_disable(struct usb_spi_config const *config)
-{
- spi_enable(&spi_devices[0], 0);
-
- /* Disable clocks to SPI2 module */
- STM32_RCC_APB1ENR &= ~STM32_RCC_PB1_SPI2;
-
- /* Release SPI GPIOs */
- gpio_config_module(MODULE_SPI_FLASH, 0);
-
- /* Reset all four SPI pins to low speed */
- STM32_GPIO_OSPEEDR(GPIO_B) &= ~0xff000000;
-}
-
-USB_SPI_CONFIG(usb_spi, USB_IFACE_SPI, USB_EP_SPI,
- USB_SPI_CONFIG_FLAGS_IGNORE_HOST_SIDE_ENABLE);
-
-/******************************************************************************
- * Check parity setting on usarts.
- */
-static int command_uart_parity(int argc, char **argv)
-{
- int parity = 0, newparity;
- struct usart_config const *usart;
- char *e;
-
- if ((argc < 2) || (argc > 3))
- return EC_ERROR_PARAM_COUNT;
-
- if (!strcasecmp(argv[1], "usart1"))
- usart = &usart1;
- else if (!strcasecmp(argv[1], "usart3"))
- usart = &usart3;
- else if (!strcasecmp(argv[1], "usart4"))
- usart = &usart4;
- else
- return EC_ERROR_PARAM1;
-
- if (argc == 3) {
- parity = strtoi(argv[2], &e, 0);
- if (*e || (parity < 0) || (parity > 2))
- return EC_ERROR_PARAM2;
-
- usart_set_parity(usart, parity);
- }
-
- newparity = usart_get_parity(usart);
- ccprintf("Parity on %s is %d.\n", argv[1], newparity);
-
- if ((argc == 3) && (newparity != parity))
- return EC_ERROR_UNKNOWN;
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(parity, command_uart_parity,
- "usart[2|3|4] [0|1|2]",
- "Set parity on uart");
-
-/******************************************************************************
- * Set baud rate setting on usarts.
- */
-static int command_uart_baud(int argc, char **argv)
-{
- int baud = 0;
- struct usart_config const *usart;
- char *e;
-
- if ((argc < 2) || (argc > 3))
- return EC_ERROR_PARAM_COUNT;
-
- if (!strcasecmp(argv[1], "usart1"))
- usart = &usart1;
- else if (!strcasecmp(argv[1], "usart3"))
- usart = &usart3;
- else if (!strcasecmp(argv[1], "usart4"))
- usart = &usart4;
- else
- return EC_ERROR_PARAM1;
-
- baud = strtoi(argv[2], &e, 0);
- if (*e || baud < 0)
- return EC_ERROR_PARAM2;
-
- usart_set_baud(usart, baud);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(baud, command_uart_baud,
- "usart[2|3|4] rate",
- "Set baud rate on uart");
-
-/******************************************************************************
- * Hold the usart pins low while disabling it, or return it to normal.
- */
-static int command_hold_usart_low(int argc, char **argv)
-{
- enum bus_lock *bus;
- enum gpio_signal rx;
-
- if (argc > 3 || argc < 2)
- return EC_ERROR_PARAM_COUNT;
-
- if (!strcasecmp(argv[1], "usart1")) {
- bus = &ec_pins;
- rx = GPIO_UART_EC_TX_DBG_RX_SDA;
- } else if (!strcasecmp(argv[1], "usart3")) {
- bus = &ap_pins;
- rx = GPIO_UART_AP_TX_DBG_RX_INA_SDA;
- } else if (!strcasecmp(argv[1], "usart4")) {
- bus = &h1_pins;
- rx = GPIO_UART_H1_TX_DBG_RX;
- } else {
- return EC_ERROR_PARAM1;
- }
-
- /* Updating the status of this port */
- if (argc == 3) {
- char *e;
- const int hold_low = strtoi(argv[2], &e, 0);
-
- if (*e || (hold_low < 0) || (hold_low > 1))
- return EC_ERROR_PARAM2;
-
- mutex_lock(&vref_bus_state_mutex);
-
- if (hold_low && *bus != BUS_UART_HELD) {
- /* Ensure no other use of these pins */
- if (*bus != BUS_UNLOCKED) {
- ccprintf("Cannot hold low! Pins busy: %s.\n",
- lock_to_string(*bus));
- goto busy_error_unlock;
- }
-
- /*
- * No need to shutdown UART, just de-mux the RX pin from
- * UART and change it to a GPIO temporarily
- */
- gpio_config_pin(MODULE_USART, rx, 0);
- gpio_set_flags(rx, GPIO_OUT_LOW);
-
- /* Update global uart state */
- *bus = BUS_UART_HELD;
- } else if (!hold_low && *bus == BUS_UART_HELD) {
- /*
- * Mux the RX pin back to GPIO mode
- */
- gpio_config_pin(MODULE_USART, rx, 1);
-
- /* Update global uart state */
- *bus = BUS_UNLOCKED;
- }
-
- mutex_unlock(&vref_bus_state_mutex);
- }
-
- /* Print status for get and set case. */
- ccprintf("USART status: %s\n",
- *bus == BUS_UART_HELD ? "held low" : "normal");
-
- return EC_SUCCESS;
-
-busy_error_unlock:
- mutex_unlock(&vref_bus_state_mutex);
- return EC_ERROR_BUSY;
-}
-DECLARE_CONSOLE_COMMAND(hold_usart_low, command_hold_usart_low,
- "usart[1|3|4] [0|1]?",
- "Get/set the hold-low state for usart port");
-
-
-/******************************************************************************
- * Console commands SPI programming
- */
-enum vref {
- OFF = 0,
- PP1800 = 1800,
- PP3300 = 3300,
-};
-
-static int command_enable_spi(int argc, char **argv)
-{
- static enum vref current_spi_vref_state;
-
- if (argc > 2)
- return EC_ERROR_PARAM_COUNT;
-
- /* Updating the state */
- if (argc == 2) {
- int i;
- char *e;
- const enum vref spi_vref = strtoi(argv[1], &e, 0);
- const enum gpio_signal uart_pins[] = {
- GPIO_UART_DBG_TX_H1_RX,
- GPIO_UART_H1_TX_DBG_RX,
- GPIO_UART_DBG_TX_EC_RX_SCL,
- GPIO_UART_EC_TX_DBG_RX_SDA,
- };
-
- if (*e)
- return EC_ERROR_PARAM1;
- if (spi_vref != OFF && spi_vref != PP1800 && spi_vref != PP3300)
- return EC_ERROR_PARAM1;
-
- mutex_lock(&vref_bus_state_mutex);
-
- if (vref_monitor_disable & ~VREF_MON_DIS_SPI_MODE) {
- ccprintf("Cannot update SPI with reset held.\n");
- goto busy_error_unlock;
- }
-
- if (current_spi_vref_state == spi_vref) {
- /* No change, do nothing */
- } else if (spi_vref == OFF) {
- /* We are transitioning from SPI to UART mode: */
- /* Disable level shifter pass through */
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, 0);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, 0);
-
- /* Disable SPI. Sets SPI pins to inputs. */
- usb_spi_enable(&usb_spi, 0);
-
- /* Set default state for chip select */
- gpio_set_flags(GPIO_SPI_CSN, GPIO_INPUT);
-
- /* Re-enable all UARTs pins we used. */
- for (i = 0; i < ARRAY_SIZE(uart_pins); ++i)
- gpio_config_pin(MODULE_USART, uart_pins[i], 1);
-
- /* Ensure DUT's muxes are switched to UART mode */
- gpio_set_level(GPIO_C2D2_MUX_UART_ODL, 0);
-
- /* Update state and defer Vrefs update */
- h1_pins = BUS_UNLOCKED;
- ec_pins = BUS_UNLOCKED;
- vref_monitor_disable &= ~VREF_MON_DIS_SPI_MODE;
- hook_call_deferred(&update_vrefs_and_shifters_data, 0);
- } else if (vref_monitor_disable & VREF_MON_DIS_SPI_MODE) {
- /* We are just changing voltages */
- gpio_set_level(GPIO_SEL_SPIVREF_H1VREF_3V3,
- spi_vref == PP3300);
- gpio_set_level(GPIO_SEL_SPIVREF_ECVREF_3V3,
- spi_vref == PP3300);
- } else {
- /* Ensure no other use of these pins */
- if (h1_pins != BUS_UNLOCKED ||
- ec_pins != BUS_UNLOCKED) {
- ccprintf(
- "Cannot enter SPI! H1 pins: %s; EC pins: %s.\n",
- lock_to_string(h1_pins),
- lock_to_string(ec_pins));
- goto busy_error_unlock;
- }
-
- /* We are transitioning from UART to SPI mode: */
- /* Turn off comparator interrupt for Vref detection */
- STM32_EXTI_IMR &= ~EXTI_COMP2_EVENT;
-
- /* Disable level shifters to avoid glitching output */
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, 0);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, 0);
-
- /*
- * De-select UART on all UARTs pins we are using to
- * avoid drive fights with SPI pins.
- */
- for (i = 0; i < ARRAY_SIZE(uart_pins); ++i)
- gpio_config_pin(MODULE_USART, uart_pins[i], 0);
-
- /* Set default state for chip select */
- gpio_set_flags(GPIO_SPI_CSN, GPIO_OUT_HIGH);
-
- /* Enable SPI. Sets SPI pins to SPI alternate mode. */
- usb_spi_enable(&usb_spi, 1);
-
- /* Set requested Vref voltage */
- gpio_set_level(GPIO_SEL_SPIVREF_H1VREF_3V3,
- spi_vref == PP3300);
- gpio_set_level(GPIO_SEL_SPIVREF_ECVREF_3V3,
- spi_vref == PP3300);
-
- /* Ensure DUT's muxes are switched to SPI mode */
- gpio_set_level(GPIO_C2D2_MUX_UART_ODL, 1);
-
- /* Enable level shifters passthrough */
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, 1);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, 1);
-
- h1_pins = BUS_SPI;
- ec_pins = BUS_SPI;
- vref_monitor_disable |= VREF_MON_DIS_SPI_MODE;
- }
-
- current_spi_vref_state = spi_vref;
-
- mutex_unlock(&vref_bus_state_mutex);
- }
-
- /* Print status for get and set case. */
- ccprintf("SPI Vref: %d\n", current_spi_vref_state);
-
- return EC_SUCCESS;
-
-busy_error_unlock:
- mutex_unlock(&vref_bus_state_mutex);
- return EC_ERROR_BUSY;
-}
-DECLARE_CONSOLE_COMMAND(enable_spi, command_enable_spi,
- "[0|1800|3300]?",
- "Get/set the SPI Vref");
-
-/******************************************************************************
- * Console commands I2c programming mode
- */
-static bool is_ec_i2c_enabled(void)
-{
- return ec_pins == BUS_I2C;
-}
-
-static inline enum i2c_freq to_i2c_freq(int kbps)
-{
- switch (kbps) {
- case 400:
- return I2C_FREQ_400KHZ;
- case 1000:
- return I2C_FREQ_1000KHZ;
- default:
- return I2C_FREQ_100KHZ;
- }
-}
-
-static inline int to_kbps(enum i2c_freq freq)
-{
- switch (freq) {
- case I2C_FREQ_400KHZ:
- return 400;
- case I2C_FREQ_1000KHZ:
- return 1000;
- default:
- return 100;
- }
-}
-
-static int command_enable_i2c(int argc, char **argv)
-{
- int i2c_index;
- enum bus_lock *bus;
- enum gpio_signal sda, scl;
-
- if (argc > 3 || argc < 2)
- return EC_ERROR_PARAM_COUNT;
-
- if (!strcasecmp(argv[1], "ec")) {
- bus = &ec_pins;
- i2c_index = I2C_PORT_EC;
- sda = GPIO_UART_EC_TX_DBG_RX_SDA;
- scl = GPIO_UART_DBG_TX_EC_RX_SCL;
-
- } else if (!strcasecmp(argv[1], "ap")) {
- bus = &ap_pins;
- i2c_index = I2C_PORT_AUX;
- sda = GPIO_UART_AP_TX_DBG_RX_INA_SDA;
- scl = GPIO_UART_DBG_TX_AP_RX_INA_SCL;
- } else {
- return EC_ERROR_PARAM1;
- }
-
- /* Updating the state */
- if (argc == 3) {
- char *e;
- const int speed = strtoi(argv[2], &e, 0);
-
- if (*e)
- return EC_ERROR_PARAM2;
- if (speed != 0 && speed != 100 && speed != 400 && speed != 1000)
- return EC_ERROR_PARAM2;
-
- mutex_lock(&vref_bus_state_mutex);
-
- if (speed != 0 && *bus != BUS_I2C) {
- /* Ensure no other use of these pins */
- if (*bus != BUS_UNLOCKED) {
- ccprintf("Cannot enable i2c! Pin busy: %s.\n",
- lock_to_string(*bus));
- goto busy_error_unlock;
- }
-
- /* Change alternate mode to I2C */
- gpio_config_pin(MODULE_I2C, sda, 1);
- gpio_config_pin(MODULE_I2C, scl, 1);
-
- /* Update state */
- *bus = BUS_I2C;
- } else if (speed == 0 && *bus == BUS_I2C) {
- /* Update back to default UART mode */
- gpio_config_pin(MODULE_USART, sda, 1);
- gpio_config_pin(MODULE_USART, scl, 1);
-
- /* Update state */
- *bus = BUS_UNLOCKED;
- }
-
- mutex_unlock(&vref_bus_state_mutex);
-
- /* If we have a non-zero speed, then set frequency */
- if (speed)
- i2c_set_freq(i2c_index, to_i2c_freq(speed));
- }
-
- /* Print status for get and set case. */
- ccprintf("I2C speed kbps: %d\n",
- *bus == BUS_I2C ? to_kbps(i2c_get_freq(i2c_index)) : 0);
-
- return EC_SUCCESS;
-
-busy_error_unlock:
- mutex_unlock(&vref_bus_state_mutex);
- return EC_ERROR_BUSY;
-}
-DECLARE_CONSOLE_COMMAND(enable_i2c, command_enable_i2c,
- "[ec|ap] [0|100|400|1000]?",
- "Get/set the I2C speed in kbps for EC and AP pins");
-
-/******************************************************************************
- * Console commands for asserting H1 reset and EC Power button
- */
-
-static int command_vref_alternate(int argc, char **argv,
- const enum gpio_signal vref_signal,
- const enum gpio_signal en_signal,
- const int state_flag,
- const char *const print_name)
-{
- if (argc > 2)
- return EC_ERROR_PARAM_COUNT;
-
- /* Updating the state */
- if (argc == 2) {
- char *e;
- const int hold_low = strtoi(argv[1], &e, 0);
-
- if (*e || (hold_low < 0) || (hold_low > 1))
- return EC_ERROR_PARAM1;
-
- mutex_lock(&vref_bus_state_mutex);
-
- if (vref_monitor_disable & VREF_MON_DIS_SPI_MODE) {
- ccprintf("Cannot hold pin while in SPI mode.\n");
- goto busy_error_unlock;
- }
-
- if (!!(vref_monitor_disable & state_flag) == hold_low) {
- /* No change, do nothing */
- } else if (hold_low) {
- /* Turn off comparator interrupt for vref detection */
- STM32_EXTI_IMR &= ~EXTI_COMP2_EVENT;
- /* Start holding the ODL signal line low */
- gpio_set_flags(vref_signal, GPIO_OUT_LOW);
- /* Ensure the switch is connecting STM to DUT */
- gpio_set_level(en_signal, 1);
- vref_monitor_disable |= state_flag;
- } else {
- /* Return GPIO back to input for vref detection */
- gpio_set_flags(vref_signal, GPIO_INPUT);
- /* Transitioning out of hold, correct vrefs */
- hook_call_deferred(&update_vrefs_and_shifters_data, 0);
- vref_monitor_disable &= ~state_flag;
- }
-
- mutex_unlock(&vref_bus_state_mutex);
- }
-
- /* Print status for both get and set case */
- ccprintf("%s held: %s\n", print_name,
- vref_monitor_disable & state_flag ? "yes" : "no");
-
-
- return EC_SUCCESS;
-
-busy_error_unlock:
- mutex_unlock(&vref_bus_state_mutex);
- return EC_ERROR_BUSY;
-}
-
-static int command_pwr_button(int argc, char **argv)
-{
- return command_vref_alternate(argc, argv,
- GPIO_SPIVREF_HOLDN_ECVREF_H1_PWRBTN_ODL,
- GPIO_EN_SPIVREF_HOLDN_ECVREF_H1_PWRBTN,
- VREF_MON_DIS_EC_PWR_HELD, "Power button");
-}
-DECLARE_CONSOLE_COMMAND(pwr_button, command_pwr_button,
- "[0|1]?",
- "Get/set the power button state");
-
-static int command_h1_reset(int argc, char **argv)
-{
- return command_vref_alternate(argc, argv,
- GPIO_SPIVREF_RSVD_H1VREF_H1_RST_ODL,
- GPIO_EN_SPIVREF_RSVD_H1VREF_H1_RST,
- VREF_MON_DIS_H1_RST_HELD, "H1 reset");
-}
-DECLARE_CONSOLE_COMMAND(h1_reset, command_h1_reset,
- "[0|1]?",
- "Get/set the h1 reset state");
-
-
-/******************************************************************************
- * Vref detection logic
- */
-
-/* Set by update and read by console command that polls for Vref presence */
-static enum vref h1_vref;
-static enum vref ec_vref;
-
-static int command_h1_vref_present(int argc, char **argv)
-{
- ccprintf("H1 Vref: %s\n", h1_vref ? "on" : "off");
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(h1_vref, command_h1_vref_present,
- "",
- "Get if the h1 vref is present");
-
-/* Voltage thresholds for rail detection */
-#define VREF_3300_MIN_MV 2300
-#define VREF_1800_MIN_MV 1500
-
-static enum vref get_vref(enum adc_channel chan)
-{
- const int adc = adc_read_channel(chan);
-
- if (adc == ADC_READ_ERROR)
- return OFF;
- else if (adc > VREF_3300_MIN_MV)
- return PP3300;
- else if (adc > VREF_1800_MIN_MV)
- return PP1800;
- else
- return OFF;
-}
-
-static inline void drain_vref_lines(void)
-{
- mutex_lock(&vref_bus_state_mutex);
- if (vref_monitor_disable) {
- mutex_unlock(&vref_bus_state_mutex);
- return;
- }
-
- /*
- * Disconnect level shifters to prevent any leakage on DUT side while we
- * are draining Vref lines for a proper read.
- */
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, 0);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, 0);
-
- /* Disconnect Vref switches */
- gpio_set_level(GPIO_EN_SPIVREF_RSVD_H1VREF_H1_RST, 0);
- gpio_set_level(GPIO_EN_SPIVREF_HOLDN_ECVREF_H1_PWRBTN, 0);
-
- /* Actively pull down floating voltage */
- gpio_set_flags(GPIO_SPIVREF_RSVD_H1VREF_H1_RST_ODL, GPIO_OUT_LOW);
- gpio_set_flags(GPIO_SPIVREF_HOLDN_ECVREF_H1_PWRBTN_ODL, GPIO_OUT_LOW);
-
- /* Ensure we have enough time to drain line. Not in mutex */
- mutex_unlock(&vref_bus_state_mutex);
- msleep(5);
- mutex_lock(&vref_bus_state_mutex);
- if (vref_monitor_disable) {
- mutex_unlock(&vref_bus_state_mutex);
- /*
- * One or both of the Vref signals will still be low. This is
- * okay since anyone that just took over these signal will
- * also take over the enabled switch signals appropriately.
- *
- * If no one takes over the Vref signal, then the switch will
- * remain off and we won't pull down the DUT side.
- */
- return;
- }
-
- /* Reset Vref GPIOs back to input for Vref detection */
- gpio_set_flags(GPIO_SPIVREF_RSVD_H1VREF_H1_RST_ODL, GPIO_INPUT);
- gpio_set_flags(GPIO_SPIVREF_HOLDN_ECVREF_H1_PWRBTN_ODL, GPIO_INPUT);
-
- /* Reconnect Vref switches */
- gpio_set_level(GPIO_EN_SPIVREF_RSVD_H1VREF_H1_RST, 1);
- gpio_set_level(GPIO_EN_SPIVREF_HOLDN_ECVREF_H1_PWRBTN, 1);
-
- mutex_unlock(&vref_bus_state_mutex);
- /* Ensure we have enough time to charge line up to real voltage */
- msleep(10);
-}
-
-/* This if forward declared as a deferred function above */
-static void update_vrefs_and_shifters(void)
-{
- static enum vref prev_h1_vref, prev_ec_vref;
-
- int adc_mv;
-
- /* Disable Vref comparator interrupt before draining and measuring */
- STM32_EXTI_IMR &= ~EXTI_COMP2_EVENT;
-
- drain_vref_lines();
-
- /* Ensure we aren't actively using Vref lines for other purposes */
- mutex_lock(&vref_bus_state_mutex);
- if (vref_monitor_disable) {
- mutex_unlock(&vref_bus_state_mutex);
- return;
- }
-
- /* Only get the EC Vref if H1 Vref is on */
- h1_vref = get_vref(ADC_H1_SPI_VREF);
- ec_vref = (h1_vref == OFF) ? OFF : get_vref(ADC_EC_SPI_VREF);
-
- /*
- * It is possible that the user is physically holding the power button
- * while inserting the c2d2 connector on the DUT. In that case the
- * EC Vref (shared with power button ODL) will be OFF while H1 Vref is
- * on. We won't get a valid read on the EC Vref, so we just keep trying
- * to read in the background until we get out of that state.
- */
- if (h1_vref != OFF && ec_vref == OFF) {
- CPRINTS("Looks like DUT power button is held. Will try again.");
- hook_call_deferred(&update_vrefs_and_shifters_data, 100 * MSEC);
- }
-
- /* Update C2D2 Vref and level shifters based on ADC Vref values */
- gpio_set_level(GPIO_SEL_SPIVREF_H1VREF_3V3, h1_vref == PP3300);
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, h1_vref != OFF);
- gpio_set_level(GPIO_SEL_SPIVREF_ECVREF_3V3, ec_vref == PP3300);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, ec_vref != OFF);
-
- /* Set up DAC2 for comparison on H1 Vref */
- adc_mv = (h1_vref == PP3300) ? VREF_3300_MIN_MV : VREF_1800_MIN_MV;
- /* 8-bit DAC based off of 3.3V rail */
- STM32_DAC_DHR8R2 = 256 * adc_mv / 3300;
-
- /* Clear any pending interrupts and enabled H1 Vref comparator */
- STM32_EXTI_PR = EXTI_COMP2_EVENT;
- STM32_EXTI_IMR |= EXTI_COMP2_EVENT;
-
- mutex_unlock(&vref_bus_state_mutex);
-
- if (prev_h1_vref != h1_vref || prev_ec_vref != ec_vref)
- CPRINTS("Vref updated. H1: %d -> %d; EC: %d -> %d",
- prev_h1_vref, h1_vref, prev_ec_vref, ec_vref);
-
- /*
- * Transitioning from 3.3V to 1.8V should not happen and most likely
- * indicates a leakage path on the DUT being backpowered from C2D2 or
- * something else.
- */
- if (prev_h1_vref == PP3300 && h1_vref == PP1800)
- CPRINTS("Check for H1 Leakage!!!");
- if (prev_ec_vref == PP3300 && ec_vref == PP1800)
- CPRINTS("Check for EC Leakage!!!");
- prev_h1_vref = h1_vref;
- prev_ec_vref = ec_vref;
-}
-
-void set_up_comparator(void)
-{
- /* Overwrite any previous values. This is the only comparator usage */
- STM32_COMP_CSR = STM32_COMP_CMP2HYST_HI |
- STM32_COMP_CMP2OUTSEL_NONE |
- STM32_COMP_CMP2INSEL_INM5 | /* Watch DAC_OUT2 (PA5) */
- STM32_COMP_CMP2MODE_LSPEED |
- STM32_COMP_CMP2EN;
-
- /* Set Falling and Rising interrupts for COMP2 */
- STM32_EXTI_FTSR |= EXTI_COMP2_EVENT;
- STM32_EXTI_RTSR |= EXTI_COMP2_EVENT;
-
- /* Interrupt for COMP2 enabled when setting Vrefs */
-
- /* Ensure IRQ will get called when comp module enables interrupt */
- task_enable_irq(STM32_IRQ_COMP);
-}
-
-static void h1_vref_change(void)
-{
- /* Ack the interrupt */
- STM32_EXTI_PR = EXTI_COMP2_EVENT;
-
- /* Disable interrupt, setting Vref will enable again */
- STM32_EXTI_IMR &= ~EXTI_COMP2_EVENT;
-
- hook_call_deferred(&update_vrefs_and_shifters_data, 0);
-}
-DECLARE_IRQ(STM32_IRQ_COMP, h1_vref_change, 1);
-
-/******************************************************************************
- * Initialize board.
- */
-static void board_init(void)
-{
- /* USB to serial queues */
- queue_init(&usart1_to_usb);
- queue_init(&usb_to_usart1);
- queue_init(&usart3_to_usb);
- queue_init(&usb_to_usart3);
- queue_init(&usart4_to_usb);
- queue_init(&usb_to_usart4);
-
- /* UART init */
- usart_init(&usart1);
- usart_init(&usart3);
- usart_init(&usart4);
-
- /* Enabled DAC, when setting Vref, this voltage is adjusted */
- STM32_DAC_CR = STM32_DAC_CR_EN2;
-
- /* Set Vrefs and enabled level shifters */
- set_up_comparator();
-
- /*
- * Ensure we set up vrefs at least once. Don't call here because
- * there are delays in the reads
- */
- hook_call_deferred(&update_vrefs_and_shifters_data, 0);
-}
-DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
-
-/******************************************************************************
- * Turn down USART before jumping to RW.
- */
-static void board_jump(void)
-{
- /* Put the board into safer state while jumping */
- gpio_set_level(GPIO_EN_SPIVREF_RSVD_H1VREF_H1_RST, 0);
- gpio_set_level(GPIO_EN_SPIVREF_HOLDN_ECVREF_H1_PWRBTN, 0);
- gpio_set_level(GPIO_EN_CLK_CSN_EC_UART, 0);
- gpio_set_level(GPIO_EN_MISO_MOSI_H1_UART, 0);
-
- /*
- * Shutdown all UARTS before jumping to RW. They will be reinitialized
- * after the jump is successful.
- */
- usart_shutdown(&usart1);
- usart_shutdown(&usart3);
- usart_shutdown(&usart4);
-
- /* Ensure SPI2 is disabled as well */
- usb_spi_enable(&usb_spi, 0);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, board_jump, HOOK_PRIO_DEFAULT);