summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorJes B. Klinke <jbk@chromium.org>2023-03-14 20:25:45 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-03-17 21:28:25 +0000
commit60b941b4e0f1afe1584d146550af61d9e88d3785 (patch)
tree7aea70ed4f0f2c252fe4ad7ebe473ebe4e51c1ad /chip
parent768903a5bf71508226d5adf52b8cabef8a783e42 (diff)
downloadchrome-ec-60b941b4e0f1afe1584d146550af61d9e88d3785.tar.gz
chip/stm32: Interface extensions for serial flash
Enhance the interface to board-specific SPI driver such that it can take flags for advanced serial flash chip protocols (dual/quad lanes, dummy cycles, double transfer rate). BUG=b:273601311 TEST=c2d2 can still flash (using single-lane) Change-Id: Iee6a17077ea8c382c7d59bd404bf5d033bd9b517 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4336273 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Jes Klinke <jbk@chromium.org> Tested-by: Jes Klinke <jbk@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/stm32/usb_spi.c22
-rw-r--r--chip/stm32/usb_spi.h109
2 files changed, 114 insertions, 17 deletions
diff --git a/chip/stm32/usb_spi.c b/chip/stm32/usb_spi.c
index 555e201b0b..a350415dab 100644
--- a/chip/stm32/usb_spi.c
+++ b/chip/stm32/usb_spi.c
@@ -442,11 +442,19 @@ void usb_spi_deferred(struct usb_spi_config const *config)
}
#endif
- status_code = (custom_board_driver ? usb_spi_board_transaction :
- spi_transaction)(
- current_device, config->state->spi_write_ctx.buffer,
- config->state->spi_write_ctx.transfer_size,
- config->state->spi_read_ctx.buffer, read_count);
+ if (custom_board_driver) {
+ status_code = usb_spi_board_transaction(
+ current_device, 0 /* flash_flags */,
+ config->state->spi_write_ctx.buffer,
+ config->state->spi_write_ctx.transfer_size,
+ config->state->spi_read_ctx.buffer, read_count);
+ } else {
+ status_code = spi_transaction(
+ current_device,
+ config->state->spi_write_ctx.buffer,
+ config->state->spi_write_ctx.transfer_size,
+ config->state->spi_read_ctx.buffer, read_count);
+ }
/* Cast the EC status code to USB SPI and start the response. */
status_code = usb_spi_map_error(status_code);
@@ -669,8 +677,8 @@ int usb_spi_interface(struct usb_spi_config const *config, usb_uint *rx_buf,
__overridable int
usb_spi_board_transaction(const struct spi_device_t *spi_device,
- const uint8_t *txdata, int txlen, uint8_t *rxdata,
- int rxlen)
+ uint32_t flash_flags, const uint8_t *txdata,
+ int txlen, uint8_t *rxdata, int rxlen)
{
return EC_ERROR_UNIMPLEMENTED;
}
diff --git a/chip/stm32/usb_spi.h b/chip/stm32/usb_spi.h
index 28462caea8..34d69225cf 100644
--- a/chip/stm32/usb_spi.h
+++ b/chip/stm32/usb_spi.h
@@ -285,10 +285,15 @@
*/
/* Is the USB host allowed to operate on SPI device. */
-#define USB_SPI_ENABLED (BIT(0))
-
+#define USB_SPI_ENABLED BIT(0)
/* Use board specific SPI driver when forwarding to this device. */
-#define USB_SPI_CUSTOM_SPI_DEVICE (BIT(1))
+#define USB_SPI_CUSTOM_SPI_DEVICE BIT(1)
+/* This SPI device supports dual lane mode. */
+#define USB_SPI_FLASH_DUAL_SUPPORT BIT(2)
+/* This SPI device supports four lane mode. */
+#define USB_SPI_FLASH_QUAD_SUPPORT BIT(3)
+/* This SPI device supports eight lane mode. */
+#define USB_SPI_FLASH_OCTO_SUPPORT BIT(4)
enum packet_id_type {
/* Request USB SPI configuration data from device. */
@@ -668,14 +673,98 @@ void usb_spi_board_enable(struct usb_spi_config const *config);
void usb_spi_board_disable(struct usb_spi_config const *config);
/*
- * In order to facilitate odd cases of e.g. a SPI bus sitting behind a second
- * microcontroller, or otherwise needing a non-standard driver, setting the
- * USB_SPI_CUSTOM_SPI_DEVICE_MASK bit of spi_device->port will cause the
- * USB->SPI forwarding logic to invoke this method rather than the standard
- * spi_transaction().
+ * In order to facilitate special SPI busses not covered by standard EC
+ * drivers, setting the USB_SPI_CUSTOM_SPI_DEVICE_MASK bit of spi_device->port
+ * will cause the USB to SPI forwarding logic to invoke this method rather
+ * than the standard spi_transaction_async().
*/
int usb_spi_board_transaction(const struct spi_device_t *spi_device,
- const uint8_t *txdata, int txlen, uint8_t *rxdata,
- int rxlen);
+ uint32_t flash_flags, const uint8_t *txdata,
+ int txlen, uint8_t *rxdata, int rxlen);
+
+/*
+ * Flags to use in usb_spi_board_transaction_async() for advanced serial flash
+ * communication, when supported.
+ */
+
+/* Data width during the opcode stage. */
+#define FLASH_FLAG_OPCODE_WIDTH_POS 0
+#define FLASH_FLAG_OPCODE_WIDTH_MSK (0x3U << FLASH_FLAG_OPCODE_WIDTH_POS)
+#define FLASH_FLAG_OPCODE_WIDTH_1WIRE (0x0U << FLASH_FLAG_OPCODE_WIDTH_POS)
+#define FLASH_FLAG_OPCODE_WIDTH_2WIRE (0x1U << FLASH_FLAG_OPCODE_WIDTH_POS)
+#define FLASH_FLAG_OPCODE_WIDTH_4WIRE (0x2U << FLASH_FLAG_OPCODE_WIDTH_POS)
+#define FLASH_FLAG_OPCODE_WIDTH_8WIRE (0x3U << FLASH_FLAG_OPCODE_WIDTH_POS)
+
+/* Transmit opcode bits at both rising and falling clock edges. */
+#define FLASH_FLAG_OPCODE_DTR_POS 2
+#define FLASH_FLAG_OPCODE_DTR (0x1U << FLASH_FLAG_OPCODE_DTR_POS)
+
+/* Number of bytes of opcode (0-4). */
+#define FLASH_FLAG_OPCODE_LEN_POS 3
+#define FLASH_FLAG_OPCODE_LEN_MSK (0x7U << FLASH_FLAG_OPCODE_LEN_POS)
+
+/* Data width during the address stage. */
+#define FLASH_FLAG_ADDR_WIDTH_POS 6
+#define FLASH_FLAG_ADDR_WIDTH_MSK (0x3U << FLASH_FLAG_ADDR_WIDTH_POS)
+#define FLASH_FLAG_ADDR_WIDTH_1WIRE (0x0U << FLASH_FLAG_ADDR_WIDTH_POS)
+#define FLASH_FLAG_ADDR_WIDTH_2WIRE (0x1U << FLASH_FLAG_ADDR_WIDTH_POS)
+#define FLASH_FLAG_ADDR_WIDTH_4WIRE (0x2U << FLASH_FLAG_ADDR_WIDTH_POS)
+#define FLASH_FLAG_ADDR_WIDTH_8WIRE (0x3U << FLASH_FLAG_ADDR_WIDTH_POS)
+
+/* Transmit address bits at both rising and falling clock edges. */
+#define FLASH_FLAG_ADDR_DTR_POS 8
+#define FLASH_FLAG_ADDR_DTR (0x1U << FLASH_FLAG_ADDR_DTR_POS)
+
+/* Number of bytes of address (0-4). */
+#define FLASH_FLAG_ADDR_LEN_POS 9
+#define FLASH_FLAG_ADDR_LEN_MSK (0x7U << FLASH_FLAG_ADDR_LEN_POS)
+
+/* Data width during the "alternate bytes" stage. */
+#define FLASH_FLAG_ALT_WIDTH_POS 12
+#define FLASH_FLAG_ALT_WIDTH_MSK (0x3U << FLASH_FLAG_ALT_WIDTH_POS)
+#define FLASH_FLAG_ALT_WIDTH_1WIRE (0x0U << FLASH_FLAG_ALT_WIDTH_POS)
+#define FLASH_FLAG_ALT_WIDTH_2WIRE (0x1U << FLASH_FLAG_ALT_WIDTH_POS)
+#define FLASH_FLAG_ALT_WIDTH_4WIRE (0x2U << FLASH_FLAG_ALT_WIDTH_POS)
+#define FLASH_FLAG_ALT_WIDTH_8WIRE (0x3U << FLASH_FLAG_ALT_WIDTH_POS)
+
+/* Transmit alternate bits at both rising and falling clock edges. */
+#define FLASH_FLAG_ALT_DTR_POS 14
+#define FLASH_FLAG_ALT_DTR (0x1U << FLASH_FLAG_ALT_DTR_POS)
+
+/* Number of bytes of alternate data (0-4). */
+#define FLASH_FLAG_ALT_LEN_POS 15
+#define FLASH_FLAG_ALT_LEN_MSK (0x7U << FLASH_FLAG_ALT_LEN_POS)
+
+/* Number of dummy clock cycles (0-31). */
+#define FLASH_FLAG_DUMMY_CYCLES_POS 18
+#define FLASH_FLAG_DUMMY_CYCLES_MSK (0x1FU << FLASH_FLAG_DUMMY_CYCLES_POS)
+
+/* Data width during the data stage. */
+#define FLASH_FLAG_DATA_WIDTH_POS 23
+#define FLASH_FLAG_DATA_WIDTH_MSK (0x3U << FLASH_FLAG_DATA_WIDTH_POS)
+#define FLASH_FLAG_DATA_WIDTH_1WIRE (0x0U << FLASH_FLAG_DATA_WIDTH_POS)
+#define FLASH_FLAG_DATA_WIDTH_2WIRE (0x1U << FLASH_FLAG_DATA_WIDTH_POS)
+#define FLASH_FLAG_DATA_WIDTH_4WIRE (0x2U << FLASH_FLAG_DATA_WIDTH_POS)
+#define FLASH_FLAG_DATA_WIDTH_8WIRE (0x3U << FLASH_FLAG_DATA_WIDTH_POS)
+
+/* Transmit data bits at both rising and falling clock edges. */
+#define FLASH_FLAG_DATA_DTR_POS 25
+#define FLASH_FLAG_DATA_DTR (0x1U << FLASH_FLAG_DATA_DTR_POS)
+
+/*
+ * Mask of the flags that cannot be ignored. This is basically any flags
+ * which call for wires to switch direction, or data being clocked on both
+ * rising and falling edges. As long as none of these are present, then the
+ * remaining flags specifying the length of opcode/address can be ignored, as
+ * the entire data buffer can be transmitted as a sequence of bytes, without
+ * the controller knowing which parts are to be interpreted as
+ * opcode/address/data.
+ */
+#define FLASH_FLAGS_REQUIRING_SUPPORT \
+ (FLASH_FLAG_OPCODE_WIDTH_MSK | FLASH_FLAG_OPCODE_DTR | \
+ FLASH_FLAG_ADDR_WIDTH_MSK | FLASH_FLAG_ADDR_DTR | \
+ FLASH_FLAG_ALT_WIDTH_MSK | FLASH_FLAG_ALT_DTR | \
+ FLASH_FLAG_DUMMY_CYCLES_MSK | FLASH_FLAG_DATA_WIDTH_MSK | \
+ FLASH_FLAG_DATA_DTR)
#endif /* __CROS_EC_USB_SPI_H */