@@ -30,58 +30,16 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/gpio.h>
#include <mach/hardware.h>
#include <mach/memory.h>
-#include <mach/gpio.h>
-#include <mach/cputype.h>
-
-#include <asm/mach-types.h>
#include "musb_core.h"
-#ifdef CONFIG_MACH_DAVINCI_EVM
-#define GPIO_nVBUS_DRV 144
-#endif
-
#include "davinci.h"
#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
- * (overriding SUSPENDM?) then likely needs to stay off.
- */
-
-static inline void phy_on(void)
-{
- 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)
-{
- 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;
void musb_platform_enable(struct musb *musb)
@@ -142,62 +100,6 @@ void musb_platform_disable(struct musb *musb)
#define portstate(stmt)
#endif
-
-/*
- * 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...
- */
-static void evm_deferred_drvvbus(struct work_struct *ignored)
-{
- gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
- vbus_state = !vbus_state;
-}
-
-#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;
-
- if (vbus_state == is_on)
- return;
- vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */
-
- 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);
- }
- if (immediate)
- vbus_state = is_on;
-#endif
-}
-
-static void davinci_set_vbus(struct musb *musb, int is_on)
-{
- WARN_ON(is_on && is_peripheral_active(musb));
- davinci_source_power(musb, is_on, 0);
-}
-
-
#define POLL_SECONDS 2
static struct timer_list otg_workaround;
@@ -346,7 +248,8 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
/* NOTE: this must complete poweron within 100 msec
* (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
*/
- davinci_source_power(musb, drvvbus, 0);
+ if (musb->board_set_vbus)
+ musb->board_set_vbus(musb, drvvbus);
DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
drvvbus ? "on" : "off",
otg_state_string(musb),
@@ -381,6 +284,8 @@ int __init musb_platform_init(struct musb *musb)
{
void __iomem *tibase = musb->ctrl_base;
u32 revision;
+ struct device *dev = musb->controller;
+ struct musb_hdrc_platform_data *plat = dev->platform_data;
usb_nop_xceiv_register();
musb->xceiv = otg_get_transceiver();
@@ -399,47 +304,25 @@ int __init musb_platform_init(struct musb *musb)
if (is_host_enabled(musb))
setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
- musb->board_set_vbus = davinci_set_vbus;
- davinci_source_power(musb, 0, 1);
+ /* Subscribe VBUS handler to the platform specific VBUs handler */
+ musb->board_set_vbus = (void *) plat->set_vbus;
- /* 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);
- }
-
- /* On dm355, the default-A state machine needs DRVVBUS control.
- * If we won't be a host, there's no need to turn it on.
- */
- if (cpu_is_davinci_dm355()) {
- u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
-
- if (is_host_enabled(musb)) {
- deepsleep &= ~DRVVBUS_OVERRIDE;
- } else {
- deepsleep &= ~DRVVBUS_FORCE;
- deepsleep |= DRVVBUS_OVERRIDE;
- }
- __raw_writel(deepsleep, DM355_DEEPSLEEP);
- }
+ /* Turn off the VBUS by default */
+ if (musb->board_set_vbus)
+ musb->board_set_vbus(musb, 0);
/* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
/* start the on-chip PHY and its PLL */
- phy_on();
+ if (plat->phy_config)
+ plat->phy_config(dev, musb->board_mode, 1);
msleep(5);
/* 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(USB_PHY_CTRL),
- musb_readb(tibase, DAVINCI_USB_CTRL_REG));
+ pr_debug("DaVinci OTG revision %08x control %02x\n",
+ revision, musb_readb(tibase, DAVINCI_USB_CTRL_REG));
musb->isr = davinci_interrupt;
return 0;
@@ -451,19 +334,14 @@ fail:
int musb_platform_exit(struct musb *musb)
{
+ struct device *dev = musb->controller;
+ struct musb_hdrc_platform_data *plat = dev->platform_data;
+
if (is_host_enabled(musb))
del_timer_sync(&otg_workaround);
- /* force VBUS off */
- if (cpu_is_davinci_dm355()) {
- u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
-
- deepsleep &= ~DRVVBUS_FORCE;
- deepsleep |= DRVVBUS_OVERRIDE;
- __raw_writel(deepsleep, DM355_DEEPSLEEP);
- }
-
- davinci_source_power(musb, 0 /*off*/, 1);
+ if (musb->board_set_vbus)
+ musb->board_set_vbus(musb, 0);
/* delay, to avoid problems with module reload */
if (is_host_enabled(musb) && musb->xceiv->default_a) {
@@ -491,7 +369,9 @@ int musb_platform_exit(struct musb *musb)
DBG(1, "VBUS off timeout (devctl %02x)\n", devctl);
}
- phy_off();
+ /* Turn off the PHY */
+ if (plat->phy_config)
+ plat->phy_config(dev, musb->board_mode, 0);
clk_disable(musb->clock);
@@ -14,23 +14,6 @@
* DaVinci-specific definitions
*/
-/* Integrated highspeed/otg PHY */
-#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
#define DAVINCI_USB_CTRL_REG 0x04
@@ -448,7 +448,8 @@ struct musb {
static inline void musb_set_vbus(struct musb *musb, int is_on)
{
- musb->board_set_vbus(musb, is_on);
+ if (musb->board_set_vbus)
+ musb->board_set_vbus(musb, is_on);
}
#ifdef CONFIG_USB_GADGET_MUSB_HDRC