USB: musb: partial DaVinci dm355 support

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>
This commit is contained in:
David Brownell 2009-02-24 15:31:54 -08:00 committed by Greg Kroah-Hartman
parent 743821717c
commit a227fd7db7
3 changed files with 62 additions and 30 deletions

View 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"

View 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
@ -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;

View File

@ -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