USB: musb: partial DaVinci dm355 support
David Brownell [Tue, 24 Feb 2009 23:31:54 +0000 (15:31 -0800)]
Partial support for DaVinci DM355, on the EVM board; peripheral
mode should work, once mainline merges DM355 support.  Missing:

  (a) renumbering the GPIO for DRVVBUS on the DM6446 EVM,
      when DAVINCI_N_GPIO increases;

  (b) disabling DM355_DEEPSLEEP.DRVVBUS_OVERRIDE so VBUS is
      driven according to the ID signal, if cpu_is_..._dm355()

The new PHY control bits are ignored on DM6446.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

drivers/usb/musb/Kconfig
drivers/usb/musb/davinci.c
drivers/usb/musb/davinci.h

index 9985db0..b66e854 100644 (file)
@@ -20,8 +20,8 @@ config USB_MUSB_HDRC
          it's being used with, including the USB peripheral role,
          or the USB host role, or both.
 
-         Texas Instruments parts using this IP include DaVinci 644x,
-         OMAP 243x, OMAP 343x, and TUSB 6010.
+         Texas Instruments familiies using this IP include DaVinci
+         (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
 
          Analog Devices parts using this IP include Blackfin BF54x,
          BF525 and BF527.
@@ -40,7 +40,7 @@ config USB_MUSB_SOC
        default y if (BF54x && !BF544)
        default y if (BF52x && !BF522 && !BF523)
 
-comment "DaVinci 644x USB support"
+comment "DaVinci 35x and 644x USB support"
        depends on USB_MUSB_HDRC && ARCH_DAVINCI
 
 comment "OMAP 243x high speed USB support"
index 2dc7606..10d11ab 100644 (file)
@@ -48,6 +48,9 @@
 #include "cppi_dma.h"
 
 
+#define USB_PHY_CTRL   IO_ADDRESS(USBPHY_CTL_PADDR)
+#define DM355_DEEPSLEEP        IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
+
 /* REVISIT (PM) we should be able to keep the PHY in low power mode most
  * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
  * and, when in host mode, autosuspending idle root ports... PHYPLLON
 
 static inline void phy_on(void)
 {
-       /* start the on-chip PHY and its PLL */
-       __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
-                       (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
-       while ((__raw_readl((void __force __iomem *)
-                               IO_ADDRESS(USBPHY_CTL_PADDR))
-                       & USBPHY_PHYCLKGD) == 0)
+       u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+       /* power everything up; start the on-chip PHY and its PLL */
+       phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN);
+       phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON;
+       __raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+       /* wait for PLL to lock before proceeding */
+       while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
                cpu_relax();
 }
 
 static inline void phy_off(void)
 {
-       /* powerdown the on-chip PHY and its oscillator */
-       __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
-                       IO_ADDRESS(USBPHY_CTL_PADDR));
+       u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+       /* powerdown the on-chip PHY, its PLL, and the OTG block */
+       phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON);
+       phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN;
+       __raw_writel(phy_ctrl, USB_PHY_CTRL);
 }
 
 static int dma_off = 1;
@@ -126,10 +135,6 @@ void musb_platform_disable(struct musb *musb)
 }
 
 
-/* REVISIT it's not clear whether DaVinci can support full OTG.  */
-
-static int vbus_state = -1;
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 #define        portstate(stmt)         stmt
 #else
@@ -137,10 +142,19 @@ static int vbus_state = -1;
 #endif
 
 
-/* VBUS SWITCHING IS BOARD-SPECIFIC */
+/*
+ * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM,
+ * which doesn't wire DRVVBUS to the FET that switches it.  Unclear
+ * if that's a problem with the DM6446 chip or just with that board.
+ *
+ * In either case, the DM355 EVM automates DRVVBUS the normal way,
+ * when J10 is out, and TI documents it as handling OTG.
+ */
 
 #ifdef CONFIG_MACH_DAVINCI_EVM
 
+static int vbus_state = -1;
+
 /* I2C operations are always synchronous, and require a task context.
  * With unloaded systems, using the shared workqueue seems to suffice
  * to satisfy the 100msec A_WAIT_VRISE timeout...
@@ -150,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored)
        gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
        vbus_state = !vbus_state;
 }
-static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
 
 #endif /* EVM */
 
 static void davinci_source_power(struct musb *musb, int is_on, int immediate)
 {
+#ifdef CONFIG_MACH_DAVINCI_EVM
        if (is_on)
                is_on = 1;
 
@@ -163,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
                return;
        vbus_state = !is_on;            /* 0/1 vs "-1 == unknown/init" */
 
-#ifdef CONFIG_MACH_DAVINCI_EVM
        if (machine_is_davinci_evm()) {
+               static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
                if (immediate)
                        gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
                else
                        schedule_work(&evm_vbus_work);
        }
-#endif
        if (immediate)
                vbus_state = is_on;
+#endif
 }
 
 static void davinci_set_vbus(struct musb *musb, int is_on)
@@ -391,6 +406,17 @@ int __init musb_platform_init(struct musb *musb)
        musb->board_set_vbus = davinci_set_vbus;
        davinci_source_power(musb, 0, 1);
 
+       /* dm355 EVM swaps D+/D- for signal integrity, and
+        * is clocked from the main 24 MHz crystal.
+        */
+       if (machine_is_davinci_dm355_evm()) {
+               u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+               phy_ctrl &= ~(3 << 9);
+               phy_ctrl |= USBPHY_DATAPOL;
+               __raw_writel(phy_ctrl, USB_PHY_CTRL);
+       }
+
        /* reset the controller */
        musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
 
@@ -401,8 +427,7 @@ int __init musb_platform_init(struct musb *musb)
 
        /* NOTE:  irqs are in mixed mode, not bypass to pure-musb */
        pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
-               revision, __raw_readl((void __force __iomem *)
-                               IO_ADDRESS(USBPHY_CTL_PADDR)),
+               revision, __raw_readl(USB_PHY_CTRL),
                musb_readb(tibase, DAVINCI_USB_CTRL_REG));
 
        musb->isr = davinci_interrupt;
index 7fb6238..046c844 100644 (file)
  */
 
 /* Integrated highspeed/otg PHY */
-#define        USBPHY_CTL_PADDR        (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
-#define        USBPHY_PHYCLKGD         (1 << 8)
-#define        USBPHY_SESNDEN          (1 << 7)        /* v(sess_end) comparator */
-#define        USBPHY_VBDTCTEN         (1 << 6)        /* v(bus) comparator */
-#define        USBPHY_PHYPLLON         (1 << 4)        /* override pll suspend */
-#define        USBPHY_CLKO1SEL         (1 << 3)
-#define        USBPHY_OSCPDWN          (1 << 2)
-#define        USBPHY_PHYPDWN          (1 << 0)
+#define USBPHY_CTL_PADDR       (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USBPHY_DATAPOL         BIT(11) /* (dm355) switch D+/D- */
+#define USBPHY_PHYCLKGD                BIT(8)
+#define USBPHY_SESNDEN         BIT(7)  /* v(sess_end) comparator */
+#define USBPHY_VBDTCTEN                BIT(6)  /* v(bus) comparator */
+#define USBPHY_VBUSSENS                BIT(5)  /* (dm355,ro) is vbus > 0.5V */
+#define USBPHY_PHYPLLON                BIT(4)  /* override pll suspend */
+#define USBPHY_CLKO1SEL                BIT(3)
+#define USBPHY_OSCPDWN         BIT(2)
+#define USBPHY_OTGPDWN         BIT(1)
+#define USBPHY_PHYPDWN         BIT(0)
+
+#define DM355_DEEPSLEEP_PADDR  (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DRVVBUS_FORCE          BIT(2)
+#define DRVVBUS_OVERRIDE       BIT(1)
 
 /* For now include usb OTG module registers here */
 #define DAVINCI_USB_VERSION_REG                0x00