Adds separate functions to get the host and device specific hardware
parameters. The functions check whether the parameters need to be read
at all, depending on dr_mode, and forces the mode only if necessary.
This saves some delays during probe. This also adds two device mode
parameters that will be used by the gadget.

Signed-off-by: John Youn <johny...@synopsys.com>
---
 drivers/usb/dwc2/core.c | 88 +++++++++++++++++++++++++++++++++++++------------
 drivers/usb/dwc2/core.h |  3 ++
 2 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 4d36133..097fd9f 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -3210,6 +3210,63 @@ static bool dwc2_force_mode_if_needed(struct dwc2_hsotg 
*hsotg, bool host)
        return dwc2_force_mode(hsotg, host);
 }
 
+/*
+ * Gets host hardware parameters. Forces host mode if not currently in
+ * host mode. Should be called immediately after a core soft reset in
+ * order to get the reset values.
+ */
+static void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg)
+{
+       struct dwc2_hw_params *hw = &hsotg->hw_params;
+       u32 gnptxfsiz;
+       u32 hptxfsiz;
+       bool forced;
+
+       if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+               return;
+
+       forced = dwc2_force_mode_if_needed(hsotg, true);
+
+       gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+       hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
+       dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
+       dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
+
+       if (forced)
+               dwc2_clear_force_mode(hsotg);
+
+       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;
+}
+
+/*
+ * Gets device hardware parameters. Forces device mode if not
+ * currently in device mode. Should be called immediately after a core
+ * soft reset in order to get the reset values.
+ */
+static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
+{
+       struct dwc2_hw_params *hw = &hsotg->hw_params;
+       bool forced;
+       u32 gnptxfsiz;
+
+       if (hsotg->dr_mode == USB_DR_MODE_HOST)
+               return;
+
+       forced = dwc2_force_mode_if_needed(hsotg, false);
+
+       gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+       dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
+
+       if (forced)
+               dwc2_clear_force_mode(hsotg);
+
+       hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
+                                      FIFOSIZE_DEPTH_SHIFT;
+}
+
 /**
  * During device initialization, read various hardware configuration
  * registers and interpret the contents.
@@ -3222,8 +3279,7 @@ 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 = 0;
+       u32 grxfsiz;
        int retval;
 
        /*
@@ -3260,22 +3316,16 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
        dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4);
        dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
 
-       /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */
-       if (hsotg->dr_mode != USB_DR_MODE_HOST) {
-               gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
-               dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE,
-                           hsotg->regs + GUSBCFG);
-               usleep_range(25000, 50000);
-       }
+       /*
+        * Host specific hardware parameters. Reading these parameters
+        * requires the controller to be in host mode. The mode will
+        * be forced, if necessary, to read these values.
+        */
+       dwc2_get_host_hwparams(hsotg);
+       dwc2_get_dev_hwparams(hsotg);
 
-       gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
-       hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
-       dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
-       dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
-       if (hsotg->dr_mode != USB_DR_MODE_HOST) {
-               dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
-               usleep_range(25000, 50000);
-       }
+       /* hwcfg1 */
+       hw->dev_ep_dirs = hwcfg1;
 
        /* hwcfg2 */
        hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
@@ -3324,10 +3374,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
        /* 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",
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 3dbb86f..90955fb 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -468,6 +468,7 @@ struct dwc2_core_params {
  *                       1 - 16 bits
  *                       2 - 8 or 16 bits
  * @snpsid:             Value from SNPSID register
+ * @dev_ep_dirs:        Direction of device endpoints (GHWCFG1)
  */
 struct dwc2_hw_params {
        unsigned op_mode:3;
@@ -478,6 +479,7 @@ struct dwc2_hw_params {
        unsigned en_multiple_tx_fifo:1;
        unsigned host_rx_fifo_size:16;
        unsigned host_nperio_tx_fifo_size:16;
+       unsigned dev_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;
@@ -494,6 +496,7 @@ struct dwc2_hw_params {
        unsigned power_optimized:1;
        unsigned utmi_phy_data_width:2;
        u32 snpsid;
+       u32 dev_ep_dirs;
 };
 
 /* Size of control and EP0 buffers */
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to