From 4d3190e1f84f08692f4b87461108f72e9a0b452c Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Tue, 16 Jul 2013 12:22:12 -0700 Subject: [PATCH] staging: dwc2: add driver parameter to set AHB config register value 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 Tested-by: Stephen Warren Reviewed-by: Matthijs Kooijman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dwc2/core.c | 51 ++++++++++--------------------------- drivers/staging/dwc2/core.h | 13 +++++----- drivers/staging/dwc2/hw.h | 4 +++ drivers/staging/dwc2/pci.c | 2 +- 4 files changed, 25 insertions(+), 45 deletions(-) diff --git a/drivers/staging/dwc2/core.c b/drivers/staging/dwc2/core.c index e3a0e770301d..a090f79bb5f5 100644 --- a/drivers/staging/dwc2/core.c +++ b/drivers/staging/dwc2/core.c @@ -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; diff --git a/drivers/staging/dwc2/core.h b/drivers/staging/dwc2/core.h index fc075a7c1de5..e771e405453f 100644 --- a/drivers/staging/dwc2/core.h +++ b/drivers/staging/dwc2/core.h @@ -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); diff --git a/drivers/staging/dwc2/hw.h b/drivers/staging/dwc2/hw.h index 382a1d74865d..cf0dc97d5520 100644 --- a/drivers/staging/dwc2/hw.h +++ b/drivers/staging/dwc2/hw.h @@ -78,6 +78,10 @@ #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) diff --git a/drivers/staging/dwc2/pci.c b/drivers/staging/dwc2/pci.c index 3ca54d6782fd..fdfbc719663c 100644 --- a/drivers/staging/dwc2/pci.c +++ b/drivers/staging/dwc2/pci.c @@ -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, }; /**