2019-05-23 11:14:42 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-12-10 17:58:20 +05:30
/*
* This file configures the internal USB PHY in OMAP4430 . Used
* with TWL6030 transceiver and MUSB on OMAP4430 .
*
2020-07-19 12:30:33 +02:00
* Copyright ( C ) 2010 Texas Instruments Incorporated - https : //www.ti.com
2010-12-10 17:58:20 +05:30
* Author : Hema HK < hemahk @ ti . com >
*/
2014-10-07 23:16:16 +09:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2010-12-10 17:58:20 +05:30
# include <linux/types.h>
# include <linux/delay.h>
# include <linux/clk.h>
# include <linux/io.h>
# include <linux/err.h>
# include <linux/usb.h>
2012-10-24 14:26:18 -07:00
# include <linux/usb/musb.h>
2012-08-27 17:43:01 -07:00
2012-08-31 10:59:07 -07:00
# include "soc.h"
2011-02-16 17:34:40 +05:30
# include "control.h"
2012-10-24 14:26:18 -07:00
# include "usb.h"
2010-12-10 17:58:20 +05:30
2012-11-09 16:30:35 +02:00
# define CONTROL_DEV_CONF 0x300
# define PHY_PD 0x1
/**
* omap4430_phy_power_down : disable MUSB PHY during early init
*
* OMAP4 MUSB PHY module is enabled by default on reset , but this will
* prevent core retention if not disabled by SW . USB driver will
* later on enable this , once and if the driver needs it .
*/
static int __init omap4430_phy_power_down ( void )
{
void __iomem * ctrl_base ;
if ( ! cpu_is_omap44xx ( ) )
return 0 ;
ctrl_base = ioremap ( OMAP443X_SCM_BASE , SZ_1K ) ;
if ( ! ctrl_base ) {
pr_err ( " control module ioremap failed \n " ) ;
return - ENOMEM ;
}
/* Power down the phy */
2014-04-15 20:37:46 +03:00
writel_relaxed ( PHY_PD , ctrl_base + CONTROL_DEV_CONF ) ;
2012-11-09 16:30:35 +02:00
iounmap ( ctrl_base ) ;
return 0 ;
}
2013-01-11 11:24:18 -08:00
omap_early_initcall ( omap4430_phy_power_down ) ;
2012-11-09 16:30:35 +02:00
2011-02-16 17:34:40 +05:30
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 ) ;
2014-10-07 23:16:16 +09:00
pr_info ( " Waiting for PHY clock good... \n " ) ;
2011-02-16 17:34:40 +05:30
while ( ! ( omap_ctrl_readl ( AM35XX_CONTROL_DEVCONF2 )
& CONF2_PHYCLKGD ) ) {
cpu_relax ( ) ;
if ( time_after ( jiffies , timeout ) ) {
2014-10-07 23:16:16 +09:00
pr_err ( " musb PHY clock good timed out \n " ) ;
2011-02-16 17:34:40 +05:30
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 12:45:05 +03:00
void am35x_set_mode ( u8 musb_mode )
2011-02-16 17:34:40 +05:30
{
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 :
2014-10-07 23:16:16 +09:00
pr_info ( " Unsupported mode %u \n " , musb_mode ) ;
2011-02-16 17:34:40 +05:30
}
omap_ctrl_writel ( devconf2 , AM35XX_CONTROL_DEVCONF2 ) ;
}