summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2015-12-09 17:36:15 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-12-16 15:07:20 -0800
commit8895f2a3a3ec8af76949717cf6fcd8a8955521be (patch)
tree6fec19b5b3e6c220044593d76a2a7f2b9c863fab
parentc14a2c3e722684bafb1d0938e56d309496732591 (diff)
downloadchrome-ec-8895f2a3a3ec8af76949717cf6fcd8a8955521be.tar.gz
Cr50: Revise FIFO SRAM settings
This allocates more space for FIFO buffers, according to the instructions in the Programmer's Guide. Many more comments and some slight refactoring was added to explain the configuration more clearly. BUG=chrome-os-partner:34893 BRANCH=none TEST=make buildall, manual Connect the Cr50 to my workstation via USB: * /bin/dmesg reports no errors * verify EP0 with lsusb -v -d 18d1:5014 * verify EP1 with './extra/usb_console -e 1 -p 5014' (reverses case of input text) * verify EP2 with the 'hid' command on the EC console (types a 'g') Signed-off-by: Bill Richardson <wfrichar@chromium.org> Change-Id: I1a870a4b1dc628729f7cd1b80bab7ec6dfd11f37 Reviewed-on: https://chromium-review.googlesource.com/318262 Reviewed-by: Dominic Rizzo <domrizzo@google.com>
-rw-r--r--chip/g/usb.c127
1 files changed, 89 insertions, 38 deletions
diff --git a/chip/g/usb.c b/chip/g/usb.c
index f8b1e12ece..76991f9da6 100644
--- a/chip/g/usb.c
+++ b/chip/g/usb.c
@@ -17,25 +17,8 @@
#include "usb_descriptor.h"
#include "watchdog.h"
-/* Rev A1 has a RTL bug in the FIFO */
-#if CONCAT2(GC_, GC___MAJOR_REV__) == GC___REVA__
-/*
- * WORKAROUND: only the first 256 entries are usable as TX FIFO
- *
- * Use the last 128 entries for EP_INFO (not affected by the bug)
- * and 256 entries for RX/TX FIFOs : total 384 entries.
- *
- * RX FIFO needs more than 64 entries (for reserved space)
- * set RX FIFO to 80 entries
- * set TX0-TX10 FIFO to 64 bytes = 16 (x 32-bit) entries
- * let TX11-TX15 uninitialized for now (WORKAROUND).
- */
-#define FIFO_SIZE 0x180
-#define TX_FIFO_CNT 11
-#else
-#define FIFO_SIZE 0x400
-#define TX_FIFO_CNT 16
-#endif
+/****************************************************************************/
+/* Debug output */
/* Console output macro */
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
@@ -192,6 +175,9 @@ DECLARE_CONSOLE_COMMAND(usb, command_usb,
#endif /* DEBUG_ME */
+/****************************************************************************/
+/* Standard USB stuff */
+
#ifdef CONFIG_USB_BOS
/* v2.01 (vs 2.00) BOS Descriptor provided */
#define USB_DEV_BCDUSB 0x0201
@@ -243,6 +229,9 @@ const uint8_t usb_string_desc[] = {
0x09, 0x04 /* LangID = 0x0409: U.S. English */
};
+/****************************************************************************/
+/* Packet-handling stuff, specific to this SoC */
+
/* Descriptors for USB controller S/G DMA */
static struct g_usb_desc ep0_out_desc;
static struct g_usb_desc ep0_in_desc;
@@ -257,6 +246,19 @@ static int desc_left;
/* pointer to descriptor data if any */
static const uint8_t *desc_ptr;
+/* Reset all this to a good starting state. */
+static void initialize_dma_buffers(void)
+{
+ ep0_out_desc.flags = DOEPDMA_RXBYTES(64) | DOEPDMA_LAST |
+ DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
+ ep0_out_desc.addr = ep0_buf_rx;
+ ep0_in_desc.flags = DIEPDMA_TXBYTES(0) | DIEPDMA_LAST |
+ DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC;
+ ep0_in_desc.addr = ep0_buf_tx;
+ GR_USB_DIEPDMA(0) = (uint32_t)&ep0_in_desc;
+ GR_USB_DOEPDMA(0) = (uint32_t)&ep0_out_desc;
+}
+
/* Load the EP0 IN FIFO buffer with some data (zero-length works too). Returns
* len, or negative on error. */
int load_in_fifo(const void *source, uint32_t len)
@@ -504,45 +506,94 @@ static void ep0_reset(void)
{
/* Reset EP0 address */
GWRITE_FIELD(USB, DCFG, DEVADDR, 0);
+ initialize_dma_buffers();
- ep0_out_desc.flags = DOEPDMA_RXBYTES(64) | DOEPDMA_LAST |
- DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
- ep0_out_desc.addr = ep0_buf_rx;
- ep0_in_desc.flags = DIEPDMA_TXBYTES(0) | DIEPDMA_LAST |
- DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC;
- ep0_in_desc.addr = ep0_buf_tx;
- GR_USB_DIEPDMA(0) = (uint32_t)&ep0_in_desc;
- GR_USB_DOEPDMA(0) = (uint32_t)&ep0_out_desc;
GR_USB_DOEPCTL(0) = DXEPCTL_MPS64 | DXEPCTL_USBACTEP |
DXEPCTL_EPTYPE_CTRL |
DXEPCTL_CNAK | DXEPCTL_EPENA;
GR_USB_DIEPCTL(0) = DXEPCTL_MPS64 | DXEPCTL_USBACTEP |
DXEPCTL_EPTYPE_CTRL;
GR_USB_DAINTMSK = DAINT_OUTEP(0) | DAINT_INEP(0);
+
}
USB_DECLARE_EP(0, ep0_tx, ep0_rx, ep0_reset);
+/****************************************************************************/
+/* USB device initialization and shutdown routines */
+
+/*
+ * DATA FIFO Setup. There is an internal SPRAM used to buffer the IN/OUT
+ * packets and track related state without hammering the AHB and system RAM
+ * during USB transactions. We have to specify where and how much of that SPRAM
+ * to use for what.
+ *
+ * See Programmer's Guide chapter 2, "Calculating FIFO Size".
+ * We're using Dedicated TxFIFO Operation, without enabling thresholding.
+ *
+ * Section 2.1.1.2, page 30: RXFIFO size is the same as for Shared FIFO, which
+ * is Section 2.1.1.1, page 28. This is also the same as Method 2 on page 45.
+ *
+ * We support up to 3 control EPs, no periodic IN EPs, up to 16 TX EPs. Max
+ * data packet size is 64 bytes. Total SPRAM available is 1024 slots.
+ */
+#define MAX_CONTROL_EPS 3
+#define MAX_NORMAL_EPS 16
+#define FIFO_RAM_DEPTH 1024
+/*
+ * Device RX FIFO size is thus:
+ * (4 * 3 + 6) + 2 * ((64 / 4) + 1) + (2 * 16) + 1 == 85
+ */
+#define RXFIFO_SIZE ((4 * MAX_CONTROL_EPS + 6) + \
+ 2 * ((USB_MAX_PACKET_SIZE / 4) + 1) + \
+ (2 * MAX_NORMAL_EPS) + 1)
+/*
+ * Device TX FIFO size is 2 * (64 / 4) == 32 for each IN EP (Page 46).
+ */
+#define TXFIFO_SIZE (2 * (USB_MAX_PACKET_SIZE / 4))
+/*
+ * We need 4 slots per endpoint direction for endpoint status stuff (Table 2-1,
+ * unconfigurable).
+ */
+#define EP_STATUS_SIZE (4 * MAX_NORMAL_EPS * 2)
+/*
+ * Make sure all that fits.
+ */
+BUILD_ASSERT(RXFIFO_SIZE + TXFIFO_SIZE * MAX_NORMAL_EPS + EP_STATUS_SIZE <
+ FIFO_RAM_DEPTH);
+
+/* Now put those constants into the correct registers */
static void setup_data_fifos(void)
{
int i;
print_later("setup_data_fifos()", 0, 0, 0, 0, 0);
+ /* Programmer's Guide, p31 */
+ GR_USB_GRXFSIZ = RXFIFO_SIZE; /* RXFIFO */
+ GR_USB_GNPTXFSIZ = (TXFIFO_SIZE << 16) | RXFIFO_SIZE; /* TXFIFO 0 */
+
+ /* TXFIFO 1..15 */
+ for (i = 1; i < MAX_NORMAL_EPS; i++)
+ GR_USB_DIEPTXF(i) = ((TXFIFO_SIZE << 16) |
+ (RXFIFO_SIZE + i * TXFIFO_SIZE));
+
/*
- * Setup FIFOs configuration
- * RX FIFO needs more than 64 entries (for reserved space)
- * set RX FIFO to 80 entries
- * set TX FIFO to 64 bytes = 16 (x 32-bit) entries
+ * TODO: The Programmer's Guide is confusing about when or whether to
+ * flush the FIFOs. Section 2.1.1.2 (p31) just says to flush. Section
+ * 2.2.2 (p55) says to stop all the FIFOs first, then flush. Section
+ * 7.5.4 (p162) says that flushing the RXFIFO at reset is not
+ * recommended at all.
+ *
+ * I'm also unclear on whether or not the individual EPs are expected
+ * to be disabled already (DIEPCTLn/DOEPCTLn.EPENA == 0), and if so,
+ * whether by firmware or hardware.
*/
- GR_USB_GRXFSIZ = 80;
- GR_USB_GNPTXFSIZ = 80 | (16 << 16);
- for (i = 1; i < TX_FIFO_CNT; i++)
- GR_USB_DIEPTXF(i) = (80 + i*16) | (16 << 16);
- /* Flush all FIFOs */
+
+ /* Flush all FIFOs according to Section 2.1.1.2 */
GR_USB_GRSTCTL = GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH
- | GRSTCTL_RXFFLSH;
+ | GRSTCTL_RXFFLSH;
while (GR_USB_GRSTCTL & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH))
- ; /* timeout 100ms */
+ ; /* TODO: timeout 100ms */
}
static void usb_reset(void)