X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fehci-hcd.c;h=13aa70d606614a61eb0db6fd04a4651786958671;hb=5cf618ee60a752d058a767372ca1ecb8d9c09b16;hp=c85dbcecfa739fb2b43a3e162ac5ed441c29cfca;hpb=2431492aef1de33bd222c97ecc131a338d9c454e;p=u-boot diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c85dbcecfa..13aa70d606 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -134,6 +134,8 @@ static void ehci_set_usbmode(struct ehci_ctrl *ctrl) tmp |= USBMODE_CM_HC; #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN) tmp |= USBMODE_BE; +#else + tmp &= ~USBMODE_BE; #endif ehci_writel(reg_ptr, tmp); } @@ -208,6 +210,9 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) return -EINVAL; cmd = ehci_readl(&ctrl->hcor->or_usbcmd); + /* If not run, directly return */ + if (!(cmd & CMD_RUN)) + return 0; cmd &= ~(CMD_PSE | CMD_ASE); ehci_writel(&ctrl->hcor->or_usbcmd, cmd); ret = handshake(&ctrl->hcor->or_usbsts, STS_ASS | STS_PSS, 0, @@ -235,7 +240,7 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) { uint32_t delta, next; - uint32_t addr = (unsigned long)buf; + unsigned long addr = (unsigned long)buf; int idx; if (addr != ALIGN(addr, ARCH_DMA_MINALIGN)) @@ -245,7 +250,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; @@ -279,56 +284,16 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed) static void ehci_update_endpt2_dev_n_port(struct usb_device *udev, struct QH *qh) { - struct usb_device *ttdev; - int parent_devnum; + uint8_t portnr = 0; + uint8_t hubaddr = 0; if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL) return; - /* - * For full / low speed devices we need to get the devnum and portnr of - * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs - * in the tree before that one! - */ -#ifdef CONFIG_DM_USB - /* - * When called from usb-uclass.c: usb_scan_device() udev->dev points - * to the parent udevice, not the actual udevice belonging to the - * udev as the device is not instantiated yet. So when searching - * for the first usb-2 parent start with udev->dev not - * udev->dev->parent . - */ - struct udevice *parent; - struct usb_device *uparent; - - ttdev = udev; - parent = udev->dev; - uparent = dev_get_parent_priv(parent); + usb_find_usb2_hub_address_port(udev, &hubaddr, &portnr); - while (uparent->speed != USB_SPEED_HIGH) { - struct udevice *dev = parent; - - if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) { - printf("ehci: Error cannot find high-speed parent of usb-1 device\n"); - return; - } - - ttdev = dev_get_parent_priv(dev); - parent = dev->parent; - uparent = dev_get_parent_priv(parent); - } - parent_devnum = uparent->devnum; -#else - ttdev = udev; - while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH) - ttdev = ttdev->parent; - if (!ttdev->parent) - return; - parent_devnum = ttdev->parent->devnum; -#endif - - qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) | - QH_ENDPT2_HUBADDR(parent_devnum)); + qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(portnr) | + QH_ENDPT2_HUBADDR(hubaddr)); } static int @@ -438,7 +403,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) | @@ -455,7 +420,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) @@ -478,7 +442,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; } @@ -537,7 +501,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 @@ -568,11 +532,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, @@ -582,7 +546,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)); @@ -1029,7 +993,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); @@ -1041,7 +1005,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 @@ -1654,6 +1618,12 @@ int ehci_register(struct udevice *dev, struct ehci_hccr *hccr, if (ret) goto err; + if (ctrl->ops.init_after_reset) { + ret = ctrl->ops.init_after_reset(ctrl); + if (ret) + goto err; + } + ret = ehci_common_init(ctrl, tweaks); if (ret) goto err;