diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/dwc3/dwc3-generic.c | 9 | ||||
-rw-r--r-- | drivers/usb/eth/asix88179.c | 45 | ||||
-rw-r--r-- | drivers/usb/gadget/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/ci_udc.c | 24 | ||||
-rw-r--r-- | drivers/usb/gadget/ci_udc.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci-rcar-r8a779x_usb3_v3.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-rcar.c | 2 |
8 files changed, 72 insertions, 19 deletions
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 2ab41cbae45..55e62b35c61 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -51,7 +51,8 @@ struct dwc3_generic_host_priv { }; static int dwc3_generic_probe(struct udevice *dev, - struct dwc3_generic_priv *priv) + struct dwc3_generic_priv *priv, + enum usb_dr_mode mode) { int rc; struct dwc3_generic_plat *plat = dev_get_plat(dev); @@ -62,7 +63,7 @@ static int dwc3_generic_probe(struct udevice *dev, dwc3->dev = dev; dwc3->maximum_speed = plat->maximum_speed; - dwc3->dr_mode = plat->dr_mode; + dwc3->dr_mode = mode; #if CONFIG_IS_ENABLED(OF_CONTROL) dwc3_of_parse(dwc3); @@ -197,7 +198,7 @@ static int dwc3_generic_peripheral_probe(struct udevice *dev) { struct dwc3_generic_priv *priv = dev_get_priv(dev); - return dwc3_generic_probe(dev, priv); + return dwc3_generic_probe(dev, priv, USB_DR_MODE_PERIPHERAL); } static int dwc3_generic_peripheral_remove(struct udevice *dev) @@ -241,7 +242,7 @@ static int dwc3_generic_host_probe(struct udevice *dev) struct dwc3_generic_host_priv *priv = dev_get_priv(dev); int rc; - rc = dwc3_generic_probe(dev, &priv->gen_priv); + rc = dwc3_generic_probe(dev, &priv->gen_priv, USB_DR_MODE_HOST); if (rc) return rc; diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c index 4bd3b9d10dc..69d3073b669 100644 --- a/drivers/usb/eth/asix88179.c +++ b/drivers/usb/eth/asix88179.c @@ -173,9 +173,10 @@ #define USB_BULK_SEND_TIMEOUT 5000 #define USB_BULK_RECV_TIMEOUT 5000 -#define AX_RX_URB_SIZE 1024 * 0x12 +#define AX_RX_URB_SIZE 1024 * 0x1a #define BLK_FRAME_SIZE 0x200 #define PHY_CONNECT_TIMEOUT 5000 +#define PHY_RESET_TIMEOUT 500 #define TIMEOUT_RESOLUTION 50 /* ms */ @@ -192,10 +193,10 @@ static const struct { unsigned char ctrl, timer_l, timer_h, size, ifg; } AX88179_BULKIN_SIZE[] = { - {7, 0x4f, 0, 0x02, 0xff}, - {7, 0x20, 3, 0x03, 0xff}, - {7, 0xae, 7, 0x04, 0xff}, - {7, 0xcc, 0x4c, 0x04, 8}, + {7, 0x4f, 0, 0x12, 0xff}, + {7, 0x20, 3, 0x16, 0xff}, + {7, 0xae, 7, 0x18, 0xff}, + {7, 0xcc, 0x4c, 0x18, 8}, }; /* driver private */ @@ -285,6 +286,26 @@ static int asix_write_mac(struct ueth_data *dev, uint8_t *enetaddr) return ret; } +static int asix_reset_phy(struct ueth_data *dev) +{ + u16 bmcr; + u32 t; + + /* Reset the PHY */ + bmcr = BMCR_RESET; + asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &bmcr); + + for (t = 0; t < PHY_RESET_TIMEOUT; t += TIMEOUT_RESOLUTION) { + asix_read_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &bmcr); + if (!(bmcr & BMCR_RESET)) + return 0; + mdelay(TIMEOUT_RESOLUTION); + } + + debug("Reset PHY timeout\n"); + return -ETIMEDOUT; +} + static int asix_basic_reset(struct ueth_data *dev, struct asix_private *dev_priv) { @@ -311,7 +332,7 @@ static int asix_basic_reset(struct ueth_data *dev, memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); asix_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - dev_priv->rx_urb_size = 128 * 20; + dev_priv->rx_urb_size = 1024 * 20; /* Water Level configuration */ *tmp = 0x34; @@ -344,14 +365,22 @@ static int asix_basic_reset(struct ueth_data *dev, AX_MEDIUM_GIGAMODE | AX_MEDIUM_JUMBO_EN; asix_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16); + asix_reset_phy(dev); + u16 adv = 0; - adv = ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_LPACK | - ADVERTISE_NPAGE | ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP; + adv = ADVERTISE_ALL | ADVERTISE_CSMA | + ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP; asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_ADVERTISE, 2, &adv); adv = ADVERTISE_1000FULL; asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_CTRL1000, 2, &adv); + /* Restart auto-negotiation */ + u16 bmcr = 0; + asix_read_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &bmcr); + bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; + asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_BMCR, 2, &bmcr); + return 0; } diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 010084ef7f3..c815764c2bc 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -115,10 +115,10 @@ config USB_GADGET_DWC2_OTG USB_GADGET to be enabled. config USB_RENESAS_USBHS - bool "Renesas RCar USB2.0 HS controller (gadget mode)" + bool "Renesas R-Car USB2.0 HS controller (gadget mode)" select USB_GADGET_DUALSPEED help - The Renesas Rcar USB 2.0 high-speed gadget controller + The Renesas R-Car USB 2.0 high-speed gadget controller integrated into Salvator and Kingfisher boards. Select this option if you want the driver to operate in Peripheral mode. This option requires USB_GADGET to be enabled. 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 { diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bb5893d56db..24786a2bc91 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -103,12 +103,12 @@ config USB_XHCI_PCI Enables support for the PCI-based xHCI controller. config USB_XHCI_RCAR - bool "Renesas RCar USB 3.0 support" + bool "Renesas R-Car USB 3.0 support" default y depends on ARCH_RENESAS help Choose this option to add support for USB 3.0 driver on Renesas - RCar Gen3 SoCs. + R-Car Gen3 SoCs. config USB_XHCI_STI bool "Support for STMicroelectronics STiH407 family on-chip xHCI USB controller" diff --git a/drivers/usb/host/xhci-rcar-r8a779x_usb3_v3.h b/drivers/usb/host/xhci-rcar-r8a779x_usb3_v3.h index 8db88f0dcfa..7c909b4697a 100644 --- a/drivers/usb/host/xhci-rcar-r8a779x_usb3_v3.h +++ b/drivers/usb/host/xhci-rcar-r8a779x_usb3_v3.h @@ -1,5 +1,5 @@ /* - * Renesas RCar xHCI controller firmware version 3 + * Renesas R-Car xHCI controller firmware version 3 * * Copyright (c) 2014, Renesas Electronics Corporation * All rights reserved. diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 38c5928faed..b72807053c4 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com> * - * Renesas RCar USB HOST xHCI Controller + * Renesas R-Car USB HOST xHCI Controller */ #include <clk.h> |