Skip to content

Commit 371254c

Browse files
georgecherianFelipe Balbi
authored andcommitted
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 <[email protected]> Tested-by: Bin Liu <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent d871c62 commit 371254c

File tree

2 files changed

+90
-6
lines changed

2 files changed

+90
-6
lines changed

drivers/usb/musb/musb_dsps.c

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ struct dsps_glue {
144144
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
145145
struct timer_list timer; /* otg_workaround timer */
146146
unsigned long last_timer; /* last timer data for each instance */
147+
bool sw_babble_enabled;
147148

148149
struct dsps_context context;
149150
struct debugfs_regset32 regset;
@@ -477,6 +478,19 @@ static int dsps_musb_init(struct musb *musb)
477478
val &= ~(1 << wrp->otg_disable);
478479
dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
479480

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+
480494
ret = dsps_musb_dbg_init(musb, glue);
481495
if (ret)
482496
return ret;
@@ -544,19 +558,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
544558
return 0;
545559
}
546560

561+
static 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+
547612
static int dsps_musb_reset(struct musb *musb)
548613
{
549614
struct device *dev = musb->controller;
550615
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
551616
const struct dsps_musb_wrapper *wrp = glue->wrp;
617+
int session_restart = 0;
552618

553-
dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
554-
usleep_range(100, 200);
555-
usb_phy_shutdown(musb->xceiv);
556-
usleep_range(100, 200);
557-
usb_phy_init(musb->xceiv);
619+
if (glue->sw_babble_enabled)
620+
session_restart = sw_babble_control(musb);
621+
/*
622+
* In case of new silicon version babble condition can be recovered
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+
}
558635

559-
return 0;
636+
return !session_restart;
560637
}
561638

562639
static struct musb_platform_ops dsps_ops = {

drivers/usb/musb/musb_regs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@
7272
#define MUSB_DEVCTL_HR 0x02
7373
#define MUSB_DEVCTL_SESSION 0x01
7474

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+
7581
/* MUSB ULPI VBUSCONTROL */
7682
#define MUSB_ULPI_USE_EXTVBUS 0x01
7783
#define MUSB_ULPI_USE_EXTVBUSIND 0x02
@@ -246,6 +252,7 @@
246252
*/
247253

248254
#define MUSB_DEVCTL 0x60 /* 8 bit */
255+
#define MUSB_BABBLE_CTL 0x61 /* 8 bit */
249256

250257
/* These are always controlled through the INDEX register */
251258
#define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */

0 commit comments

Comments
 (0)