mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 08:01:08 +00:00
usb: ehci: Implement V2P mapping
Certain processor architectures, like MIPS, require that the USB structures and transfer buffers are passed with their PA to the USB controller. If VA is passed, the USB will not work. Add the necessary virt_to_phys() calls into the USB EHCI code to make it work. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Cc: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
643cacb6d6
commit
cf7c93cdd7
1 changed files with 9 additions and 10 deletions
|
@ -245,7 +245,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
|
|||
|
||||
idx = 0;
|
||||
while (idx < QT_BUFFER_CNT) {
|
||||
td->qt_buffer[idx] = cpu_to_hc32(addr);
|
||||
td->qt_buffer[idx] = cpu_to_hc32(virt_to_phys((void *)addr));
|
||||
td->qt_buffer_hi[idx] = 0;
|
||||
next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1);
|
||||
delta = next - addr;
|
||||
|
@ -398,7 +398,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
* qh_overlay.qt_next ...... 13-10 H
|
||||
* - qh_overlay.qt_altnext
|
||||
*/
|
||||
qh->qh_link = cpu_to_hc32((unsigned long)&ctrl->qh_list | QH_LINK_TYPE_QH);
|
||||
qh->qh_link = cpu_to_hc32(virt_to_phys(&ctrl->qh_list) | QH_LINK_TYPE_QH);
|
||||
c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
|
||||
maxpacket = usb_maxpacket(dev, pipe);
|
||||
endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
|
||||
|
@ -415,7 +415,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||
|
||||
tdp = &qh->qh_overlay.qt_next;
|
||||
|
||||
if (req != NULL) {
|
||||
/*
|
||||
* Setup request qTD (3.5 in ehci-r10.pdf)
|
||||
|
@ -438,7 +437,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
goto fail;
|
||||
}
|
||||
/* Update previous qTD! */
|
||||
*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
|
||||
*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
|
||||
tdp = &qtd[qtd_counter++].qt_next;
|
||||
toggle = 1;
|
||||
}
|
||||
|
@ -497,7 +496,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
goto fail;
|
||||
}
|
||||
/* Update previous qTD! */
|
||||
*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
|
||||
*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
|
||||
tdp = &qtd[qtd_counter++].qt_next;
|
||||
/*
|
||||
* Data toggle has to be adjusted since the qTD transfer
|
||||
|
@ -528,11 +527,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
|
||||
qtd[qtd_counter].qt_token = cpu_to_hc32(token);
|
||||
/* Update previous qTD! */
|
||||
*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
|
||||
*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
|
||||
tdp = &qtd[qtd_counter++].qt_next;
|
||||
}
|
||||
|
||||
ctrl->qh_list.qh_link = cpu_to_hc32((unsigned long)qh | QH_LINK_TYPE_QH);
|
||||
ctrl->qh_list.qh_link = cpu_to_hc32(virt_to_phys(qh) | QH_LINK_TYPE_QH);
|
||||
|
||||
/* Flush dcache */
|
||||
flush_dcache_range((unsigned long)&ctrl->qh_list,
|
||||
|
@ -542,7 +541,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
|
||||
|
||||
/* Set async. queue head pointer. */
|
||||
ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)&ctrl->qh_list);
|
||||
ehci_writel(&ctrl->hcor->or_asynclistaddr, virt_to_phys(&ctrl->qh_list));
|
||||
|
||||
usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
|
||||
ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
|
||||
|
@ -989,7 +988,7 @@ static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
|
|||
|
||||
/* Set head of reclaim list */
|
||||
memset(qh_list, 0, sizeof(*qh_list));
|
||||
qh_list->qh_link = cpu_to_hc32((unsigned long)qh_list | QH_LINK_TYPE_QH);
|
||||
qh_list->qh_link = cpu_to_hc32(virt_to_phys(qh_list) | QH_LINK_TYPE_QH);
|
||||
qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) |
|
||||
QH_ENDPT1_EPS(USB_SPEED_HIGH));
|
||||
qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||
|
@ -1001,7 +1000,7 @@ static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
|
|||
ALIGN_END_ADDR(struct QH, qh_list, 1));
|
||||
|
||||
/* Set async. queue head pointer. */
|
||||
ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)qh_list);
|
||||
ehci_writel(&ctrl->hcor->or_asynclistaddr, virt_to_phys(qh_list));
|
||||
|
||||
/*
|
||||
* Set up periodic list
|
||||
|
|
Loading…
Reference in a new issue