2010-12-10 15:28:20 +03:00
/*
* This file configures the internal USB PHY in OMAP4430 . Used
* with TWL6030 transceiver and MUSB on OMAP4430 .
*
* Copyright ( C ) 2010 Texas Instruments Incorporated - http : //www.ti.com
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* Author : Hema HK < hemahk @ ti . com >
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
*/
# include <linux/types.h>
# include <linux/delay.h>
# include <linux/clk.h>
# include <linux/io.h>
# include <linux/err.h>
# include <linux/usb.h>
# include <plat/usb.h>
2012-08-28 04:43:01 +04:00
2012-08-31 21:59:07 +04:00
# include "soc.h"
2011-02-16 15:04:40 +03:00
# include "control.h"
2010-12-10 15:28:20 +03:00
2011-02-16 15:04:40 +03:00
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 ) ;
}
2011-05-02 13:45:05 +04:00
void am35x_set_mode ( u8 musb_mode )
2011-02-16 15:04:40 +03:00
{
u32 devconf2 = omap_ctrl_readl ( AM35XX_CONTROL_DEVCONF2 ) ;
devconf2 & = ~ CONF2_OTGMODE ;
switch ( musb_mode ) {
case MUSB_HOST : /* Force VBUS valid, ID = 0 */
devconf2 | = CONF2_FORCE_HOST ;
break ;
case MUSB_PERIPHERAL : /* Force VBUS valid, ID = 1 */
devconf2 | = CONF2_FORCE_DEVICE ;
break ;
case MUSB_OTG : /* Don't override the VBUS/ID comparators */
devconf2 | = CONF2_NO_OVERRIDE ;
break ;
default :
pr_info ( KERN_INFO " Unsupported mode %u \n " , musb_mode ) ;
}
omap_ctrl_writel ( devconf2 , AM35XX_CONTROL_DEVCONF2 ) ;
}
2011-12-13 22:50:58 +04:00
void ti81xx_musb_phy_power ( u8 on )
{
void __iomem * scm_base = NULL ;
u32 usbphycfg ;
scm_base = ioremap ( TI81XX_SCM_BASE , SZ_2K ) ;
if ( ! scm_base ) {
pr_err ( " system control module ioremap failed \n " ) ;
return ;
}
usbphycfg = __raw_readl ( scm_base + USBCTRL0 ) ;
if ( on ) {
if ( cpu_is_ti816x ( ) ) {
usbphycfg | = TI816X_USBPHY0_NORMAL_MODE ;
usbphycfg & = ~ TI816X_USBPHY_REFCLK_OSC ;
} else if ( cpu_is_ti814x ( ) ) {
usbphycfg & = ~ ( USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN
| USBPHY_DPINPUT | USBPHY_DMINPUT ) ;
usbphycfg | = ( USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN
| USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL ) ;
}
} else {
if ( cpu_is_ti816x ( ) )
usbphycfg & = ~ TI816X_USBPHY0_NORMAL_MODE ;
else if ( cpu_is_ti814x ( ) )
usbphycfg | = USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN ;
}
__raw_writel ( usbphycfg , scm_base + USBCTRL0 ) ;
iounmap ( scm_base ) ;
}