2009-04-23 12:24:13 +01:00
/*
* Freescale STMP37XX / STMP378X core routines
*
* Embedded Alley Solutions , Inc < source @ embeddedalley . com >
*
* Copyright 2008 Freescale Semiconductor , Inc . All Rights Reserved .
* Copyright 2008 Embedded Alley Solutions , Inc All Rights Reserved .
*/
/*
* The code contained herein is licensed under the GNU General Public
* License . You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations :
*
* http : //www.opensource.org/licenses/gpl-license.html
* http : //www.gnu.org/copyleft/gpl.html
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/io.h>
# include <mach/stmp3xxx.h>
2009-05-31 13:32:11 +01:00
# include <mach/platform.h>
2009-04-23 12:24:13 +01:00
# include <mach/dma.h>
# include <mach/regs-clkctrl.h>
static int __stmp3xxx_reset_block ( void __iomem * hwreg , int just_enable )
{
u32 c ;
int timeout ;
/* the process of software reset of IP block is done
in several steps :
- clear SFTRST and wait for block is enabled ;
- clear clock gating ( CLKGATE bit ) ;
- set the SFTRST again and wait for block is in reset ;
- clear SFTRST and wait for reset completion .
*/
c = __raw_readl ( hwreg ) ;
c & = ~ ( 1 < < 31 ) ; /* clear SFTRST */
__raw_writel ( c , hwreg ) ;
for ( timeout = 1000000 ; timeout > 0 ; timeout - - )
/* still in SFTRST state ? */
if ( ( __raw_readl ( hwreg ) & ( 1 < < 31 ) ) = = 0 )
break ;
if ( timeout < = 0 ) {
printk ( KERN_ERR " %s(%p): timeout when enabling \n " ,
__func__ , hwreg ) ;
return - ETIME ;
}
c = __raw_readl ( hwreg ) ;
c & = ~ ( 1 < < 30 ) ; /* clear CLKGATE */
__raw_writel ( c , hwreg ) ;
if ( ! just_enable ) {
c = __raw_readl ( hwreg ) ;
c | = ( 1 < < 31 ) ; /* now again set SFTRST */
__raw_writel ( c , hwreg ) ;
for ( timeout = 1000000 ; timeout > 0 ; timeout - - )
/* poll until CLKGATE set */
if ( __raw_readl ( hwreg ) & ( 1 < < 30 ) )
break ;
if ( timeout < = 0 ) {
printk ( KERN_ERR " %s(%p): timeout when resetting \n " ,
__func__ , hwreg ) ;
return - ETIME ;
}
c = __raw_readl ( hwreg ) ;
c & = ~ ( 1 < < 31 ) ; /* clear SFTRST */
__raw_writel ( c , hwreg ) ;
for ( timeout = 1000000 ; timeout > 0 ; timeout - - )
/* still in SFTRST state ? */
if ( ( __raw_readl ( hwreg ) & ( 1 < < 31 ) ) = = 0 )
break ;
if ( timeout < = 0 ) {
printk ( KERN_ERR " %s(%p): timeout when enabling "
" after reset \n " , __func__ , hwreg ) ;
return - ETIME ;
}
c = __raw_readl ( hwreg ) ;
c & = ~ ( 1 < < 30 ) ; /* clear CLKGATE */
__raw_writel ( c , hwreg ) ;
}
for ( timeout = 1000000 ; timeout > 0 ; timeout - - )
/* still in SFTRST state ? */
if ( ( __raw_readl ( hwreg ) & ( 1 < < 30 ) ) = = 0 )
break ;
if ( timeout < = 0 ) {
printk ( KERN_ERR " %s(%p): timeout when unclockgating \n " ,
__func__ , hwreg ) ;
return - ETIME ;
}
return 0 ;
}
int stmp3xxx_reset_block ( void __iomem * hwreg , int just_enable )
{
int try = 10 ;
int r ;
while ( try - - ) {
r = __stmp3xxx_reset_block ( hwreg , just_enable ) ;
if ( ! r )
break ;
pr_debug ( " %s: try %d failed \n " , __func__ , 10 - try ) ;
}
return r ;
}
EXPORT_SYMBOL ( stmp3xxx_reset_block ) ;
struct platform_device stmp3xxx_dbguart = {
. name = " stmp3xxx-dbguart " ,
. id = - 1 ,
} ;
void __init stmp3xxx_init ( void )
{
/* Turn off auto-slow and other tricks */
2009-05-31 13:32:11 +01:00
stmp3xxx_clearl ( 0x7f00000 , REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS ) ;
2009-04-23 12:24:13 +01:00
stmp3xxx_dma_init ( ) ;
}