@@ -39,6 +39,7 @@
#include <mach/serial.h>
#include <mach/nand.h>
#include <mach/mmc.h>
+#include <mach/usb_davinci.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);
@@ -31,6 +31,9 @@
#include <mach/serial.h>
#include <mach/common.h>
#include <mach/asp.h>
+#include <mach/usb_musb.h>
+#include <mach/usb_davinci.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);
@@ -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 */
@@ -30,6 +30,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 */
@@ -40,4 +41,9 @@
#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)
+
#endif