xref: /openbmc/u-boot/arch/arm/mach-keystone/psc.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
239a72345SMasahiro Yamada /*
339a72345SMasahiro Yamada  * Keystone: PSC configuration module
439a72345SMasahiro Yamada  *
539a72345SMasahiro Yamada  * (C) Copyright 2012-2014
639a72345SMasahiro Yamada  *     Texas Instruments Incorporated, <www.ti.com>
739a72345SMasahiro Yamada  */
839a72345SMasahiro Yamada 
939a72345SMasahiro Yamada #include <common.h>
105d97dff0SMasahiro Yamada #include <linux/errno.h>
1139a72345SMasahiro Yamada #include <asm/io.h>
1239a72345SMasahiro Yamada #include <asm/processor.h>
1339a72345SMasahiro Yamada #include <asm/arch/psc_defs.h>
1439a72345SMasahiro Yamada 
1582ff21bdSNishanth Menon /**
1682ff21bdSNishanth Menon  * psc_delay() - delay for psc
1782ff21bdSNishanth Menon  *
1882ff21bdSNishanth Menon  * Return: 10
1982ff21bdSNishanth Menon  */
psc_delay(void)2039a72345SMasahiro Yamada int psc_delay(void)
2139a72345SMasahiro Yamada {
2239a72345SMasahiro Yamada 	udelay(10);
2339a72345SMasahiro Yamada 	return 10;
2439a72345SMasahiro Yamada }
2539a72345SMasahiro Yamada 
2682ff21bdSNishanth Menon /**
2782ff21bdSNishanth Menon  * psc_wait() - Wait for end of transitional state
2882ff21bdSNishanth Menon  * @domain_num: GPSC domain number
2939a72345SMasahiro Yamada  *
3082ff21bdSNishanth Menon  * Polls pstat for the selected domain and waits for transitions to be complete.
3182ff21bdSNishanth Menon  * Since this is boot loader code it is *ASSUMED* that interrupts are disabled
3282ff21bdSNishanth Menon  * and no other core is mucking around with the psc at the same time.
3339a72345SMasahiro Yamada  *
3482ff21bdSNishanth Menon  * Return: 0 when the domain is free. Returns -1 if a timeout occurred waiting
3582ff21bdSNishanth Menon  * for the completion.
3639a72345SMasahiro Yamada  */
psc_wait(u32 domain_num)3739a72345SMasahiro Yamada int psc_wait(u32 domain_num)
3839a72345SMasahiro Yamada {
3939a72345SMasahiro Yamada 	u32 retry;
4039a72345SMasahiro Yamada 	u32 ptstat;
4139a72345SMasahiro Yamada 
4239a72345SMasahiro Yamada 	/*
4339a72345SMasahiro Yamada 	 * Do nothing if the power domain is in transition. This should never
4439a72345SMasahiro Yamada 	 * happen since the boot code is the only software accesses psc.
4539a72345SMasahiro Yamada 	 * It's still remotely possible that the hardware state machines
4639a72345SMasahiro Yamada 	 * initiate transitions.
4739a72345SMasahiro Yamada 	 * Don't trap if the domain (or a module in this domain) is
4839a72345SMasahiro Yamada 	 * stuck in transition.
4939a72345SMasahiro Yamada 	 */
5039a72345SMasahiro Yamada 	retry = 0;
5139a72345SMasahiro Yamada 
5239a72345SMasahiro Yamada 	do {
5339a72345SMasahiro Yamada 		ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
5439a72345SMasahiro Yamada 		ptstat = ptstat & (1 << domain_num);
5539a72345SMasahiro Yamada 	} while ((ptstat != 0) && ((retry += psc_delay()) <
5639a72345SMasahiro Yamada 		 PSC_PTSTAT_TIMEOUT_LIMIT));
5739a72345SMasahiro Yamada 
5839a72345SMasahiro Yamada 	if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
5939a72345SMasahiro Yamada 		return -1;
6039a72345SMasahiro Yamada 
6139a72345SMasahiro Yamada 	return 0;
6239a72345SMasahiro Yamada }
6339a72345SMasahiro Yamada 
6482ff21bdSNishanth Menon /**
6582ff21bdSNishanth Menon  * psc_get_domain_num() - Get the domain number
6682ff21bdSNishanth Menon  * @mod_num:	LPSC module number
6782ff21bdSNishanth Menon  */
psc_get_domain_num(u32 mod_num)6839a72345SMasahiro Yamada u32 psc_get_domain_num(u32 mod_num)
6939a72345SMasahiro Yamada {
7039a72345SMasahiro Yamada 	u32 domain_num;
7139a72345SMasahiro Yamada 
7239a72345SMasahiro Yamada 	/* Get the power domain associated with the module number */
7339a72345SMasahiro Yamada 	domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
7439a72345SMasahiro Yamada 	domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
7539a72345SMasahiro Yamada 
7639a72345SMasahiro Yamada 	return domain_num;
7739a72345SMasahiro Yamada }
7839a72345SMasahiro Yamada 
7982ff21bdSNishanth Menon /**
8082ff21bdSNishanth Menon  * psc_set_state() - powers up/down a module
8182ff21bdSNishanth Menon  * @mod_num:	LPSC module number
8282ff21bdSNishanth Menon  * @state:	1 to enable, 0 to disable.
8339a72345SMasahiro Yamada  *
8482ff21bdSNishanth Menon  * Powers up/down the requested module and the associated power domain if
8582ff21bdSNishanth Menon  * required. No action is taken it the module is already powered up/down.
8682ff21bdSNishanth Menon  * This only controls modules. The domain in which the module resides will
8782ff21bdSNishanth Menon  * be left in the power on state. Multiple modules can exist in a power
8882ff21bdSNishanth Menon  * domain, so powering down the domain based on a single module is not done.
8939a72345SMasahiro Yamada  *
9082ff21bdSNishanth Menon  * Return: 0 on success, -1 if the module can't be powered up, or if there is a
9182ff21bdSNishanth Menon  * timeout waiting for the transition.
9239a72345SMasahiro Yamada  */
psc_set_state(u32 mod_num,u32 state)9339a72345SMasahiro Yamada int psc_set_state(u32 mod_num, u32 state)
9439a72345SMasahiro Yamada {
9539a72345SMasahiro Yamada 	u32 domain_num;
9639a72345SMasahiro Yamada 	u32 pdctl;
9739a72345SMasahiro Yamada 	u32 mdctl;
9839a72345SMasahiro Yamada 	u32 ptcmd;
9939a72345SMasahiro Yamada 	u32 reset_iso;
10039a72345SMasahiro Yamada 	u32 v;
10139a72345SMasahiro Yamada 
10239a72345SMasahiro Yamada 	/*
10339a72345SMasahiro Yamada 	 * Get the power domain associated with the module number, and reset
10439a72345SMasahiro Yamada 	 * isolation functionality
10539a72345SMasahiro Yamada 	 */
10639a72345SMasahiro Yamada 	v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
10739a72345SMasahiro Yamada 	domain_num = PSC_REG_MDCFG_GET_PD(v);
10839a72345SMasahiro Yamada 	reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
10939a72345SMasahiro Yamada 
11039a72345SMasahiro Yamada 	/* Wait for the status of the domain/module to be non-transitional */
11139a72345SMasahiro Yamada 	if (psc_wait(domain_num) != 0)
11239a72345SMasahiro Yamada 		return -1;
11339a72345SMasahiro Yamada 
11439a72345SMasahiro Yamada 	/*
11539a72345SMasahiro Yamada 	 * Perform configuration even if the current status matches the
11639a72345SMasahiro Yamada 	 * existing state
11739a72345SMasahiro Yamada 	 *
11839a72345SMasahiro Yamada 	 * Set the next state of the power domain to on. It's OK if the domain
11939a72345SMasahiro Yamada 	 * is always on. This code will not ever power down a domain, so no
12039a72345SMasahiro Yamada 	 * change is made if the new state is power down.
12139a72345SMasahiro Yamada 	 */
12239a72345SMasahiro Yamada 	if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
12339a72345SMasahiro Yamada 		pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
12439a72345SMasahiro Yamada 		pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
12539a72345SMasahiro Yamada 					       PSC_REG_VAL_PDCTL_NEXT_ON);
12639a72345SMasahiro Yamada 		__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
12739a72345SMasahiro Yamada 	}
12839a72345SMasahiro Yamada 
12939a72345SMasahiro Yamada 	/* Set the next state for the module to enabled/disabled */
13039a72345SMasahiro Yamada 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
13139a72345SMasahiro Yamada 	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
13239a72345SMasahiro Yamada 	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
13339a72345SMasahiro Yamada 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
13439a72345SMasahiro Yamada 
13539a72345SMasahiro Yamada 	/* Trigger the enable */
13639a72345SMasahiro Yamada 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
13739a72345SMasahiro Yamada 	ptcmd |= (u32)(1<<domain_num);
13839a72345SMasahiro Yamada 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
13939a72345SMasahiro Yamada 
14039a72345SMasahiro Yamada 	/* Wait on the complete */
14139a72345SMasahiro Yamada 	return psc_wait(domain_num);
14239a72345SMasahiro Yamada }
14339a72345SMasahiro Yamada 
14482ff21bdSNishanth Menon /**
14582ff21bdSNishanth Menon  * psc_enable_module() - power up a module
14682ff21bdSNishanth Menon  * @mod_num:	LPSC module number
14739a72345SMasahiro Yamada  *
14882ff21bdSNishanth Menon  * Powers up the requested module and the associated power domain
14982ff21bdSNishanth Menon  * if required. No action is taken it the module is already powered up.
15039a72345SMasahiro Yamada  *
15182ff21bdSNishanth Menon  * Return: 0 on success, -1 if the module can't be powered up, or
15239a72345SMasahiro Yamada  * if there is a timeout waiting for the transition.
15382ff21bdSNishanth Menon  *
15439a72345SMasahiro Yamada  */
psc_enable_module(u32 mod_num)15539a72345SMasahiro Yamada int psc_enable_module(u32 mod_num)
15639a72345SMasahiro Yamada {
15739a72345SMasahiro Yamada 	u32 mdctl;
15839a72345SMasahiro Yamada 
15939a72345SMasahiro Yamada 	/* Set the bit to apply reset */
16039a72345SMasahiro Yamada 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
16139a72345SMasahiro Yamada 	if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
16239a72345SMasahiro Yamada 		return 0;
16339a72345SMasahiro Yamada 
16439a72345SMasahiro Yamada 	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
16539a72345SMasahiro Yamada }
16639a72345SMasahiro Yamada 
16782ff21bdSNishanth Menon /**
16882ff21bdSNishanth Menon  * psc_disable_module() - Power down a module
16982ff21bdSNishanth Menon  * @mod_num:	LPSC module number
17039a72345SMasahiro Yamada  *
17182ff21bdSNishanth Menon  * Return: 0 on success, -1 on failure or timeout.
17239a72345SMasahiro Yamada  */
psc_disable_module(u32 mod_num)17339a72345SMasahiro Yamada int psc_disable_module(u32 mod_num)
17439a72345SMasahiro Yamada {
17539a72345SMasahiro Yamada 	u32 mdctl;
17639a72345SMasahiro Yamada 
17739a72345SMasahiro Yamada 	/* Set the bit to apply reset */
17839a72345SMasahiro Yamada 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
17939a72345SMasahiro Yamada 	if ((mdctl & 0x3f) == 0)
18039a72345SMasahiro Yamada 		return 0;
18139a72345SMasahiro Yamada 	mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
18239a72345SMasahiro Yamada 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
18339a72345SMasahiro Yamada 
18439a72345SMasahiro Yamada 	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
18539a72345SMasahiro Yamada }
18639a72345SMasahiro Yamada 
18782ff21bdSNishanth Menon /**
18882ff21bdSNishanth Menon  * psc_set_reset_iso() - Set the reset isolation bit in mdctl
18982ff21bdSNishanth Menon  * @mod_num:	LPSC module number
19039a72345SMasahiro Yamada  *
19182ff21bdSNishanth Menon  * The reset isolation enable bit is set. The state of the module is not
19282ff21bdSNishanth Menon  * changed.
19382ff21bdSNishanth Menon  *
19482ff21bdSNishanth Menon  * Return: 0 if the module config showed that reset isolation is supported.
19582ff21bdSNishanth Menon  * Returns 1 otherwise. This is not an error, but setting the bit in mdctl
19682ff21bdSNishanth Menon  * has no effect.
19739a72345SMasahiro Yamada  */
psc_set_reset_iso(u32 mod_num)19839a72345SMasahiro Yamada int psc_set_reset_iso(u32 mod_num)
19939a72345SMasahiro Yamada {
20039a72345SMasahiro Yamada 	u32 v;
20139a72345SMasahiro Yamada 	u32 mdctl;
20239a72345SMasahiro Yamada 
20339a72345SMasahiro Yamada 	/* Set the reset isolation bit */
20439a72345SMasahiro Yamada 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
20539a72345SMasahiro Yamada 	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
20639a72345SMasahiro Yamada 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
20739a72345SMasahiro Yamada 
20839a72345SMasahiro Yamada 	v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
20939a72345SMasahiro Yamada 	if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
21039a72345SMasahiro Yamada 		return 0;
21139a72345SMasahiro Yamada 
21239a72345SMasahiro Yamada 	return 1;
21339a72345SMasahiro Yamada }
21439a72345SMasahiro Yamada 
21582ff21bdSNishanth Menon /**
21682ff21bdSNishanth Menon  * psc_disable_domain() - Disable a power domain
21782ff21bdSNishanth Menon  * @domain_num: GPSC domain number
21839a72345SMasahiro Yamada  */
psc_disable_domain(u32 domain_num)21939a72345SMasahiro Yamada int psc_disable_domain(u32 domain_num)
22039a72345SMasahiro Yamada {
22139a72345SMasahiro Yamada 	u32 pdctl;
22239a72345SMasahiro Yamada 	u32 ptcmd;
22339a72345SMasahiro Yamada 
22439a72345SMasahiro Yamada 	pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
22539a72345SMasahiro Yamada 	pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
22639a72345SMasahiro Yamada 	pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
22739a72345SMasahiro Yamada 	__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
22839a72345SMasahiro Yamada 
22939a72345SMasahiro Yamada 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
23039a72345SMasahiro Yamada 	ptcmd |= (u32)(1 << domain_num);
23139a72345SMasahiro Yamada 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
23239a72345SMasahiro Yamada 
23339a72345SMasahiro Yamada 	return psc_wait(domain_num);
23439a72345SMasahiro Yamada }
235ec00b2e3SNishanth Menon 
236ec00b2e3SNishanth Menon /**
237ec00b2e3SNishanth Menon  * psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state
238ec00b2e3SNishanth Menon  * @mod_num:	LPSC module number
239ec00b2e3SNishanth Menon  * @gate_clocks: Can the clocks be gated on this module?
240ec00b2e3SNishanth Menon  *
241ec00b2e3SNishanth Menon  * Enable the module, but do not release the module from local reset. This is
242ec00b2e3SNishanth Menon  * necessary for many processor systems on keystone SoCs to allow for system
243ec00b2e3SNishanth Menon  * initialization from a master processor prior to releasing the processor
244ec00b2e3SNishanth Menon  * from reset.
245ec00b2e3SNishanth Menon  */
psc_module_keep_in_reset_enabled(u32 mod_num,bool gate_clocks)246ec00b2e3SNishanth Menon int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks)
247ec00b2e3SNishanth Menon {
248ec00b2e3SNishanth Menon 	u32 mdctl, ptcmd, mdstat;
249ec00b2e3SNishanth Menon 	u32 next_state;
250ec00b2e3SNishanth Menon 	int domain_num = psc_get_domain_num(mod_num);
251ec00b2e3SNishanth Menon 	int timeout = 100000;
252ec00b2e3SNishanth Menon 
253ec00b2e3SNishanth Menon 	/* Wait for any previous transitions to complete */
254ec00b2e3SNishanth Menon 	psc_wait(domain_num);
255ec00b2e3SNishanth Menon 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
256ec00b2e3SNishanth Menon 	/* Should be set 0 to assert Local reset */
257ec00b2e3SNishanth Menon 	if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) {
258ec00b2e3SNishanth Menon 		mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
259ec00b2e3SNishanth Menon 		__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
260ec00b2e3SNishanth Menon 		/* Wait for transition to take place */
261ec00b2e3SNishanth Menon 		psc_wait(domain_num);
262ec00b2e3SNishanth Menon 	}
263ec00b2e3SNishanth Menon 
264ec00b2e3SNishanth Menon 	/* Clear Module reset */
265ec00b2e3SNishanth Menon 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
266ec00b2e3SNishanth Menon 	next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
267ec00b2e3SNishanth Menon 			PSC_REG_VAL_MDCTL_NEXT_ON;
268ec00b2e3SNishanth Menon 	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state);
269ec00b2e3SNishanth Menon 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
270ec00b2e3SNishanth Menon 	/* Trigger PD transition */
271ec00b2e3SNishanth Menon 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
272ec00b2e3SNishanth Menon 	ptcmd |= (u32)(1 << domain_num);
273ec00b2e3SNishanth Menon 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
274ec00b2e3SNishanth Menon 	psc_wait(domain_num);
275ec00b2e3SNishanth Menon 
276ec00b2e3SNishanth Menon 	mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
277ec00b2e3SNishanth Menon 	while (timeout) {
278ec00b2e3SNishanth Menon 		mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
279ec00b2e3SNishanth Menon 
280ec00b2e3SNishanth Menon 		if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
281ec00b2e3SNishanth Menon 		    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
282ec00b2e3SNishanth Menon 		    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
283ec00b2e3SNishanth Menon 			break;
284ec00b2e3SNishanth Menon 		timeout--;
285ec00b2e3SNishanth Menon 	}
286ec00b2e3SNishanth Menon 
287ec00b2e3SNishanth Menon 	if (!timeout) {
288ec00b2e3SNishanth Menon 		printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
289ec00b2e3SNishanth Menon 		       __func__, mdstat);
290ec00b2e3SNishanth Menon 		return -ETIMEDOUT;
291ec00b2e3SNishanth Menon 	}
292ec00b2e3SNishanth Menon 	return 0;
293ec00b2e3SNishanth Menon }
294ec00b2e3SNishanth Menon 
295ec00b2e3SNishanth Menon /**
296ec00b2e3SNishanth Menon  * psc_module_release_from_reset() - Release the module from reset
297ec00b2e3SNishanth Menon  * @mod_num:	LPSC module number
298ec00b2e3SNishanth Menon  *
299ec00b2e3SNishanth Menon  * This is the follow through for the command 'psc_module_keep_in_reset_enabled'
300ec00b2e3SNishanth Menon  * Allowing the module to be released from reset once all required inits are
301ec00b2e3SNishanth Menon  * complete for the module. Typically, this allows the processor module to start
302ec00b2e3SNishanth Menon  * execution.
303ec00b2e3SNishanth Menon  */
psc_module_release_from_reset(u32 mod_num)304ec00b2e3SNishanth Menon int psc_module_release_from_reset(u32 mod_num)
305ec00b2e3SNishanth Menon {
306ec00b2e3SNishanth Menon 	u32 mdctl, mdstat;
307ec00b2e3SNishanth Menon 	int domain_num = psc_get_domain_num(mod_num);
308ec00b2e3SNishanth Menon 	int timeout = 100000;
309ec00b2e3SNishanth Menon 
310ec00b2e3SNishanth Menon 	/* Wait for any previous transitions to complete */
311ec00b2e3SNishanth Menon 	psc_wait(domain_num);
312ec00b2e3SNishanth Menon 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
313ec00b2e3SNishanth Menon 	/* Should be set to 1 to de-assert Local reset */
314ec00b2e3SNishanth Menon 	if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) {
315ec00b2e3SNishanth Menon 		mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1);
316ec00b2e3SNishanth Menon 		__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
317ec00b2e3SNishanth Menon 		/* Wait for transition to take place */
318ec00b2e3SNishanth Menon 		psc_wait(domain_num);
319ec00b2e3SNishanth Menon 	}
320ec00b2e3SNishanth Menon 	mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
321ec00b2e3SNishanth Menon 	while (timeout) {
322ec00b2e3SNishanth Menon 		mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
323ec00b2e3SNishanth Menon 
324ec00b2e3SNishanth Menon 		if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
325ec00b2e3SNishanth Menon 		    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
326ec00b2e3SNishanth Menon 		    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
327ec00b2e3SNishanth Menon 			break;
328ec00b2e3SNishanth Menon 		timeout--;
329ec00b2e3SNishanth Menon 	}
330ec00b2e3SNishanth Menon 
331ec00b2e3SNishanth Menon 	if (!timeout) {
332ec00b2e3SNishanth Menon 		printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
333ec00b2e3SNishanth Menon 		       __func__, mdstat);
334ec00b2e3SNishanth Menon 		return -ETIMEDOUT;
335ec00b2e3SNishanth Menon 	}
336ec00b2e3SNishanth Menon 
337ec00b2e3SNishanth Menon 	return 0;
338ec00b2e3SNishanth Menon }
339