aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/core.c
diff options
context:
space:
mode:
authorJohn Youn <johnyoun@synopsys.com>2016-09-07 22:39:43 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-09-08 07:02:54 -0400
commit2938fc63e0c26bf694436ac81bc776c8b7eced0c (patch)
tree46b4d9f5763f7cd6e37aade7db3fd948d78fbe77 /drivers/usb/dwc2/core.c
parentfef6bc37dbafe0d6d71c808c8867a8c5ab4b9816 (diff)
usb: dwc2: Properly account for the force mode delays
When a force mode bit is set and the IDDIG debounce filter is enabled, there is a delay for the forced mode to take effect. This delay is due to the IDDIG debounce filter and is variable depending on the platform's PHY clock speed. To account for this delay we can poll for the expected mode. On a clear force mode, since we don't know what mode to poll for, delay for a fixed 100 ms. This is the maximum delay based on the slowest PHY clock speed. Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2/core.c')
-rw-r--r--drivers/usb/dwc2/core.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index a3068e01c609..fa9b26b91507 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -395,9 +395,9 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg)
395 * Checks are done in this function to determine whether doing a force 395 * Checks are done in this function to determine whether doing a force
396 * would be valid or not. 396 * would be valid or not.
397 * 397 *
398 * If a force is done, it requires a 25ms delay to take effect. 398 * If a force is done, it requires a IDDIG debounce filter delay if
399 * 399 * the filter is configured and enabled. We poll the current mode of
400 * Returns true if the mode was forced. 400 * the controller to account for this delay.
401 */ 401 */
402static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) 402static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
403{ 403{
@@ -432,12 +432,18 @@ static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
432 gusbcfg |= set; 432 gusbcfg |= set;
433 dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); 433 dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
434 434
435 msleep(25); 435 dwc2_wait_for_mode(hsotg, host);
436 return true; 436 return true;
437} 437}
438 438
439/* 439/**
440 * Clears the force mode bits. 440 * dwc2_clear_force_mode() - Clears the force mode bits.
441 *
442 * After clearing the bits, wait up to 100 ms to account for any
443 * potential IDDIG filter delay. We can't know if we expect this delay
444 * or not because the value of the connector ID status is affected by
445 * the force mode. We only need to call this once during probe if
446 * dr_mode == OTG.
441 */ 447 */
442static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) 448static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
443{ 449{
@@ -448,11 +454,8 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
448 gusbcfg &= ~GUSBCFG_FORCEDEVMODE; 454 gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
449 dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); 455 dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
450 456
451 /* 457 if (dwc2_iddig_filter_enabled(hsotg))
452 * NOTE: This long sleep is _very_ important, otherwise the core will 458 usleep_range(100000, 110000);
453 * not stay in host mode after a connector ID change!
454 */
455 msleep(25);
456} 459}
457 460
458/* 461/*
@@ -475,12 +478,6 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
475 __func__, hsotg->dr_mode); 478 __func__, hsotg->dr_mode);
476 break; 479 break;
477 } 480 }
478
479 /*
480 * NOTE: This is required for some rockchip soc based
481 * platforms.
482 */
483 msleep(50);
484} 481}
485 482
486/* 483/*