xref: /freebsd/sys/contrib/ncsw/inc/flib/fsl_fman_rtc.h (revision a8089ea5aee578e08acab2438e82fc9a9ae50ed8)
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  */
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(&regs->tmr_cnt_l);
325     time |= ((uint64_t)ioread32be(&regs->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  */
335 static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
336 {
337 	iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
338 	iowrite32be((uint32_t)(val >> 32), &regs->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