aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/musb/musb_dsps.c89
-rw-r--r--drivers/usb/musb/musb_regs.h7
2 files changed, 90 insertions, 6 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 53a4351aef97..f119a62140ef 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -144,6 +144,7 @@ struct dsps_glue {
144 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ 144 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
145 struct timer_list timer; /* otg_workaround timer */ 145 struct timer_list timer; /* otg_workaround timer */
146 unsigned long last_timer; /* last timer data for each instance */ 146 unsigned long last_timer; /* last timer data for each instance */
147 bool sw_babble_enabled;
147 148
148 struct dsps_context context; 149 struct dsps_context context;
149 struct debugfs_regset32 regset; 150 struct debugfs_regset32 regset;
@@ -477,6 +478,19 @@ static int dsps_musb_init(struct musb *musb)
477 val &= ~(1 << wrp->otg_disable); 478 val &= ~(1 << wrp->otg_disable);
478 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); 479 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
479 480
481 /*
482 * Check whether the dsps version has babble control enabled.
483 * In latest silicon revision the babble control logic is enabled.
484 * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
485 * logic enabled.
486 */
487 val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
488 if (val == MUSB_BABBLE_RCV_DISABLE) {
489 glue->sw_babble_enabled = true;
490 val |= MUSB_BABBLE_SW_SESSION_CTRL;
491 dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val);
492 }
493
480 ret = dsps_musb_dbg_init(musb, glue); 494 ret = dsps_musb_dbg_init(musb, glue);
481 if (ret) 495 if (ret)
482 return ret; 496 return ret;
@@ -544,19 +558,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
544 return 0; 558 return 0;
545} 559}
546 560
561static bool sw_babble_control(struct musb *musb)
562{
563 u8 babble_ctl;
564 bool session_restart = false;
565
566 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
567 dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n",
568 babble_ctl);
569 /*
570 * check line monitor flag to check whether babble is
571 * due to noise
572 */
573 dev_dbg(musb->controller, "STUCK_J is %s\n",
574 babble_ctl & MUSB_BABBLE_STUCK_J ? "set" : "reset");
575
576 if (babble_ctl & MUSB_BABBLE_STUCK_J) {
577 int timeout = 10;
578
579 /*
580 * babble is due to noise, then set transmit idle (d7 bit)
581 * to resume normal operation
582 */
583 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
584 babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
585 dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl);
586
587 /* wait till line monitor flag cleared */
588 dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n");
589 do {
590 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
591 udelay(1);
592 } while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--);
593
594 /* check whether stuck_at_j bit cleared */
595 if (babble_ctl & MUSB_BABBLE_STUCK_J) {
596 /*
597 * real babble condition has occurred
598 * restart the controller to start the
599 * session again
600 */
601 dev_dbg(musb->controller, "J not cleared, misc (%x)\n",
602 babble_ctl);
603 session_restart = true;
604 }
605 } else {
606 session_restart = true;
607 }
608
609 return session_restart;
610}
611
547static int dsps_musb_reset(struct musb *musb) 612static int dsps_musb_reset(struct musb *musb)
548{ 613{
549 struct device *dev = musb->controller; 614 struct device *dev = musb->controller;
550 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 615 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
551 const struct dsps_musb_wrapper *wrp = glue->wrp; 616 const struct dsps_musb_wrapper *wrp = glue->wrp;
617 int session_restart = 0;
552 618
553 dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); 619 if (glue->sw_babble_enabled)
554 usleep_range(100, 200); 620 session_restart = sw_babble_control(musb);
555 usb_phy_shutdown(musb->xceiv); 621 /*
556 usleep_range(100, 200); 622 * In case of new silicon version babble condition can be recovered
557 usb_phy_init(musb->xceiv); 623 * without resetting the MUSB. But for older silicon versions, MUSB
624 * reset is needed
625 */
626 if (session_restart || !glue->sw_babble_enabled) {
627 dev_info(musb->controller, "Restarting MUSB to recover from Babble\n");
628 dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
629 usleep_range(100, 200);
630 usb_phy_shutdown(musb->xceiv);
631 usleep_range(100, 200);
632 usb_phy_init(musb->xceiv);
633 session_restart = 1;
634 }
558 635
559 return 0; 636 return !session_restart;
560} 637}
561 638
562static struct musb_platform_ops dsps_ops = { 639static struct musb_platform_ops dsps_ops = {
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 03f2655af290..b9bcda5e3945 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -72,6 +72,12 @@
72#define MUSB_DEVCTL_HR 0x02 72#define MUSB_DEVCTL_HR 0x02
73#define MUSB_DEVCTL_SESSION 0x01 73#define MUSB_DEVCTL_SESSION 0x01
74 74
75/* BABBLE_CTL */
76#define MUSB_BABBLE_FORCE_TXIDLE 0x80
77#define MUSB_BABBLE_SW_SESSION_CTRL 0x40
78#define MUSB_BABBLE_STUCK_J 0x20
79#define MUSB_BABBLE_RCV_DISABLE 0x04
80
75/* MUSB ULPI VBUSCONTROL */ 81/* MUSB ULPI VBUSCONTROL */
76#define MUSB_ULPI_USE_EXTVBUS 0x01 82#define MUSB_ULPI_USE_EXTVBUS 0x01
77#define MUSB_ULPI_USE_EXTVBUSIND 0x02 83#define MUSB_ULPI_USE_EXTVBUSIND 0x02
@@ -246,6 +252,7 @@
246 */ 252 */
247 253
248#define MUSB_DEVCTL 0x60 /* 8 bit */ 254#define MUSB_DEVCTL 0x60 /* 8 bit */
255#define MUSB_BABBLE_CTL 0x61 /* 8 bit */
249 256
250/* These are always controlled through the INDEX register */ 257/* These are always controlled through the INDEX register */
251#define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ 258#define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */