1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/io.h>
18
19#include "iomap.h"
20#include "common.h"
21#include "prcm-common.h"
22#include "prm44xx.h"
23#include "prm54xx.h"
24#include "prm7xx.h"
25#include "prminst44xx.h"
26#include "prm-regbits-44xx.h"
27#include "prcm44xx.h"
28#include "prcm43xx.h"
29#include "prcm_mpu44xx.h"
30#include "soc.h"
31
32static struct omap_domain_base _prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
33
34static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
35
36
37
38
39
40
41
42void omap_prm_base_init(void)
43{
44 memcpy(&_prm_bases[OMAP4430_PRM_PARTITION], &prm_base,
45 sizeof(prm_base));
46 memcpy(&_prm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base,
47 sizeof(prcm_mpu_base));
48}
49
50s32 omap4_prmst_get_prm_dev_inst(void)
51{
52 return prm_dev_inst;
53}
54
55void omap4_prminst_set_prm_dev_inst(s32 dev_inst)
56{
57 prm_dev_inst = dev_inst;
58}
59
60
61u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
62{
63 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
64 part == OMAP4430_INVALID_PRCM_PARTITION ||
65 !_prm_bases[part].va);
66 return readl_relaxed(_prm_bases[part].va + inst + idx);
67}
68
69
70void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
71{
72 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
73 part == OMAP4430_INVALID_PRCM_PARTITION ||
74 !_prm_bases[part].va);
75 writel_relaxed(val, _prm_bases[part].va + inst + idx);
76}
77
78
79u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
80 u16 idx)
81{
82 u32 v;
83
84 v = omap4_prminst_read_inst_reg(part, inst, idx);
85 v &= ~mask;
86 v |= bits;
87 omap4_prminst_write_inst_reg(v, part, inst, idx);
88
89 return v;
90}
91
92
93
94
95
96
97
98
99
100
101
102int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
103 u16 rstctrl_offs)
104{
105 u32 v;
106
107 v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs);
108 v &= 1 << shift;
109 v >>= shift;
110
111 return v;
112}
113
114
115
116
117
118
119
120
121
122
123
124
125
126int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
127 u16 rstctrl_offs)
128{
129 u32 mask = 1 << shift;
130
131 omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs);
132
133 return 0;
134}
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
156 u16 rstctrl_offs, u16 rstst_offs)
157{
158 int c;
159 u32 mask = 1 << shift;
160 u32 st_mask = 1 << st_shift;
161
162
163 if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
164 rstctrl_offs) == 0)
165 return -EEXIST;
166
167
168 omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
169 rstst_offs);
170
171 omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
172
173 omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
174 inst, rstst_offs),
175 MAX_MODULE_HARDRESET_WAIT, c);
176
177 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
178}
179
180
181void omap4_prminst_global_warm_sw_reset(void)
182{
183 u32 v;
184 s32 inst = omap4_prmst_get_prm_dev_inst();
185
186 if (inst == PRM_INSTANCE_UNKNOWN)
187 return;
188
189 v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst,
190 OMAP4_PRM_RSTCTRL_OFFSET);
191 v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
192 omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
193 inst, OMAP4_PRM_RSTCTRL_OFFSET);
194
195
196 v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
197 inst, OMAP4_PRM_RSTCTRL_OFFSET);
198}
199