diff options
Diffstat (limited to 'drivers/staging/dwc2')
-rw-r--r-- | drivers/staging/dwc2/core.c | 307 | ||||
-rw-r--r-- | drivers/staging/dwc2/core.h | 96 | ||||
-rw-r--r-- | drivers/staging/dwc2/core_intr.c | 4 | ||||
-rw-r--r-- | drivers/staging/dwc2/hcd.c | 80 | ||||
-rw-r--r-- | drivers/staging/dwc2/hcd.h | 1 | ||||
-rw-r--r-- | drivers/staging/dwc2/hcd_intr.c | 2 |
6 files changed, 290 insertions, 200 deletions
diff --git a/drivers/staging/dwc2/core.c b/drivers/staging/dwc2/core.c index 2f84c24a84ee..825c5e5f157f 100644 --- a/drivers/staging/dwc2/core.c +++ b/drivers/staging/dwc2/core.c @@ -90,14 +90,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) */ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) { - u32 hs_phy_type = (hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >> - GHWCFG2_HS_PHY_TYPE_SHIFT; - u32 fs_phy_type = (hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> - GHWCFG2_FS_PHY_TYPE_SHIFT; u32 hcfg, val; - if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && - fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && + if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && + hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && hsotg->core_params->ulpi_fs_ls > 0) || hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { /* Full speed PHY */ @@ -247,7 +243,7 @@ static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) { - u32 usbcfg, hs_phy_type, fs_phy_type; + u32 usbcfg; if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL && hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { @@ -258,13 +254,8 @@ static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) dwc2_hs_phy_init(hsotg, select_phy); } - hs_phy_type = (hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >> - GHWCFG2_HS_PHY_TYPE_SHIFT; - fs_phy_type = (hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> - GHWCFG2_FS_PHY_TYPE_SHIFT; - - if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && - fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && + if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && + hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && hsotg->core_params->ulpi_fs_ls > 0) { dev_dbg(hsotg->dev, "Setting ULPI FSLS\n"); usbcfg = readl(hsotg->regs + GUSBCFG); @@ -283,8 +274,7 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) { u32 ahbcfg = readl(hsotg->regs + GAHBCFG); - switch ((hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >> - GHWCFG2_ARCHITECTURE_SHIFT) { + switch (hsotg->hw_params.arch) { case GHWCFG2_EXT_DMA_ARCH: dev_err(hsotg->dev, "External DMA Mode not supported\n"); return -EINVAL; @@ -333,8 +323,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) usbcfg = readl(hsotg->regs + GUSBCFG); usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP); - switch ((hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK) >> - GHWCFG2_OP_MODE_SHIFT) { + switch (hsotg->hw_params.op_mode) { case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: if (hsotg->core_params->otg_cap == DWC2_CAP_PARAM_HNP_SRP_CAPABLE) @@ -395,23 +384,6 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) /* Reset the Controller */ dwc2_core_reset(hsotg); - dev_dbg(hsotg->dev, "num_dev_perio_in_ep=%d\n", - hsotg->hwcfg4 >> GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT & - GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK >> - GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT); - - hsotg->total_fifo_size = hsotg->hwcfg3 >> GHWCFG3_DFIFO_DEPTH_SHIFT & - GHWCFG3_DFIFO_DEPTH_MASK >> GHWCFG3_DFIFO_DEPTH_SHIFT; - hsotg->rx_fifo_size = (readl(hsotg->regs + GRXFSIZ) & - GRXFSIZ_DEPTH_MASK) >> - GRXFSIZ_DEPTH_SHIFT; - hsotg->nperio_tx_fifo_size = - readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff; - - dev_dbg(hsotg->dev, "Total FIFO SZ=%d\n", hsotg->total_fifo_size); - dev_dbg(hsotg->dev, "RxFIFO SZ=%d\n", hsotg->rx_fifo_size); - dev_dbg(hsotg->dev, "NP TxFIFO SZ=%d\n", hsotg->nperio_tx_fifo_size); - /* * This needs to happen in FS mode before any other programming occurs */ @@ -514,13 +486,6 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) if (!params->enable_dynamic_fifo) return; - dev_dbg(hsotg->dev, "Total FIFO Size=%d\n", hsotg->total_fifo_size); - dev_dbg(hsotg->dev, "Rx FIFO Size=%d\n", params->host_rx_fifo_size); - dev_dbg(hsotg->dev, "NP Tx FIFO Size=%d\n", - params->host_nperio_tx_fifo_size); - dev_dbg(hsotg->dev, "P Tx FIFO Size=%d\n", - params->host_perio_tx_fifo_size); - /* Rx FIFO */ grxfsiz = readl(hsotg->regs + GRXFSIZ); dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz); @@ -554,7 +519,7 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) readl(hsotg->regs + HPTXFSIZ)); if (hsotg->core_params->en_multiple_tx_fifo > 0 && - hsotg->snpsid <= DWC2_CORE_REV_2_94a) { + hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) { /* * Global DFIFOCFG calculation for Host mode - * include RxFIFO, NPTXFIFO and HPTXFIFO @@ -609,11 +574,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) } if (hsotg->core_params->dma_desc_enable > 0) { - u32 op_mode = (hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK) >> - GHWCFG2_OP_MODE_SHIFT; - - if (hsotg->snpsid < DWC2_CORE_REV_2_90a || - !(hsotg->hwcfg4 & GHWCFG4_DESC_DMA) || + u32 op_mode = hsotg->hw_params.op_mode; + if (hsotg->hw_params.snpsid < DWC2_CORE_REV_2_90a || + !hsotg->hw_params.dma_desc_enable || op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE || op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE || op_mode == GHWCFG2_OP_MODE_UNDEFINED) { @@ -1659,19 +1622,16 @@ void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) { u32 usbcfg; - u32 hwcfg2; u32 hprt0; int clock = 60; /* default value */ usbcfg = readl(hsotg->regs + GUSBCFG); - hwcfg2 = readl(hsotg->regs + GHWCFG2); hprt0 = readl(hsotg->regs + HPRT0); if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & GUSBCFG_PHYIF16)) clock = 60; - if ((usbcfg & GUSBCFG_PHYSEL) && - (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> GHWCFG2_FS_PHY_TYPE_SHIFT == + if ((usbcfg & GUSBCFG_PHYSEL) && hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_ULPI) clock = 48; if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && @@ -1684,12 +1644,10 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16)) clock = 48; if ((usbcfg & GUSBCFG_PHYSEL) && !(usbcfg & GUSBCFG_PHYIF16) && - (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> GHWCFG2_FS_PHY_TYPE_SHIFT == - GHWCFG2_FS_PHY_TYPE_SHARED_UTMI) + hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_UTMI) clock = 48; if ((usbcfg & GUSBCFG_PHYSEL) && - (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> GHWCFG2_FS_PHY_TYPE_SHIFT == - GHWCFG2_FS_PHY_TYPE_DEDICATED) + hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) clock = 48; if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED) @@ -1961,18 +1919,14 @@ int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) { int valid = 1; int retval = 0; - u32 op_mode; - - op_mode = (hsotg->hwcfg2 & GHWCFG2_OP_MODE_MASK) >> - GHWCFG2_OP_MODE_SHIFT; switch (val) { case DWC2_CAP_PARAM_HNP_SRP_CAPABLE: - if (op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) + if (hsotg->hw_params.op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) valid = 0; break; case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE: - switch (op_mode) { + switch (hsotg->hw_params.op_mode) { case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: @@ -1996,7 +1950,7 @@ int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for otg_cap parameter. Check HW configuration.\n", val); - switch (op_mode) { + switch (hsotg->hw_params.op_mode) { case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: val = DWC2_CAP_PARAM_HNP_SRP_CAPABLE; break; @@ -2022,8 +1976,7 @@ int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) int valid = 1; int retval = 0; - if (val > 0 && (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >> - GHWCFG2_ARCHITECTURE_SHIFT == GHWCFG2_SLAVE_ONLY_ARCH) + if (val > 0 && hsotg->hw_params.arch == GHWCFG2_SLAVE_ONLY_ARCH) valid = 0; if (val < 0) valid = 0; @@ -2033,8 +1986,7 @@ int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for dma_enable parameter. Check HW configuration.\n", val); - val = (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >> - GHWCFG2_ARCHITECTURE_SHIFT != GHWCFG2_SLAVE_ONLY_ARCH; + val = hsotg->hw_params.arch != GHWCFG2_SLAVE_ONLY_ARCH; dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val); retval = -EINVAL; } @@ -2049,7 +2001,7 @@ int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) int retval = 0; if (val > 0 && (hsotg->core_params->dma_enable <= 0 || - !(hsotg->hwcfg4 & GHWCFG4_DESC_DMA))) + !hsotg->hw_params.dma_desc_enable)) valid = 0; if (val < 0) valid = 0; @@ -2060,7 +2012,7 @@ int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) "%d invalid for dma_desc_enable parameter. Check HW configuration.\n", val); val = (hsotg->core_params->dma_enable > 0 && - (hsotg->hwcfg4 & GHWCFG4_DESC_DMA)); + hsotg->hw_params.dma_desc_enable); dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val); retval = -EINVAL; } @@ -2096,7 +2048,7 @@ int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) int valid = 1; int retval = 0; - if (val > 0 && !(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO)) + if (val > 0 && !hsotg->hw_params.enable_dynamic_fifo) valid = 0; if (val < 0) valid = 0; @@ -2106,7 +2058,7 @@ int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for enable_dynamic_fifo parameter. Check HW configuration.\n", val); - val = !!(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO); + val = hsotg->hw_params.enable_dynamic_fifo; dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val); retval = -EINVAL; } @@ -2120,9 +2072,7 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) int valid = 1; int retval = 0; - if (val < 16 || val > (readl(hsotg->regs + GRXFSIZ) & - GRXFSIZ_DEPTH_MASK) >> - GRXFSIZ_DEPTH_SHIFT) + if (val < 16 || val > hsotg->hw_params.host_rx_fifo_size) valid = 0; if (!valid) { @@ -2130,9 +2080,7 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for host_rx_fifo_size. Check HW configuration.\n", val); - val = (readl(hsotg->regs + GRXFSIZ) & - GRXFSIZ_DEPTH_MASK) >> - GRXFSIZ_DEPTH_SHIFT; + val = hsotg->hw_params.host_rx_fifo_size; dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val); retval = -EINVAL; } @@ -2146,7 +2094,7 @@ int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) int valid = 1; int retval = 0; - if (val < 16 || val > (readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff)) + if (val < 16 || val > hsotg->hw_params.host_nperio_tx_fifo_size) valid = 0; if (!valid) { @@ -2154,7 +2102,7 @@ int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n", val); - val = readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff; + val = hsotg->hw_params.host_nperio_tx_fifo_size; dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n", val); retval = -EINVAL; @@ -2169,7 +2117,7 @@ int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) int valid = 1; int retval = 0; - if (val < 16 || val > (hsotg->hptxfsiz >> 16)) + if (val < 16 || val > hsotg->hw_params.host_perio_tx_fifo_size) valid = 0; if (!valid) { @@ -2177,7 +2125,7 @@ int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n", val); - val = hsotg->hptxfsiz >> 16; + val = hsotg->hw_params.host_perio_tx_fifo_size; dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n", val); retval = -EINVAL; @@ -2191,11 +2139,8 @@ int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) { int valid = 1; int retval = 0; - int width = hsotg->hwcfg3 >> GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT & - GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK >> - GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT; - if (val < 2047 || val >= (1 << (width + 11))) + if (val < 2047 || val > hsotg->hw_params.max_transfer_size) valid = 0; if (!valid) { @@ -2203,7 +2148,7 @@ int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for max_transfer_size. Check HW configuration.\n", val); - val = (1 << (width + 11)) - 1; + val = hsotg->hw_params.max_transfer_size; dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val); retval = -EINVAL; } @@ -2216,11 +2161,8 @@ int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) { int valid = 1; int retval = 0; - int width = hsotg->hwcfg3 >> GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT & - GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK >> - GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT; - if (val < 15 || val >= (1 << (width + 4))) + if (val < 15 || val > hsotg->hw_params.max_packet_count) valid = 0; if (!valid) { @@ -2228,7 +2170,7 @@ int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for max_packet_count. Check HW configuration.\n", val); - val = (1 << (width + 4)) - 1; + val = hsotg->hw_params.max_packet_count; dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val); retval = -EINVAL; } @@ -2241,10 +2183,8 @@ int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) { int valid = 1; int retval = 0; - int num_chan = hsotg->hwcfg2 >> GHWCFG2_NUM_HOST_CHAN_SHIFT & - GHWCFG2_NUM_HOST_CHAN_MASK >> GHWCFG2_NUM_HOST_CHAN_SHIFT; - if (val < 1 || val > num_chan + 1) + if (val < 1 || val > hsotg->hw_params.host_channels) valid = 0; if (!valid) { @@ -2252,7 +2192,7 @@ int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for host_channels. Check HW configuration.\n", val); - val = num_chan + 1; + val = hsotg->hw_params.host_channels; dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val); retval = -EINVAL; } @@ -2265,8 +2205,7 @@ int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) { #ifndef NO_FS_PHY_HW_CHECKS int valid = 0; - u32 hs_phy_type; - u32 fs_phy_type; + u32 hs_phy_type, fs_phy_type; #endif int retval = 0; @@ -2287,11 +2226,8 @@ int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) } #ifndef NO_FS_PHY_HW_CHECKS - hs_phy_type = (hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >> - GHWCFG2_HS_PHY_TYPE_SHIFT; - fs_phy_type = (hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> - GHWCFG2_FS_PHY_TYPE_SHIFT; - + hs_phy_type = hsotg->hw_params.hs_phy_type; + fs_phy_type = hsotg->hw_params.fs_phy_type; if (val == DWC2_PHY_TYPE_PARAM_UTMI && (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI || hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)) @@ -2515,7 +2451,7 @@ int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) } #ifndef NO_FS_PHY_HW_CHECKS - if (val == 1 && !(hsotg->hwcfg3 & GHWCFG3_I2C)) + if (val == 1 && !(hsotg->hw_params.i2c_enable)) valid = 0; if (!valid) { @@ -2523,7 +2459,7 @@ int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for i2c_enable. Check HW configuration.\n", val); - val = !!(hsotg->hwcfg3 & GHWCFG3_I2C); + val = hsotg->hw_params.i2c_enable; dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val); retval = -EINVAL; } @@ -2548,7 +2484,7 @@ int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) valid = 0; } - if (val == 1 && !(hsotg->hwcfg4 & GHWCFG4_DED_FIFO_EN)) + if (val == 1 && !hsotg->hw_params.en_multiple_tx_fifo) valid = 0; if (!valid) { @@ -2556,7 +2492,7 @@ int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n", val); - val = !!(hsotg->hwcfg4 & GHWCFG4_DED_FIFO_EN); + val = hsotg->hw_params.en_multiple_tx_fifo; dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val); retval = -EINVAL; } @@ -2579,7 +2515,7 @@ int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) valid = 0; } - if (val == 1 && hsotg->snpsid < DWC2_CORE_REV_2_92a) + if (val == 1 && hsotg->hw_params.snpsid < DWC2_CORE_REV_2_92a) valid = 0; if (!valid) { @@ -2587,7 +2523,7 @@ int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) dev_err(hsotg->dev, "%d invalid for parameter reload_ctl. Check HW configuration.\n", val); - val = hsotg->snpsid >= DWC2_CORE_REV_2_92a; + val = hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_92a; dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val); retval = -EINVAL; } @@ -2626,6 +2562,161 @@ int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val) return retval; } +/** + * During device initialization, read various hardware configuration + * registers and interpret the contents. + */ +int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) +{ + struct dwc2_hw_params *hw = &hsotg->hw_params; + unsigned width; + u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; + u32 hptxfsiz, grxfsiz, gnptxfsiz; + u32 gusbcfg; + + /* + * Attempt to ensure this device is really a DWC_otg Controller. + * Read and verify the GSNPSID register contents. The value should be + * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3", + * as in "OTG version 2.xx" or "OTG version 3.xx". + */ + hw->snpsid = readl(hsotg->regs + GSNPSID); + if ((hw->snpsid & 0xfffff000) != 0x4f542000 && + (hw->snpsid & 0xfffff000) != 0x4f543000) { + dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", + hw->snpsid); + return -ENODEV; + } + + dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n", + hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, + hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); + + hwcfg1 = readl(hsotg->regs + GHWCFG1); + hwcfg2 = readl(hsotg->regs + GHWCFG2); + hwcfg3 = readl(hsotg->regs + GHWCFG3); + hwcfg4 = readl(hsotg->regs + GHWCFG4); + gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); + grxfsiz = readl(hsotg->regs + GRXFSIZ); + + dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1); + dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2); + dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hwcfg3); + dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4); + dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); + dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); + + /* Force host mode to get HPTXFSIZ exact power on value */ + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + + hptxfsiz = readl(hsotg->regs + HPTXFSIZ); + dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + usleep_range(100000, 150000); + + /* hwcfg2 */ + hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >> + GHWCFG2_OP_MODE_SHIFT; + hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >> + GHWCFG2_ARCHITECTURE_SHIFT; + hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO); + hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >> + GHWCFG2_NUM_HOST_CHAN_SHIFT); + hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >> + GHWCFG2_HS_PHY_TYPE_SHIFT; + hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >> + GHWCFG2_FS_PHY_TYPE_SHIFT; + hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >> + GHWCFG2_NUM_DEV_EP_SHIFT; + hw->nperio_tx_q_depth = + (hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >> + GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1; + hw->host_perio_tx_q_depth = + (hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >> + GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1; + hw->dev_token_q_depth = + (hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >> + GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT; + + /* hwcfg3 */ + width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >> + GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT; + hw->max_transfer_size = (1 << (width + 11)) - 1; + width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >> + GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT; + hw->max_packet_count = (1 << (width + 4)) - 1; + hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C); + hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >> + GHWCFG3_DFIFO_DEPTH_SHIFT; + + /* hwcfg4 */ + hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN); + hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >> + GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT; + hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); + hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ); + + /* fifo sizes */ + hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> + GRXFSIZ_DEPTH_SHIFT; + hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >> + FIFOSIZE_DEPTH_SHIFT; + hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >> + FIFOSIZE_DEPTH_SHIFT; + + dev_dbg(hsotg->dev, "Detected values from hardware:\n"); + dev_dbg(hsotg->dev, " op_mode=%d\n", + hw->op_mode); + dev_dbg(hsotg->dev, " arch=%d\n", + hw->arch); + dev_dbg(hsotg->dev, " dma_desc_enable=%d\n", + hw->dma_desc_enable); + dev_dbg(hsotg->dev, " power_optimized=%d\n", + hw->power_optimized); + dev_dbg(hsotg->dev, " i2c_enable=%d\n", + hw->i2c_enable); + dev_dbg(hsotg->dev, " hs_phy_type=%d\n", + hw->hs_phy_type); + dev_dbg(hsotg->dev, " fs_phy_type=%d\n", + hw->fs_phy_type); + dev_dbg(hsotg->dev, " num_dev_ep=%d\n", + hw->num_dev_ep); + dev_dbg(hsotg->dev, " num_dev_perio_in_ep=%d\n", + hw->num_dev_perio_in_ep); + dev_dbg(hsotg->dev, " host_channels=%d\n", + hw->host_channels); + dev_dbg(hsotg->dev, " max_transfer_size=%d\n", + hw->max_transfer_size); + dev_dbg(hsotg->dev, " max_packet_count=%d\n", + hw->max_packet_count); + dev_dbg(hsotg->dev, " nperio_tx_q_depth=0x%0x\n", + hw->nperio_tx_q_depth); + dev_dbg(hsotg->dev, " host_perio_tx_q_depth=0x%0x\n", + hw->host_perio_tx_q_depth); + dev_dbg(hsotg->dev, " dev_token_q_depth=0x%0x\n", + hw->dev_token_q_depth); + dev_dbg(hsotg->dev, " enable_dynamic_fifo=%d\n", + hw->enable_dynamic_fifo); + dev_dbg(hsotg->dev, " en_multiple_tx_fifo=%d\n", + hw->en_multiple_tx_fifo); + dev_dbg(hsotg->dev, " total_fifo_size=%d\n", + hw->total_fifo_size); + dev_dbg(hsotg->dev, " host_rx_fifo_size=%d\n", + hw->host_rx_fifo_size); + dev_dbg(hsotg->dev, " host_nperio_tx_fifo_size=%d\n", + hw->host_nperio_tx_fifo_size); + dev_dbg(hsotg->dev, " host_perio_tx_fifo_size=%d\n", + hw->host_perio_tx_fifo_size); + dev_dbg(hsotg->dev, "\n"); + + return 0; +} + /* * This function is called during module intialization to pass module parameters * for the DWC_otg core. It returns non-0 if any parameters are invalid. diff --git a/drivers/staging/dwc2/core.h b/drivers/staging/dwc2/core.h index e5b4dc8948a3..e4eb3a0d0b5b 100644 --- a/drivers/staging/dwc2/core.h +++ b/drivers/staging/dwc2/core.h @@ -194,21 +194,87 @@ struct dwc2_core_params { }; /** + * struct dwc2_hw_params - Autodetected parameters. + * + * These parameters are the various parameters read from hardware + * registers during initialization. They typically contain the best + * supported or maximum value that can be configured in the + * corresponding dwc2_core_params value. + * + * The values that are not in dwc2_core_params are documented below. + * + * @op_mode Mode of Operation + * 0 - HNP- and SRP-Capable OTG (Host & Device) + * 1 - SRP-Capable OTG (Host & Device) + * 2 - Non-HNP and Non-SRP Capable OTG (Host & Device) + * 3 - SRP-Capable Device + * 4 - Non-OTG Device + * 5 - SRP-Capable Host + * 6 - Non-OTG Host + * @arch Architecture + * 0 - Slave only + * 1 - External DMA + * 2 - Internal DMA + * @power_optimized Are power optimizations enabled? + * @num_dev_ep Number of device endpoints available + * @num_dev_perio_in_ep Number of device periodic IN endpoints + * avaialable + * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue + * Depth + * 0 to 30 + * @host_perio_tx_q_depth + * Host Mode Periodic Request Queue Depth + * 2, 4 or 8 + * @nperio_tx_q_depth + * Non-Periodic Request Queue Depth + * 2, 4 or 8 + * @hs_phy_type High-speed PHY interface type + * 0 - High-speed interface not supported + * 1 - UTMI+ + * 2 - ULPI + * 3 - UTMI+ and ULPI + * @fs_phy_type Full-speed PHY interface type + * 0 - Full speed interface not supported + * 1 - Dedicated full speed interface + * 2 - FS pins shared with UTMI+ pins + * 3 - FS pins shared with ULPI pins + * @total_fifo_size: Total internal RAM for FIFOs (bytes) + * @snpsid: Value from SNPSID register + */ +struct dwc2_hw_params { + unsigned op_mode:3; + unsigned arch:2; + unsigned dma_desc_enable:1; + unsigned enable_dynamic_fifo:1; + unsigned en_multiple_tx_fifo:1; + unsigned host_rx_fifo_size:16; + unsigned host_nperio_tx_fifo_size:16; + unsigned host_perio_tx_fifo_size:16; + unsigned nperio_tx_q_depth:3; + unsigned host_perio_tx_q_depth:3; + unsigned dev_token_q_depth:5; + unsigned max_transfer_size:26; + unsigned max_packet_count:11; + unsigned host_channels:4; + unsigned hs_phy_type:2; + unsigned fs_phy_type:2; + unsigned i2c_enable:1; + unsigned num_dev_ep:4; + unsigned num_dev_perio_in_ep:4; + unsigned total_fifo_size:16; + unsigned power_optimized:1; + u32 snpsid; +}; + +/** * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic * and periodic schedules * * @dev: The struct device pointer * @regs: Pointer to controller regs * @core_params: Parameters that define how the core should be configured - * @hwcfg1: Hardware Configuration - stored here for convenience - * @hwcfg2: Hardware Configuration - stored here for convenience - * @hwcfg3: Hardware Configuration - stored here for convenience - * @hwcfg4: Hardware Configuration - stored here for convenience - * @hptxfsiz: Hardware Configuration - stored here for convenience - * @snpsid: Value from SNPSID register - * @total_fifo_size: Total internal RAM for FIFOs (bytes) - * @rx_fifo_size: Size of Rx FIFO (bytes) - * @nperio_tx_fifo_size: Size of Non-periodic Tx FIFO (Bytes) + * @hw_params: Parameters that were autodetected from the + * hardware registers * @op_state: The operational State, during transitions (a_host=> * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine @@ -296,16 +362,10 @@ struct dwc2_core_params { struct dwc2_hsotg { struct device *dev; void __iomem *regs; + /** Params detected from hardware */ + struct dwc2_hw_params hw_params; + /** Params to actually use */ struct dwc2_core_params *core_params; - u32 hwcfg1; - u32 hwcfg2; - u32 hwcfg3; - u32 hwcfg4; - u32 hptxfsiz; - u32 snpsid; - u16 total_fifo_size; - u16 rx_fifo_size; - u16 nperio_tx_fifo_size; enum usb_otg_state op_state; unsigned int queuing_high_bandwidth:1; diff --git a/drivers/staging/dwc2/core_intr.c b/drivers/staging/dwc2/core_intr.c index 98c51bba6622..07cfa2f6aa2b 100644 --- a/drivers/staging/dwc2/core_intr.c +++ b/drivers/staging/dwc2/core_intr.c @@ -166,7 +166,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) * WA for 3.00a- HW is not setting cur_mode, even sometimes * this does not help */ - if (hsotg->snpsid >= DWC2_CORE_REV_3_00a) + if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) udelay(100); if (gotgctl & GOTGCTL_HSTNEGSCS) { if (dwc2_is_host_mode(hsotg)) { @@ -380,7 +380,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", !!(dsts & DSTS_SUSPSTS), - !!(hsotg->hwcfg4 & GHWCFG4_POWER_OPTIMIZ)); + hsotg->hw_params.power_optimized); } else { if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg->dev, "a_peripheral->a_host\n"); diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index 9a1e062b7297..da0d35cc33ce 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -2678,7 +2678,7 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) writel(ahbcfg, hsotg->regs + GAHBCFG); writel(0, hsotg->regs + GINTMSK); - if (hsotg->snpsid >= DWC2_CORE_REV_3_00a) { + if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) { dctl = readl(hsotg->regs + DCTL); dctl |= DCTL_SFTDISCON; writel(dctl, hsotg->regs + DCTL); @@ -2730,80 +2730,22 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, { struct usb_hcd *hcd; struct dwc2_host_chan *channel; - u32 gusbcfg, hcfg; + u32 hcfg; int i, num_channels; - int retval = -ENOMEM; + int retval; dev_dbg(hsotg->dev, "DWC OTG HCD INIT\n"); - /* - * Attempt to ensure this device is really a DWC_otg Controller. - * Read and verify the GSNPSID register contents. The value should be - * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3", - * as in "OTG version 2.xx" or "OTG version 3.xx". - */ - hsotg->snpsid = readl(hsotg->regs + GSNPSID); - if ((hsotg->snpsid & 0xfffff000) != 0x4f542000 && - (hsotg->snpsid & 0xfffff000) != 0x4f543000) { - dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", - hsotg->snpsid); - retval = -ENODEV; - goto error1; - } + /* Detect config values from hardware */ + retval = dwc2_get_hwparams(hsotg); - /* - * Store the contents of the hardware configuration registers here for - * easy access later - */ - hsotg->hwcfg1 = readl(hsotg->regs + GHWCFG1); - hsotg->hwcfg2 = readl(hsotg->regs + GHWCFG2); - hsotg->hwcfg3 = readl(hsotg->regs + GHWCFG3); - hsotg->hwcfg4 = readl(hsotg->regs + GHWCFG4); - - dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hsotg->hwcfg1); - dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hsotg->hwcfg2); - dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hsotg->hwcfg3); - dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hsotg->hwcfg4); - - /* Force host mode to get HPTXFSIZ exact power on value */ - gusbcfg = readl(hsotg->regs + GUSBCFG); - gusbcfg |= GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); - - hsotg->hptxfsiz = readl(hsotg->regs + HPTXFSIZ); - dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hsotg->hptxfsiz); - gusbcfg = readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + if (retval) + return retval; + + retval = -ENOMEM; hcfg = readl(hsotg->regs + HCFG); dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg); - dev_dbg(hsotg->dev, "op_mode=%0x\n", - hsotg->hwcfg2 >> GHWCFG2_OP_MODE_SHIFT & - GHWCFG2_OP_MODE_MASK >> GHWCFG2_OP_MODE_SHIFT); - dev_dbg(hsotg->dev, "arch=%0x\n", - hsotg->hwcfg2 >> GHWCFG2_ARCHITECTURE_SHIFT & - GHWCFG2_ARCHITECTURE_MASK >> GHWCFG2_ARCHITECTURE_SHIFT); - dev_dbg(hsotg->dev, "num_dev_ep=%d\n", - hsotg->hwcfg2 >> GHWCFG2_NUM_DEV_EP_SHIFT & - GHWCFG2_NUM_DEV_EP_MASK >> GHWCFG2_NUM_DEV_EP_SHIFT); - dev_dbg(hsotg->dev, "max_host_chan=%d\n", - hsotg->hwcfg2 >> GHWCFG2_NUM_HOST_CHAN_SHIFT & - GHWCFG2_NUM_HOST_CHAN_MASK >> GHWCFG2_NUM_HOST_CHAN_SHIFT); - dev_dbg(hsotg->dev, "nonperio_tx_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT & - GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK >> - GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT); - dev_dbg(hsotg->dev, "host_perio_tx_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT & - GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK >> - GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT); - dev_dbg(hsotg->dev, "dev_token_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT & - GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK >> - GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT); #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS hsotg->frame_num_array = kzalloc(sizeof(*hsotg->frame_num_array) * @@ -2877,10 +2819,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, } INIT_WORK(&hsotg->wf_otg, dwc2_conn_id_status_change); - dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x\n", - hsotg->snpsid >> 12 & 0xf, hsotg->snpsid >> 8 & 0xf, - hsotg->snpsid >> 4 & 0xf, hsotg->snpsid & 0xf); - setup_timer(&hsotg->wkp_timer, dwc2_wakeup_detected, (unsigned long)hsotg); diff --git a/drivers/staging/dwc2/hcd.h b/drivers/staging/dwc2/hcd.h index 65c782e90e93..cc0a11708319 100644 --- a/drivers/staging/dwc2/hcd.h +++ b/drivers/staging/dwc2/hcd.h @@ -453,6 +453,7 @@ extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg, const struct dwc2_core_params *params); extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); +extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); /* Transaction Execution Functions */ extern enum dwc2_transaction_type dwc2_hcd_select_transactions( diff --git a/drivers/staging/dwc2/hcd_intr.c b/drivers/staging/dwc2/hcd_intr.c index f60b836b3d13..e143f69939f5 100644 --- a/drivers/staging/dwc2/hcd_intr.c +++ b/drivers/staging/dwc2/hcd_intr.c @@ -1759,7 +1759,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, * For core with OUT NAK enhancement, the flow for high-speed * CONTROL/BULK OUT is handled a little differently */ - if (hsotg->snpsid >= DWC2_CORE_REV_2_71a) { + if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_71a) { if (chan->speed == USB_SPEED_HIGH && !chan->ep_is_in && (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || chan->ep_type == USB_ENDPOINT_XFER_BULK)) { |