X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fdwc2.c;h=b2f4bc685af165c535eb0ecc2e73f583a333a862;hb=08b24722f0ac9159697360faed35d12852592eb3;hp=291e4a5f57d356e08a37171db78d2d67f446ee11;hpb=d2ff51b372a6800fcf1394fc2ca9821d86b15335;p=oweals%2Fu-boot.git diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 291e4a5f57..b2f4bc685a 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "dwc2.h" @@ -34,7 +35,8 @@ struct dwc2_priv { uint8_t *aligned_buffer; uint8_t *status_buffer; #endif - int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + u8 in_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + u8 out_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; struct dwc2_core_regs *regs; int root_hub_devnum; }; @@ -52,27 +54,6 @@ static struct dwc2_priv local; /* * DWC2 IP interface */ -static int wait_for_bit(void *reg, const uint32_t mask, bool set) -{ - unsigned int timeout = 1000000; - uint32_t val; - - while (--timeout) { - val = readl(reg); - if (!set) - val = ~val; - - if ((val & mask) == mask) - return 0; - - udelay(1); - } - - debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", - __func__, reg, mask, set); - - return -ETIMEDOUT; -} /* * Initializes the FSLSPClkSel field of the HCFG register @@ -117,7 +98,8 @@ static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num) writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET), ®s->grstctl); - ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_TXFFLSH, 0); + ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_TXFFLSH, + false, 1000, false); if (ret) printf("%s: Timeout!\n", __func__); @@ -135,7 +117,8 @@ static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs) int ret; writel(DWC2_GRSTCTL_RXFFLSH, ®s->grstctl); - ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_RXFFLSH, 0); + ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_RXFFLSH, + false, 1000, false); if (ret) printf("%s: Timeout!\n", __func__); @@ -152,13 +135,15 @@ static void dwc_otg_core_reset(struct dwc2_core_regs *regs) int ret; /* Wait for AHB master IDLE state. */ - ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_AHBIDLE, 1); + ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_AHBIDLE, + true, 1000, false); if (ret) printf("%s: Timeout!\n", __func__); /* Core Soft Reset */ writel(DWC2_GRSTCTL_CSFTRST, ®s->grstctl); - ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_CSFTRST, 0); + ret = wait_for_bit(__func__, ®s->grstctl, DWC2_GRSTCTL_CSFTRST, + false, 1000, false); if (ret) printf("%s: Timeout!\n", __func__); @@ -243,8 +228,8 @@ static void dwc_otg_core_host_init(struct dwc2_core_regs *regs) clrsetbits_le32(®s->hc_regs[i].hcchar, DWC2_HCCHAR_EPDIR, DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS); - ret = wait_for_bit(®s->hc_regs[i].hcchar, - DWC2_HCCHAR_CHEN, 0); + ret = wait_for_bit(__func__, ®s->hc_regs[i].hcchar, + DWC2_HCCHAR_CHEN, false, 1000, false); if (ret) printf("%s: Timeout!\n", __func__); } @@ -278,7 +263,9 @@ static void dwc_otg_core_init(struct dwc2_core_regs *regs) /* Program the ULPI External VBUS bit if needed */ #ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS - usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV; + usbcfg |= (DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV | + DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR | + DWC2_GUSBCFG_INDICATOR_PASSTHROUGH); #else usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV; #endif @@ -739,12 +726,13 @@ static int dwc_otg_submit_rh_msg(struct dwc2_priv *priv, struct usb_device *dev, return stat; } -int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, int *toggle) +int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle) { int ret; uint32_t hcint, hctsiz; - ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true); + ret = wait_for_bit(__func__, &hc_regs->hcint, DWC2_HCINT_CHHLTD, true, + 1000, false); if (ret) return ret; @@ -775,7 +763,7 @@ static int dwc2_eptype[] = { }; static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, - int *pid, int in, void *buffer, int num_packets, + u8 *pid, int in, void *buffer, int num_packets, int xfer_len, int *actual_len, int odd_frame) { int ret = 0; @@ -829,7 +817,7 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, } int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, - unsigned long pipe, int *pid, int in, void *buffer, int len) + unsigned long pipe, u8 *pid, int in, void *buffer, int len) { struct dwc2_core_regs *regs = priv->regs; struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; @@ -960,14 +948,19 @@ int _submit_bulk_msg(struct dwc2_priv *priv, struct usb_device *dev, { int devnum = usb_pipedevice(pipe); int ep = usb_pipeendpoint(pipe); + u8* pid; - if (devnum == priv->root_hub_devnum) { + if ((devnum >= MAX_DEVICE) || (devnum == priv->root_hub_devnum)) { dev->status = 0; return -EINVAL; } - return chunk_msg(priv, dev, pipe, &priv->bulk_data_toggle[devnum][ep], - usb_pipein(pipe), buffer, len); + if (usb_pipein(pipe)) + pid = &priv->in_data_toggle[devnum][ep]; + else + pid = &priv->out_data_toggle[devnum][ep]; + + return chunk_msg(priv, dev, pipe, pid, usb_pipein(pipe), buffer, len); } static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev, @@ -975,7 +968,8 @@ static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev, struct devrequest *setup) { int devnum = usb_pipedevice(pipe); - int pid, ret, act_len; + int ret, act_len; + u8 pid; /* For CONTROL endpoint pid should start with DATA1 */ int status_direction; @@ -1075,8 +1069,10 @@ static int dwc2_init_common(struct dwc2_priv *priv) DWC2_HPRT0_PRTRST); for (i = 0; i < MAX_DEVICE; i++) { - for (j = 0; j < MAX_ENDPOINT; j++) - priv->bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0; + for (j = 0; j < MAX_ENDPOINT; j++) { + priv->in_data_toggle[i][j] = DWC2_HC_PID_DATA0; + priv->out_data_toggle[i][j] = DWC2_HC_PID_DATA0; + } } return 0;