@ -233,3 +233,107 @@ int psc_disable_domain(u32 domain_num)
return psc_wait ( domain_num ) ;
}
/**
* psc_module_keep_in_reset_enabled ( ) - Keep module in enabled , in - reset state
* @ mod_num : LPSC module number
* @ gate_clocks : Can the clocks be gated on this module ?
*
* Enable the module , but do not release the module from local reset . This is
* necessary for many processor systems on keystone SoCs to allow for system
* initialization from a master processor prior to releasing the processor
* from reset .
*/
int psc_module_keep_in_reset_enabled ( u32 mod_num , bool gate_clocks )
{
u32 mdctl , ptcmd , mdstat ;
u32 next_state ;
int domain_num = psc_get_domain_num ( mod_num ) ;
int timeout = 100000 ;
/* Wait for any previous transitions to complete */
psc_wait ( domain_num ) ;
mdctl = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
/* Should be set 0 to assert Local reset */
if ( ( mdctl & PSC_REG_MDCTL_SET_LRSTZ ( mdctl , 1 ) ) ) {
mdctl = PSC_REG_MDCTL_SET_LRSTZ ( mdctl , 0 ) ;
__raw_writel ( mdctl , KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
/* Wait for transition to take place */
psc_wait ( domain_num ) ;
}
/* Clear Module reset */
mdctl = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
PSC_REG_VAL_MDCTL_NEXT_ON ;
mdctl = PSC_REG_MDCTL_SET_NEXT ( mdctl , next_state ) ;
__raw_writel ( mdctl , KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
/* Trigger PD transition */
ptcmd = __raw_readl ( KS2_PSC_BASE + PSC_REG_PTCMD ) ;
ptcmd | = ( u32 ) ( 1 < < domain_num ) ;
__raw_writel ( ptcmd , KS2_PSC_BASE + PSC_REG_PTCMD ) ;
psc_wait ( domain_num ) ;
mdstat = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDSTAT ( mod_num ) ) ;
while ( timeout ) {
mdstat = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDSTAT ( mod_num ) ) ;
if ( ! ( PSC_REG_MDSTAT_GET_STATUS ( mdstat ) & 0x30 ) & &
PSC_REG_MDSTAT_GET_MRSTDONE ( mdstat ) & &
PSC_REG_MDSTAT_GET_LRSTDONE ( mdstat ) )
break ;
timeout - - ;
}
if ( ! timeout ) {
printf ( " %s: Timedout waiting for mdstat(0x%08x) to change \n " ,
__func__ , mdstat ) ;
return - ETIMEDOUT ;
}
return 0 ;
}
/**
* psc_module_release_from_reset ( ) - Release the module from reset
* @ mod_num : LPSC module number
*
* This is the follow through for the command ' psc_module_keep_in_reset_enabled '
* Allowing the module to be released from reset once all required inits are
* complete for the module . Typically , this allows the processor module to start
* execution .
*/
int psc_module_release_from_reset ( u32 mod_num )
{
u32 mdctl , mdstat ;
int domain_num = psc_get_domain_num ( mod_num ) ;
int timeout = 100000 ;
/* Wait for any previous transitions to complete */
psc_wait ( domain_num ) ;
mdctl = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
/* Should be set to 1 to de-assert Local reset */
if ( ( mdctl & PSC_REG_MDCTL_SET_LRSTZ ( mdctl , 0 ) ) ) {
mdctl = PSC_REG_MDCTL_SET_LRSTZ ( mdctl , 1 ) ;
__raw_writel ( mdctl , KS2_PSC_BASE + PSC_REG_MDCTL ( mod_num ) ) ;
/* Wait for transition to take place */
psc_wait ( domain_num ) ;
}
mdstat = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDSTAT ( mod_num ) ) ;
while ( timeout ) {
mdstat = __raw_readl ( KS2_PSC_BASE + PSC_REG_MDSTAT ( mod_num ) ) ;
if ( ! ( PSC_REG_MDSTAT_GET_STATUS ( mdstat ) & 0x30 ) & &
PSC_REG_MDSTAT_GET_MRSTDONE ( mdstat ) & &
PSC_REG_MDSTAT_GET_LRSTDONE ( mdstat ) )
break ;
timeout - - ;
}
if ( ! timeout ) {
printf ( " %s: Timedout waiting for mdstat(0x%08x) to change \n " ,
__func__ , mdstat ) ;
return - ETIMEDOUT ;
}
return 0 ;
}