Path: blob/main/sys/contrib/ncsw/inc/flib/fsl_fman_rtc.h
48375 views
/*1* Copyright 2013 Freescale Semiconductor Inc.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10* * Neither the name of Freescale Semiconductor nor the11* names of its contributors may be used to endorse or promote products12* derived from this software without specific prior written permission.13*14*15* ALTERNATIVELY, this software may be distributed under the terms of the16* GNU General Public License ("GPL") as published by the Free Software17* Foundation, either version 2 of that License or (at your option) any18* later version.19*20* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY21* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY24* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;26* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND27* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132#ifndef __FSL_FMAN_RTC_H33#define __FSL_FMAN_RTC_H3435#include "common/general.h"3637/* FM RTC Registers definitions */38#define FMAN_RTC_TMR_CTRL_ALMP1 0x8000000039#define FMAN_RTC_TMR_CTRL_ALMP2 0x4000000040#define FMAN_RTC_TMR_CTRL_FS 0x1000000041#define FMAN_RTC_TMR_CTRL_PP1L 0x0800000042#define FMAN_RTC_TMR_CTRL_PP2L 0x0400000043#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF000044#define FMAN_RTC_TMR_CTRL_FRD 0x0000400045#define FMAN_RTC_TMR_CTRL_SLV 0x0000200046#define FMAN_RTC_TMR_CTRL_ETEP1 0x0000010047#define FMAN_RTC_TMR_CTRL_COPH 0x0000008048#define FMAN_RTC_TMR_CTRL_CIPH 0x0000004049#define FMAN_RTC_TMR_CTRL_TMSR 0x0000002050#define FMAN_RTC_TMR_CTRL_DBG 0x0000001051#define FMAN_RTC_TMR_CTRL_BYP 0x0000000852#define FMAN_RTC_TMR_CTRL_TE 0x0000000453#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x0000000354#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x0000000155#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x0000000056#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 165758#define FMAN_RTC_TMR_TEVENT_ETS2 0x0200000059#define FMAN_RTC_TMR_TEVENT_ETS1 0x0100000060#define FMAN_RTC_TMR_TEVENT_ALM2 0x0002000061#define FMAN_RTC_TMR_TEVENT_ALM1 0x0001000062#define FMAN_RTC_TMR_TEVENT_PP1 0x0000008063#define FMAN_RTC_TMR_TEVENT_PP2 0x0000004064#define FMAN_RTC_TMR_TEVENT_PP3 0x0000002065#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\66FMAN_RTC_TMR_TEVENT_ETS1 |\67FMAN_RTC_TMR_TEVENT_ALM2 |\68FMAN_RTC_TMR_TEVENT_ALM1 |\69FMAN_RTC_TMR_TEVENT_PP1 |\70FMAN_RTC_TMR_TEVENT_PP2 |\71FMAN_RTC_TMR_TEVENT_PP3)7273#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF7475/**************************************************************************//**76@Description FM RTC Alarm Polarity Options.77*//***************************************************************************/78enum fman_rtc_alarm_polarity {79E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */80E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */81};8283/**************************************************************************//**84@Description FM RTC Trigger Polarity Options.85*//***************************************************************************/86enum fman_rtc_trigger_polarity {87E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */88E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */89};9091/**************************************************************************//**92@Description IEEE1588 Timer Module FM RTC Optional Clock Sources.93*//***************************************************************************/94enum fman_src_clock {95E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer96reference clock */97E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */98E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */99};100101/* RTC default values */102#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM103#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE104#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE105#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH106#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE107#define DEFAULT_PULSE_REALIGN FALSE108109#define FMAN_RTC_MAX_NUM_OF_ALARMS 3110#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4111#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3112113/**************************************************************************//**114@Description FM RTC timer alarm115*//***************************************************************************/116struct t_tmr_alarm{117uint32_t tmr_alarm_h; /**< */118uint32_t tmr_alarm_l; /**< */119};120121/**************************************************************************//**122@Description FM RTC timer Ex trigger123*//***************************************************************************/124struct t_tmr_ext_trigger{125uint32_t tmr_etts_h; /**< */126uint32_t tmr_etts_l; /**< */127};128129struct rtc_regs {130uint32_t tmr_id; /* 0x000 Module ID register */131uint32_t tmr_id2; /* 0x004 Controller ID register */132uint32_t reserved0008[30];133uint32_t tmr_ctrl; /* 0x0080 timer control register */134uint32_t tmr_tevent; /* 0x0084 timer event register */135uint32_t tmr_temask; /* 0x0088 timer event mask register */136uint32_t reserved008c[3];137uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */138uint32_t tmr_cnt_l; /* 0x009c timer counter low register */139uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */140uint32_t tmr_acc; /* 0x00a4 timer accumulator register */141uint32_t tmr_prsc; /* 0x00a8 timer prescale */142uint32_t reserved00ac;143uint32_t tmr_off_h; /* 0x00b0 timer offset high */144uint32_t tmr_off_l; /* 0x00b4 timer offset low */145struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer146alarm */147uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer148fixed period interval */149struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];150/* 0x00e0 time stamp general purpose external */151uint32_t reserved00f0[4];152};153154struct rtc_cfg {155enum fman_src_clock src_clk;156uint32_t ext_src_clk_freq;157uint32_t rtc_freq_hz;158bool timer_slave_mode;159bool invert_input_clk_phase;160bool invert_output_clk_phase;161uint32_t events_mask;162bool bypass; /**< Indicates if frequency compensation163is bypassed */164bool pulse_realign;165enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];166enum fman_rtc_trigger_polarity trigger_polarity167[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];168};169170/**171* fman_rtc_defconfig() - Get default RTC configuration172* @cfg: pointer to configuration structure.173*174* Call this function to obtain a default set of configuration values for175* initializing RTC. The user can overwrite any of the values before calling176* fman_rtc_init(), if specific configuration needs to be applied.177*/178void fman_rtc_defconfig(struct rtc_cfg *cfg);179180/**181* fman_rtc_get_events() - Get the events182* @regs: Pointer to RTC register block183*184* Returns: The events185*/186uint32_t fman_rtc_get_events(struct rtc_regs *regs);187188/**189* fman_rtc_get_interrupt_mask() - Get the events mask190* @regs: Pointer to RTC register block191*192* Returns: The events mask193*/194uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);195196197/**198* fman_rtc_set_interrupt_mask() - Set the events mask199* @regs: Pointer to RTC register block200* @mask: The mask to set201*/202void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);203204/**205* fman_rtc_get_event() - Check if specific events occurred206* @regs: Pointer to RTC register block207* @ev_mask: a mask of the events to check208*209* Returns: 0 if the events did not occur. Non zero if one of the events occurred210*/211uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);212213/**214* fman_rtc_check_and_clear_event() - Clear events which are on215* @regs: Pointer to RTC register block216*217* Returns: A mask of the events which were cleared218*/219uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);220221/**222* fman_rtc_ack_event() - Clear events223* @regs: Pointer to RTC register block224* @events: The events to disable225*/226void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);227228/**229* fman_rtc_enable_interupt() - Enable events interrupts230* @regs: Pointer to RTC register block231* @mask: The events to disable232*/233void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);234235/**236* fman_rtc_disable_interupt() - Disable events interrupts237* @regs: Pointer to RTC register block238* @mask: The events to disable239*/240void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);241242/**243* fman_rtc_get_timer_ctrl() - Get the control register244* @regs: Pointer to RTC register block245*246* Returns: The control register value247*/248uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);249250/**251* fman_rtc_set_timer_ctrl() - Set timer control register252* @regs: Pointer to RTC register block253* @val: The value to set254*/255void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);256257/**258* fman_rtc_get_frequency_compensation() - Get the frequency compensation259* @regs: Pointer to RTC register block260*261* Returns: The timer counter262*/263uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);264265/**266* fman_rtc_set_frequency_compensation() - Set frequency compensation267* @regs: Pointer to RTC register block268* @val: The value to set269*/270void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);271272/**273* fman_rtc_get_trigger_stamp() - Get a trigger stamp274* @regs: Pointer to RTC register block275* @id: The id of the trigger stamp276*277* Returns: The time stamp278*/279uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);280281/**282* fman_rtc_set_timer_alarm_l() - Set timer alarm low register283* @regs: Pointer to RTC register block284* @index: The index of alarm to set285* @val: The value to set286*/287void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,288uint32_t val);289290/**291* fman_rtc_set_timer_alarm() - Set timer alarm292* @regs: Pointer to RTC register block293* @index: The index of alarm to set294* @val: The value to set295*/296void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);297298/**299* fman_rtc_set_timer_fiper() - Set timer fiper300* @regs: Pointer to RTC register block301* @index: The index of fiper to set302* @val: The value to set303*/304void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);305306/**307* fman_rtc_set_timer_offset() - Set timer offset308* @regs: Pointer to RTC register block309* @val: The value to set310*/311void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);312313/**314* fman_rtc_get_timer() - Get the timer counter315* @regs: Pointer to RTC register block316*317* Returns: The timer counter318*/319static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)320{321uint64_t time;322/* TMR_CNT_L must be read first to get an accurate value */323time = (uint64_t)ioread32be(®s->tmr_cnt_l);324time |= ((uint64_t)ioread32be(®s->tmr_cnt_h) << 32);325326return time;327}328329/**330* fman_rtc_set_timer() - Set timer counter331* @regs: Pointer to RTC register block332* @val: The value to set333*/334static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)335{336iowrite32be((uint32_t)val, ®s->tmr_cnt_l);337iowrite32be((uint32_t)(val >> 32), ®s->tmr_cnt_h);338}339340/**341* fman_rtc_timers_soft_reset() - Soft reset342* @regs: Pointer to RTC register block343*344* Resets all the timer registers and state machines for the 1588 IP and345* the attached client 1588346*/347void fman_rtc_timers_soft_reset(struct rtc_regs *regs);348349/**350* fman_rtc_clear_external_trigger() - Clear an external trigger351* @regs: Pointer to RTC register block352* @id: The id of the trigger to clear353*/354void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);355356/**357* fman_rtc_clear_periodic_pulse() - Clear periodic pulse358* @regs: Pointer to RTC register block359* @id: The id of the fiper to clear360*/361void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);362363/**364* fman_rtc_enable() - Enable RTC hardware block365* @regs: Pointer to RTC register block366*/367void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);368369/**370* fman_rtc_is_enabled() - Is RTC hardware block enabled371* @regs: Pointer to RTC register block372*373* Return: TRUE if enabled374*/375bool fman_rtc_is_enabled(struct rtc_regs *regs);376377/**378* fman_rtc_disable() - Disable RTC hardware block379* @regs: Pointer to RTC register block380*/381void fman_rtc_disable(struct rtc_regs *regs);382383/**384* fman_rtc_init() - Init RTC hardware block385* @cfg: RTC configuration data386* @regs: Pointer to RTC register block387* @num_alarms: Number of alarms in RTC388* @num_fipers: Number of fipers in RTC389* @num_ext_triggers: Number of external triggers in RTC390* @freq_compensation: Frequency compensation391* @output_clock_divisor: Output clock divisor392*393* This function initializes RTC and applies basic configuration.394*/395void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,396int num_fipers, int num_ext_triggers, bool init_freq_comp,397uint32_t freq_compensation, uint32_t output_clock_divisor);398399/**400* fman_rtc_set_alarm() - Set an alarm401* @regs: Pointer to RTC register block402* @id: id of alarm403* @val: value to write404* @enable: should interrupt be enabled405*/406void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);407408/**409* fman_rtc_set_periodic_pulse() - Set an alarm410* @regs: Pointer to RTC register block411* @id: id of fiper412* @val: value to write413* @enable: should interrupt be enabled414*/415void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,416bool enable);417418/**419* fman_rtc_set_ext_trigger() - Set an external trigger420* @regs: Pointer to RTC register block421* @id: id of trigger422* @enable: should interrupt be enabled423* @use_pulse_as_input: use the pulse as input424*/425void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,426bool use_pulse_as_input);427428struct fm_rtc_alarm_params {429uint8_t alarm_id; /**< 0 or 1 */430uint64_t alarm_time; /**< In nanoseconds, the time when the431alarm should go off - must be a432multiple of the RTC period */433void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will434be called when RTC reaches alarmTime */435bool clear_on_expiration; /**< TRUE to turn off the alarm once436expired.*/437};438439struct fm_rtc_periodic_pulse_params {440uint8_t periodic_pulse_id; /**< 0 or 1 */441uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple442of the RTC period */443void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This444routine will be called every445periodicPulsePeriod. */446};447448#endif /* __FSL_FMAN_RTC_H */449450451