From: Madalin Bucur <madalin.bu...@freescale.com> --- drivers/soc/fsl/fman/flib/fsl_fman_rtc.h | 414 ++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 drivers/soc/fsl/fman/flib/fsl_fman_rtc.h
diff --git a/drivers/soc/fsl/fman/flib/fsl_fman_rtc.h b/drivers/soc/fsl/fman/flib/fsl_fman_rtc.h new file mode 100644 index 0000000..a084b11 --- /dev/null +++ b/drivers/soc/fsl/fman/flib/fsl_fman_rtc.h @@ -0,0 +1,414 @@ +/* + * Copyright 2008 - 2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_FMAN_RTC_H +#define __FSL_FMAN_RTC_H + +#include "common/general.h" + +/* FM RTC Registers definitions */ +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16 + +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\ + FMAN_RTC_TMR_TEVENT_ETS1 |\ + FMAN_RTC_TMR_TEVENT_ALM2 |\ + FMAN_RTC_TMR_TEVENT_ALM1 |\ + FMAN_RTC_TMR_TEVENT_PP1 |\ + FMAN_RTC_TMR_TEVENT_PP2 |\ + FMAN_RTC_TMR_TEVENT_PP3) + +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF + +/* FM RTC Alarm Polarity Options. */ +enum fman_rtc_alarm_polarity { + FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, + /* Active-high output polarity */ + FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW/* Active-low output polarity */ +}; + +/* FM RTC Trigger Polarity Options. */ +enum fman_rtc_trigger_polarity { + FMAN_RTC_TRIGGER_ON_RISING_EDGE,/* Trigger on rising edge */ + FMAN_RTC_TRIGGER_ON_FALLING_EDGE/* Trigger on falling edge */ +}; + +/* IEEE1588 Timer Module FM RTC Optional Clock Sources. */ +enum fman_src_clock { + FMAN_RTC_SOURCE_CLOCK_EXTERNAL, + /* external high precision timer + * reference clock + */ + FMAN_RTC_SOURCE_CLOCK_SYSTEM,/* MAC system clock */ + FMAN_RTC_SOURCE_CLOCK_OSCILATOR + /* RTC clock oscilator */ +}; + +/* RTC default values */ +#define DEFAULT_SRC_CLOCK FMAN_RTC_SOURCE_CLOCK_SYSTEM +#define DEFAULT_INVERT_INPUT_CLK_PHASE false +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE false +#define DEFAULT_ALARM_POLARITY FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH +#define DEFAULT_TRIGGER_POLARITY FMAN_RTC_TRIGGER_ON_FALLING_EDGE +#define DEFAULT_PULSE_REALIGN false + +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3 + +/* FM RTC timer alarm */ +struct tmr_alarm_t { + uint32_t tmr_alarm_h; /* */ + uint32_t tmr_alarm_l; /* */ +}; + +/* FM RTC timer Ex trigger */ +struct tmr_ext_trigger_t { + uint32_t tmr_etts_h; /* */ + uint32_t tmr_etts_l; /* */ +}; + +struct rtc_regs { + uint32_t tmr_id; /* 0x000 Module ID register */ + uint32_t tmr_id2; /* 0x004 Controller ID register */ + uint32_t reserved0008[30]; + uint32_t tmr_ctrl; /* 0x0080 timer control register */ + uint32_t tmr_tevent; /* 0x0084 timer event register */ + uint32_t tmr_temask; /* 0x0088 timer event mask register */ + uint32_t reserved008c[3]; + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */ + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */ + /* 0x00a0 timer drift compensation addend register */ + uint32_t tmr_add; + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */ + uint32_t tmr_prsc; /* 0x00a8 timer prescale */ + uint32_t reserved00ac; + uint32_t tmr_off_h; /* 0x00b0 timer offset high */ + uint32_t tmr_off_l; /* 0x00b4 timer offset low */ + /* 0x00b8 timer alarm */ + struct tmr_alarm_t tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; + /* 0x00d0 timer fixed period interval */ + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; + struct tmr_ext_trigger_t tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; + /* 0x00e0 time stamp general purpose external */ + uint32_t reserved00f0[4]; +}; + +struct rtc_cfg { + enum fman_src_clock src_clk; + uint32_t ext_src_clk_freq; + uint32_t rtc_freq_hz; + bool timer_slave_mode; + bool invert_input_clk_phase; + bool invert_output_clk_phase; + uint32_t events_mask; + bool bypass; /* Indicates if frequency compensation + * is bypassed + */ + bool pulse_realign; + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS]; + enum fman_rtc_trigger_polarity trigger_polarity + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; +}; + +/* fman_rtc_defconfig() - Get default RTC configuration + * cfg: pointer to configuration structure. + * Call this function to obtain a default set of configuration values for + * initializing RTC. The user can overwrite any of the values before calling + * fman_rtc_init(), if specific configuration needs to be applied. + */ +void fman_rtc_defconfig(struct rtc_cfg *cfg); + +/* fman_rtc_get_events() - Get the events + * regs: Pointer to RTC register block + * Returns: The events + */ +uint32_t fman_rtc_get_events(struct rtc_regs __iomem *regs); + +/* fman_rtc_get_interrupt_mask() - Get the events mask + * regs: Pointer to RTC register block + * Returns: The events mask + */ +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs __iomem *regs); + +/* fman_rtc_set_interrupt_mask() - Set the events mask + * regs: Pointer to RTC register block + * mask: The mask to set + */ +void fman_rtc_set_interrupt_mask(struct rtc_regs __iomem *regs, uint32_t mask); + +/* fman_rtc_get_event() - Check if specific events occurred + * regs: Pointer to RTC register block + * ev_mask: a mask of the events to check + * Returns: 0 if the events did not occur. + * Non zero if one of the events occurred + */ +uint32_t fman_rtc_get_event(struct rtc_regs __iomem *regs, uint32_t ev_mask); + +/* fman_rtc_check_and_clear_event() - Clear events which are on + * regs: Pointer to RTC register block + * Returns: A mask of the events which were cleared + */ +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs __iomem *regs); + +/* fman_rtc_ack_event() - Clear events + * regs: Pointer to RTC register block + * events: The events to disable + */ +void fman_rtc_ack_event(struct rtc_regs __iomem *regs, uint32_t events); + +/* fman_rtc_enable_interrupt() - Enable events interrupts + * regs: Pointer to RTC register block + * mask: The events to disable + */ +void fman_rtc_enable_interrupt(struct rtc_regs __iomem *regs, uint32_t mask); + +/* fman_rtc_disable_interrupt() - Disable events interrupts + * regs: Pointer to RTC register block + * mask: The events to disable + */ +void fman_rtc_disable_interrupt(struct rtc_regs __iomem *regs, uint32_t mask); + +/* fman_rtc_get_timer_ctrl() - Get the control register + * regs: Pointer to RTC register block + * Returns: The control register value + */ +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs __iomem *regs); + +/* fman_rtc_set_timer_ctrl() - Set timer control register + * regs: Pointer to RTC register block + * val: The value to set + */ +void fman_rtc_set_timer_ctrl(struct rtc_regs __iomem *regs, uint32_t val); + +/* fman_rtc_get_frequency_compensation() - Get the frequency compensation + * regs: Pointer to RTC register block + * + * Returns: The timer counter + */ +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs __iomem *regs); + +/* fman_rtc_set_frequency_compensation() - Set frequency compensation + * regs: Pointer to RTC register block + * val: The value to set + */ +void fman_rtc_set_frequency_compensation(struct rtc_regs __iomem *regs, + uint32_t val); + +/* fman_rtc_get_trigger_stamp() - Get a trigger stamp + * regs: Pointer to RTC register block + * id: The id of the trigger stamp + * + * Returns: The time stamp + */ +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs __iomem *regs, int id); + +/* fman_rtc_set_timer_alarm_l() - Set timer alarm low register + * regs: Pointer to RTC register block + * index: The index of alarm to set + * val: The value to set + */ +void fman_rtc_set_timer_alarm_l(struct rtc_regs __iomem *regs, int index, + uint32_t val); + +/* fman_rtc_set_timer_alarm() - Set timer alarm + * regs: Pointer to RTC register block + * index: The index of alarm to set + * val: The value to set + */ +void fman_rtc_set_timer_alarm(struct rtc_regs __iomem *regs, int index, + int64_t val); + +/* fman_rtc_set_timer_fiper() - Set timer fiper + * regs: Pointer to RTC register block + * index: The index of fiper to set + * val: The value to set + */ +void fman_rtc_set_timer_fiper(struct rtc_regs __iomem *regs, int index, + uint32_t val); + +/* fman_rtc_set_timer_offset() - Set timer offset + * regs: Pointer to RTC register block + * val: The value to set + */ +void fman_rtc_set_timer_offset(struct rtc_regs __iomem *regs, int64_t val); + +/* fman_rtc_get_timer() - Get the timer counter + * regs: Pointer to RTC register block + * Returns: The timer counter + */ +static inline uint64_t fman_rtc_get_timer(struct rtc_regs __iomem *regs) +{ + uint64_t time; + /* TMR_CNT_L must be read first to get an accurate value */ + time = (uint64_t)ioread32be(®s->tmr_cnt_l); + time |= ((uint64_t)ioread32be(®s->tmr_cnt_h) << 32); + + return time; +} + +/* fman_rtc_set_timer() - Set timer counter + * regs: Pointer to RTC register block + * val: The value to set + */ +static inline void fman_rtc_set_timer(struct rtc_regs __iomem *regs, + int64_t val) +{ + iowrite32be((uint32_t)val, ®s->tmr_cnt_l); + iowrite32be((uint32_t)(val >> 32), ®s->tmr_cnt_h); +} + +/* fman_rtc_timers_soft_reset() - Soft reset + * regs: Pointer to RTC register block + * Resets all the timer registers and state machines for the 1588 IP and + * the attached client 1588 + */ +void fman_rtc_timers_soft_reset(struct rtc_regs __iomem *regs); + +/* fman_rtc_clear_external_trigger() - Clear an external trigger + * regs: Pointer to RTC register block + * id: The id of the trigger to clear + */ +void fman_rtc_clear_external_trigger(struct rtc_regs __iomem *regs, int id); + +/* fman_rtc_clear_periodic_pulse() - Clear periodic pulse + * regs: Pointer to RTC register block + * id: The id of the fiper to clear + */ +void fman_rtc_clear_periodic_pulse(struct rtc_regs __iomem *regs, int id); + +/* fman_rtc_enable() - Enable RTC hardware block + * regs: Pointer to RTC register block + */ +void fman_rtc_enable(struct rtc_regs __iomem *regs, bool reset_clock); + +/* fman_rtc_is_enabled() - Is RTC hardware block enabled + * regs: Pointer to RTC register block + * Return: true if enabled + */ +bool fman_rtc_is_enabled(struct rtc_regs __iomem *regs); + +/* fman_rtc_disable() - Disable RTC hardware block + * regs: Pointer to RTC register block + */ +void fman_rtc_disable(struct rtc_regs __iomem *regs); + +/* fman_rtc_init() - Init RTC hardware block + * cfg: RTC configuration data + * regs: Pointer to RTC register block + * num_alarms: Number of alarms in RTC + * num_fipers: Number of fipers in RTC + * num_ext_triggers: Number of external triggers in RTC + * freq_compensation: Frequency compensation + * output_clock_divisor: Output clock divisor + * This function initializes RTC and applies basic configuration. + */ +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs __iomem *regs, + int num_alarms, int num_fipers, int num_ext_triggers, + bool init_freq_comp, uint32_t freq_compensation, + uint32_t output_clock_divisor); + +/* fman_rtc_set_alarm() - Set an alarm + * regs: Pointer to RTC register block + * id: id of alarm + * val: value to write + * enable: should interrupt be enabled + */ +void fman_rtc_set_alarm(struct rtc_regs __iomem *regs, int id, uint32_t val, + bool enable); + +/* fman_rtc_set_periodic_pulse() - Set an alarm + * regs: Pointer to RTC register block + * id: id of fiper + * val: value to write + * enable: should interrupt be enabled + */ +void fman_rtc_set_periodic_pulse(struct rtc_regs __iomem *regs, int id, + uint32_t val, bool enable); + +/* fman_rtc_set_ext_trigger() - Set an external trigger + * regs: Pointer to RTC register block + * id: id of trigger + * enable: should interrupt be enabled + * use_pulse_as_input: use the pulse as input + */ +void fman_rtc_set_ext_trigger(struct rtc_regs __iomem *regs, int id, + bool enable, bool use_pulse_as_input); + +struct fm_rtc_alarm_params { + uint8_t alarm_id; /* 0 or 1 */ + uint64_t alarm_time; /* In nanoseconds, the time when the + * alarm should go off - must be a + * multiple of the RTC period + */ + void (*f_alarm_callback)(void *app, uint8_t id);/* This routine will + * be called when RTC + * reaches alarm_time + */ + bool clear_on_expiration; /* true to turn off the alarm once + * expired. + */ +}; + +struct fm_rtc_periodic_pulse_params { + uint8_t periodic_pulse_id; /* 0 or 1 */ + uint64_t periodic_pulse_period; /* In Nanoseconds. Must be a multiple + * of the RTC period + */ + /* This routine will be called every periodic_pulse_period. */ + void (*f_periodic_pulse_callback)(void *app, uint8_t id); +}; + +#endif /* __FSL_FMAN_RTC_H */ -- 1.7.9.5 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev