]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
musb_hdrc: Workaround for tusb spontaneous wake-up issue
authorTony Lindgren <tony@atomide.com>
Mon, 11 Jun 2007 07:39:09 +0000 (00:39 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 11 Jun 2007 09:59:45 +0000 (02:59 -0700)
At least tusb3.0 has a problem of waking up to spontaneously from idle
when WBUS wake-up events are enabled (Issue #2). This patch disables
power detection in PHY for the duration of idle.

Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/usb/musb/tusb6010.c

index 23bff72bfc0b4cb6d30a2bd9fe53c5bfe630dc70..21defbb749990934e1440c04ca8c688f484fa1db 100644 (file)
@@ -60,6 +60,53 @@ static int __init tusb_print_revision(struct musb *musb)
        return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV));
 }
 
+#define WBUS_QUIRK_MASK        (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1    \
+                               | TUSB_PHY_OTG_CTRL_TESTM0)
+
+/*
+ * Workaround for spontaneous WBUS wake-up issue #2 for tusb3.0.
+ * Disables power detection in PHY for the duration of idle.
+ */
+static void tusb_wbus_quirk(struct musb *musb, int enabled)
+{
+       void __iomem    *base = musb->ctrl_base;
+       static u32      phy_otg_ena = 0, phy_otg_ctrl = 0;
+       u32             int_src, tmp;
+
+       if (enabled) {
+               phy_otg_ena = musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE);
+               phy_otg_ctrl = musb_readl(base, TUSB_PHY_OTG_CTRL);
+               tmp = TUSB_PHY_OTG_CTRL_WRPROTECT
+                               | phy_otg_ena | WBUS_QUIRK_MASK;
+               musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE, tmp);
+               tmp = phy_otg_ctrl & ~WBUS_QUIRK_MASK;
+               tmp |= TUSB_PHY_OTG_CTRL_WRPROTECT | TUSB_PHY_OTG_CTRL_TESTM2;
+               musb_writel(base, TUSB_PHY_OTG_CTRL, tmp);
+               DBG(2, "Enabled tusb wbus quirk ena %08x ctrl %08x\n",
+                       musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE),
+                       musb_readl(base, TUSB_PHY_OTG_CTRL));
+       } else if (musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE)
+                                       & TUSB_PHY_OTG_CTRL_TESTM2) {
+               tmp = TUSB_PHY_OTG_CTRL_WRPROTECT
+                               | phy_otg_ena | WBUS_QUIRK_MASK;
+               musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE, tmp);
+               tmp = TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ctrl;
+               musb_writel(base, TUSB_PHY_OTG_CTRL, tmp);
+               tmp = TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ena;
+               musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE, tmp);
+               DBG(2, "Disabled tusb wbus quirk ena %08x ctrl %08x\n",
+                       musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE),
+                       musb_readl(base, TUSB_PHY_OTG_CTRL));
+               phy_otg_ena = 0;
+               phy_otg_ctrl = 0;
+       }
+
+       int_src = musb_readl(base, TUSB_INT_SRC);
+       if (int_src & TUSB_INT_SRC_ID_STATUS_CHNG)
+               musb_writel(base, TUSB_INT_SRC_CLEAR,
+                               TUSB_INT_SRC_ID_STATUS_CHNG);
+}
+
 /*
  * TUSB 6010 may use a parallel bus that doesn't support byte ops;
  * so both loading and unloading FIFOs need explicit byte counts.
@@ -287,6 +334,10 @@ static void tusb_allow_idle(struct musb *musb, u32 wakeup_enables)
        void __iomem    *base = musb->ctrl_base;
        u32             reg;
 
+       if ((wakeup_enables & TUSB_PRCM_WBUS)
+                       && (tusb_get_revision(musb) == TUSB_REV_30))
+               tusb_wbus_quirk(musb, 1);
+
        tusb_set_clock_source(musb, 0);
 
        wakeup_enables |= TUSB_PRCM_WNORCS;
@@ -685,6 +736,9 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci)
                u32     reg;
                u32     i;
 
+               if (tusb_get_revision(musb) == TUSB_REV_30)
+                       tusb_wbus_quirk(musb, 0);
+
                /* there are issues re-locking the PLL on wakeup ... */
 
                /* work around issue 8 */