summaryrefslogtreecommitdiff
path: root/chip/stm32/usb_spi.h
diff options
context:
space:
mode:
Diffstat (limited to 'chip/stm32/usb_spi.h')
-rw-r--r--chip/stm32/usb_spi.h220
1 files changed, 154 insertions, 66 deletions
diff --git a/chip/stm32/usb_spi.h b/chip/stm32/usb_spi.h
index 385aaaf730..e0dfd34b18 100644
--- a/chip/stm32/usb_spi.h
+++ b/chip/stm32/usb_spi.h
@@ -146,6 +146,7 @@
* 0x0008: An unexpected packet arrived that the device could not
* process.
* 0x0009: The device does not support full duplex mode.
+ * 0x000A: Requested serial flash mode not supported
* 0x8000: Unknown error mask
* The bottom 15 bits will contain the bottom 15 bits from the EC
* error code.
@@ -218,7 +219,12 @@
*
* feature bitmap: Bitmap of supported features.
* BIT(0): Full duplex SPI mode is supported
- * BIT(1:15): Reserved for future use
+ * BIT(1): Serial flash extensions are supported
+ * BIT(2): Dual mode flash supported
+ * BIT(3): Quad mode flash supported
+ * BIT(4): Octo mode flash supported
+ * BIT(5): Double transfer rate supported
+ * BIT(6:15): Reserved for future use
*
* Command Restart Response Packet (Host to Device):
*
@@ -256,6 +262,64 @@
* 0x0000: Success
* others: Error
*
+ * Flash Command Start Packet (Host to Device):
+ *
+ * Start of the USB serial flash SPI command, contains the number of
+ * bytes to write or read on SPI and up to the first 58 bytes of write
+ * payload. Longer writes will use the continue packets with packet id
+ * USB_SPI_PKT_ID_CMD_TRANSFER_CONTINUE to transmit the remaining data.
+ *
+ * The reading or writing of the "main" data will be preceded by an
+ * short sequence of opcode, optional address, optional "alternate data",
+ * and optional 'dummy cycles" on the SPI bus. Flags indicate how many
+ * bytes of each stage to send, and whether to use advanced features such
+ * as dual or quad signal lanes for each stage of the transfer".
+ *
+ * The indicated number of opcode, address and alternate bytes will be
+ * the first in the "write payload". The "count" field will contain the
+ * number of data bytes to be written/read after the opcode, address and
+ * alternate bytes.
+ *
+ * This request is only supported if bit 1 of the "feature bitmap"
+ * indicates that serial flash extensions are supported. Implementations
+ * will further advertise whether they support dual, quad or octo modes, if
+ * none of these are supported, then support for "dummy cycles" is not
+ * guaranteed either, and callers should use one or two bytes of "extra
+ * address data" for dummy cycles, address length can be up to 7 bytes for
+ * this reason.
+ *
+ * +----------------+------------+------------+---------------+
+ * | packet id : 2B | count : 2B | flags : 4B | w.p. : <= 56B |
+ * +----------------+------------+------------+---------------+
+ *
+ * packet id: 2 byte enum defined by packet_id_type
+ * Valid values packet id =
+ * USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START
+ *
+ * count: 2 byte, zero based count of bytes to read or write
+ *
+ * flags: 4 byte, flags
+ * bits 0:1 opcode length in bytes (0-3)
+ * bits 2:4 address length in bytes (0-7)
+ * bits 5:6 mode (0: 1-1-1, 1: 1-1-N, 2: 1-N-N, 3: N-N-N)
+ * bits 7:8 width (0: N=1, 1: N=2, 2: N=4, 3: N=8)
+ * bit 9 double transfer rate (in phases marked as N)
+ * bits 10:14 number of dummy cycles (0-31)
+ * bits 15:27 reserved, must be zero
+ * bit 28 write to be preceded by "write enable"
+ * bit 29 write to be followed by polling of JEDEC "busy bit"
+ * bit 30 reserved, must be zero
+ * bit 31 read (0) / write (1)
+ *
+ * write payload: Up to 56 bytes of data to write to SPI, the total length
+ * of all TX packets must match: write enable length (zero or
+ * one, depending on bit 27) + opcode length + address length
+ * + count, (the last one only if bit 31 indicates a write
+ * operation). Due to data alignment constraints, this must
+ * be an even number of bytes unless this is the final
+ * packet.
+ *
+ *
* USB Error Codes:
*
* send_command return codes have the following format:
@@ -278,6 +342,8 @@
#define USB_SPI_PAYLOAD_SIZE_V2_ERROR (60)
+#define USB_SPI_PAYLOAD_SIZE_FLASH_START (56)
+
#define USB_SPI_MIN_PACKET_SIZE (2)
/*
@@ -294,6 +360,8 @@
#define USB_SPI_FLASH_QUAD_SUPPORT BIT(3)
/* This SPI device supports eight lane mode. */
#define USB_SPI_FLASH_OCTO_SUPPORT BIT(4)
+/* This SPI device supports double transfer rate (data on both clock edges). */
+#define USB_SPI_FLASH_DTR_SUPPORT BIT(5)
enum packet_id_type {
/* Request USB SPI configuration data from device. */
@@ -325,11 +393,34 @@ enum packet_id_type {
USB_SPI_PKT_ID_CMD_CHIP_SELECT = 7,
/* Response to above request. */
USB_SPI_PKT_ID_RSP_CHIP_SELECT = 8,
+ /*
+ * Start a USB serial flash SPI transfer.
+ */
+ USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START = 9,
};
enum feature_bitmap {
/* Indicates the platform supports full duplex mode. */
- USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = BIT(0)
+ USB_SPI_FEATURE_FULL_DUPLEX_SUPPORTED = BIT(0),
+ /* Indicates support for USB_SPI_PKT_ID_CMD_FLASH_TRANSFER_START. */
+ USB_SPI_FEATURE_FLASH_EXTENSIONS = BIT(1),
+ /*
+ * Indicates that chip and any MUXes support bidirectional data on the
+ * two SPI data lines.
+ */
+ USB_SPI_FEATURE_DUAL_MODE_SUPPORTED = BIT(2),
+ /*
+ * Indicates that chip and any MUXes support bidirectional data on the
+ * "hold" and "write protect" lines.
+ */
+ USB_SPI_FEATURE_QUAD_MODE_SUPPORTED = BIT(3),
+ /* Indicates support for eight-line bidirectional data. */
+ USB_SPI_FEATURE_OCTO_MODE_SUPPORTED = BIT(4),
+ /*
+ * Indicates support for double transfer rate, i.e. data bit shift on
+ * both rising and falling clock edges.
+ */
+ USB_SPI_FEATURE_DTR_SUPPORTED = BIT(5),
};
struct usb_spi_response_configuration_v2 {
@@ -374,11 +465,36 @@ struct usb_spi_chip_select_response {
uint16_t status_code;
} __packed;
+struct usb_spi_flash_command {
+ uint16_t packet_id;
+ uint16_t count;
+ uint32_t flags;
+ uint8_t data[USB_SPI_PAYLOAD_SIZE_FLASH_START];
+} __packed;
+
+/*
+ * Mask of the flags that are handled by logic in sub_spi.c, and not passed to
+ * SPI drivers through usb_spi_board_transaction().
+ */
+#define FLASH_FLAGS_NONBOARD 0xF0000000UL
+
+#define FLASH_FLAG_WRITE_ENABLE_POS 28U
+#define FLASH_FLAG_WRITE_ENABLE (0x1UL << FLASH_FLAG_WRITE_ENABLE_POS)
+
+#define FLASH_FLAG_POLL_POS 29U
+#define FLASH_FLAG_POLL (0x1UL << FLASH_FLAG_POLL_POS)
+
+#define FLASH_FLAG_READ_WRITE_POS 31U
+#define FLASH_FLAG_READ_WRITE_MSK (0x1UL << FLASH_FLAG_READ_WRITE_POS)
+#define FLASH_FLAG_READ_WRITE_READ 0
+#define FLASH_FLAG_READ_WRITE_WRITE (0x1UL << FLASH_FLAG_READ_WRITE_POS)
+
struct usb_spi_packet_ctx {
union {
uint8_t bytes[USB_MAX_PACKET_SIZE];
uint16_t packet_id;
struct usb_spi_command_v2 cmd_start;
+ struct usb_spi_flash_command cmd_flash_start;
struct usb_spi_continue_v2 cmd_continue;
struct usb_spi_response_configuration_v2 rsp_config;
struct usb_spi_response_v2 rsp_start;
@@ -412,6 +528,8 @@ enum usb_spi_error {
USB_SPI_RX_UNEXPECTED_PACKET = 0x0008,
/* The device does not support full duplex mode. */
USB_SPI_UNSUPPORTED_FULL_DUPLEX = 0x0009,
+ /* The device does not support dual/quad wire mode. */
+ USB_SPI_UNSUPPORTED_FLASH_MODE = 0x000A,
USB_SPI_UNKNOWN_ERROR = 0x8000,
};
@@ -508,6 +626,12 @@ struct usb_spi_state {
struct usb_spi_packet_ctx transmit_packet;
/*
+ * Flags describing if and how multi-lane (dual/quad), double transfer
+ * rate, and other advanced flash protocol features are to be used.
+ */
+ uint32_t flash_flags;
+
+ /*
* Context structures representing the progress receiving the SPI
* write data and transmitting the SPI read data.
*/
@@ -666,70 +790,38 @@ int usb_spi_board_transaction(const struct spi_device_t *spi_device,
* 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)
+/* Number of bytes of opcode (0-3). */
+#define FLASH_FLAG_OPCODE_LEN_POS 0
+#define FLASH_FLAG_OPCODE_LEN_MSK (0x3U << FLASH_FLAG_OPCODE_LEN_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 address plus additional data bytes (0-7). */
+#define FLASH_FLAG_ADDR_LEN_POS 2
+#define FLASH_FLAG_ADDR_LEN_MSK (0x7U << FLASH_FLAG_ADDR_LEN_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)
+/* At what stage to switch to multi-lane mode (if any). */
+#define FLASH_FLAG_MODE_POS 5
+#define FLASH_FLAG_MODE_MSK (0x3U << FLASH_FLAG_MODE_POS)
+#define FLASH_FLAG_MODE_111 (0x0U << FLASH_FLAG_MODE_POS)
+#define FLASH_FLAG_MODE_11N (0x1U << FLASH_FLAG_MODE_POS)
+#define FLASH_FLAG_MODE_1NN (0x2U << FLASH_FLAG_MODE_POS)
+#define FLASH_FLAG_MODE_NNN (0x3U << FLASH_FLAG_MODE_POS)
+
+/* Data width during the later stages (value of N, above). */
+#define FLASH_FLAG_WIDTH_POS 7
+#define FLASH_FLAG_WIDTH_MSK (0x3U << FLASH_FLAG_WIDTH_POS)
+#define FLASH_FLAG_WIDTH_1WIRE (0x0U << FLASH_FLAG_WIDTH_POS)
+#define FLASH_FLAG_WIDTH_2WIRE (0x1U << FLASH_FLAG_WIDTH_POS)
+#define FLASH_FLAG_WIDTH_4WIRE (0x2U << FLASH_FLAG_WIDTH_POS)
+#define FLASH_FLAG_WIDTH_8WIRE (0x3U << FLASH_FLAG_WIDTH_POS)
+
+/* Transmit opcode bits at both clock edges in later stages. */
+#define FLASH_FLAG_DTR_POS 9
+#define FLASH_FLAG_DTR (0x1U << FLASH_FLAG_DTR_POS)
/* Number of dummy clock cycles (0-31). */
-#define FLASH_FLAG_DUMMY_CYCLES_POS 18
+#define FLASH_FLAG_DUMMY_CYCLES_POS 10
#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
@@ -739,11 +831,7 @@ int usb_spi_board_transaction(const struct spi_device_t *spi_device,
* 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)
+#define FLASH_FLAGS_REQUIRING_SUPPORT \
+ (FLASH_FLAG_MODE_MSK | FLASH_FLAG_DTR | FLASH_FLAG_DUMMY_CYCLES_MSK)
#endif /* __CROS_EC_USB_SPI_H */