aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_dsps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musb_dsps.c')
-rw-r--r--drivers/usb/musb/musb_dsps.c104
1 files changed, 97 insertions, 7 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 09529f94e72d..c791ba5da91a 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -56,16 +56,24 @@ static const struct of_device_id musb_dsps_of_match[];
56 * dependent on musb core layer symbols. 56 * dependent on musb core layer symbols.
57 */ 57 */
58static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) 58static inline u8 dsps_readb(const void __iomem *addr, unsigned offset)
59 { return __raw_readb(addr + offset); } 59{
60 return __raw_readb(addr + offset);
61}
60 62
61static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) 63static inline u32 dsps_readl(const void __iomem *addr, unsigned offset)
62 { return __raw_readl(addr + offset); } 64{
65 return __raw_readl(addr + offset);
66}
63 67
64static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) 68static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data)
65 { __raw_writeb(data, addr + offset); } 69{
70 __raw_writeb(data, addr + offset);
71}
66 72
67static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) 73static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data)
68 { __raw_writel(data, addr + offset); } 74{
75 __raw_writel(data, addr + offset);
76}
69 77
70/** 78/**
71 * DSPS musb wrapper register offset. 79 * DSPS musb wrapper register offset.
@@ -136,6 +144,7 @@ struct dsps_glue {
136 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ 144 const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
137 struct timer_list timer; /* otg_workaround timer */ 145 struct timer_list timer; /* otg_workaround timer */
138 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;
139 148
140 struct dsps_context context; 149 struct dsps_context context;
141 struct debugfs_regset32 regset; 150 struct debugfs_regset32 regset;
@@ -469,6 +478,19 @@ static int dsps_musb_init(struct musb *musb)
469 val &= ~(1 << wrp->otg_disable); 478 val &= ~(1 << wrp->otg_disable);
470 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); 479 dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
471 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
472 ret = dsps_musb_dbg_init(musb, glue); 494 ret = dsps_musb_dbg_init(musb, glue);
473 if (ret) 495 if (ret)
474 return ret; 496 return ret;
@@ -535,14 +557,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
535 return 0; 557 return 0;
536} 558}
537 559
538static void dsps_musb_reset(struct musb *musb) 560static bool sw_babble_control(struct musb *musb)
561{
562 u8 babble_ctl;
563 bool session_restart = false;
564
565 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
566 dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n",
567 babble_ctl);
568 /*
569 * check line monitor flag to check whether babble is
570 * due to noise
571 */
572 dev_dbg(musb->controller, "STUCK_J is %s\n",
573 babble_ctl & MUSB_BABBLE_STUCK_J ? "set" : "reset");
574
575 if (babble_ctl & MUSB_BABBLE_STUCK_J) {
576 int timeout = 10;
577
578 /*
579 * babble is due to noise, then set transmit idle (d7 bit)
580 * to resume normal operation
581 */
582 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
583 babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
584 dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl);
585
586 /* wait till line monitor flag cleared */
587 dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n");
588 do {
589 babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
590 udelay(1);
591 } while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--);
592
593 /* check whether stuck_at_j bit cleared */
594 if (babble_ctl & MUSB_BABBLE_STUCK_J) {
595 /*
596 * real babble condition has occurred
597 * restart the controller to start the
598 * session again
599 */
600 dev_dbg(musb->controller, "J not cleared, misc (%x)\n",
601 babble_ctl);
602 session_restart = true;
603 }
604 } else {
605 session_restart = true;
606 }
607
608 return session_restart;
609}
610
611static int dsps_musb_reset(struct musb *musb)
539{ 612{
540 struct device *dev = musb->controller; 613 struct device *dev = musb->controller;
541 struct dsps_glue *glue = dev_get_drvdata(dev->parent); 614 struct dsps_glue *glue = dev_get_drvdata(dev->parent);
542 const struct dsps_musb_wrapper *wrp = glue->wrp; 615 const struct dsps_musb_wrapper *wrp = glue->wrp;
616 int session_restart = 0;
617
618 if (glue->sw_babble_enabled)
619 session_restart = sw_babble_control(musb);
620 /*
621 * In case of new silicon version babble condition can be recovered
622 * without resetting the MUSB. But for older silicon versions, MUSB
623 * reset is needed
624 */
625 if (session_restart || !glue->sw_babble_enabled) {
626 dev_info(musb->controller, "Restarting MUSB to recover from Babble\n");
627 dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
628 usleep_range(100, 200);
629 usb_phy_shutdown(musb->xceiv);
630 usleep_range(100, 200);
631 usb_phy_init(musb->xceiv);
632 session_restart = 1;
633 }
543 634
544 dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); 635 return !session_restart;
545 udelay(100);
546} 636}
547 637
548static struct musb_platform_ops dsps_ops = { 638static struct musb_platform_ops dsps_ops = {