diff mbox

[Ver,1.0,5/7] DM355 USB updates for new DaVinci platform USB infrastructure.

Message ID 1255621580-24379-6-git-send-email-swami.iyer@ti.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Subbrathnam, Swaminathan Oct. 15, 2009, 3:46 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index f87ef58..b6e61e2 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -39,6 +39,7 @@ 
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x01e10000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
@@ -318,9 +319,25 @@  static struct spi_board_info dm355_evm_spi_info[] __initconst = {
 	},
 };
 
+static struct musb_hdrc_platform_data usb_evm_data[] = {
+	{
+#if defined(CONFIG_USB_MUSB_OTG)
+		.mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+		.mode =  MUSB_PERIPHERAL,
+#elif defined(CONFIG_USB_MUSB_HOST)
+		.mode = MUSB_HOST,
+#endif
+		.power = 255,
+		.potpgt = 8,
+		.set_vbus = NULL, /* VBUS is controller by USB IP */
+	}
+};
+
 static __init void dm355_evm_init(void)
 {
 	struct clk *aemif;
+	u32	phy_ctrl = __raw_readl(USB_PHY_CTRL);
 
 	gpio_request(1, "dm9000");
 	gpio_direction_input(1);
@@ -341,11 +358,18 @@  static __init void dm355_evm_init(void)
 	 * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
 	 * but could be 0x0400008c for about 25% faster page reads.
 	 */
-
 	gpio_request(2, "usb_id_toggle");
 	gpio_direction_output(2, USB_ID_VALUE);
+
+	/* dm355 EVM swaps usb D+/D- for signal integrity, and
+	 * is clocked from the main 24 MHz crystal.
+	 */
+	phy_ctrl &= ~(3 << 9);
+	phy_ctrl |= USBPHY_DATAPOL;
+	__raw_writel(phy_ctrl, USB_PHY_CTRL);
+
 	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	dm355_usb_configure(usb_evm_data, ARRAY_SIZE(usb_evm_data));
 
 	davinci_setup_mmc(0, &dm355evm_mmc_config);
 	davinci_setup_mmc(1, &dm355evm_mmc_config);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 0596700..c7dfab8 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -31,6 +31,9 @@ 
 #include <mach/serial.h>
 #include <mach/common.h>
 #include <mach/asp.h>
+#include <mach/usb_musb.h>
+#include <mach/usb.h>
+
 
 #include "clock.h"
 #include "mux.h"
@@ -849,6 +852,78 @@  void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
 	platform_device_register(&dm355_asp1_device);
 }
 
+/*
+ * Configure the USB PHY for DM355 platforms.
+ */
+static int dm355_usb_phy_config(struct device *dev, u8 mode, int is_on)
+{
+	u32	deepsleep = __raw_readl(DM355_DEEPSLEEP);
+	u32	phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+	if (is_on) {
+
+		/* 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;
+		deepsleep &= ~DRVVBUS_OVERRIDE;
+		__raw_writel(deepsleep, DM355_DEEPSLEEP);
+	} else {
+		/* 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);
+
+	if (is_on) {
+		/* wait for PLL to lock before proceeding */
+		while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
+			cpu_relax();
+	}
+
+	return 0;
+}
+
+static struct resource usb_resources[] = {
+	{
+		.start	= DAVINCI_USB_OTG_BASE,
+		.end	= DAVINCI_USB_OTG_BASE + 0x5ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_USBINT,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct plat_res_data dm355_usb_res;
+static struct usb_plat_data dm355_usb_plat_data;
+
+/*
+ * Initialize DM355 related USB information such as Memory maps, IRQ etc.
+ * Since DM355 supprots a single MUSB controller initialize the instance
+ * value to 1.
+ */
+void dm355_usb_configure(struct musb_hdrc_platform_data *pdata, u8 num_inst)
+{
+	pdata->phy_config = dm355_usb_phy_config;
+
+	dm355_usb_res.plat_data = pdata;
+	dm355_usb_res.res_data = usb_resources;
+	dm355_usb_res.num_res = ARRAY_SIZE(usb_resources);
+
+	dm355_usb_plat_data.prdata = &dm355_usb_res;
+	dm355_usb_plat_data.num_inst = num_inst;
+
+	/* Call the generic platform register function.  The USB
+	 * configuration w.r.t no. of ep's, capabalities etc. are common
+	 * across DaVinci platforms and hence allow the generic handler
+	 * to populate the information.
+	 */
+	setup_usb(&dm355_usb_plat_data);
+}
+
 void __init dm355_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm355);
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
index 85536d8..0d1686d 100644
--- a/arch/arm/mach-davinci/include/mach/dm355.h
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -14,6 +14,7 @@ 
 #include <mach/hardware.h>
 #include <mach/asp.h>
 #include <media/davinci/vpfe_capture.h>
+#include <linux/usb/musb.h>
 
 #define ASP1_TX_EVT_EN	1
 #define ASP1_RX_EVT_EN	2
@@ -25,5 +26,7 @@  void dm355_init_spi0(unsigned chipselect_mask,
 		struct spi_board_info *info, unsigned len);
 void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
 void dm355_set_vpfe_config(struct vpfe_config *cfg);
+extern void dm355_usb_configure(struct musb_hdrc_platform_data *pdata,
+					u8 num_inst);
 
 #endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/include/mach/usb.h b/arch/arm/mach-davinci/include/mach/usb.h
index 6fb9620..6a1b470 100644
--- a/arch/arm/mach-davinci/include/mach/usb.h
+++ b/arch/arm/mach-davinci/include/mach/usb.h
@@ -43,6 +43,7 @@ 
 #define USBPHY_NDATAPOL		BIT(18)
 #define USBPHY_SESSION_VBUS	BIT(17)
 #define USBPHY_PERI_USBID	BIT(16)
+#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 */
@@ -53,6 +54,11 @@ 
 #define USBPHY_OTGPDWN		BIT(1)
 #define USBPHY_PHYPDWN		BIT(0)
 
+#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
+#define DRVVBUS_FORCE		BIT(2)
+#define DRVVBUS_OVERRIDE	BIT(1)
+
 struct	da8xx_ohci_root_hub;
 
 typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,