Skip to content
Snippets Groups Projects
Commit ec00b2e3 authored by Nishanth Menon's avatar Nishanth Menon Committed by Tom Rini
Browse files

ARM: keystone2: psc: introduce function to hold and release module in reset.


These are useful for modules that need to be held in reset and are
enabled for data to be loaded on to them. Typically these are
microcontrollers or other processing entities in the system.

Signed-off-by: default avatarNishanth Menon <nm@ti.com>
Reviewed-by: default avatarTom Rini <trini@konsulko.com>
parent 7ca12b97
No related branches found
No related tags found
No related merge requests found
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
#define PSC_REG_MDSTAT_GET_STATUS(x) BOOT_READ_BITFIELD((x), 5, 0) #define PSC_REG_MDSTAT_GET_STATUS(x) BOOT_READ_BITFIELD((x), 5, 0)
#define PSC_REG_MDSTAT_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) #define PSC_REG_MDSTAT_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8)
#define PSC_REG_MDSTAT_GET_LRSTDONE(x) BOOT_READ_BITFIELD((x), 9, 9) #define PSC_REG_MDSTAT_GET_LRSTDONE(x) BOOT_READ_BITFIELD((x), 9, 9)
#define PSC_REG_MDSTAT_GET_MRSTZ(x) BOOT_READ_BITFIELD((x), 10, 10)
#define PSC_REG_MDSTAT_GET_MRSTDONE(x) BOOT_READ_BITFIELD((x), 11, 11)
/* PDCTL states */ /* PDCTL states */
#define PSC_REG_VAL_PDCTL_NEXT_ON 1 #define PSC_REG_VAL_PDCTL_NEXT_ON 1
...@@ -86,5 +88,7 @@ u32 psc_get_domain_num(u32 mod_num); ...@@ -86,5 +88,7 @@ u32 psc_get_domain_num(u32 mod_num);
int psc_enable_module(u32 mod_num); int psc_enable_module(u32 mod_num);
int psc_disable_module(u32 mod_num); int psc_disable_module(u32 mod_num);
int psc_disable_domain(u32 domain_num); int psc_disable_domain(u32 domain_num);
int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks);
int psc_module_release_from_reset(u32 mod_num);
#endif /* _PSC_DEFS_H_ */ #endif /* _PSC_DEFS_H_ */
...@@ -233,3 +233,107 @@ int psc_disable_domain(u32 domain_num) ...@@ -233,3 +233,107 @@ int psc_disable_domain(u32 domain_num)
return psc_wait(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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment