2 * Keystone: PSC configuration module
4 * (C) Copyright 2012-2014
5 * Texas Instruments Incorporated, <www.ti.com>
7 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm-generic/errno.h>
13 #include <asm/processor.h>
14 #include <asm/arch/psc_defs.h>
16 #define DEVICE_REG32_R(addr) __raw_readl((u32 *)(addr))
17 #define DEVICE_REG32_W(addr, val) __raw_writel(val, (u32 *)(addr))
26 * FUNCTION PURPOSE: Wait for end of transitional state
28 * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
31 * Since this is boot loader code it is *ASSUMED* that interrupts
32 * are disabled and no other core is mucking around with the psc
35 * Returns 0 when the domain is free. Returns -1 if a timeout
36 * occurred waiting for the completion.
38 int psc_wait(u32 domain_num)
44 * Do nothing if the power domain is in transition. This should never
45 * happen since the boot code is the only software accesses psc.
46 * It's still remotely possible that the hardware state machines
47 * initiate transitions.
48 * Don't trap if the domain (or a module in this domain) is
49 * stuck in transition.
54 ptstat = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_PSTAT);
55 ptstat = ptstat & (1 << domain_num);
56 } while ((ptstat != 0) && ((retry += psc_delay()) <
57 PSC_PTSTAT_TIMEOUT_LIMIT));
59 if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
65 u32 psc_get_domain_num(u32 mod_num)
69 /* Get the power domain associated with the module number */
70 domain_num = DEVICE_REG32_R(KS2_PSC_BASE +
71 PSC_REG_MDCFG(mod_num));
72 domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
78 * FUNCTION PURPOSE: Power up/down a module
80 * DESCRIPTION: Powers up/down the requested module and the associated power
81 * domain if required. No action is taken it the module is
82 * already powered up/down.
84 * This only controls modules. The domain in which the module
85 * resides will be left in the power on state. Multiple modules
86 * can exist in a power domain, so powering down the domain based
87 * on a single module is not done.
89 * Returns 0 on success, -1 if the module can't be powered up, or
90 * if there is a timeout waiting for the transition.
92 int psc_set_state(u32 mod_num, u32 state)
102 * Get the power domain associated with the module number, and reset
103 * isolation functionality
105 v = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
106 domain_num = PSC_REG_MDCFG_GET_PD(v);
107 reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v);
109 /* Wait for the status of the domain/module to be non-transitional */
110 if (psc_wait(domain_num) != 0)
114 * Perform configuration even if the current status matches the
117 * Set the next state of the power domain to on. It's OK if the domain
118 * is always on. This code will not ever power down a domain, so no
119 * change is made if the new state is power down.
121 if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
122 pdctl = DEVICE_REG32_R(KS2_PSC_BASE +
123 PSC_REG_PDCTL(domain_num));
124 pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
125 PSC_REG_VAL_PDCTL_NEXT_ON);
126 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num),
130 /* Set the next state for the module to enabled/disabled */
131 mdctl = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
132 mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
133 mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
134 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
136 /* Trigger the enable */
137 ptcmd = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_PTCMD);
138 ptcmd |= (u32)(1<<domain_num);
139 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_PTCMD, ptcmd);
141 /* Wait on the complete */
142 return psc_wait(domain_num);
146 * FUNCTION PURPOSE: Power up a module
148 * DESCRIPTION: Powers up the requested module and the associated power domain
149 * if required. No action is taken it the module is already
152 * Returns 0 on success, -1 if the module can't be powered up, or
153 * if there is a timeout waiting for the transition.
155 int psc_enable_module(u32 mod_num)
159 /* Set the bit to apply reset */
160 mdctl = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
161 if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
164 return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
168 * FUNCTION PURPOSE: Power down a module
170 * DESCRIPTION: Powers down the requested module.
172 * Returns 0 on success, -1 on failure or timeout.
174 int psc_disable_module(u32 mod_num)
178 /* Set the bit to apply reset */
179 mdctl = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
180 if ((mdctl & 0x3f) == 0)
182 mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
183 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
185 return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
189 * FUNCTION PURPOSE: Set the reset isolation bit in mdctl
191 * DESCRIPTION: The reset isolation enable bit is set. The state of the module
192 * is not changed. Returns 0 if the module config showed that
193 * reset isolation is supported. Returns 1 otherwise. This is not
194 * an error, but setting the bit in mdctl has no effect.
196 int psc_set_reset_iso(u32 mod_num)
201 /* Set the reset isolation bit */
202 mdctl = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
203 mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
204 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
206 v = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
207 if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
214 * FUNCTION PURPOSE: Disable a power domain
216 * DESCRIPTION: The power domain is disabled
218 int psc_disable_domain(u32 domain_num)
223 pdctl = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
224 pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
225 pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
226 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num), pdctl);
228 ptcmd = DEVICE_REG32_R(KS2_PSC_BASE + PSC_REG_PTCMD);
229 ptcmd |= (u32)(1 << domain_num);
230 DEVICE_REG32_W(KS2_PSC_BASE + PSC_REG_PTCMD, ptcmd);
232 return psc_wait(domain_num);