staging: dwc2: add driver parameter to set AHB config register value
authorPaul Zimmerman <Paul.Zimmerman@synopsys.com>
Tue, 16 Jul 2013 19:22:12 +0000 (12:22 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 21:56:19 +0000 (14:56 -0700)
The dwc2 driver sets the value of the DWC2 GAHBCFG register to 0x6,
which is GAHBCFG_HBSTLEN_INCR4. But different platforms may require
different values. In particular, the Broadcom 2835 SOC used in the
Raspberry Pi needs a value of 0x10, otherwise the DWC2 controller
stops working after a short period of heavy USB traffic.

So this patch adds another driver parameter named 'ahbcfg'. The
default value is 0x6. Any platform needing a different value should
add a DT attribute to set it.

This patch also removes the 'ahb_single' driver parameter, since
that bit can now be set using 'ahbcfg'.

This patch does not add DT support to platform.c, I will leave that
to whoever owns the first platform that needs a non-default value.
(Stephen?)

Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Tested-by: Stephen Warren <swarren@wwwdotorg.org>
Reviewed-by: Matthijs Kooijman <matthijs@stdin.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/dwc2/core.c
drivers/staging/dwc2/core.h
drivers/staging/dwc2/hw.h
drivers/staging/dwc2/pci.c

index e3a0e770301d53893cd9aef708972eea0344a99c..a090f79bb5f5306e4671c8f8c6154132803fa710 100644 (file)
@@ -277,7 +277,7 @@ static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 
 static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 {
-       u32 ahbcfg = 0;
+       u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
 
        switch (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) {
        case GHWCFG2_EXT_DMA_ARCH:
@@ -286,11 +286,11 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 
        case GHWCFG2_INT_DMA_ARCH:
                dev_dbg(hsotg->dev, "Internal DMA Mode\n");
-               /*
-                * Old value was GAHBCFG_HBSTLEN_INCR - done for
-                * Host mode ISOC in issue fix - vahrama
-                */
-               ahbcfg |= GAHBCFG_HBSTLEN_INCR4;
+               if (hsotg->core_params->ahbcfg != -1) {
+                       ahbcfg &= GAHBCFG_CTRL_MASK;
+                       ahbcfg |= hsotg->core_params->ahbcfg &
+                                 ~GAHBCFG_CTRL_MASK;
+               }
                break;
 
        case GHWCFG2_SLAVE_ONLY_ARCH:
@@ -313,9 +313,6 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
                hsotg->core_params->dma_desc_enable = 0;
        }
 
-       if (hsotg->core_params->ahb_single > 0)
-               ahbcfg |= GAHBCFG_AHB_SINGLE;
-
        if (hsotg->core_params->dma_enable > 0)
                ahbcfg |= GAHBCFG_DMA_EN;
 
@@ -2586,35 +2583,13 @@ int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
        return retval;
 }
 
-int dwc2_set_param_ahb_single(struct dwc2_hsotg *hsotg, int val)
+int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
 {
-       int valid = 1;
-       int retval = 0;
-
-       if (DWC2_PARAM_TEST(val, 0, 1)) {
-               if (val >= 0) {
-                       dev_err(hsotg->dev,
-                               "'%d' invalid for parameter ahb_single\n", val);
-                       dev_err(hsotg->dev, "ahb_single must be 0 or 1\n");
-               }
-               valid = 0;
-       }
-
-       if (val > 0 && hsotg->snpsid < DWC2_CORE_REV_2_94a)
-               valid = 0;
-
-       if (!valid) {
-               if (val >= 0)
-                       dev_err(hsotg->dev,
-                               "%d invalid for parameter ahb_single. Check HW configuration.\n",
-                               val);
-               val = 0;
-               dev_dbg(hsotg->dev, "Setting ahb_single to %d\n", val);
-               retval = -EINVAL;
-       }
-
-       hsotg->core_params->ahb_single = val;
-       return retval;
+       if (val != -1)
+               hsotg->core_params->ahbcfg = val;
+       else
+               hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4;
+       return 0;
 }
 
 int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
@@ -2681,7 +2656,7 @@ int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
        retval |= dwc2_set_param_en_multiple_tx_fifo(hsotg,
                        params->en_multiple_tx_fifo);
        retval |= dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
-       retval |= dwc2_set_param_ahb_single(hsotg, params->ahb_single);
+       retval |= dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
        retval |= dwc2_set_param_otg_ver(hsotg, params->otg_ver);
 
        return retval;
index fc075a7c1de5f132f8ea917bc6188d85afee210b..e771e405453f68baafdd34c2bde365594f0e045a 100644 (file)
@@ -150,10 +150,11 @@ enum dwc2_lx_state {
  *                      are enabled
  * @reload_ctl:         True to allow dynamic reloading of HFIR register during
  *                      runtime
- * @ahb_single:         This bit enables SINGLE transfers for remainder data in
- *                      a transfer for DMA mode of operation.
- *                       0 - remainder data will be sent using INCR burst size
- *                       1 - remainder data will be sent using SINGLE burst size
+ * @ahbcfg:             This field allows the default value of the GAHBCFG
+ *                      register to be overridden
+ *                       -1         - GAHBCFG value will not be overridden
+ *                       all others - GAHBCFG value will be overridden with
+ *                                    this value
  * @otg_ver:            OTG version supported
  *                       0 - 1.3
  *                       1 - 2.0
@@ -189,7 +190,7 @@ struct dwc2_core_params {
        int host_ls_low_power_phy_clk;
        int ts_dline;
        int reload_ctl;
-       int ahb_single;
+       int ahbcfg;
 };
 
 /**
@@ -643,7 +644,7 @@ extern int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg,
 
 extern int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val);
 
-extern int dwc2_set_param_ahb_single(struct dwc2_hsotg *hsotg, int val);
+extern int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val);
 
 extern int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val);
 
index 382a1d74865d288cf26e4b256e67e21be5f3c4cc..cf0dc97d5520eeace91e1c259b5d7e1b2abee4a5 100644 (file)
 #define GAHBCFG_HBSTLEN_INCR8                  (5 << 1)
 #define GAHBCFG_HBSTLEN_INCR16                 (7 << 1)
 #define GAHBCFG_GLBL_INTR_EN           (1 << 0)
+#define GAHBCFG_CTRL_MASK              (GAHBCFG_P_TXF_EMP_LVL | \
+                                        GAHBCFG_NP_TXF_EMP_LVL | \
+                                        GAHBCFG_DMA_EN | \
+                                        GAHBCFG_GLBL_INTR_EN)
 
 #define GUSBCFG                                HSOTG_REG(0x00C)
 #define GUSBCFG_FORCEDEVMODE           (1 << 30)
index 3ca54d6782fdc4a69af5a44e025c4cb71d915db8..fdfbc719663c5f3fe4a5d951d4c5102efe07bec1 100644 (file)
@@ -83,7 +83,7 @@ static const struct dwc2_core_params dwc2_module_params = {
        .host_ls_low_power_phy_clk      = -1,
        .ts_dline                       = -1,
        .reload_ctl                     = -1,
-       .ahb_single                     = -1,
+       .ahbcfg                         = -1,
 };
 
 /**