xref: /linux/arch/arm/mach-omap2/prm44xx.c (revision b68fc09be48edbc47de1a0f3d42ef8adf6c0ac55)
1 /*
2  * OMAP4 PRM module functions
3  *
4  * Copyright (C) 2011-2012 Texas Instruments, Inc.
5  * Copyright (C) 2010 Nokia Corporation
6  * Benoît Cousson
7  * Paul Walmsley
8  * Rajendra Nayak <rnayak@ti.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14 
15 #include <linux/cpu_pm.h>
16 #include <linux/kernel.h>
17 #include <linux/delay.h>
18 #include <linux/errno.h>
19 #include <linux/err.h>
20 #include <linux/io.h>
21 #include <linux/of_irq.h>
22 #include <linux/of.h>
23 
24 #include "soc.h"
25 #include "iomap.h"
26 #include "common.h"
27 #include "vp.h"
28 #include "prm44xx.h"
29 #include "prcm43xx.h"
30 #include "prm-regbits-44xx.h"
31 #include "prcm44xx.h"
32 #include "prminst44xx.h"
33 #include "powerdomain.h"
34 #include "pm.h"
35 
36 /* Static data */
37 
38 static void omap44xx_prm_read_pending_irqs(unsigned long *events);
39 static void omap44xx_prm_ocp_barrier(void);
40 static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
41 static void omap44xx_prm_restore_irqen(u32 *saved_mask);
42 static void omap44xx_prm_reconfigure_io_chain(void);
43 
44 static const struct omap_prcm_irq omap4_prcm_irqs[] = {
45 	OMAP_PRCM_IRQ("io",     9,      1),
46 };
47 
48 static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
49 	.ack			= OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
50 	.mask			= OMAP4_PRM_IRQENABLE_MPU_OFFSET,
51 	.pm_ctrl		= OMAP4_PRM_IO_PMCTRL_OFFSET,
52 	.nr_regs		= 2,
53 	.irqs			= omap4_prcm_irqs,
54 	.nr_irqs		= ARRAY_SIZE(omap4_prcm_irqs),
55 	.read_pending_irqs	= &omap44xx_prm_read_pending_irqs,
56 	.ocp_barrier		= &omap44xx_prm_ocp_barrier,
57 	.save_and_clear_irqen	= &omap44xx_prm_save_and_clear_irqen,
58 	.restore_irqen		= &omap44xx_prm_restore_irqen,
59 	.reconfigure_io_chain	= &omap44xx_prm_reconfigure_io_chain,
60 };
61 
62 struct omap_prm_irq_context {
63 	unsigned long irq_enable;
64 	unsigned long pm_ctrl;
65 };
66 
67 static struct omap_prm_irq_context omap_prm_context;
68 
69 /*
70  * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
71  *   hardware register (which are specific to OMAP44xx SoCs) to reset
72  *   source ID bit shifts (which is an OMAP SoC-independent
73  *   enumeration)
74  */
75 static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
76 	{ OMAP4430_GLOBAL_WARM_SW_RST_SHIFT,
77 	  OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
78 	{ OMAP4430_GLOBAL_COLD_RST_SHIFT,
79 	  OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
80 	{ OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
81 	  OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
82 	{ OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
83 	{ OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
84 	{ OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
85 	{ OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
86 	  OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
87 	{ OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
88 	  OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
89 	{ OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
90 	  OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
91 	{ OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
92 	{ OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
93 	{ -1, -1 },
94 };
95 
96 /* PRM low-level functions */
97 
98 /* Read a register in a CM/PRM instance in the PRM module */
99 static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
100 {
101 	return readl_relaxed(prm_base.va + inst + reg);
102 }
103 
104 /* Write into a register in a CM/PRM instance in the PRM module */
105 static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
106 {
107 	writel_relaxed(val, prm_base.va + inst + reg);
108 }
109 
110 /* Read-modify-write a register in a PRM module. Caller must lock */
111 static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
112 {
113 	u32 v;
114 
115 	v = omap4_prm_read_inst_reg(inst, reg);
116 	v &= ~mask;
117 	v |= bits;
118 	omap4_prm_write_inst_reg(v, inst, reg);
119 
120 	return v;
121 }
122 
123 /* PRM VP */
124 
125 /*
126  * struct omap4_vp - OMAP4 VP register access description.
127  * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
128  * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
129  */
130 struct omap4_vp {
131 	u32 irqstatus_mpu;
132 	u32 tranxdone_status;
133 };
134 
135 static struct omap4_vp omap4_vp[] = {
136 	[OMAP4_VP_VDD_MPU_ID] = {
137 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
138 		.tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
139 	},
140 	[OMAP4_VP_VDD_IVA_ID] = {
141 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
142 		.tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
143 	},
144 	[OMAP4_VP_VDD_CORE_ID] = {
145 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
146 		.tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
147 	},
148 };
149 
150 static u32 omap4_prm_vp_check_txdone(u8 vp_id)
151 {
152 	struct omap4_vp *vp = &omap4_vp[vp_id];
153 	u32 irqstatus;
154 
155 	irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
156 						OMAP4430_PRM_OCP_SOCKET_INST,
157 						vp->irqstatus_mpu);
158 	return irqstatus & vp->tranxdone_status;
159 }
160 
161 static void omap4_prm_vp_clear_txdone(u8 vp_id)
162 {
163 	struct omap4_vp *vp = &omap4_vp[vp_id];
164 
165 	omap4_prminst_write_inst_reg(vp->tranxdone_status,
166 				     OMAP4430_PRM_PARTITION,
167 				     OMAP4430_PRM_OCP_SOCKET_INST,
168 				     vp->irqstatus_mpu);
169 };
170 
171 u32 omap4_prm_vcvp_read(u8 offset)
172 {
173 	s32 inst = omap4_prmst_get_prm_dev_inst();
174 
175 	if (inst == PRM_INSTANCE_UNKNOWN)
176 		return 0;
177 
178 	return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
179 					   inst, offset);
180 }
181 
182 void omap4_prm_vcvp_write(u32 val, u8 offset)
183 {
184 	s32 inst = omap4_prmst_get_prm_dev_inst();
185 
186 	if (inst == PRM_INSTANCE_UNKNOWN)
187 		return;
188 
189 	omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
190 				     inst, offset);
191 }
192 
193 u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
194 {
195 	s32 inst = omap4_prmst_get_prm_dev_inst();
196 
197 	if (inst == PRM_INSTANCE_UNKNOWN)
198 		return 0;
199 
200 	return omap4_prminst_rmw_inst_reg_bits(mask, bits,
201 					       OMAP4430_PRM_PARTITION,
202 					       inst,
203 					       offset);
204 }
205 
206 static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
207 {
208 	u32 mask, st;
209 
210 	/* XXX read mask from RAM? */
211 	mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
212 				       irqen_offs);
213 	st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs);
214 
215 	return mask & st;
216 }
217 
218 /**
219  * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
220  * @events: ptr to two consecutive u32s, preallocated by caller
221  *
222  * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
223  * MPU IRQs, and store the result into the two u32s pointed to by @events.
224  * No return value.
225  */
226 static void omap44xx_prm_read_pending_irqs(unsigned long *events)
227 {
228 	int i;
229 
230 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
231 		events[i] = _read_pending_irq_reg(omap4_prcm_irq_setup.mask +
232 				i * 4, omap4_prcm_irq_setup.ack + i * 4);
233 }
234 
235 /**
236  * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
237  *
238  * Force any buffered writes to the PRM IP block to complete.  Needed
239  * by the PRM IRQ handler, which reads and writes directly to the IP
240  * block, to avoid race conditions after acknowledging or clearing IRQ
241  * bits.  No return value.
242  */
243 static void omap44xx_prm_ocp_barrier(void)
244 {
245 	omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
246 				OMAP4_REVISION_PRM_OFFSET);
247 }
248 
249 /**
250  * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
251  * @saved_mask: ptr to a u32 array to save IRQENABLE bits
252  *
253  * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
254  * @saved_mask.  @saved_mask must be allocated by the caller.
255  * Intended to be used in the PRM interrupt handler suspend callback.
256  * The OCP barrier is needed to ensure the write to disable PRM
257  * interrupts reaches the PRM before returning; otherwise, spurious
258  * interrupts might occur.  No return value.
259  */
260 static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
261 {
262 	int i;
263 	u16 reg;
264 
265 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) {
266 		reg = omap4_prcm_irq_setup.mask + i * 4;
267 
268 		saved_mask[i] =
269 			omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
270 						reg);
271 		omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, reg);
272 	}
273 
274 	/* OCP barrier */
275 	omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
276 				OMAP4_REVISION_PRM_OFFSET);
277 }
278 
279 /**
280  * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
281  * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
282  *
283  * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
284  * @saved_mask.  Intended to be used in the PRM interrupt handler resume
285  * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
286  * No OCP barrier should be needed here; any pending PRM interrupts will fire
287  * once the writes reach the PRM.  No return value.
288  */
289 static void omap44xx_prm_restore_irqen(u32 *saved_mask)
290 {
291 	int i;
292 
293 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
294 		omap4_prm_write_inst_reg(saved_mask[i],
295 					 OMAP4430_PRM_OCP_SOCKET_INST,
296 					 omap4_prcm_irq_setup.mask + i * 4);
297 }
298 
299 /**
300  * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
301  *
302  * Clear any previously-latched I/O wakeup events and ensure that the
303  * I/O wakeup gates are aligned with the current mux settings.  Works
304  * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
305  * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
306  * No return value. XXX Are the final two steps necessary?
307  */
308 static void omap44xx_prm_reconfigure_io_chain(void)
309 {
310 	int i = 0;
311 	s32 inst = omap4_prmst_get_prm_dev_inst();
312 
313 	if (inst == PRM_INSTANCE_UNKNOWN)
314 		return;
315 
316 	/* Trigger WUCLKIN enable */
317 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
318 				    OMAP4430_WUCLK_CTRL_MASK,
319 				    inst,
320 				    omap4_prcm_irq_setup.pm_ctrl);
321 	omap_test_timeout(
322 		(((omap4_prm_read_inst_reg(inst,
323 					   omap4_prcm_irq_setup.pm_ctrl) &
324 		   OMAP4430_WUCLK_STATUS_MASK) >>
325 		  OMAP4430_WUCLK_STATUS_SHIFT) == 1),
326 		MAX_IOPAD_LATCH_TIME, i);
327 	if (i == MAX_IOPAD_LATCH_TIME)
328 		pr_warn("PRM: I/O chain clock line assertion timed out\n");
329 
330 	/* Trigger WUCLKIN disable */
331 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
332 				    inst,
333 				    omap4_prcm_irq_setup.pm_ctrl);
334 	omap_test_timeout(
335 		(((omap4_prm_read_inst_reg(inst,
336 					   omap4_prcm_irq_setup.pm_ctrl) &
337 		   OMAP4430_WUCLK_STATUS_MASK) >>
338 		  OMAP4430_WUCLK_STATUS_SHIFT) == 0),
339 		MAX_IOPAD_LATCH_TIME, i);
340 	if (i == MAX_IOPAD_LATCH_TIME)
341 		pr_warn("PRM: I/O chain clock line deassertion timed out\n");
342 
343 	return;
344 }
345 
346 /**
347  * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
348  *
349  * Activates the I/O wakeup event latches and allows events logged by
350  * those latches to signal a wakeup event to the PRCM.  For I/O wakeups
351  * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
352  * omap44xx_prm_reconfigure_io_chain() must be called.  No return value.
353  */
354 static void __init omap44xx_prm_enable_io_wakeup(void)
355 {
356 	s32 inst = omap4_prmst_get_prm_dev_inst();
357 
358 	if (inst == PRM_INSTANCE_UNKNOWN)
359 		return;
360 
361 	omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
362 				    OMAP4430_GLOBAL_WUEN_MASK,
363 				    inst,
364 				    omap4_prcm_irq_setup.pm_ctrl);
365 }
366 
367 /**
368  * omap44xx_prm_read_reset_sources - return the last SoC reset source
369  *
370  * Return a u32 representing the last reset sources of the SoC.  The
371  * returned reset source bits are standardized across OMAP SoCs.
372  */
373 static u32 omap44xx_prm_read_reset_sources(void)
374 {
375 	struct prm_reset_src_map *p;
376 	u32 r = 0;
377 	u32 v;
378 	s32 inst = omap4_prmst_get_prm_dev_inst();
379 
380 	if (inst == PRM_INSTANCE_UNKNOWN)
381 		return 0;
382 
383 
384 	v = omap4_prm_read_inst_reg(inst,
385 				    OMAP4_RM_RSTST);
386 
387 	p = omap44xx_prm_reset_src_map;
388 	while (p->reg_shift >= 0 && p->std_shift >= 0) {
389 		if (v & (1 << p->reg_shift))
390 			r |= 1 << p->std_shift;
391 		p++;
392 	}
393 
394 	return r;
395 }
396 
397 /**
398  * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
399  * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
400  * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
401  * @idx: CONTEXT register offset
402  *
403  * Return 1 if any bits were set in the *_CONTEXT_* register
404  * identified by (@part, @inst, @idx), which means that some context
405  * was lost for that module; otherwise, return 0.
406  */
407 static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
408 {
409 	return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
410 }
411 
412 /**
413  * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
414  * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
415  * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
416  * @idx: CONTEXT register offset
417  *
418  * Clear hardware context loss bits for the module identified by
419  * (@part, @inst, @idx).  No return value.  XXX Writes to reserved bits;
420  * is there a way to avoid this?
421  */
422 static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
423 						      u16 idx)
424 {
425 	omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
426 }
427 
428 /* Powerdomain low-level functions */
429 
430 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
431 {
432 	omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
433 					(pwrst << OMAP_POWERSTATE_SHIFT),
434 					pwrdm->prcm_partition,
435 					pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
436 	return 0;
437 }
438 
439 static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
440 {
441 	u32 v;
442 
443 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
444 					OMAP4_PM_PWSTCTRL);
445 	v &= OMAP_POWERSTATE_MASK;
446 	v >>= OMAP_POWERSTATE_SHIFT;
447 
448 	return v;
449 }
450 
451 static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
452 {
453 	u32 v;
454 
455 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
456 					OMAP4_PM_PWSTST);
457 	v &= OMAP_POWERSTATEST_MASK;
458 	v >>= OMAP_POWERSTATEST_SHIFT;
459 
460 	return v;
461 }
462 
463 static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
464 {
465 	u32 v;
466 
467 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
468 					OMAP4_PM_PWSTST);
469 	v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
470 	v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
471 
472 	return v;
473 }
474 
475 static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
476 {
477 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
478 					(1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
479 					pwrdm->prcm_partition,
480 					pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
481 	return 0;
482 }
483 
484 static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
485 {
486 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
487 					OMAP4430_LASTPOWERSTATEENTERED_MASK,
488 					pwrdm->prcm_partition,
489 					pwrdm->prcm_offs, OMAP4_PM_PWSTST);
490 	return 0;
491 }
492 
493 static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
494 {
495 	u32 v;
496 
497 	v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
498 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
499 					pwrdm->prcm_partition, pwrdm->prcm_offs,
500 					OMAP4_PM_PWSTCTRL);
501 
502 	return 0;
503 }
504 
505 static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
506 				    u8 pwrst)
507 {
508 	u32 m;
509 
510 	m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
511 
512 	omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
513 					pwrdm->prcm_partition, pwrdm->prcm_offs,
514 					OMAP4_PM_PWSTCTRL);
515 
516 	return 0;
517 }
518 
519 static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
520 				     u8 pwrst)
521 {
522 	u32 m;
523 
524 	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
525 
526 	omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
527 					pwrdm->prcm_partition, pwrdm->prcm_offs,
528 					OMAP4_PM_PWSTCTRL);
529 
530 	return 0;
531 }
532 
533 static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
534 {
535 	u32 v;
536 
537 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
538 					OMAP4_PM_PWSTST);
539 	v &= OMAP4430_LOGICSTATEST_MASK;
540 	v >>= OMAP4430_LOGICSTATEST_SHIFT;
541 
542 	return v;
543 }
544 
545 static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
546 {
547 	u32 v;
548 
549 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
550 					OMAP4_PM_PWSTCTRL);
551 	v &= OMAP4430_LOGICRETSTATE_MASK;
552 	v >>= OMAP4430_LOGICRETSTATE_SHIFT;
553 
554 	return v;
555 }
556 
557 /**
558  * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
559  * @pwrdm: struct powerdomain * to read the state for
560  *
561  * Reads the previous logic powerstate for a powerdomain. This
562  * function must determine the previous logic powerstate by first
563  * checking the previous powerstate for the domain. If that was OFF,
564  * then logic has been lost. If previous state was RETENTION, the
565  * function reads the setting for the next retention logic state to
566  * see the actual value.  In every other case, the logic is
567  * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
568  * depending whether the logic was retained or not.
569  */
570 static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
571 {
572 	int state;
573 
574 	state = omap4_pwrdm_read_prev_pwrst(pwrdm);
575 
576 	if (state == PWRDM_POWER_OFF)
577 		return PWRDM_POWER_OFF;
578 
579 	if (state != PWRDM_POWER_RET)
580 		return PWRDM_POWER_RET;
581 
582 	return omap4_pwrdm_read_logic_retst(pwrdm);
583 }
584 
585 static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
586 {
587 	u32 m, v;
588 
589 	m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
590 
591 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
592 					OMAP4_PM_PWSTST);
593 	v &= m;
594 	v >>= __ffs(m);
595 
596 	return v;
597 }
598 
599 static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
600 {
601 	u32 m, v;
602 
603 	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
604 
605 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
606 					OMAP4_PM_PWSTCTRL);
607 	v &= m;
608 	v >>= __ffs(m);
609 
610 	return v;
611 }
612 
613 /**
614  * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
615  * @pwrdm: struct powerdomain * to read mem powerstate for
616  * @bank: memory bank index
617  *
618  * Reads the previous memory powerstate for a powerdomain. This
619  * function must determine the previous memory powerstate by first
620  * checking the previous powerstate for the domain. If that was OFF,
621  * then logic has been lost. If previous state was RETENTION, the
622  * function reads the setting for the next memory retention state to
623  * see the actual value.  In every other case, the logic is
624  * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
625  * depending whether logic was retained or not.
626  */
627 static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
628 {
629 	int state;
630 
631 	state = omap4_pwrdm_read_prev_pwrst(pwrdm);
632 
633 	if (state == PWRDM_POWER_OFF)
634 		return PWRDM_POWER_OFF;
635 
636 	if (state != PWRDM_POWER_RET)
637 		return PWRDM_POWER_RET;
638 
639 	return omap4_pwrdm_read_mem_retst(pwrdm, bank);
640 }
641 
642 static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
643 {
644 	u32 c = 0;
645 
646 	/*
647 	 * REVISIT: pwrdm_wait_transition() may be better implemented
648 	 * via a callback and a periodic timer check -- how long do we expect
649 	 * powerdomain transitions to take?
650 	 */
651 
652 	/* XXX Is this udelay() value meaningful? */
653 	while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
654 					    pwrdm->prcm_offs,
655 					    OMAP4_PM_PWSTST) &
656 		OMAP_INTRANSITION_MASK) &&
657 	       (c++ < PWRDM_TRANSITION_BAILOUT))
658 		udelay(1);
659 
660 	if (c > PWRDM_TRANSITION_BAILOUT) {
661 		pr_err("powerdomain: %s: waited too long to complete transition\n",
662 		       pwrdm->name);
663 		return -EAGAIN;
664 	}
665 
666 	pr_debug("powerdomain: completed transition in %d loops\n", c);
667 
668 	return 0;
669 }
670 
671 static int omap4_check_vcvp(void)
672 {
673 	if (prm_features & PRM_HAS_VOLTAGE)
674 		return 1;
675 
676 	return 0;
677 }
678 
679 /**
680  * omap4_pwrdm_save_context - Saves the powerdomain state
681  * @pwrdm: pointer to individual powerdomain
682  *
683  * The function saves the powerdomain state control information.
684  * This is needed in rtc+ddr modes where we lose powerdomain context.
685  */
686 static void omap4_pwrdm_save_context(struct powerdomain *pwrdm)
687 {
688 	pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
689 						     pwrdm->prcm_offs,
690 						     pwrdm->pwrstctrl_offs);
691 
692 	/*
693 	 * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
694 	 * reading back a 1 indicates a request in progress.
695 	 */
696 	pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK;
697 }
698 
699 /**
700  * omap4_pwrdm_restore_context - Restores the powerdomain state
701  * @pwrdm: pointer to individual powerdomain
702  *
703  * The function restores the powerdomain state control information.
704  * This is needed in rtc+ddr modes where we lose powerdomain context.
705  */
706 static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm)
707 {
708 	int st, ctrl;
709 
710 	st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
711 					 pwrdm->prcm_offs,
712 					 pwrdm->pwrstctrl_offs);
713 
714 	omap4_prminst_write_inst_reg(pwrdm->context,
715 				     pwrdm->prcm_partition,
716 				     pwrdm->prcm_offs,
717 				     pwrdm->pwrstctrl_offs);
718 
719 	/* Make sure we only wait for a transition if there is one */
720 	st &= OMAP_POWERSTATEST_MASK;
721 	ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
722 
723 	if (st != ctrl)
724 		omap4_pwrdm_wait_transition(pwrdm);
725 }
726 
727 struct pwrdm_ops omap4_pwrdm_operations = {
728 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
729 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
730 	.pwrdm_read_pwrst	= omap4_pwrdm_read_pwrst,
731 	.pwrdm_read_prev_pwrst	= omap4_pwrdm_read_prev_pwrst,
732 	.pwrdm_set_lowpwrstchange	= omap4_pwrdm_set_lowpwrstchange,
733 	.pwrdm_clear_all_prev_pwrst	= omap4_pwrdm_clear_all_prev_pwrst,
734 	.pwrdm_set_logic_retst	= omap4_pwrdm_set_logic_retst,
735 	.pwrdm_read_logic_pwrst	= omap4_pwrdm_read_logic_pwrst,
736 	.pwrdm_read_prev_logic_pwrst	= omap4_pwrdm_read_prev_logic_pwrst,
737 	.pwrdm_read_logic_retst	= omap4_pwrdm_read_logic_retst,
738 	.pwrdm_read_mem_pwrst	= omap4_pwrdm_read_mem_pwrst,
739 	.pwrdm_read_mem_retst	= omap4_pwrdm_read_mem_retst,
740 	.pwrdm_read_prev_mem_pwrst	= omap4_pwrdm_read_prev_mem_pwrst,
741 	.pwrdm_set_mem_onst	= omap4_pwrdm_set_mem_onst,
742 	.pwrdm_set_mem_retst	= omap4_pwrdm_set_mem_retst,
743 	.pwrdm_wait_transition	= omap4_pwrdm_wait_transition,
744 	.pwrdm_has_voltdm	= omap4_check_vcvp,
745 	.pwrdm_save_context	= omap4_pwrdm_save_context,
746 	.pwrdm_restore_context	= omap4_pwrdm_restore_context,
747 };
748 
749 static int omap44xx_prm_late_init(void);
750 
751 void prm_save_context(void)
752 {
753 	omap_prm_context.irq_enable =
754 			omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
755 						omap4_prcm_irq_setup.mask);
756 
757 	omap_prm_context.pm_ctrl =
758 			omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
759 						omap4_prcm_irq_setup.pm_ctrl);
760 }
761 
762 void prm_restore_context(void)
763 {
764 	omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
765 				 OMAP4430_PRM_OCP_SOCKET_INST,
766 				 omap4_prcm_irq_setup.mask);
767 
768 	omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
769 				 AM43XX_PRM_DEVICE_INST,
770 				 omap4_prcm_irq_setup.pm_ctrl);
771 }
772 
773 static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
774 {
775 	switch (cmd) {
776 	case CPU_CLUSTER_PM_ENTER:
777 		if (enable_off_mode)
778 			prm_save_context();
779 		break;
780 	case CPU_CLUSTER_PM_EXIT:
781 		if (enable_off_mode)
782 			prm_restore_context();
783 		break;
784 	}
785 
786 	return NOTIFY_OK;
787 }
788 
789 /*
790  * XXX document
791  */
792 static struct prm_ll_data omap44xx_prm_ll_data = {
793 	.read_reset_sources = &omap44xx_prm_read_reset_sources,
794 	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
795 	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
796 	.late_init = &omap44xx_prm_late_init,
797 	.assert_hardreset	= omap4_prminst_assert_hardreset,
798 	.deassert_hardreset	= omap4_prminst_deassert_hardreset,
799 	.is_hardreset_asserted	= omap4_prminst_is_hardreset_asserted,
800 	.reset_system		= omap4_prminst_global_warm_sw_reset,
801 	.vp_check_txdone	= omap4_prm_vp_check_txdone,
802 	.vp_clear_txdone	= omap4_prm_vp_clear_txdone,
803 };
804 
805 static const struct omap_prcm_init_data *prm_init_data;
806 
807 int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
808 {
809 	static struct notifier_block nb;
810 	omap_prm_base_init();
811 
812 	prm_init_data = data;
813 
814 	if (data->flags & PRM_HAS_IO_WAKEUP)
815 		prm_features |= PRM_HAS_IO_WAKEUP;
816 
817 	if (data->flags & PRM_HAS_VOLTAGE)
818 		prm_features |= PRM_HAS_VOLTAGE;
819 
820 	omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
821 
822 	/* Add AM437X specific differences */
823 	if (of_device_is_compatible(data->np, "ti,am4-prcm")) {
824 		omap4_prcm_irq_setup.nr_irqs = 1;
825 		omap4_prcm_irq_setup.nr_regs = 1;
826 		omap4_prcm_irq_setup.pm_ctrl = AM43XX_PRM_IO_PMCTRL_OFFSET;
827 		omap4_prcm_irq_setup.ack = AM43XX_PRM_IRQSTATUS_MPU_OFFSET;
828 		omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
829 	}
830 
831 	/* Only AM43XX can lose prm context during rtc-ddr suspend */
832 	if (soc_is_am43xx()) {
833 		nb.notifier_call = cpu_notifier;
834 		cpu_pm_register_notifier(&nb);
835 	}
836 
837 	return prm_register(&omap44xx_prm_ll_data);
838 }
839 
840 static int omap44xx_prm_late_init(void)
841 {
842 	int irq_num;
843 
844 	if (!(prm_features & PRM_HAS_IO_WAKEUP))
845 		return 0;
846 
847 	irq_num = of_irq_get(prm_init_data->np, 0);
848 	if (irq_num == -EPROBE_DEFER)
849 		return irq_num;
850 
851 	omap4_prcm_irq_setup.irq = irq_num;
852 
853 	omap44xx_prm_enable_io_wakeup();
854 
855 	return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
856 }
857 
858 static void __exit omap44xx_prm_exit(void)
859 {
860 	prm_unregister(&omap44xx_prm_ll_data);
861 }
862 __exitcall(omap44xx_prm_exit);
863