diff options
Diffstat (limited to 'arch/arm/mach-omap2/cm2xxx_3xxx.c')
-rw-r--r-- | arch/arm/mach-omap2/cm2xxx_3xxx.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c new file mode 100644 index 000000000000..5978ce426ec5 --- /dev/null +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * OMAP2/3 CM module functions | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include <plat/common.h> | ||
22 | |||
23 | #include "cm.h" | ||
24 | #include "cm2xxx_3xxx.h" | ||
25 | #include "cm-regbits-24xx.h" | ||
26 | #include "cm-regbits-34xx.h" | ||
27 | |||
28 | static const u8 cm_idlest_offs[] = { | ||
29 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 | ||
30 | }; | ||
31 | |||
32 | |||
33 | u32 cm_read_mod_reg(s16 module, u16 idx) | ||
34 | { | ||
35 | return __raw_readl(cm_base + module + idx); | ||
36 | } | ||
37 | |||
38 | void cm_write_mod_reg(u32 val, s16 module, u16 idx) | ||
39 | { | ||
40 | __raw_writel(val, cm_base + module + idx); | ||
41 | } | ||
42 | |||
43 | /* Read-modify-write a register in a CM module. Caller must lock */ | ||
44 | u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) | ||
45 | { | ||
46 | u32 v; | ||
47 | |||
48 | v = cm_read_mod_reg(module, idx); | ||
49 | v &= ~mask; | ||
50 | v |= bits; | ||
51 | cm_write_mod_reg(v, module, idx); | ||
52 | |||
53 | return v; | ||
54 | } | ||
55 | |||
56 | u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
57 | { | ||
58 | return cm_rmw_mod_reg_bits(bits, bits, module, idx); | ||
59 | } | ||
60 | |||
61 | u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
62 | { | ||
63 | return cm_rmw_mod_reg_bits(bits, 0x0, module, idx); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby | ||
68 | * @prcm_mod: PRCM module offset | ||
69 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) | ||
70 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | ||
71 | * | ||
72 | * XXX document | ||
73 | */ | ||
74 | int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | ||
75 | { | ||
76 | int ena = 0, i = 0; | ||
77 | u8 cm_idlest_reg; | ||
78 | u32 mask; | ||
79 | |||
80 | if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs))) | ||
81 | return -EINVAL; | ||
82 | |||
83 | cm_idlest_reg = cm_idlest_offs[idlest_id - 1]; | ||
84 | |||
85 | mask = 1 << idlest_shift; | ||
86 | |||
87 | if (cpu_is_omap24xx()) | ||
88 | ena = mask; | ||
89 | else if (cpu_is_omap34xx()) | ||
90 | ena = 0; | ||
91 | else | ||
92 | BUG(); | ||
93 | |||
94 | omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena), | ||
95 | MAX_MODULE_READY_TIME, i); | ||
96 | |||
97 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | ||
98 | } | ||
99 | |||