diff options
author | Marek Vasut <marex@denx.de> | 2013-07-10 03:16:40 +0200 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2013-07-29 23:01:32 +0200 |
commit | 8a095a68ce8e7989dec6af4011f0f41bbc554f22 (patch) | |
tree | 5953b488cc016d5233b629e45cde9cea5a044e36 /drivers | |
parent | b5cd45bfad3a25db25b40cfda9e7db80e5ee65f7 (diff) | |
download | u-boot-imx-8a095a68ce8e7989dec6af4011f0f41bbc554f22.zip u-boot-imx-8a095a68ce8e7989dec6af4011f0f41bbc554f22.tar.gz u-boot-imx-8a095a68ce8e7989dec6af4011f0f41bbc554f22.tar.bz2 |
usb: mv_udc: Improve allocation of qTD items
Allocate the qTD items all at once instead of allocating them
separately. Moreover, make sure each qTD is properly aligned
to 32-bytes boundary and that cache can be safely flushed over
each qTD touple.
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.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 04787be..dbdf878 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -444,6 +444,7 @@ void udc_disconnect(void) static int mvudc_probe(void) { struct ept_queue_head *head; + uint8_t *imem; int i; const int num = 2 * NUM_ENDPOINTS; @@ -453,12 +454,29 @@ static int mvudc_probe(void) const int eplist_raw_sz = num * sizeof(struct ept_queue_head); const int eplist_sz = roundup(eplist_raw_sz, ARCH_DMA_MINALIGN); + const int ilist_align = roundup(ARCH_DMA_MINALIGN, 32); + const int ilist_ent_raw_sz = 2 * sizeof(struct ept_queue_item); + const int ilist_ent_sz = roundup(ilist_ent_raw_sz, ARCH_DMA_MINALIGN); + const int ilist_sz = NUM_ENDPOINTS * ilist_ent_sz; + /* 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); + /* + * Each qTD item must be 32-byte aligned, each qTD touple must be + * cacheline aligned. There are two qTD items for each endpoint and + * only one of them is used for the endpoint at time, so we can group + * them together. + */ + controller.items_mem = memalign(ilist_align, ilist_sz); + if (!controller.items_mem) { + free(controller.epts); + return -ENOMEM; + } + for (i = 0; i < 2 * NUM_ENDPOINTS; i++) { /* * Configure QH for each endpoint. The structure of the QH list @@ -477,8 +495,11 @@ static int mvudc_probe(void) head->next = TERMINATE; head->info = 0; - controller.items[i] = memalign(roundup(32, ARCH_DMA_MINALIGN), - sizeof(struct ept_queue_item)); + imem = controller.items_mem + ((i >> 1) * ilist_ent_sz); + if (i & 1) + imem += sizeof(struct ept_queue_item); + + controller.items[i] = (struct ept_queue_item *)imem; } INIT_LIST_HEAD(&controller.gadget.ep_list); |