aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGeorge Cherian <george.cherian@ti.com>2014-07-16 08:52:12 -0400
committerFelipe Balbi <balbi@ti.com>2014-07-16 11:00:02 -0400
commit371254ce462fcea2d09ffa30e20f01538b833080 (patch)
tree8478c839d30fcef3cdb90864d03450be6b38622c /drivers
parentd871c622e202efc663f953a4fcbd2cba6a28a24f (diff)
usb: musb: dsps: Add the sw_babble_control() and Enable for newer silicon
Add sw_babble_control() logic to differentiate between transient babble and real babble condition. Also add the SW babble control register definitions. Babble control register logic is implemented in the latest revision of AM335x. Find whether we are running on newer silicon. The babble control register reads 0x4 by default in newer silicon as opposed to 0 in old versions of AM335x. Based on this enable the sw babble control logic. Signed-off-by: George Cherian <george.cherian@ti.com> Tested-by: Bin Liu <b-liu@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers')
-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) */