1 /*
2 * Copyright 2008-2013 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "fsl_fman_rtc.h"
34
fman_rtc_defconfig(struct rtc_cfg * cfg)35 void fman_rtc_defconfig(struct rtc_cfg *cfg)
36 {
37 int i;
38 cfg->src_clk = DEFAULT_SRC_CLOCK;
39 cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
40 cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
41 cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
42 for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
43 cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
44 for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
45 cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
46 }
47
fman_rtc_get_events(struct rtc_regs * regs)48 uint32_t fman_rtc_get_events(struct rtc_regs *regs)
49 {
50 return ioread32be(®s->tmr_tevent);
51 }
52
fman_rtc_get_event(struct rtc_regs * regs,uint32_t ev_mask)53 uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
54 {
55 return ioread32be(®s->tmr_tevent) & ev_mask;
56 }
57
fman_rtc_get_interrupt_mask(struct rtc_regs * regs)58 uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
59 {
60 return ioread32be(®s->tmr_temask);
61 }
62
fman_rtc_set_interrupt_mask(struct rtc_regs * regs,uint32_t mask)63 void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
64 {
65 iowrite32be(mask, ®s->tmr_temask);
66 }
67
fman_rtc_ack_event(struct rtc_regs * regs,uint32_t events)68 void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
69 {
70 iowrite32be(events, ®s->tmr_tevent);
71 }
72
fman_rtc_check_and_clear_event(struct rtc_regs * regs)73 uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
74 {
75 uint32_t event;
76
77 event = ioread32be(®s->tmr_tevent);
78 event &= ioread32be(®s->tmr_temask);
79
80 if (event)
81 iowrite32be(event, ®s->tmr_tevent);
82 return event;
83 }
84
fman_rtc_get_frequency_compensation(struct rtc_regs * regs)85 uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
86 {
87 return ioread32be(®s->tmr_add);
88 }
89
fman_rtc_set_frequency_compensation(struct rtc_regs * regs,uint32_t val)90 void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
91 {
92 iowrite32be(val, ®s->tmr_add);
93 }
94
fman_rtc_enable_interupt(struct rtc_regs * regs,uint32_t events)95 void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
96 {
97 fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
98 }
99
fman_rtc_disable_interupt(struct rtc_regs * regs,uint32_t events)100 void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
101 {
102 fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
103 }
104
fman_rtc_set_timer_alarm_l(struct rtc_regs * regs,int index,uint32_t val)105 void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
106 {
107 iowrite32be(val, ®s->tmr_alarm[index].tmr_alarm_l);
108 }
109
fman_rtc_set_timer_fiper(struct rtc_regs * regs,int index,uint32_t val)110 void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
111 {
112 iowrite32be(val, ®s->tmr_fiper[index]);
113 }
114
fman_rtc_set_timer_alarm(struct rtc_regs * regs,int index,int64_t val)115 void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
116 {
117 iowrite32be((uint32_t)val, ®s->tmr_alarm[index].tmr_alarm_l);
118 iowrite32be((uint32_t)(val >> 32), ®s->tmr_alarm[index].tmr_alarm_h);
119 }
120
fman_rtc_set_timer_offset(struct rtc_regs * regs,int64_t val)121 void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
122 {
123 iowrite32be((uint32_t)val, ®s->tmr_off_l);
124 iowrite32be((uint32_t)(val >> 32), ®s->tmr_off_h);
125 }
126
fman_rtc_get_trigger_stamp(struct rtc_regs * regs,int id)127 uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
128 {
129 uint64_t time;
130 /* TMR_CNT_L must be read first to get an accurate value */
131 time = (uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_l);
132 time |= ((uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_h)
133 << 32);
134
135 return time;
136 }
137
fman_rtc_get_timer_ctrl(struct rtc_regs * regs)138 uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
139 {
140 return ioread32be(®s->tmr_ctrl);
141 }
142
fman_rtc_set_timer_ctrl(struct rtc_regs * regs,uint32_t val)143 void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
144 {
145 iowrite32be(val, ®s->tmr_ctrl);
146 }
147
fman_rtc_timers_soft_reset(struct rtc_regs * regs)148 void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
149 {
150 fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
151 DELAY(10);
152 fman_rtc_set_timer_ctrl(regs, 0);
153 }
154
fman_rtc_init(struct rtc_cfg * cfg,struct rtc_regs * regs,int num_alarms,int num_fipers,int num_ext_triggers,bool init_freq_comp,uint32_t freq_compensation,uint32_t output_clock_divisor)155 void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
156 int num_fipers, int num_ext_triggers, bool init_freq_comp,
157 uint32_t freq_compensation, uint32_t output_clock_divisor)
158 {
159 uint32_t tmr_ctrl;
160 int i;
161
162 fman_rtc_timers_soft_reset(regs);
163
164 /* Set the source clock */
165 switch (cfg->src_clk) {
166 case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
167 tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
168 break;
169 case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
170 tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
171 break;
172 default:
173 /* Use a clock from the External TMR reference clock.*/
174 tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
175 break;
176 }
177
178 /* whatever period the user picked, the timestamp will advance in '1'
179 * every time the period passed. */
180 tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
181 FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
182
183 if (cfg->invert_input_clk_phase)
184 tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
185 if (cfg->invert_output_clk_phase)
186 tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
187
188 for (i = 0; i < num_alarms; i++) {
189 if (cfg->alarm_polarity[i] ==
190 E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
191 tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
192 }
193
194 for (i = 0; i < num_ext_triggers; i++)
195 if (cfg->trigger_polarity[i] ==
196 E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
197 tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
198
199 if (!cfg->timer_slave_mode && cfg->bypass)
200 tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
201
202 fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
203 if (init_freq_comp)
204 fman_rtc_set_frequency_compensation(regs, freq_compensation);
205
206 /* Clear TMR_ALARM registers */
207 for (i = 0; i < num_alarms; i++)
208 fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
209
210 /* Clear TMR_TEVENT */
211 fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
212
213 /* Initialize TMR_TEMASK */
214 fman_rtc_set_interrupt_mask(regs, 0);
215
216 /* Clear TMR_FIPER registers */
217 for (i = 0; i < num_fipers; i++)
218 fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
219
220 /* Initialize TMR_PRSC */
221 iowrite32be(output_clock_divisor, ®s->tmr_prsc);
222
223 /* Clear TMR_OFF */
224 fman_rtc_set_timer_offset(regs, 0);
225 }
226
fman_rtc_is_enabled(struct rtc_regs * regs)227 bool fman_rtc_is_enabled(struct rtc_regs *regs)
228 {
229 return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
230 }
231
fman_rtc_enable(struct rtc_regs * regs,bool reset_clock)232 void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
233 {
234 uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
235
236 /* TODO check that no timestamping MACs are working in this stage. */
237 if (reset_clock) {
238 fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
239
240 DELAY(10);
241 /* Clear TMR_OFF */
242 fman_rtc_set_timer_offset(regs, 0);
243 }
244
245 fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
246 }
247
fman_rtc_disable(struct rtc_regs * regs)248 void fman_rtc_disable(struct rtc_regs *regs)
249 {
250 fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
251 & ~(FMAN_RTC_TMR_CTRL_TE)));
252 }
253
fman_rtc_clear_periodic_pulse(struct rtc_regs * regs,int id)254 void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
255 {
256 uint32_t tmp_reg;
257 if (id == 0)
258 tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
259 else
260 tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
261 fman_rtc_disable_interupt(regs, tmp_reg);
262
263 tmp_reg = fman_rtc_get_timer_ctrl(regs);
264 if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
265 fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
266
267 fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
268 }
269
fman_rtc_clear_external_trigger(struct rtc_regs * regs,int id)270 void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
271 {
272 uint32_t tmpReg, tmp_ctrl;
273
274 if (id == 0)
275 tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
276 else
277 tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
278 fman_rtc_disable_interupt(regs, tmpReg);
279
280 if (id == 0)
281 tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
282 else
283 tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
284 tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
285 if (tmp_ctrl & tmpReg)
286 fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
287 }
288
fman_rtc_set_alarm(struct rtc_regs * regs,int id,uint32_t val,bool enable)289 void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
290 {
291 uint32_t tmpReg;
292 fman_rtc_set_timer_alarm(regs, id, val);
293 if (enable) {
294 if (id == 0)
295 tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
296 else
297 tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
298 fman_rtc_enable_interupt(regs, tmpReg);
299 }
300 }
301
fman_rtc_set_periodic_pulse(struct rtc_regs * regs,int id,uint32_t val,bool enable)302 void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
303 bool enable)
304 {
305 uint32_t tmpReg;
306 fman_rtc_set_timer_fiper(regs, id, val);
307 if (enable) {
308 if (id == 0)
309 tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
310 else
311 tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
312 fman_rtc_enable_interupt(regs, tmpReg);
313 }
314 }
315
fman_rtc_set_ext_trigger(struct rtc_regs * regs,int id,bool enable,bool use_pulse_as_input)316 void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
317 bool use_pulse_as_input)
318 {
319 uint32_t tmpReg;
320 if (enable) {
321 if (id == 0)
322 tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
323 else
324 tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
325 fman_rtc_enable_interupt(regs, tmpReg);
326 }
327 if (use_pulse_as_input) {
328 if (id == 0)
329 tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
330 else
331 tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
332 fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
333 }
334 }
335