diff options
Diffstat (limited to 'drivers/usb/host/dwc2.c')
-rw-r--r-- | drivers/usb/host/dwc2.c | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 954650d856a..d4245b9cb71 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -19,6 +19,7 @@ #include <asm/cache.h> #include <asm/io.h> #include <dm/device_compat.h> +#include <linux/bitfield.h> #include <linux/delay.h> #include <linux/usb/otg.h> #include <power/regulator.h> @@ -95,10 +96,8 @@ static void init_fslspclksel(struct dwc2_core_regs *regs) #ifdef DWC2_ULPI_FS_LS uint32_t hwcfg2 = readl(®s->global_regs.ghwcfg2); - uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >> - DWC2_HWCFG2_HS_PHY_TYPE_OFFSET; - uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >> - DWC2_HWCFG2_FS_PHY_TYPE_OFFSET; + uint32_t hval = FIELD_GET(GHWCFG2_HS_PHY_TYPE_MASK, ghwcfg2); + uint32_t fval = FIELD_GET(GHWCFG2_FS_PHY_TYPE_MASK, ghwcfg2); if (hval == 2 && fval == 1) phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ; /* Full speed PHY */ @@ -106,7 +105,7 @@ static void init_fslspclksel(struct dwc2_core_regs *regs) clrsetbits_le32(®s->host_regs.hcfg, DWC2_HCFG_FSLSPCLKSEL_MASK, - phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET); + FIELD_PREP(DWC2_HCFG_FSLSPCLKSEL_MASK, phyclk)); } /* @@ -120,7 +119,7 @@ static void dwc_otg_flush_tx_fifo(struct udevice *dev, { int ret; - writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET), + writel(DWC2_GRSTCTL_TXFFLSH | FIELD_PREP(DWC2_GRSTCTL_TXFNUM_MASK, num), ®s->global_regs.grstctl); ret = wait_for_bit_le32(®s->global_regs.grstctl, DWC2_GRSTCTL_TXFFLSH, false, 1000, false); @@ -266,18 +265,14 @@ static void dwc_otg_core_host_init(struct udevice *dev, writel(DWC2_HOST_RX_FIFO_SIZE, ®s->global_regs.grxfsiz); /* Non-periodic Tx FIFO */ - nptxfifosize |= DWC2_HOST_NPERIO_TX_FIFO_SIZE << - DWC2_FIFOSIZE_DEPTH_OFFSET; - nptxfifosize |= DWC2_HOST_RX_FIFO_SIZE << - DWC2_FIFOSIZE_STARTADDR_OFFSET; + nptxfifosize |= FIELD_PREP(DWC2_FIFOSIZE_DEPTH_MASK, DWC2_HOST_NPERIO_TX_FIFO_SIZE); + nptxfifosize |= FIELD_PREP(DWC2_FIFOSIZE_STARTADDR_MASK, DWC2_HOST_RX_FIFO_SIZE); writel(nptxfifosize, ®s->global_regs.gnptxfsiz); /* Periodic Tx FIFO */ - ptxfifosize |= DWC2_HOST_PERIO_TX_FIFO_SIZE << - DWC2_FIFOSIZE_DEPTH_OFFSET; - ptxfifosize |= (DWC2_HOST_RX_FIFO_SIZE + - DWC2_HOST_NPERIO_TX_FIFO_SIZE) << - DWC2_FIFOSIZE_STARTADDR_OFFSET; + ptxfifosize |= FIELD_PREP(DWC2_FIFOSIZE_DEPTH_MASK, DWC2_HOST_PERIO_TX_FIFO_SIZE); + ptxfifosize |= FIELD_PREP(DWC2_FIFOSIZE_STARTADDR_MASK, DWC2_HOST_RX_FIFO_SIZE + + DWC2_HOST_NPERIO_TX_FIFO_SIZE); writel(ptxfifosize, ®s->global_regs.hptxfsiz); } #endif @@ -290,10 +285,8 @@ static void dwc_otg_core_host_init(struct udevice *dev, dwc_otg_flush_rx_fifo(dev, regs); /* Flush out any leftover queued requests. */ - num_channels = readl(®s->global_regs.ghwcfg2); - num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK; - num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET; - num_channels += 1; + num_channels = FIELD_GET(DWC2_HWCFG2_NUM_HOST_CHAN_MASK, + readl(®s->global_regs.ghwcfg2)) + 1; for (i = 0; i < num_channels; i++) clrsetbits_le32(®s->host_regs.hc[i].hcchar, @@ -390,7 +383,7 @@ static void dwc_otg_core_init(struct udevice *dev) /* Program GI2CCTL.I2CEn */ clrsetbits_le32(®s->global_regs.gi2cctl, DWC2_GI2CCTL_I2CEN | DWC2_GI2CCTL_I2CDEVADDR_MASK, - 1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET); + FIELD_PREP(DWC2_GI2CCTL_I2CDEVADDR_MASK, 1)); setbits_le32(®s->global_regs.gi2cctl, DWC2_GI2CCTL_I2CEN); #endif @@ -429,10 +422,8 @@ static void dwc_otg_core_init(struct udevice *dev) usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M); #ifdef DWC2_ULPI_FS_LS uint32_t hwcfg2 = readl(®s->global_regs.ghwcfg2); - uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >> - DWC2_HWCFG2_HS_PHY_TYPE_OFFSET; - uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >> - DWC2_HWCFG2_FS_PHY_TYPE_OFFSET; + uint32_t hval = FIELD_GET(DWC2_HWCFG2_HS_PHY_TYPE_MASK, ghwcfg2); + uint32_t fval = FIELD_GET(DWC2_HWCFG2_FS_PHY_TYPE_MASK, ghwcfg2); if (hval == 2 && fval == 1) { usbcfg |= DWC2_GUSBCFG_ULPI_FSLS; usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M; @@ -444,12 +435,11 @@ static void dwc_otg_core_init(struct udevice *dev) writel(usbcfg, ®s->global_regs.gusbcfg); /* Program the GAHBCFG Register. */ - switch (readl(®s->global_regs.ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) { + switch (FIELD_GET(DWC2_HWCFG2_ARCHITECTURE_MASK, readl(®s->global_regs.ghwcfg2))) { case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY: break; case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA: - ahbcfg |= (LOG2(brst_sz >> 1) << DWC2_GAHBCFG_HBURSTLEN_OFFSET) & - DWC2_GAHBCFG_HBURSTLEN_MASK; + ahbcfg |= FIELD_PREP(DWC2_GAHBCFG_HBURSTLEN_MASK, LOG2(brst_sz >> 1)); #ifdef DWC2_DMA_ENABLE ahbcfg |= DWC2_GAHBCFG_DMAENABLE; @@ -492,11 +482,11 @@ static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num, uint8_t ep_is_in, uint8_t ep_type, uint16_t max_packet) { struct dwc2_hc_regs *hc_regs = ®s->host_regs.hc[hc_num]; - uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) | - (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) | - (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) | - (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) | - (max_packet << DWC2_HCCHAR_MPS_OFFSET); + u32 hcchar = FIELD_PREP(DWC2_HCCHAR_DEVADDR_MASK, dev_addr) | + FIELD_PREP(DWC2_HCCHAR_EPNUM_MASK, ep_num) | + FIELD_PREP(DWC2_HCCHAR_EPDIR, ep_is_in) | + FIELD_PREP(DWC2_HCCHAR_EPTYPE_MASK, ep_type) | + FIELD_PREP(DWC2_HCCHAR_MPS_MASK, max_packet); if (dev->speed == USB_SPEED_LOW) hcchar |= DWC2_HCCHAR_LSPDDEV; @@ -517,8 +507,8 @@ static void dwc_otg_hc_init_split(struct dwc2_hc_regs *hc_regs, uint32_t hcsplt = 0; hcsplt = DWC2_HCSPLT_SPLTENA; - hcsplt |= hub_devnum << DWC2_HCSPLT_HUBADDR_OFFSET; - hcsplt |= hub_port << DWC2_HCSPLT_PRTADDR_OFFSET; + hcsplt |= FIELD_PREP(DWC2_HCSPLT_HUBADDR_MASK, hub_devnum); + hcsplt |= FIELD_PREP(DWC2_HCSPLT_PRTADDR_MASK, hub_port); /* Program the HCSPLIT register for SPLITs */ writel(hcsplt, &hc_regs->hcsplt); @@ -567,11 +557,14 @@ static int dwc_otg_submit_rh_msg_in_status(struct dwc2_core_regs *regs, if (hprt0 & DWC2_HPRT0_PRTPWR) port_status |= USB_PORT_STAT_POWER; - if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) == DWC2_HPRT0_PRTSPD_LOW) + switch (FIELD_GET(DWC2_HPRT0_PRTSPD_MASK, hprt0)) { + case DWC2_HPRT0_PRTSPD_LOW: port_status |= USB_PORT_STAT_LOW_SPEED; - else if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) == - DWC2_HPRT0_PRTSPD_HIGH) + break; + case DWC2_HPRT0_PRTSPD_HIGH: port_status |= USB_PORT_STAT_HIGH_SPEED; + break; + } if (hprt0 & DWC2_HPRT0_PRTENCHNG) port_change |= USB_PORT_STAT_C_ENABLE; @@ -822,9 +815,8 @@ int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle) hcint = readl(&hc_regs->hcint); hctsiz = readl(&hc_regs->hctsiz); - *sub = (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK) >> - DWC2_HCTSIZ_XFERSIZE_OFFSET; - *toggle = (hctsiz & DWC2_HCTSIZ_PID_MASK) >> DWC2_HCTSIZ_PID_OFFSET; + *sub = FIELD_GET(DWC2_HCTSIZ_XFERSIZE_MASK, hctsiz); + *toggle = FIELD_GET(DWC2_HCTSIZ_PID_MASK, hctsiz); debug("%s: HCINT=%08x sub=%u toggle=%d\n", __func__, hcint, *sub, *toggle); @@ -856,9 +848,9 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, debug("%s: chunk: pid %d xfer_len %u pkts %u\n", __func__, *pid, xfer_len, num_packets); - writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) | - (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) | - (*pid << DWC2_HCTSIZ_PID_OFFSET), + writel(FIELD_PREP(DWC2_HCTSIZ_XFERSIZE_MASK, xfer_len) | + FIELD_PREP(DWC2_HCTSIZ_PKTCNT_MASK, num_packets) | + FIELD_PREP(DWC2_HCTSIZ_PID_MASK, *pid), &hc_regs->hctsiz); if (xfer_len) { @@ -885,8 +877,8 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK | DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS | DWC2_HCCHAR_ODDFRM, - (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | - (odd_frame << DWC2_HCCHAR_ODDFRM_OFFSET) | + FIELD_PREP(DWC2_HCCHAR_MULTICNT_MASK, 1) | + FIELD_PREP(DWC2_HCCHAR_ODDFRM, odd_frame) | DWC2_HCCHAR_CHEN); ret = wait_for_chhltd(hc_regs, &sub, pid); @@ -950,8 +942,7 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, uint8_t hub_port; uint32_t hprt0 = readl(®s->host_regs.hprt0); - if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) == - DWC2_HPRT0_PRTSPD_HIGH) { + if (FIELD_GET(DWC2_HPRT0_PRTSPD_MASK, hprt0) == DWC2_HPRT0_PRTSPD_HIGH) { usb_find_usb2_hub_address_port(dev, &hub_addr, &hub_port); dwc_otg_hc_init_split(hc_regs, hub_addr, hub_port); @@ -995,17 +986,17 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, stop_transfer = 0; if (hcint & DWC2_HCINT_NYET) { ret = 0; - int frame_num = DWC2_HFNUM_MAX_FRNUM & - readl(&host_regs->hfnum); - if (((frame_num - ssplit_frame_num) & - DWC2_HFNUM_MAX_FRNUM) > 4) + int frame_num = FIELD_GET(DWC2_HFNUM_FRNUM_MASK, + readl(&host_regs->hfnum)); + + if (((frame_num - ssplit_frame_num) & DWC2_HFNUM_FRNUM_MASK) > 4) ret = -EAGAIN; } else complete_split = 0; } else if (do_split) { if (hcint & DWC2_HCINT_ACK) { - ssplit_frame_num = DWC2_HFNUM_MAX_FRNUM & - readl(&host_regs->hfnum); + ssplit_frame_num = FIELD_GET(DWC2_HFNUM_FRNUM_MASK, + readl(&host_regs->hfnum)); ret = 0; complete_split = 1; } @@ -1183,8 +1174,8 @@ static int dwc2_init_common(struct udevice *dev, struct dwc2_priv *priv) dev_info(dev, "Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff); - if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx && - (snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_3xx) { + if (FIELD_GET(DWC2_SNPSID_DEVID_MASK, snpsid) != DWC2_SNPSID_DEVID_VER_2xx && + FIELD_GET(DWC2_SNPSID_DEVID_MASK, snpsid) != DWC2_SNPSID_DEVID_VER_3xx) { dev_info(dev, "SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid); return -ENODEV; |