mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-26 13:44:29 +08:00
usb: mv_udc: Add proper cache management
Implement functions to flush/invalidate dcache over QH and qTDs and make use of them where appropriate. Also use them to replace the old incorrect cache management attempt. This is the first step towards making this driver work with data cache enabled. 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>
This commit is contained in:
parent
ede709c0d2
commit
f19a343e73
@ -136,6 +136,68 @@ static struct ept_queue_item *mv_get_qtd(int ep_num, int dir_in)
|
||||
return controller.items[(ep_num * 2) + dir_in];
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_flush_qh - flush cache over queue head
|
||||
* @ep_num: Endpoint number
|
||||
*
|
||||
* This function flushes cache over QH for particular endpoint.
|
||||
*/
|
||||
static void mv_flush_qh(int ep_num)
|
||||
{
|
||||
struct ept_queue_head *head = mv_get_qh(ep_num, 0);
|
||||
const uint32_t start = (uint32_t)head;
|
||||
const uint32_t end = start + 2 * sizeof(*head);
|
||||
|
||||
flush_dcache_range(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_invalidate_qh - invalidate cache over queue head
|
||||
* @ep_num: Endpoint number
|
||||
*
|
||||
* This function invalidates cache over QH for particular endpoint.
|
||||
*/
|
||||
static void mv_invalidate_qh(int ep_num)
|
||||
{
|
||||
struct ept_queue_head *head = mv_get_qh(ep_num, 0);
|
||||
uint32_t start = (uint32_t)head;
|
||||
uint32_t end = start + 2 * sizeof(*head);
|
||||
|
||||
invalidate_dcache_range(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_flush_qtd - flush cache over queue item
|
||||
* @ep_num: Endpoint number
|
||||
*
|
||||
* This function flushes cache over qTD pair for particular endpoint.
|
||||
*/
|
||||
static void mv_flush_qtd(int ep_num)
|
||||
{
|
||||
struct ept_queue_item *item = mv_get_qtd(ep_num, 0);
|
||||
const uint32_t start = (uint32_t)item;
|
||||
const uint32_t end_raw = start + 2 * sizeof(*item);
|
||||
const uint32_t end = roundup(end_raw, ARCH_DMA_MINALIGN);
|
||||
|
||||
flush_dcache_range(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_invalidate_qtd - invalidate cache over queue item
|
||||
* @ep_num: Endpoint number
|
||||
*
|
||||
* This function invalidates cache over qTD pair for particular endpoint.
|
||||
*/
|
||||
static void mv_invalidate_qtd(int ep_num)
|
||||
{
|
||||
struct ept_queue_item *item = mv_get_qtd(ep_num, 0);
|
||||
const uint32_t start = (uint32_t)item;
|
||||
const uint32_t end_raw = start + 2 * sizeof(*item);
|
||||
const uint32_t end = roundup(end_raw, ARCH_DMA_MINALIGN);
|
||||
|
||||
invalidate_dcache_range(start, end);
|
||||
}
|
||||
|
||||
static struct usb_request *
|
||||
mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
|
||||
{
|
||||
@ -161,8 +223,10 @@ static void ep_enable(int num, int in)
|
||||
else
|
||||
n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
|
||||
|
||||
if (num != 0)
|
||||
if (num != 0) {
|
||||
head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) | CONFIG_ZLT;
|
||||
mv_flush_qh(num);
|
||||
}
|
||||
writel(n, &udc->epctrl[num]);
|
||||
}
|
||||
|
||||
@ -215,8 +279,9 @@ static int mv_ep_queue(struct usb_ep *ep,
|
||||
else
|
||||
bit = EPT_RX(num);
|
||||
|
||||
flush_cache(phys, len);
|
||||
flush_cache((unsigned long)item, sizeof(struct ept_queue_item));
|
||||
mv_flush_qh(num);
|
||||
mv_flush_qtd(num);
|
||||
|
||||
writel(bit, &udc->epprime);
|
||||
|
||||
return 0;
|
||||
@ -231,7 +296,8 @@ static void handle_ep_complete(struct mv_ep *ep)
|
||||
if (num == 0)
|
||||
ep->desc = &ep0_out_desc;
|
||||
item = mv_get_qtd(num, in);
|
||||
|
||||
mv_invalidate_qtd(num);
|
||||
|
||||
if (item->info & 0xff)
|
||||
printf("EP%d/%s FAIL nfo=%x pg0=%x\n",
|
||||
num, in ? "in" : "out", item->info, item->page0);
|
||||
@ -261,7 +327,7 @@ static void handle_setup(void)
|
||||
char *buf;
|
||||
head = mv_get_qh(0, 0); /* EP0 OUT */
|
||||
|
||||
flush_cache((unsigned long)head, sizeof(struct ept_queue_head));
|
||||
mv_invalidate_qh(0);
|
||||
memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest));
|
||||
writel(EPT_RX(0), &udc->epstat);
|
||||
DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
|
||||
@ -342,6 +408,7 @@ static void stop_activity(void)
|
||||
& USB_DIR_IN) != 0;
|
||||
head = mv_get_qh(num, in);
|
||||
head->info = INFO_ACTIVE;
|
||||
mv_flush_qh(num);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -513,6 +580,11 @@ static int mvudc_probe(void)
|
||||
imem += sizeof(struct ept_queue_item);
|
||||
|
||||
controller.items[i] = (struct ept_queue_item *)imem;
|
||||
|
||||
if (i & 1) {
|
||||
mv_flush_qh(i - 1);
|
||||
mv_flush_qtd(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&controller.gadget.ep_list);
|
||||
|
Loading…
Reference in New Issue
Block a user