summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2013-07-10 03:16:37 +0200
committerMarek Vasut <marex@denx.de>2013-07-29 23:01:32 +0200
commitab65da1446d8ba423514c2236291962adf2bd2a6 (patch)
tree9a944d2572fb5500a1a72c53b6b79ba59842f6de /drivers
parentab52df19c1195699516430be14b6be2d27229444 (diff)
downloadu-boot-imx-ab65da1446d8ba423514c2236291962adf2bd2a6.zip
u-boot-imx-ab65da1446d8ba423514c2236291962adf2bd2a6.tar.gz
u-boot-imx-ab65da1446d8ba423514c2236291962adf2bd2a6.tar.bz2
usb: mv_udc: Properly align the endpoint QH and qTD list
The endpoint QH list has to be aligned to 10-bit boundary. We also have to make sure the list is aligned on a cacheline boundary. Make sure it is. Furthermore, check if the memory allocation for the QH list didn't fail. Moveover, improve the comment about the QH list structure. Finally, the qTD item list has to be aligned only to 5-bit boundary, not 10-bit as it is now, fix this as well. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Lei Wen <leiwen@marvell.com> Cc: Otavio Salvador <otavio@ossystems.com.br> Cc: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/mv_udc.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c
index 9ff6bbb..bbf4418 100644
--- a/drivers/usb/gadget/mv_udc.c
+++ b/drivers/usb/gadget/mv_udc.c
@@ -43,8 +43,6 @@ static const char *reqname(unsigned r)
}
#endif
-#define PAGE_SIZE 4096
-
static struct usb_endpoint_descriptor ep0_out_desc = {
.bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DT_ENDPOINT,
@@ -424,15 +422,27 @@ static int mvudc_probe(void)
{
struct ept_queue_head *head;
int i;
+
const int num = 2 * NUM_ENDPOINTS;
- controller.epts = memalign(PAGE_SIZE,
- num * sizeof(struct ept_queue_head));
- memset(controller.epts, 0, num * sizeof(struct ept_queue_head));
+ const int eplist_min_align = 4096;
+ const int eplist_align = roundup(eplist_min_align, ARCH_DMA_MINALIGN);
+ const int eplist_raw_sz = num * sizeof(struct ept_queue_head);
+ const int eplist_sz = roundup(eplist_raw_sz, ARCH_DMA_MINALIGN);
+
+ /* The QH list must be aligned to 4096 bytes. */
+ controller.epts = memalign(eplist_align, eplist_sz);
+ if (!controller.epts)
+ return -ENOMEM;
+ memset(controller.epts, 0, eplist_sz);
+
for (i = 0; i < 2 * NUM_ENDPOINTS; i++) {
/*
- * For item0 and item1, they are served as ep0
- * out&in seperately
+ * Configure QH for each endpoint. The structure of the QH list
+ * is such that each two subsequent fields, N and N+1 where N is
+ * even, in the QH list represent QH for one endpoint. The Nth
+ * entry represents OUT configuration and the N+1th entry does
+ * represent IN configuration of the endpoint.
*/
head = controller.epts + i;
if (i < 2)
@@ -444,7 +454,7 @@ static int mvudc_probe(void)
head->next = TERMINATE;
head->info = 0;
- controller.items[i] = memalign(PAGE_SIZE,
+ controller.items[i] = memalign(roundup(32, ARCH_DMA_MINALIGN),
sizeof(struct ept_queue_item));
}