aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/core.c
diff options
context:
space:
mode:
authorJohn Youn <John.Youn@synopsys.com>2015-12-17 14:17:31 -0500
committerFelipe Balbi <balbi@ti.com>2015-12-22 13:00:51 -0500
commit55e1040e424b59063da627fb580ec953f4c01de7 (patch)
tree3932f964fcb76a9924d640053ce47f8009c408ff /drivers/usb/dwc2/core.c
parent09c96980dc723462ed2eeacc945fed5bcb278f85 (diff)
usb: dwc2: Improve handling of host and device hwparams
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 <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc2/core.c')
-rw-r--r--drivers/usb/dwc2/core.c88
1 files changed, 67 insertions, 21 deletions
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 436e7d1ef3c8..9dca83544b5e 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -3218,6 +3218,63 @@ static bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
3218 return dwc2_force_mode(hsotg, host); 3218 return dwc2_force_mode(hsotg, host);
3219} 3219}
3220 3220
3221/*
3222 * Gets host hardware parameters. Forces host mode if not currently in
3223 * host mode. Should be called immediately after a core soft reset in
3224 * order to get the reset values.
3225 */
3226static void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg)
3227{
3228 struct dwc2_hw_params *hw = &hsotg->hw_params;
3229 u32 gnptxfsiz;
3230 u32 hptxfsiz;
3231 bool forced;
3232
3233 if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
3234 return;
3235
3236 forced = dwc2_force_mode_if_needed(hsotg, true);
3237
3238 gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
3239 hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
3240 dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
3241 dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
3242
3243 if (forced)
3244 dwc2_clear_force_mode(hsotg);
3245
3246 hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
3247 FIFOSIZE_DEPTH_SHIFT;
3248 hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >>
3249 FIFOSIZE_DEPTH_SHIFT;
3250}
3251
3252/*
3253 * Gets device hardware parameters. Forces device mode if not
3254 * currently in device mode. Should be called immediately after a core
3255 * soft reset in order to get the reset values.
3256 */
3257static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
3258{
3259 struct dwc2_hw_params *hw = &hsotg->hw_params;
3260 bool forced;
3261 u32 gnptxfsiz;
3262
3263 if (hsotg->dr_mode == USB_DR_MODE_HOST)
3264 return;
3265
3266 forced = dwc2_force_mode_if_needed(hsotg, false);
3267
3268 gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
3269 dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
3270
3271 if (forced)
3272 dwc2_clear_force_mode(hsotg);
3273
3274 hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
3275 FIFOSIZE_DEPTH_SHIFT;
3276}
3277
3221/** 3278/**
3222 * During device initialization, read various hardware configuration 3279 * During device initialization, read various hardware configuration
3223 * registers and interpret the contents. 3280 * registers and interpret the contents.
@@ -3230,8 +3287,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
3230 struct dwc2_hw_params *hw = &hsotg->hw_params; 3287 struct dwc2_hw_params *hw = &hsotg->hw_params;
3231 unsigned width; 3288 unsigned width;
3232 u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; 3289 u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4;
3233 u32 hptxfsiz, grxfsiz, gnptxfsiz; 3290 u32 grxfsiz;
3234 u32 gusbcfg = 0;
3235 int retval; 3291 int retval;
3236 3292
3237 /* 3293 /*
@@ -3268,22 +3324,16 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
3268 dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4); 3324 dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4);
3269 dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); 3325 dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
3270 3326
3271 /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ 3327 /*
3272 if (hsotg->dr_mode != USB_DR_MODE_HOST) { 3328 * Host specific hardware parameters. Reading these parameters
3273 gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); 3329 * requires the controller to be in host mode. The mode will
3274 dwc2_writel(gusbcfg | GUSBCFG_FORCEHOSTMODE, 3330 * be forced, if necessary, to read these values.
3275 hsotg->regs + GUSBCFG); 3331 */
3276 usleep_range(25000, 50000); 3332 dwc2_get_host_hwparams(hsotg);
3277 } 3333 dwc2_get_dev_hwparams(hsotg);
3278 3334
3279 gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); 3335 /* hwcfg1 */
3280 hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); 3336 hw->dev_ep_dirs = hwcfg1;
3281 dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
3282 dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
3283 if (hsotg->dr_mode != USB_DR_MODE_HOST) {
3284 dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
3285 usleep_range(25000, 50000);
3286 }
3287 3337
3288 /* hwcfg2 */ 3338 /* hwcfg2 */
3289 hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >> 3339 hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
@@ -3339,10 +3389,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
3339 /* fifo sizes */ 3389 /* fifo sizes */
3340 hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> 3390 hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
3341 GRXFSIZ_DEPTH_SHIFT; 3391 GRXFSIZ_DEPTH_SHIFT;
3342 hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
3343 FIFOSIZE_DEPTH_SHIFT;
3344 hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >>
3345 FIFOSIZE_DEPTH_SHIFT;
3346 3392
3347 dev_dbg(hsotg->dev, "Detected values from hardware:\n"); 3393 dev_dbg(hsotg->dev, "Detected values from hardware:\n");
3348 dev_dbg(hsotg->dev, " op_mode=%d\n", 3394 dev_dbg(hsotg->dev, " op_mode=%d\n",