[PATCH 67/97] USB: musb: partial DaVinci dm355 support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>

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@xxxxxxxxxxxxxxxxxxxxx>
Cc: Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/musb/Kconfig   |    6 ++--
 drivers/usb/musb/davinci.c |   63 ++++++++++++++++++++++++++++++-------------
 drivers/usb/musb/davinci.h |   23 ++++++++++-----
 3 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 9985db0..b66e854 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -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"
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 2dc7606..10d11ab 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -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
@@ -56,20 +59,26 @@
 
 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;
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h
index 7fb6238..046c844 100644
--- a/drivers/usb/musb/davinci.h
+++ b/drivers/usb/musb/davinci.h
@@ -15,14 +15,21 @@
  */
 
 /* 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
-- 
1.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux