1 /*
2 * Copyright 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 #ifndef __FSL_FMAN_RTC_H
34 #define __FSL_FMAN_RTC_H
35
36 #include "common/general.h"
37
38 /* FM RTC Registers definitions */
39 #define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
40 #define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
41 #define FMAN_RTC_TMR_CTRL_FS 0x10000000
42 #define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
43 #define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
44 #define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
45 #define FMAN_RTC_TMR_CTRL_FRD 0x00004000
46 #define FMAN_RTC_TMR_CTRL_SLV 0x00002000
47 #define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
48 #define FMAN_RTC_TMR_CTRL_COPH 0x00000080
49 #define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
50 #define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
51 #define FMAN_RTC_TMR_CTRL_DBG 0x00000010
52 #define FMAN_RTC_TMR_CTRL_BYP 0x00000008
53 #define FMAN_RTC_TMR_CTRL_TE 0x00000004
54 #define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
55 #define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
56 #define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
57 #define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
58
59 #define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
60 #define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
61 #define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
62 #define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
63 #define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
64 #define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
65 #define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
66 #define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
67 FMAN_RTC_TMR_TEVENT_ETS1 |\
68 FMAN_RTC_TMR_TEVENT_ALM2 |\
69 FMAN_RTC_TMR_TEVENT_ALM1 |\
70 FMAN_RTC_TMR_TEVENT_PP1 |\
71 FMAN_RTC_TMR_TEVENT_PP2 |\
72 FMAN_RTC_TMR_TEVENT_PP3)
73
74 #define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
75
76 /**************************************************************************//**
77 @Description FM RTC Alarm Polarity Options.
78 *//***************************************************************************/
79 enum fman_rtc_alarm_polarity {
80 E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
81 E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
82 };
83
84 /**************************************************************************//**
85 @Description FM RTC Trigger Polarity Options.
86 *//***************************************************************************/
87 enum fman_rtc_trigger_polarity {
88 E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
89 E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
90 };
91
92 /**************************************************************************//**
93 @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
94 *//***************************************************************************/
95 enum fman_src_clock {
96 E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
97 reference clock */
98 E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
99 E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
100 };
101
102 /* RTC default values */
103 #define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
104 #define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
105 #define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
106 #define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
107 #define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
108 #define DEFAULT_PULSE_REALIGN FALSE
109
110 #define FMAN_RTC_MAX_NUM_OF_ALARMS 3
111 #define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
112 #define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
113
114 /**************************************************************************//**
115 @Description FM RTC timer alarm
116 *//***************************************************************************/
117 struct t_tmr_alarm{
118 uint32_t tmr_alarm_h; /**< */
119 uint32_t tmr_alarm_l; /**< */
120 };
121
122 /**************************************************************************//**
123 @Description FM RTC timer Ex trigger
124 *//***************************************************************************/
125 struct t_tmr_ext_trigger{
126 uint32_t tmr_etts_h; /**< */
127 uint32_t tmr_etts_l; /**< */
128 };
129
130 struct rtc_regs {
131 uint32_t tmr_id; /* 0x000 Module ID register */
132 uint32_t tmr_id2; /* 0x004 Controller ID register */
133 uint32_t reserved0008[30];
134 uint32_t tmr_ctrl; /* 0x0080 timer control register */
135 uint32_t tmr_tevent; /* 0x0084 timer event register */
136 uint32_t tmr_temask; /* 0x0088 timer event mask register */
137 uint32_t reserved008c[3];
138 uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
139 uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
140 uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
141 uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
142 uint32_t tmr_prsc; /* 0x00a8 timer prescale */
143 uint32_t reserved00ac;
144 uint32_t tmr_off_h; /* 0x00b0 timer offset high */
145 uint32_t tmr_off_l; /* 0x00b4 timer offset low */
146 struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
147 alarm */
148 uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
149 fixed period interval */
150 struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
151 /* 0x00e0 time stamp general purpose external */
152 uint32_t reserved00f0[4];
153 };
154
155 struct rtc_cfg {
156 enum fman_src_clock src_clk;
157 uint32_t ext_src_clk_freq;
158 uint32_t rtc_freq_hz;
159 bool timer_slave_mode;
160 bool invert_input_clk_phase;
161 bool invert_output_clk_phase;
162 uint32_t events_mask;
163 bool bypass; /**< Indicates if frequency compensation
164 is bypassed */
165 bool pulse_realign;
166 enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
167 enum fman_rtc_trigger_polarity trigger_polarity
168 [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
169 };
170
171 /**
172 * fman_rtc_defconfig() - Get default RTC configuration
173 * @cfg: pointer to configuration structure.
174 *
175 * Call this function to obtain a default set of configuration values for
176 * initializing RTC. The user can overwrite any of the values before calling
177 * fman_rtc_init(), if specific configuration needs to be applied.
178 */
179 void fman_rtc_defconfig(struct rtc_cfg *cfg);
180
181 /**
182 * fman_rtc_get_events() - Get the events
183 * @regs: Pointer to RTC register block
184 *
185 * Returns: The events
186 */
187 uint32_t fman_rtc_get_events(struct rtc_regs *regs);
188
189 /**
190 * fman_rtc_get_interrupt_mask() - Get the events mask
191 * @regs: Pointer to RTC register block
192 *
193 * Returns: The events mask
194 */
195 uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
196
197
198 /**
199 * fman_rtc_set_interrupt_mask() - Set the events mask
200 * @regs: Pointer to RTC register block
201 * @mask: The mask to set
202 */
203 void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
204
205 /**
206 * fman_rtc_get_event() - Check if specific events occurred
207 * @regs: Pointer to RTC register block
208 * @ev_mask: a mask of the events to check
209 *
210 * Returns: 0 if the events did not occur. Non zero if one of the events occurred
211 */
212 uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
213
214 /**
215 * fman_rtc_check_and_clear_event() - Clear events which are on
216 * @regs: Pointer to RTC register block
217 *
218 * Returns: A mask of the events which were cleared
219 */
220 uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
221
222 /**
223 * fman_rtc_ack_event() - Clear events
224 * @regs: Pointer to RTC register block
225 * @events: The events to disable
226 */
227 void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
228
229 /**
230 * fman_rtc_enable_interupt() - Enable events interrupts
231 * @regs: Pointer to RTC register block
232 * @mask: The events to disable
233 */
234 void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
235
236 /**
237 * fman_rtc_disable_interupt() - Disable events interrupts
238 * @regs: Pointer to RTC register block
239 * @mask: The events to disable
240 */
241 void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
242
243 /**
244 * fman_rtc_get_timer_ctrl() - Get the control register
245 * @regs: Pointer to RTC register block
246 *
247 * Returns: The control register value
248 */
249 uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
250
251 /**
252 * fman_rtc_set_timer_ctrl() - Set timer control register
253 * @regs: Pointer to RTC register block
254 * @val: The value to set
255 */
256 void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
257
258 /**
259 * fman_rtc_get_frequency_compensation() - Get the frequency compensation
260 * @regs: Pointer to RTC register block
261 *
262 * Returns: The timer counter
263 */
264 uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
265
266 /**
267 * fman_rtc_set_frequency_compensation() - Set frequency compensation
268 * @regs: Pointer to RTC register block
269 * @val: The value to set
270 */
271 void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
272
273 /**
274 * fman_rtc_get_trigger_stamp() - Get a trigger stamp
275 * @regs: Pointer to RTC register block
276 * @id: The id of the trigger stamp
277 *
278 * Returns: The time stamp
279 */
280 uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
281
282 /**
283 * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
284 * @regs: Pointer to RTC register block
285 * @index: The index of alarm to set
286 * @val: The value to set
287 */
288 void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
289 uint32_t val);
290
291 /**
292 * fman_rtc_set_timer_alarm() - Set timer alarm
293 * @regs: Pointer to RTC register block
294 * @index: The index of alarm to set
295 * @val: The value to set
296 */
297 void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
298
299 /**
300 * fman_rtc_set_timer_fiper() - Set timer fiper
301 * @regs: Pointer to RTC register block
302 * @index: The index of fiper to set
303 * @val: The value to set
304 */
305 void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
306
307 /**
308 * fman_rtc_set_timer_offset() - Set timer offset
309 * @regs: Pointer to RTC register block
310 * @val: The value to set
311 */
312 void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
313
314 /**
315 * fman_rtc_get_timer() - Get the timer counter
316 * @regs: Pointer to RTC register block
317 *
318 * Returns: The timer counter
319 */
fman_rtc_get_timer(struct rtc_regs * regs)320 static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
321 {
322 uint64_t time;
323 /* TMR_CNT_L must be read first to get an accurate value */
324 time = (uint64_t)ioread32be(®s->tmr_cnt_l);
325 time |= ((uint64_t)ioread32be(®s->tmr_cnt_h) << 32);
326
327 return time;
328 }
329
330 /**
331 * fman_rtc_set_timer() - Set timer counter
332 * @regs: Pointer to RTC register block
333 * @val: The value to set
334 */
fman_rtc_set_timer(struct rtc_regs * regs,int64_t val)335 static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
336 {
337 iowrite32be((uint32_t)val, ®s->tmr_cnt_l);
338 iowrite32be((uint32_t)(val >> 32), ®s->tmr_cnt_h);
339 }
340
341 /**
342 * fman_rtc_timers_soft_reset() - Soft reset
343 * @regs: Pointer to RTC register block
344 *
345 * Resets all the timer registers and state machines for the 1588 IP and
346 * the attached client 1588
347 */
348 void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
349
350 /**
351 * fman_rtc_clear_external_trigger() - Clear an external trigger
352 * @regs: Pointer to RTC register block
353 * @id: The id of the trigger to clear
354 */
355 void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
356
357 /**
358 * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
359 * @regs: Pointer to RTC register block
360 * @id: The id of the fiper to clear
361 */
362 void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
363
364 /**
365 * fman_rtc_enable() - Enable RTC hardware block
366 * @regs: Pointer to RTC register block
367 */
368 void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
369
370 /**
371 * fman_rtc_is_enabled() - Is RTC hardware block enabled
372 * @regs: Pointer to RTC register block
373 *
374 * Return: TRUE if enabled
375 */
376 bool fman_rtc_is_enabled(struct rtc_regs *regs);
377
378 /**
379 * fman_rtc_disable() - Disable RTC hardware block
380 * @regs: Pointer to RTC register block
381 */
382 void fman_rtc_disable(struct rtc_regs *regs);
383
384 /**
385 * fman_rtc_init() - Init RTC hardware block
386 * @cfg: RTC configuration data
387 * @regs: Pointer to RTC register block
388 * @num_alarms: Number of alarms in RTC
389 * @num_fipers: Number of fipers in RTC
390 * @num_ext_triggers: Number of external triggers in RTC
391 * @freq_compensation: Frequency compensation
392 * @output_clock_divisor: Output clock divisor
393 *
394 * This function initializes RTC and applies basic configuration.
395 */
396 void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
397 int num_fipers, int num_ext_triggers, bool init_freq_comp,
398 uint32_t freq_compensation, uint32_t output_clock_divisor);
399
400 /**
401 * fman_rtc_set_alarm() - Set an alarm
402 * @regs: Pointer to RTC register block
403 * @id: id of alarm
404 * @val: value to write
405 * @enable: should interrupt be enabled
406 */
407 void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
408
409 /**
410 * fman_rtc_set_periodic_pulse() - Set an alarm
411 * @regs: Pointer to RTC register block
412 * @id: id of fiper
413 * @val: value to write
414 * @enable: should interrupt be enabled
415 */
416 void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
417 bool enable);
418
419 /**
420 * fman_rtc_set_ext_trigger() - Set an external trigger
421 * @regs: Pointer to RTC register block
422 * @id: id of trigger
423 * @enable: should interrupt be enabled
424 * @use_pulse_as_input: use the pulse as input
425 */
426 void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
427 bool use_pulse_as_input);
428
429 struct fm_rtc_alarm_params {
430 uint8_t alarm_id; /**< 0 or 1 */
431 uint64_t alarm_time; /**< In nanoseconds, the time when the
432 alarm should go off - must be a
433 multiple of the RTC period */
434 void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
435 be called when RTC reaches alarmTime */
436 bool clear_on_expiration; /**< TRUE to turn off the alarm once
437 expired.*/
438 };
439
440 struct fm_rtc_periodic_pulse_params {
441 uint8_t periodic_pulse_id; /**< 0 or 1 */
442 uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
443 of the RTC period */
444 void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
445 routine will be called every
446 periodicPulsePeriod. */
447 };
448
449 #endif /* __FSL_FMAN_RTC_H */
450