diff options
author | Tom Rini <trini@konsulko.com> | 2024-11-26 08:05:11 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-11-26 08:05:11 -0600 |
commit | 9e66cb41ee78f5c1c872eaa2d8dcd95927a10311 (patch) | |
tree | aef438dac40671b05d8c4e1a0df3614d78d6dd4a /drivers/usb | |
parent | 6b96e01d70342a61586ea1153fb60989796fac22 (diff) | |
parent | 35d967f5a8219adc47628247a98c302b1870313e (diff) | |
download | u-boot-9e66cb41ee78f5c1c872eaa2d8dcd95927a10311.tar.gz |
Merge tag 'u-boot-dfu-20241126' of https://source.denx.de/u-boot/custodians/u-boot-dfu
CI: https://source.denx.de/u-boot/custodians/u-boot-dfu/-/pipelines/23572
- Fastboot:
- handle unknown partition type as "raw"
- USB gadget:
- Fix ci_udc gadget driver for Tegra 2 devices by not using USBADRA
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/ci_udc.c | 24 | ||||
-rw-r--r-- | drivers/usb/gadget/ci_udc.h | 1 |
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index bbe03cfff1f..4bff75da759 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -649,12 +649,30 @@ static void flip_ep0_direction(void) } } +/* + * This function explicitly sets the address, without the "USBADRA" (advance) + * feature, which is not supported by older versions of the controller. + */ +static void ci_set_address(struct ci_udc *udc, u8 address) +{ + DBG("%s %x\n", __func__, address); + writel(address << 25, &udc->devaddr); +} + static void handle_ep_complete(struct ci_ep *ci_ep) { struct ept_queue_item *item, *next_td; int num, in, len, j; struct ci_req *ci_req; + /* Set the device address that was previously sent by SET_ADDRESS */ + if (controller.next_device_address != 0) { + struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; + + ci_set_address(udc, controller.next_device_address); + controller.next_device_address = 0; + } + num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; in = (ci_ep->desc->bEndpointAddress & USB_DIR_IN) != 0; item = ci_get_qtd(num, in); @@ -783,7 +801,7 @@ static void handle_setup(void) * write address delayed (will take effect * after the next IN txn) */ - writel((r.wValue << 25) | (1 << 24), &udc->devaddr); + controller.next_device_address = r.wValue; req->length = 0; usb_ep_queue(controller.gadget.ep0, req, 0); return; @@ -814,6 +832,9 @@ static void stop_activity(void) int i, num, in; struct ept_queue_head *head; struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; + + ci_set_address(udc, 0); + writel(readl(&udc->epcomp), &udc->epcomp); #ifdef CONFIG_CI_UDC_HAS_HOSTPC writel(readl(&udc->epsetupstat), &udc->epsetupstat); @@ -934,6 +955,7 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on) struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; if (is_on) { /* RESET */ + controller.next_device_address = 0; writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd); udelay(200); diff --git a/drivers/usb/gadget/ci_udc.h b/drivers/usb/gadget/ci_udc.h index bea2f9f3fe3..807f2084c1e 100644 --- a/drivers/usb/gadget/ci_udc.h +++ b/drivers/usb/gadget/ci_udc.h @@ -105,6 +105,7 @@ struct ci_drv { struct ept_queue_head *epts; uint8_t *items_mem; struct ci_ep ep[NUM_ENDPOINTS]; + u8 next_device_address; }; struct ept_queue_head { |