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 void __iomem *_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 _prm_bases[OMAP4430_PRM_PARTITION] = prm_base;
45 _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base;
46}
47
48s32 omap4_prmst_get_prm_dev_inst(void)
49{
50 return prm_dev_inst;
51}
52
53void omap4_prminst_set_prm_dev_inst(s32 dev_inst)
54{
55 prm_dev_inst = dev_inst;
56}
57
58
59u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
60{
61 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
62 part == OMAP4430_INVALID_PRCM_PARTITION ||
63 !_prm_bases[part]);
64 return readl_relaxed(_prm_bases[part] + inst + idx);
65}
66
67
68void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
69{
70 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
71 part == OMAP4430_INVALID_PRCM_PARTITION ||
72 !_prm_bases[part]);
73 writel_relaxed(val, _prm_bases[part] + inst + idx);
74}
75
76
77u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
78 u16 idx)
79{
80 u32 v;
81
82 v = omap4_prminst_read_inst_reg(part, inst, idx);
83 v &= ~mask;
84 v |= bits;
85 omap4_prminst_write_inst_reg(v, part, inst, idx);
86
87 return v;
88}
89
90
91
92
93
94
95
96
97
98
99
100int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
101 u16 rstctrl_offs)
102{
103 u32 v;
104
105 v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs);
106 v &= 1 << shift;
107 v >>= shift;
108
109 return v;
110}
111
112
113
114
115
116
117
118
119
120
121
122
123
124int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
125 u16 rstctrl_offs)
126{
127 u32 mask = 1 << shift;
128
129 omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs);
130
131 return 0;
132}
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
154 u16 rstctrl_offs, u16 rstst_offs)
155{
156 int c;
157 u32 mask = 1 << shift;
158 u32 st_mask = 1 << st_shift;
159
160
161 if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
162 rstctrl_offs) == 0)
163 return -EEXIST;
164
165
166 omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
167 rstst_offs);
168
169 omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
170
171 omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
172 inst, rstst_offs),
173 MAX_MODULE_HARDRESET_WAIT, c);
174
175 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
176}
177
178
179void omap4_prminst_global_warm_sw_reset(void)
180{
181 u32 v;
182 s32 inst = omap4_prmst_get_prm_dev_inst();
183
184 if (inst == PRM_INSTANCE_UNKNOWN)
185 return;
186
187 v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst,
188 OMAP4_PRM_RSTCTRL_OFFSET);
189 v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
190 omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
191 inst, OMAP4_PRM_RSTCTRL_OFFSET);
192
193
194 v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
195 inst, OMAP4_PRM_RSTCTRL_OFFSET);
196}
197