xref: /openbmc/u-boot/arch/arm/mach-keystone/psc.c (revision 20c700f8)
1 /*
2  * Keystone: PSC configuration module
3  *
4  * (C) Copyright 2012-2014
5  *     Texas Instruments Incorporated, <www.ti.com>
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <linux/errno.h>
12 #include <asm/io.h>
13 #include <asm/processor.h>
14 #include <asm/arch/psc_defs.h>
15 
16 /**
17  * psc_delay() - delay for psc
18  *
19  * Return: 10
20  */
21 int psc_delay(void)
22 {
23 	udelay(10);
24 	return 10;
25 }
26 
27 /**
28  * psc_wait() - Wait for end of transitional state
29  * @domain_num: GPSC domain number
30  *
31  * Polls pstat for the selected domain and waits for transitions to be complete.
32  * Since this is boot loader code it is *ASSUMED* that interrupts are disabled
33  * and no other core is mucking around with the psc at the same time.
34  *
35  * Return: 0 when the domain is free. Returns -1 if a timeout occurred waiting
36  * for the completion.
37  */
38 int psc_wait(u32 domain_num)
39 {
40 	u32 retry;
41 	u32 ptstat;
42 
43 	/*
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.
50 	 */
51 	retry = 0;
52 
53 	do {
54 		ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
55 		ptstat = ptstat & (1 << domain_num);
56 	} while ((ptstat != 0) && ((retry += psc_delay()) <
57 		 PSC_PTSTAT_TIMEOUT_LIMIT));
58 
59 	if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
60 		return -1;
61 
62 	return 0;
63 }
64 
65 /**
66  * psc_get_domain_num() - Get the domain number
67  * @mod_num:	LPSC module number
68  */
69 u32 psc_get_domain_num(u32 mod_num)
70 {
71 	u32 domain_num;
72 
73 	/* Get the power domain associated with the module number */
74 	domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
75 	domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
76 
77 	return domain_num;
78 }
79 
80 /**
81  * psc_set_state() - powers up/down a module
82  * @mod_num:	LPSC module number
83  * @state:	1 to enable, 0 to disable.
84  *
85  * Powers up/down the requested module and the associated power domain if
86  * required. No action is taken it the module is already powered up/down.
87  * This only controls modules. The domain in which the module resides will
88  * be left in the power on state. Multiple modules can exist in a power
89  * domain, so powering down the domain based on a single module is not done.
90  *
91  * Return: 0 on success, -1 if the module can't be powered up, or if there is a
92  * timeout waiting for the transition.
93  */
94 int psc_set_state(u32 mod_num, u32 state)
95 {
96 	u32 domain_num;
97 	u32 pdctl;
98 	u32 mdctl;
99 	u32 ptcmd;
100 	u32 reset_iso;
101 	u32 v;
102 
103 	/*
104 	 * Get the power domain associated with the module number, and reset
105 	 * isolation functionality
106 	 */
107 	v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
108 	domain_num = PSC_REG_MDCFG_GET_PD(v);
109 	reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
110 
111 	/* Wait for the status of the domain/module to be non-transitional */
112 	if (psc_wait(domain_num) != 0)
113 		return -1;
114 
115 	/*
116 	 * Perform configuration even if the current status matches the
117 	 * existing state
118 	 *
119 	 * Set the next state of the power domain to on. It's OK if the domain
120 	 * is always on. This code will not ever power down a domain, so no
121 	 * change is made if the new state is power down.
122 	 */
123 	if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
124 		pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
125 		pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
126 					       PSC_REG_VAL_PDCTL_NEXT_ON);
127 		__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
128 	}
129 
130 	/* Set the next state for the module to enabled/disabled */
131 	mdctl = __raw_readl(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 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
135 
136 	/* Trigger the enable */
137 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
138 	ptcmd |= (u32)(1<<domain_num);
139 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
140 
141 	/* Wait on the complete */
142 	return psc_wait(domain_num);
143 }
144 
145 /**
146  * psc_enable_module() - power up a module
147  * @mod_num:	LPSC module number
148  *
149  * Powers up the requested module and the associated power domain
150  * if required. No action is taken it the module is already powered up.
151  *
152  * Return: 0 on success, -1 if the module can't be powered up, or
153  * if there is a timeout waiting for the transition.
154  *
155  */
156 int psc_enable_module(u32 mod_num)
157 {
158 	u32 mdctl;
159 
160 	/* Set the bit to apply reset */
161 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
162 	if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
163 		return 0;
164 
165 	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
166 }
167 
168 /**
169  * psc_disable_module() - Power down a module
170  * @mod_num:	LPSC module number
171  *
172  * Return: 0 on success, -1 on failure or timeout.
173  */
174 int psc_disable_module(u32 mod_num)
175 {
176 	u32 mdctl;
177 
178 	/* Set the bit to apply reset */
179 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
180 	if ((mdctl & 0x3f) == 0)
181 		return 0;
182 	mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
183 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
184 
185 	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
186 }
187 
188 /**
189  * psc_set_reset_iso() - Set the reset isolation bit in mdctl
190  * @mod_num:	LPSC module number
191  *
192  * The reset isolation enable bit is set. The state of the module is not
193  * changed.
194  *
195  * Return: 0 if the module config showed that reset isolation is supported.
196  * Returns 1 otherwise. This is not an error, but setting the bit in mdctl
197  * has no effect.
198  */
199 int psc_set_reset_iso(u32 mod_num)
200 {
201 	u32 v;
202 	u32 mdctl;
203 
204 	/* Set the reset isolation bit */
205 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
206 	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
207 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
208 
209 	v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
210 	if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
211 		return 0;
212 
213 	return 1;
214 }
215 
216 /**
217  * psc_disable_domain() - Disable a power domain
218  * @domain_num: GPSC domain number
219  */
220 int psc_disable_domain(u32 domain_num)
221 {
222 	u32 pdctl;
223 	u32 ptcmd;
224 
225 	pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
226 	pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
227 	pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
228 	__raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
229 
230 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
231 	ptcmd |= (u32)(1 << domain_num);
232 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
233 
234 	return psc_wait(domain_num);
235 }
236 
237 /**
238  * psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state
239  * @mod_num:	LPSC module number
240  * @gate_clocks: Can the clocks be gated on this module?
241  *
242  * Enable the module, but do not release the module from local reset. This is
243  * necessary for many processor systems on keystone SoCs to allow for system
244  * initialization from a master processor prior to releasing the processor
245  * from reset.
246  */
247 int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks)
248 {
249 	u32 mdctl, ptcmd, mdstat;
250 	u32 next_state;
251 	int domain_num = psc_get_domain_num(mod_num);
252 	int timeout = 100000;
253 
254 	/* Wait for any previous transitions to complete */
255 	psc_wait(domain_num);
256 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
257 	/* Should be set 0 to assert Local reset */
258 	if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) {
259 		mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
260 		__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
261 		/* Wait for transition to take place */
262 		psc_wait(domain_num);
263 	}
264 
265 	/* Clear Module reset */
266 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
267 	next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF :
268 			PSC_REG_VAL_MDCTL_NEXT_ON;
269 	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state);
270 	__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
271 	/* Trigger PD transition */
272 	ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
273 	ptcmd |= (u32)(1 << domain_num);
274 	__raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
275 	psc_wait(domain_num);
276 
277 	mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
278 	while (timeout) {
279 		mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
280 
281 		if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
282 		    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
283 		    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
284 			break;
285 		timeout--;
286 	}
287 
288 	if (!timeout) {
289 		printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
290 		       __func__, mdstat);
291 		return -ETIMEDOUT;
292 	}
293 	return 0;
294 }
295 
296 /**
297  * psc_module_release_from_reset() - Release the module from reset
298  * @mod_num:	LPSC module number
299  *
300  * This is the follow through for the command 'psc_module_keep_in_reset_enabled'
301  * Allowing the module to be released from reset once all required inits are
302  * complete for the module. Typically, this allows the processor module to start
303  * execution.
304  */
305 int psc_module_release_from_reset(u32 mod_num)
306 {
307 	u32 mdctl, mdstat;
308 	int domain_num = psc_get_domain_num(mod_num);
309 	int timeout = 100000;
310 
311 	/* Wait for any previous transitions to complete */
312 	psc_wait(domain_num);
313 	mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
314 	/* Should be set to 1 to de-assert Local reset */
315 	if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) {
316 		mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1);
317 		__raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
318 		/* Wait for transition to take place */
319 		psc_wait(domain_num);
320 	}
321 	mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
322 	while (timeout) {
323 		mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num));
324 
325 		if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) &&
326 		    PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) &&
327 		    PSC_REG_MDSTAT_GET_LRSTDONE(mdstat))
328 			break;
329 		timeout--;
330 	}
331 
332 	if (!timeout) {
333 		printf("%s: Timedout waiting for mdstat(0x%08x) to change\n",
334 		       __func__, mdstat);
335 		return -ETIMEDOUT;
336 	}
337 
338 	return 0;
339 }
340