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:
committed by
Greg Kroah-Hartman
parent
743821717c
commit
a227fd7db7
@ -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;
|
||||
|
Reference in New Issue
Block a user