mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
Cr50: USB hardware uses 8-bit buffers, not 16-bit
Our USB buffers are just arrays of uint8_t in program RAM, so let's treat them that way. The DMA descriptors are in normal RAM, too. BUG=chrome-os-partner:40693 BRANCH=none TEST=make buildall Change-Id: Ibafe1a557a328bbf8cf37ce113675fcd35bad376 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/273918 Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
eaf2f26831
commit
41533aab3a
@@ -50,13 +50,6 @@
|
||||
/* Maximum number of deferrable functions */
|
||||
#define DEFERRABLE_MAX_COUNT 8
|
||||
|
||||
/* USB : TODO FIXME */
|
||||
#define CONFIG_USB_RAM_ACCESS_TYPE uint16_t
|
||||
/* No dedicated USB RAM */
|
||||
#define CONFIG_USB_RAM_BASE 0xdead0000
|
||||
#define CONFIG_USB_RAM_ACCESS_SIZE 0
|
||||
#define CONFIG_USB_RAM_SIZE 0
|
||||
|
||||
#define GPIO_PIN(port, index) GPIO_##port, (1 << index)
|
||||
#define GPIO_PIN_MASK(port, mask) GPIO_##port, (mask)
|
||||
|
||||
|
||||
50
chip/g/usb.c
50
chip/g/usb.c
@@ -95,9 +95,8 @@ struct g_usb_desc ep0_out_desc;
|
||||
struct g_usb_desc ep0_in_desc;
|
||||
|
||||
/* Control endpoint (EP0) buffers */
|
||||
static usb_uint ep0_buf_tx[USB_MAX_PACKET_SIZE / 2] /*__usb_ram*/;
|
||||
static usb_uint ep0_buf_rx[USB_MAX_PACKET_SIZE / 2] /*__usb_ram*/;
|
||||
|
||||
static uint8_t ep0_buf_tx[USB_MAX_PACKET_SIZE];
|
||||
static uint8_t ep0_buf_rx[USB_MAX_PACKET_SIZE];
|
||||
|
||||
static int set_addr;
|
||||
/* remaining size of descriptor data to transfer */
|
||||
@@ -109,7 +108,6 @@ static const uint8_t *desc_ptr;
|
||||
static void ep0_rx(void)
|
||||
{
|
||||
uint32_t epint = GR_USB_DOEPINT(0);
|
||||
uint16_t req = ep0_buf_rx[0]; /* bRequestType | bRequest */
|
||||
|
||||
GR_USB_DOEPINT(0) = epint; /* clear IT */
|
||||
|
||||
@@ -117,19 +115,20 @@ static void ep0_rx(void)
|
||||
desc_ptr = NULL;
|
||||
|
||||
/* interface specific requests */
|
||||
if ((req & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
|
||||
uint8_t iface = ep0_buf_rx[2] & 0xff;
|
||||
if ((ep0_buf_rx[0] & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
|
||||
uint8_t iface = ep0_buf_rx[4];
|
||||
if (iface < USB_IFACE_COUNT &&
|
||||
usb_iface_request[iface](ep0_buf_rx, ep0_buf_tx))
|
||||
goto unknown_req;
|
||||
return;
|
||||
}
|
||||
|
||||
if (req == (USB_DIR_IN | (USB_REQ_GET_DESCRIPTOR << 8))) {
|
||||
uint8_t type = ep0_buf_rx[1] >> 8;
|
||||
uint8_t idx = ep0_buf_rx[1] & 0xff;
|
||||
if (ep0_buf_rx[0] == USB_DIR_IN &&
|
||||
ep0_buf_rx[1] == USB_REQ_GET_DESCRIPTOR) {
|
||||
uint8_t type = ep0_buf_rx[3];
|
||||
uint8_t idx = ep0_buf_rx[2];
|
||||
const uint8_t *desc;
|
||||
int len;
|
||||
int len, req_len;
|
||||
|
||||
switch (type) {
|
||||
case USB_DT_DEVICE: /* Setup : Get device descriptor */
|
||||
@@ -160,7 +159,8 @@ static void ep0_rx(void)
|
||||
goto unknown_req;
|
||||
}
|
||||
/* do not send more than what the host asked for */
|
||||
len = MIN(ep0_buf_rx[3], len);
|
||||
req_len = (((unsigned int)ep0_buf_rx[7]) << 8) + ep0_buf_rx[6];
|
||||
len = MIN(req_len, len);
|
||||
/*
|
||||
* if we cannot transmit everything at once,
|
||||
* keep the remainder for the next IN packet
|
||||
@@ -170,10 +170,12 @@ static void ep0_rx(void)
|
||||
desc_ptr = desc + USB_MAX_PACKET_SIZE;
|
||||
len = USB_MAX_PACKET_SIZE;
|
||||
}
|
||||
memcpy_to_usbram(ep0_buf_tx, desc, len);
|
||||
if (type == USB_DT_CONFIGURATION)
|
||||
memcpy(ep0_buf_tx, desc, len);
|
||||
if (type == USB_DT_CONFIGURATION) {
|
||||
/* set the real descriptor size */
|
||||
ep0_buf_tx[1] = USB_DESC_SIZE;
|
||||
ep0_buf_tx[2] = USB_DESC_SIZE & 0xff;
|
||||
ep0_buf_tx[3] = (USB_DESC_SIZE & 0xff00) >> 8;
|
||||
}
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY |
|
||||
DIEPDMA_IOC | DIEPDMA_TXBYTES(len);
|
||||
GR_USB_DIEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
@@ -181,21 +183,22 @@ static void ep0_rx(void)
|
||||
| DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
|
||||
GR_USB_DOEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
/* send the null OUT transaction if the transfer is complete */
|
||||
} else if (req == (USB_DIR_IN | (USB_REQ_GET_STATUS << 8))) {
|
||||
} else if (ep0_buf_rx[0] == USB_DIR_IN &&
|
||||
ep0_buf_rx[1] == USB_REQ_GET_STATUS) {
|
||||
uint16_t zero = 0;
|
||||
/* Get status */
|
||||
memcpy_to_usbram(ep0_buf_tx, (void *)&zero, 2);
|
||||
memcpy(ep0_buf_tx, &zero, 2);
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
|
||||
DIEPDMA_TXBYTES(2);
|
||||
GR_USB_DIEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
ep0_out_desc.flags = DOEPDMA_RXBYTES(64) | DOEPDMA_LAST
|
||||
| DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
|
||||
GR_USB_DOEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
} else if ((req & 0xff) == USB_DIR_OUT) {
|
||||
switch (req >> 8) {
|
||||
} else if (ep0_buf_rx[0] == USB_DIR_OUT) {
|
||||
switch (ep0_buf_rx[1]) {
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
/* set the address after we got IN packet handshake */
|
||||
set_addr = ep0_buf_rx[1] & 0xff;
|
||||
set_addr = ep0_buf_rx[2];
|
||||
/* need null IN transaction -> TX Valid */
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
|
||||
DIEPDMA_TXBYTES(0) | DIEPDMA_SP;
|
||||
@@ -205,7 +208,7 @@ static void ep0_rx(void)
|
||||
GR_USB_DOEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
break;
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
/* uint8_t cfg = ep0_buf_rx[1] & 0xff; */
|
||||
/* uint8_t cfg = ep0_buf_rx[2]; */
|
||||
/* null IN for handshake */
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
|
||||
DIEPDMA_TXBYTES(0) | DIEPDMA_SP;
|
||||
@@ -246,7 +249,7 @@ static void ep0_tx(void)
|
||||
if (desc_ptr) {
|
||||
/* we have an on-going descriptor transfer */
|
||||
int len = MIN(desc_left, USB_MAX_PACKET_SIZE);
|
||||
memcpy_to_usbram(ep0_buf_tx, desc_ptr, len);
|
||||
memcpy(ep0_buf_tx, desc_ptr, len);
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY |
|
||||
DIEPDMA_IOC | DIEPDMA_TXBYTES(len);
|
||||
desc_left -= len;
|
||||
@@ -454,8 +457,3 @@ void usb_release(void)
|
||||
clock_enable_module(MODULE_USB, 0);
|
||||
/* TODO: pin-mux */
|
||||
}
|
||||
|
||||
void *memcpy_to_usbram(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_CONSOLE, 1) =
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
static usb_uint ep_buf_tx[USB_MAX_PACKET_SIZE / 2] /*__usb_ram*/;
|
||||
static usb_uint ep_buf_rx[USB_MAX_PACKET_SIZE / 2] /*__usb_ram*/;
|
||||
static uint8_t ep_buf_tx[USB_MAX_PACKET_SIZE];
|
||||
static uint8_t ep_buf_rx[USB_MAX_PACKET_SIZE];
|
||||
static struct g_usb_desc ep_out_desc;
|
||||
static struct g_usb_desc ep_in_desc;
|
||||
|
||||
@@ -82,9 +82,7 @@ static void con_ep_rx(void)
|
||||
for (i = 0; i < rx_size; i++) {
|
||||
int rx_buf_next = RX_BUF_NEXT(rx_buf_head);
|
||||
if (rx_buf_next != rx_buf_tail) {
|
||||
rx_buf[rx_buf_head] = ((i & 1) ?
|
||||
(ep_buf_rx[i >> 1] >> 8) :
|
||||
(ep_buf_rx[i >> 1] & 0xff));
|
||||
rx_buf[rx_buf_head] = ep_buf_rx[i];
|
||||
rx_buf_head = rx_buf_next;
|
||||
}
|
||||
}
|
||||
@@ -123,7 +121,6 @@ USB_DECLARE_EP(USB_EP_CONSOLE, con_ep_tx, con_ep_rx, ep_reset);
|
||||
|
||||
static int __tx_char(void *context, int c)
|
||||
{
|
||||
usb_uint *buf = (usb_uint *)ep_buf_tx;
|
||||
int *tx_idx = context;
|
||||
|
||||
/* Do newline to CRLF translation */
|
||||
@@ -132,10 +129,8 @@ static int __tx_char(void *context, int c)
|
||||
|
||||
if (*tx_idx > 63)
|
||||
return 1;
|
||||
if (!(*tx_idx & 1))
|
||||
buf[*tx_idx/2] = c;
|
||||
else
|
||||
buf[*tx_idx/2] |= c << 8;
|
||||
|
||||
ep_buf_tx[*tx_idx] = c;
|
||||
(*tx_idx)++;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -87,12 +87,12 @@ static const uint8_t report_desc[] = {
|
||||
0x00 /* Padding */
|
||||
};
|
||||
|
||||
static usb_uint hid_ep_buf[HID_REPORT_SIZE / 2] /*__usb_ram*/;
|
||||
static uint8_t hid_ep_buf[HID_REPORT_SIZE];
|
||||
static struct g_usb_desc hid_ep_desc;
|
||||
|
||||
void set_keyboard_report(uint64_t rpt)
|
||||
{
|
||||
memcpy_to_usbram(hid_ep_buf, (const uint8_t *)&rpt, sizeof(rpt));
|
||||
memcpy(hid_ep_buf, &rpt, sizeof(rpt));
|
||||
hid_ep_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY | DIEPDMA_IOC |
|
||||
DIEPDMA_TXBYTES(HID_REPORT_SIZE);
|
||||
/* enable TX */
|
||||
@@ -122,22 +122,22 @@ USB_DECLARE_EP(USB_EP_HID, hid_tx, hid_tx, hid_reset);
|
||||
extern struct g_usb_desc ep0_in_desc;
|
||||
extern struct g_usb_desc ep0_out_desc;
|
||||
|
||||
static int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
|
||||
static int hid_iface_request(uint8_t *ep0_buf_rx, uint8_t *ep0_buf_tx)
|
||||
{
|
||||
int len;
|
||||
int len, req_len;
|
||||
|
||||
if ((ep0_buf_rx[0] == (USB_DIR_IN | USB_RECIP_INTERFACE |
|
||||
(USB_REQ_GET_DESCRIPTOR << 8))) &&
|
||||
(ep0_buf_rx[1] == (USB_HID_DT_REPORT << 8))) {
|
||||
if (ep0_buf_rx[0] == (USB_DIR_IN | USB_RECIP_INTERFACE) &&
|
||||
ep0_buf_rx[1] == USB_REQ_GET_DESCRIPTOR &&
|
||||
ep0_buf_rx[3] == USB_HID_DT_REPORT) {
|
||||
/* Setup : HID specific : Get Report descriptor */
|
||||
memcpy_to_usbram(ep0_buf_tx, report_desc,
|
||||
sizeof(report_desc));
|
||||
len = MIN(ep0_buf_rx[3], sizeof(report_desc));
|
||||
memcpy(ep0_buf_tx, report_desc, sizeof(report_desc));
|
||||
req_len = (((unsigned int)ep0_buf_rx[7]) << 8) + ep0_buf_rx[6];
|
||||
len = MIN(req_len, sizeof(report_desc));
|
||||
ep0_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_RDY |
|
||||
DIEPDMA_IOC | DIEPDMA_TXBYTES(len);
|
||||
DIEPDMA_IOC | DIEPDMA_TXBYTES(len);
|
||||
GR_USB_DIEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
ep0_out_desc.flags = DOEPDMA_RXBYTES(64) | DOEPDMA_LAST
|
||||
| DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
|
||||
| DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
|
||||
GR_USB_DOEPCTL(0) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,55 +6,6 @@
|
||||
#ifndef __CROS_EC_USB_HW_H
|
||||
#define __CROS_EC_USB_HW_H
|
||||
|
||||
/*
|
||||
* The STM32 has dedicated USB RAM visible on the APB1 bus (so all reads &
|
||||
* writes are 16-bits wide). The endpoint tables and the data buffers live in
|
||||
* this RAM.
|
||||
*/
|
||||
|
||||
/* Primitive to access the words in USB RAM */
|
||||
typedef CONFIG_USB_RAM_ACCESS_TYPE usb_uint;
|
||||
/* Linker symbol for start of USB RAM */
|
||||
extern usb_uint __usb_ram_start[];
|
||||
|
||||
/* Attribute to define a buffer variable in USB RAM */
|
||||
#define __usb_ram __attribute__((section(".usb_ram.data")))
|
||||
|
||||
struct stm32_endpoint {
|
||||
volatile usb_uint tx_addr;
|
||||
volatile usb_uint tx_count;
|
||||
volatile usb_uint rx_addr;
|
||||
volatile usb_uint rx_count;
|
||||
};
|
||||
|
||||
extern struct stm32_endpoint btable_ep[];
|
||||
|
||||
/* Attribute to put the endpoint table in USB RAM */
|
||||
#define __usb_btable __attribute__((section(".usb_ram.btable")))
|
||||
|
||||
/* Read from USB RAM into a usb_setup_packet struct */
|
||||
struct usb_setup_packet;
|
||||
void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet);
|
||||
|
||||
/*
|
||||
* Copy data to and from the USB dedicated RAM and take care of the weird
|
||||
* addressing. These functions correctly handle unaligned accesses to the USB
|
||||
* memory. They have the same prototype as memcpy, allowing them to be used
|
||||
* in places that expect memcpy. The void pointer used to represent a location
|
||||
* in the USB dedicated RAM should be the offset in that address space, not the
|
||||
* AHB address space.
|
||||
*
|
||||
* The USB packet RAM is attached to the processor via the AHB2APB bridge. This
|
||||
* bridge performs manipulations of read and write accesses as per the note in
|
||||
* section 2.1 of RM0091. The upshot is that custom memcpy-like routines need
|
||||
* to be employed.
|
||||
*/
|
||||
void *memcpy_to_usbram(void *dest, const void *src, size_t n);
|
||||
void *memcpy_from_usbram(void *dest, const void *src, size_t n);
|
||||
|
||||
/* Compute the address inside dedicate SRAM for the USB controller */
|
||||
#define usb_sram_addr(x) ((x - __usb_ram_start) * sizeof(uint16_t))
|
||||
|
||||
/* Helpers for endpoint declaration */
|
||||
#define _EP_HANDLER2(num, suffix) CONCAT3(ep_, num, suffix)
|
||||
#define _EP_TX_HANDLER(num) _EP_HANDLER2(num, _tx)
|
||||
@@ -74,12 +25,12 @@ extern void (*usb_ep_tx[]) (void);
|
||||
extern void (*usb_ep_rx[]) (void);
|
||||
extern void (*usb_ep_reset[]) (void);
|
||||
/* array with interface-specific control request callbacks */
|
||||
extern int (*usb_iface_request[]) (usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx);
|
||||
extern int (*usb_iface_request[]) (uint8_t *ep0_buf_rx, uint8_t *ep0_buf_tx);
|
||||
|
||||
#define _IFACE_HANDLER(num) CONCAT3(iface_, num, _request)
|
||||
#define USB_DECLARE_IFACE(num, handler) \
|
||||
int _IFACE_HANDLER(num)(usb_uint *ep0_buf_rx, \
|
||||
usb_uint *epo_buf_tx) \
|
||||
int _IFACE_HANDLER(num)(uint8_t *ep0_buf_rx, \
|
||||
uint8_t *epo_buf_tx) \
|
||||
__attribute__ ((alias(STRINGIFY(handler))));
|
||||
|
||||
#endif /* __CROS_EC_USB_HW_H */
|
||||
|
||||
@@ -26,7 +26,7 @@ MEMORY
|
||||
PSTATE(r) : ORIGIN = FW_OFF(SECTION) + FW_SIZE(SECTION), \
|
||||
LENGTH = CONFIG_FW_PSTATE_SIZE
|
||||
#endif
|
||||
#ifdef CONFIG_USB
|
||||
#ifdef CONFIG_USB_RAM_SIZE
|
||||
USB_RAM (rw) : \
|
||||
ORIGIN = CONFIG_USB_RAM_BASE, \
|
||||
LENGTH = CONFIG_USB_RAM_SIZE * CONFIG_USB_RAM_ACCESS_SIZE / 2
|
||||
@@ -278,7 +278,7 @@ SECTIONS
|
||||
(LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION)),
|
||||
"No room left in the flash")
|
||||
|
||||
#ifdef CONFIG_USB
|
||||
#ifdef CONFIG_USB_RAM_SIZE
|
||||
.usb_ram (NOLOAD) : {
|
||||
__usb_ram_start = .;
|
||||
. = ALIGN(8);
|
||||
|
||||
@@ -23,7 +23,7 @@ MEMORY
|
||||
PSTATE(r) : ORIGIN = FW_OFF(SECTION) + FW_SIZE(SECTION), \
|
||||
LENGTH = CONFIG_FW_PSTATE_SIZE
|
||||
#endif
|
||||
#ifdef CONFIG_USB
|
||||
#ifdef CONFIG_USB_RAM_SIZE
|
||||
USB_RAM (rw) : \
|
||||
ORIGIN = CONFIG_USB_RAM_BASE, \
|
||||
LENGTH = CONFIG_USB_RAM_SIZE * CONFIG_USB_RAM_ACCESS_SIZE / 2
|
||||
@@ -246,7 +246,7 @@ SECTIONS
|
||||
(LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION)),
|
||||
"No room left in the flash")
|
||||
|
||||
#ifdef CONFIG_USB
|
||||
#ifdef CONFIG_USB_RAM_SIZE
|
||||
.usb_ram (NOLOAD) : {
|
||||
__usb_ram_start = .;
|
||||
. = ALIGN(8);
|
||||
|
||||
@@ -1381,7 +1381,7 @@
|
||||
/* Compile chip support for the USB device controller */
|
||||
#undef CONFIG_USB
|
||||
|
||||
/* USB device buffers and descriptors */
|
||||
/* USB device buffers and descriptors in dedicated RAM */
|
||||
#undef CONFIG_USB_RAM_ACCESS_SIZE
|
||||
#undef CONFIG_USB_RAM_ACCESS_TYPE
|
||||
#undef CONFIG_USB_RAM_BASE
|
||||
|
||||
Reference in New Issue
Block a user