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(®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 */ 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