diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_phy_internal.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_phy_internal.c | 93 | 
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index ebe33df708b..e2e605fe913 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -29,6 +29,7 @@  #include <linux/usb.h>  #include <plat/usb.h> +#include "control.h"  /* OMAP control module register for UTMI PHY */  #define CONTROL_DEV_CONF		0x300 @@ -162,3 +163,95 @@ int omap4430_phy_exit(struct device *dev)  	return 0;  } + +void am35x_musb_reset(void) +{ +	u32	regval; + +	/* Reset the musb interface */ +	regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + +	regval |= AM35XX_USBOTGSS_SW_RST; +	omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + +	regval &= ~AM35XX_USBOTGSS_SW_RST; +	omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + +	regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); +} + +void am35x_musb_phy_power(u8 on) +{ +	unsigned long timeout = jiffies + msecs_to_jiffies(100); +	u32 devconf2; + +	if (on) { +		/* +		 * Start the on-chip PHY and its PLL. +		 */ +		devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + +		devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); +		devconf2 |= CONF2_PHY_PLLON; + +		omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + +		pr_info(KERN_INFO "Waiting for PHY clock good...\n"); +		while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) +				& CONF2_PHYCLKGD)) { +			cpu_relax(); + +			if (time_after(jiffies, timeout)) { +				pr_err(KERN_ERR "musb PHY clock good timed out\n"); +				break; +			} +		} +	} else { +		/* +		 * Power down the on-chip PHY. +		 */ +		devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + +		devconf2 &= ~CONF2_PHY_PLLON; +		devconf2 |=  CONF2_PHYPWRDN | CONF2_OTGPWRDN; +		omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); +	} +} + +void am35x_musb_clear_irq(void) +{ +	u32 regval; + +	regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +	regval |= AM35XX_USBOTGSS_INT_CLR; +	omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); +	regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +void am35x_musb_set_mode(u8 musb_mode) +{ +	u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + +	devconf2 &= ~CONF2_OTGMODE; +	switch (musb_mode) { +#ifdef	CONFIG_USB_MUSB_HDRC_HCD +	case MUSB_HOST:		/* Force VBUS valid, ID = 0 */ +		devconf2 |= CONF2_FORCE_HOST; +		break; +#endif +#ifdef	CONFIG_USB_GADGET_MUSB_HDRC +	case MUSB_PERIPHERAL:	/* Force VBUS valid, ID = 1 */ +		devconf2 |= CONF2_FORCE_DEVICE; +		break; +#endif +#ifdef	CONFIG_USB_MUSB_OTG +	case MUSB_OTG:		/* Don't override the VBUS/ID comparators */ +		devconf2 |= CONF2_NO_OVERRIDE; +		break; +#endif +	default: +		pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); +	} + +	omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); +}  |