xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c (revision c2c014f24c10f90d85126ac5fbd4d8524de32b1c)
1*852ba100SJustin Hibbits /*
2*852ba100SJustin Hibbits  * Copyright 2008-2012 Freescale Semiconductor Inc.
30aeed3e9SJustin Hibbits  *
40aeed3e9SJustin Hibbits  * Redistribution and use in source and binary forms, with or without
50aeed3e9SJustin Hibbits  * modification, are permitted provided that the following conditions are met:
60aeed3e9SJustin Hibbits  *     * Redistributions of source code must retain the above copyright
70aeed3e9SJustin Hibbits  *       notice, this list of conditions and the following disclaimer.
80aeed3e9SJustin Hibbits  *     * Redistributions in binary form must reproduce the above copyright
90aeed3e9SJustin Hibbits  *       notice, this list of conditions and the following disclaimer in the
100aeed3e9SJustin Hibbits  *       documentation and/or other materials provided with the distribution.
110aeed3e9SJustin Hibbits  *     * Neither the name of Freescale Semiconductor nor the
120aeed3e9SJustin Hibbits  *       names of its contributors may be used to endorse or promote products
130aeed3e9SJustin Hibbits  *       derived from this software without specific prior written permission.
140aeed3e9SJustin Hibbits  *
150aeed3e9SJustin Hibbits  *
160aeed3e9SJustin Hibbits  * ALTERNATIVELY, this software may be distributed under the terms of the
170aeed3e9SJustin Hibbits  * GNU General Public License ("GPL") as published by the Free Software
180aeed3e9SJustin Hibbits  * Foundation, either version 2 of that License or (at your option) any
190aeed3e9SJustin Hibbits  * later version.
200aeed3e9SJustin Hibbits  *
210aeed3e9SJustin Hibbits  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
220aeed3e9SJustin Hibbits  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
230aeed3e9SJustin Hibbits  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
240aeed3e9SJustin Hibbits  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
250aeed3e9SJustin Hibbits  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
260aeed3e9SJustin Hibbits  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
270aeed3e9SJustin Hibbits  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
280aeed3e9SJustin Hibbits  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
290aeed3e9SJustin Hibbits  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
300aeed3e9SJustin Hibbits  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
310aeed3e9SJustin Hibbits  */
320aeed3e9SJustin Hibbits 
33*852ba100SJustin Hibbits 
340aeed3e9SJustin Hibbits /******************************************************************************
350aeed3e9SJustin Hibbits  @File          fm_rtc.c
360aeed3e9SJustin Hibbits 
370aeed3e9SJustin Hibbits  @Description   FM RTC driver implementation.
380aeed3e9SJustin Hibbits 
390aeed3e9SJustin Hibbits  @Cautions      None
400aeed3e9SJustin Hibbits *//***************************************************************************/
41*852ba100SJustin Hibbits #include <linux/math64.h>
420aeed3e9SJustin Hibbits #include "error_ext.h"
430aeed3e9SJustin Hibbits #include "debug_ext.h"
440aeed3e9SJustin Hibbits #include "string_ext.h"
450aeed3e9SJustin Hibbits #include "part_ext.h"
460aeed3e9SJustin Hibbits #include "xx_ext.h"
470aeed3e9SJustin Hibbits #include "ncsw_ext.h"
480aeed3e9SJustin Hibbits 
490aeed3e9SJustin Hibbits #include "fm_rtc.h"
500aeed3e9SJustin Hibbits #include "fm_common.h"
510aeed3e9SJustin Hibbits 
520aeed3e9SJustin Hibbits 
530aeed3e9SJustin Hibbits 
540aeed3e9SJustin Hibbits /*****************************************************************************/
CheckInitParameters(t_FmRtc * p_Rtc)550aeed3e9SJustin Hibbits static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
560aeed3e9SJustin Hibbits {
57*852ba100SJustin Hibbits     struct rtc_cfg  *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
580aeed3e9SJustin Hibbits     int                 i;
590aeed3e9SJustin Hibbits 
60*852ba100SJustin Hibbits     if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
61*852ba100SJustin Hibbits         (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62*852ba100SJustin Hibbits         (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
630aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
640aeed3e9SJustin Hibbits 
650aeed3e9SJustin Hibbits     if (p_Rtc->outputClockDivisor == 0)
660aeed3e9SJustin Hibbits     {
670aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE,
680aeed3e9SJustin Hibbits                      ("Divisor for output clock (should be positive)"));
690aeed3e9SJustin Hibbits     }
700aeed3e9SJustin Hibbits 
710aeed3e9SJustin Hibbits     for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
720aeed3e9SJustin Hibbits     {
73*852ba100SJustin Hibbits         if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
74*852ba100SJustin Hibbits             (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
750aeed3e9SJustin Hibbits         {
760aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
770aeed3e9SJustin Hibbits         }
780aeed3e9SJustin Hibbits     }
790aeed3e9SJustin Hibbits     for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
800aeed3e9SJustin Hibbits     {
81*852ba100SJustin Hibbits         if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
82*852ba100SJustin Hibbits             (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
830aeed3e9SJustin Hibbits         {
840aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
850aeed3e9SJustin Hibbits         }
860aeed3e9SJustin Hibbits     }
870aeed3e9SJustin Hibbits 
880aeed3e9SJustin Hibbits     return E_OK;
890aeed3e9SJustin Hibbits }
900aeed3e9SJustin Hibbits 
910aeed3e9SJustin Hibbits /*****************************************************************************/
RtcExceptions(t_Handle h_FmRtc)920aeed3e9SJustin Hibbits static void RtcExceptions(t_Handle h_FmRtc)
930aeed3e9SJustin Hibbits {
940aeed3e9SJustin Hibbits     t_FmRtc             *p_Rtc = (t_FmRtc *)h_FmRtc;
95*852ba100SJustin Hibbits     struct rtc_regs     *p_MemMap;
960aeed3e9SJustin Hibbits     register uint32_t   events;
970aeed3e9SJustin Hibbits 
980aeed3e9SJustin Hibbits     ASSERT_COND(p_Rtc);
990aeed3e9SJustin Hibbits     p_MemMap = p_Rtc->p_MemMap;
1000aeed3e9SJustin Hibbits 
101*852ba100SJustin Hibbits     events = fman_rtc_check_and_clear_event(p_MemMap);
102*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_ALM1)
1030aeed3e9SJustin Hibbits     {
1040aeed3e9SJustin Hibbits         if (p_Rtc->alarmParams[0].clearOnExpiration)
1050aeed3e9SJustin Hibbits         {
106*852ba100SJustin Hibbits             fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
107*852ba100SJustin Hibbits             fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
1080aeed3e9SJustin Hibbits         }
1090aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
1100aeed3e9SJustin Hibbits         p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
1110aeed3e9SJustin Hibbits     }
112*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_ALM2)
1130aeed3e9SJustin Hibbits     {
1140aeed3e9SJustin Hibbits         if (p_Rtc->alarmParams[1].clearOnExpiration)
1150aeed3e9SJustin Hibbits         {
116*852ba100SJustin Hibbits             fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
117*852ba100SJustin Hibbits             fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
1180aeed3e9SJustin Hibbits         }
1190aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
1200aeed3e9SJustin Hibbits         p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
1210aeed3e9SJustin Hibbits     }
122*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_PP1)
1230aeed3e9SJustin Hibbits     {
1240aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
1250aeed3e9SJustin Hibbits         p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
1260aeed3e9SJustin Hibbits     }
127*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_PP2)
1280aeed3e9SJustin Hibbits     {
1290aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
1300aeed3e9SJustin Hibbits         p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
1310aeed3e9SJustin Hibbits     }
132*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_ETS1)
1330aeed3e9SJustin Hibbits     {
1340aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
1350aeed3e9SJustin Hibbits         p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
1360aeed3e9SJustin Hibbits     }
137*852ba100SJustin Hibbits     if (events & FMAN_RTC_TMR_TEVENT_ETS2)
1380aeed3e9SJustin Hibbits     {
1390aeed3e9SJustin Hibbits         ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
1400aeed3e9SJustin Hibbits         p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
1410aeed3e9SJustin Hibbits     }
1420aeed3e9SJustin Hibbits }
1430aeed3e9SJustin Hibbits 
1440aeed3e9SJustin Hibbits 
1450aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_Config(t_FmRtcParams * p_FmRtcParam)1460aeed3e9SJustin Hibbits t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
1470aeed3e9SJustin Hibbits {
1480aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc;
1490aeed3e9SJustin Hibbits 
1500aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
1510aeed3e9SJustin Hibbits 
1520aeed3e9SJustin Hibbits     /* Allocate memory for the FM RTC driver parameters */
1530aeed3e9SJustin Hibbits     p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
1540aeed3e9SJustin Hibbits     if (!p_Rtc)
1550aeed3e9SJustin Hibbits     {
1560aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
1570aeed3e9SJustin Hibbits         return NULL;
1580aeed3e9SJustin Hibbits     }
1590aeed3e9SJustin Hibbits 
1600aeed3e9SJustin Hibbits     memset(p_Rtc, 0, sizeof(t_FmRtc));
1610aeed3e9SJustin Hibbits 
1620aeed3e9SJustin Hibbits     /* Allocate memory for the FM RTC driver parameters */
163*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
1640aeed3e9SJustin Hibbits     if (!p_Rtc->p_RtcDriverParam)
1650aeed3e9SJustin Hibbits     {
1660aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
1670aeed3e9SJustin Hibbits         XX_Free(p_Rtc);
1680aeed3e9SJustin Hibbits         return NULL;
1690aeed3e9SJustin Hibbits     }
1700aeed3e9SJustin Hibbits 
171*852ba100SJustin Hibbits     memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
1720aeed3e9SJustin Hibbits 
1730aeed3e9SJustin Hibbits     /* Store RTC configuration parameters */
1740aeed3e9SJustin Hibbits     p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
1750aeed3e9SJustin Hibbits 
1760aeed3e9SJustin Hibbits     /* Set default RTC configuration parameters */
177*852ba100SJustin Hibbits     fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
178*852ba100SJustin Hibbits 
179*852ba100SJustin Hibbits     p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
180*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
181*852ba100SJustin Hibbits     p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
182*852ba100SJustin Hibbits 
1830aeed3e9SJustin Hibbits 
1840aeed3e9SJustin Hibbits     /* Store RTC parameters in the RTC control structure */
185*852ba100SJustin Hibbits     p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
1860aeed3e9SJustin Hibbits     p_Rtc->h_App    = p_FmRtcParam->h_App;
1870aeed3e9SJustin Hibbits 
1880aeed3e9SJustin Hibbits     return p_Rtc;
1890aeed3e9SJustin Hibbits }
1900aeed3e9SJustin Hibbits 
1910aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_Init(t_Handle h_FmRtc)1920aeed3e9SJustin Hibbits t_Error FM_RTC_Init(t_Handle h_FmRtc)
1930aeed3e9SJustin Hibbits {
1940aeed3e9SJustin Hibbits     t_FmRtc             *p_Rtc = (t_FmRtc *)h_FmRtc;
195*852ba100SJustin Hibbits     struct rtc_cfg      *p_RtcDriverParam;
196*852ba100SJustin Hibbits     struct rtc_regs     *p_MemMap;
197*852ba100SJustin Hibbits     uint32_t            freqCompensation = 0;
1980aeed3e9SJustin Hibbits     uint64_t            tmpDouble;
199*852ba100SJustin Hibbits     bool                init_freq_comp = FALSE;
2000aeed3e9SJustin Hibbits 
2010aeed3e9SJustin Hibbits     p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
2020aeed3e9SJustin Hibbits     p_MemMap = p_Rtc->p_MemMap;
2030aeed3e9SJustin Hibbits 
2040aeed3e9SJustin Hibbits     if (CheckInitParameters(p_Rtc)!=E_OK)
2050aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_CONFLICT,
2060aeed3e9SJustin Hibbits                      ("Init Parameters are not Valid"));
2070aeed3e9SJustin Hibbits 
208*852ba100SJustin Hibbits     /* TODO check that no timestamping MACs are working in this stage. */
2090aeed3e9SJustin Hibbits 
2100aeed3e9SJustin Hibbits     /* find source clock frequency in Mhz */
211*852ba100SJustin Hibbits     if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
212*852ba100SJustin Hibbits         p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
2130aeed3e9SJustin Hibbits     else
214*852ba100SJustin Hibbits         p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
2150aeed3e9SJustin Hibbits 
2160aeed3e9SJustin Hibbits     /* if timer in Master mode Initialize TMR_CTRL */
2170aeed3e9SJustin Hibbits     /* We want the counter (TMR_CNT) to count in nano-seconds */
218*852ba100SJustin Hibbits     if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
2190aeed3e9SJustin Hibbits         p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
2200aeed3e9SJustin Hibbits     else
2210aeed3e9SJustin Hibbits     {
2220aeed3e9SJustin Hibbits         /* Initialize TMR_ADD with the initial frequency compensation value:
2230aeed3e9SJustin Hibbits            freqCompensation = (2^32 / frequency ratio) */
2240aeed3e9SJustin Hibbits         /* frequency ratio = sorce clock/rtc clock =
2250aeed3e9SJustin Hibbits          * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
226*852ba100SJustin Hibbits         init_freq_comp = TRUE;
2270aeed3e9SJustin Hibbits         freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
2280aeed3e9SJustin Hibbits                                               p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
2290aeed3e9SJustin Hibbits     }
230*852ba100SJustin Hibbits 
2310aeed3e9SJustin Hibbits     /* check the legality of the relation between source and destination clocks */
2320aeed3e9SJustin Hibbits     /* should be larger than 1.0001 */
2330aeed3e9SJustin Hibbits     tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
2340aeed3e9SJustin Hibbits     if ((tmpDouble) <= 10001)
2350aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_CONFLICT,
2360aeed3e9SJustin Hibbits               ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
2370aeed3e9SJustin Hibbits 
238*852ba100SJustin Hibbits     fman_rtc_init(p_RtcDriverParam,
239*852ba100SJustin Hibbits              p_MemMap,
240*852ba100SJustin Hibbits              FM_RTC_NUM_OF_ALARMS,
241*852ba100SJustin Hibbits              FM_RTC_NUM_OF_PERIODIC_PULSES,
242*852ba100SJustin Hibbits              FM_RTC_NUM_OF_EXT_TRIGGERS,
243*852ba100SJustin Hibbits              init_freq_comp,
244*852ba100SJustin Hibbits              freqCompensation,
245*852ba100SJustin Hibbits              p_Rtc->outputClockDivisor);
2460aeed3e9SJustin Hibbits 
2470aeed3e9SJustin Hibbits     /* Register the FM RTC interrupt */
2480aeed3e9SJustin Hibbits     FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
2490aeed3e9SJustin Hibbits 
2500aeed3e9SJustin Hibbits     /* Free parameters structures */
2510aeed3e9SJustin Hibbits     XX_Free(p_Rtc->p_RtcDriverParam);
2520aeed3e9SJustin Hibbits     p_Rtc->p_RtcDriverParam = NULL;
2530aeed3e9SJustin Hibbits 
2540aeed3e9SJustin Hibbits     return E_OK;
2550aeed3e9SJustin Hibbits }
2560aeed3e9SJustin Hibbits 
2570aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_Free(t_Handle h_FmRtc)2580aeed3e9SJustin Hibbits t_Error FM_RTC_Free(t_Handle h_FmRtc)
2590aeed3e9SJustin Hibbits {
2600aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
2610aeed3e9SJustin Hibbits 
2620aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
2630aeed3e9SJustin Hibbits 
2640aeed3e9SJustin Hibbits     if (p_Rtc->p_RtcDriverParam)
2650aeed3e9SJustin Hibbits     {
2660aeed3e9SJustin Hibbits         XX_Free(p_Rtc->p_RtcDriverParam);
2670aeed3e9SJustin Hibbits     }
2680aeed3e9SJustin Hibbits     else
2690aeed3e9SJustin Hibbits     {
2700aeed3e9SJustin Hibbits         FM_RTC_Disable(h_FmRtc);
2710aeed3e9SJustin Hibbits     }
2720aeed3e9SJustin Hibbits 
2730aeed3e9SJustin Hibbits     /* Unregister FM RTC interrupt */
2740aeed3e9SJustin Hibbits     FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
2750aeed3e9SJustin Hibbits     XX_Free(p_Rtc);
2760aeed3e9SJustin Hibbits 
2770aeed3e9SJustin Hibbits     return E_OK;
2780aeed3e9SJustin Hibbits }
2790aeed3e9SJustin Hibbits 
2800aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,e_FmSrcClk srcClk,uint32_t freqInMhz)2810aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigSourceClock(t_Handle         h_FmRtc,
2820aeed3e9SJustin Hibbits                                     e_FmSrcClk    srcClk,
2830aeed3e9SJustin Hibbits                                     uint32_t      freqInMhz)
2840aeed3e9SJustin Hibbits {
2850aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
2860aeed3e9SJustin Hibbits 
2870aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
2880aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
2890aeed3e9SJustin Hibbits 
290*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
2910aeed3e9SJustin Hibbits     if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
292*852ba100SJustin Hibbits         p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
2930aeed3e9SJustin Hibbits 
2940aeed3e9SJustin Hibbits     return E_OK;
2950aeed3e9SJustin Hibbits }
2960aeed3e9SJustin Hibbits 
2970aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigPeriod(t_Handle h_FmRtc,uint32_t period)2980aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
2990aeed3e9SJustin Hibbits {
3000aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3010aeed3e9SJustin Hibbits 
3020aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3030aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3040aeed3e9SJustin Hibbits 
3050aeed3e9SJustin Hibbits     p_Rtc->clockPeriodNanoSec = period;
3060aeed3e9SJustin Hibbits 
3070aeed3e9SJustin Hibbits     return E_OK;
3080aeed3e9SJustin Hibbits }
3090aeed3e9SJustin Hibbits 
3100aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc,bool enabled)3110aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
3120aeed3e9SJustin Hibbits {
3130aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3140aeed3e9SJustin Hibbits 
3150aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3160aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3170aeed3e9SJustin Hibbits 
3180aeed3e9SJustin Hibbits     p_Rtc->p_RtcDriverParam->bypass = enabled;
3190aeed3e9SJustin Hibbits 
3200aeed3e9SJustin Hibbits     return E_OK;
3210aeed3e9SJustin Hibbits }
3220aeed3e9SJustin Hibbits 
3230aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc,bool inverted)3240aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
3250aeed3e9SJustin Hibbits {
3260aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3270aeed3e9SJustin Hibbits 
3280aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3290aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3300aeed3e9SJustin Hibbits 
331*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
3320aeed3e9SJustin Hibbits 
3330aeed3e9SJustin Hibbits     return E_OK;
3340aeed3e9SJustin Hibbits }
3350aeed3e9SJustin Hibbits 
3360aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc,bool inverted)3370aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
3380aeed3e9SJustin Hibbits {
3390aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3400aeed3e9SJustin Hibbits 
3410aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3420aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3430aeed3e9SJustin Hibbits 
344*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
3450aeed3e9SJustin Hibbits 
3460aeed3e9SJustin Hibbits     return E_OK;
3470aeed3e9SJustin Hibbits }
3480aeed3e9SJustin Hibbits 
3490aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc,uint16_t divisor)3500aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
3510aeed3e9SJustin Hibbits {
3520aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3530aeed3e9SJustin Hibbits 
3540aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3550aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3560aeed3e9SJustin Hibbits 
3570aeed3e9SJustin Hibbits     p_Rtc->outputClockDivisor = divisor;
3580aeed3e9SJustin Hibbits 
3590aeed3e9SJustin Hibbits     return E_OK;
3600aeed3e9SJustin Hibbits }
3610aeed3e9SJustin Hibbits 
3620aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc,bool enable)3630aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
3640aeed3e9SJustin Hibbits {
3650aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3660aeed3e9SJustin Hibbits 
3670aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3680aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3690aeed3e9SJustin Hibbits 
370*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->pulse_realign = enable;
3710aeed3e9SJustin Hibbits 
3720aeed3e9SJustin Hibbits     return E_OK;
3730aeed3e9SJustin Hibbits }
3740aeed3e9SJustin Hibbits 
3750aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,uint8_t alarmId,e_FmRtcAlarmPolarity alarmPolarity)3760aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigAlarmPolarity(t_Handle             h_FmRtc,
3770aeed3e9SJustin Hibbits                                    uint8_t              alarmId,
3780aeed3e9SJustin Hibbits                                    e_FmRtcAlarmPolarity alarmPolarity)
3790aeed3e9SJustin Hibbits {
3800aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
3810aeed3e9SJustin Hibbits 
3820aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
3830aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
3840aeed3e9SJustin Hibbits 
3850aeed3e9SJustin Hibbits     if (alarmId >= FM_RTC_NUM_OF_ALARMS)
3860aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
3870aeed3e9SJustin Hibbits 
388*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
389*852ba100SJustin Hibbits         (enum fman_rtc_alarm_polarity)alarmPolarity;
3900aeed3e9SJustin Hibbits 
3910aeed3e9SJustin Hibbits     return E_OK;
3920aeed3e9SJustin Hibbits }
3930aeed3e9SJustin Hibbits 
3940aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,uint8_t triggerId,e_FmRtcTriggerPolarity triggerPolarity)3950aeed3e9SJustin Hibbits t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle               h_FmRtc,
3960aeed3e9SJustin Hibbits                                              uint8_t                triggerId,
3970aeed3e9SJustin Hibbits                                              e_FmRtcTriggerPolarity triggerPolarity)
3980aeed3e9SJustin Hibbits {
3990aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
4000aeed3e9SJustin Hibbits 
4010aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4020aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
4030aeed3e9SJustin Hibbits 
4040aeed3e9SJustin Hibbits     if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
4050aeed3e9SJustin Hibbits     {
4060aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
4070aeed3e9SJustin Hibbits     }
4080aeed3e9SJustin Hibbits 
409*852ba100SJustin Hibbits     p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
410*852ba100SJustin Hibbits         (enum fman_rtc_trigger_polarity)triggerPolarity;
4110aeed3e9SJustin Hibbits 
4120aeed3e9SJustin Hibbits     return E_OK;
4130aeed3e9SJustin Hibbits }
4140aeed3e9SJustin Hibbits 
4150aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_Enable(t_Handle h_FmRtc,bool resetClock)4160aeed3e9SJustin Hibbits t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
4170aeed3e9SJustin Hibbits {
4180aeed3e9SJustin Hibbits     t_FmRtc         *p_Rtc = (t_FmRtc *)h_FmRtc;
4190aeed3e9SJustin Hibbits 
4200aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4210aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
4220aeed3e9SJustin Hibbits 
423*852ba100SJustin Hibbits     fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
4240aeed3e9SJustin Hibbits     return E_OK;
4250aeed3e9SJustin Hibbits }
4260aeed3e9SJustin Hibbits 
4270aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_Disable(t_Handle h_FmRtc)4280aeed3e9SJustin Hibbits t_Error FM_RTC_Disable(t_Handle h_FmRtc)
4290aeed3e9SJustin Hibbits {
4300aeed3e9SJustin Hibbits     t_FmRtc         *p_Rtc = (t_FmRtc *)h_FmRtc;
4310aeed3e9SJustin Hibbits 
4320aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4330aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
4340aeed3e9SJustin Hibbits 
4350aeed3e9SJustin Hibbits     /* TODO A check must be added here, that no timestamping MAC's
4360aeed3e9SJustin Hibbits      * are working in this stage. */
437*852ba100SJustin Hibbits     fman_rtc_disable(p_Rtc->p_MemMap);
4380aeed3e9SJustin Hibbits 
4390aeed3e9SJustin Hibbits     return E_OK;
4400aeed3e9SJustin Hibbits }
4410aeed3e9SJustin Hibbits 
4420aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetClockOffset(t_Handle h_FmRtc,int64_t offset)4430aeed3e9SJustin Hibbits t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
4440aeed3e9SJustin Hibbits {
4450aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
4460aeed3e9SJustin Hibbits 
4470aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4480aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
4490aeed3e9SJustin Hibbits 
450*852ba100SJustin Hibbits     fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
4510aeed3e9SJustin Hibbits     return E_OK;
4520aeed3e9SJustin Hibbits }
4530aeed3e9SJustin Hibbits 
4540aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetAlarm(t_Handle h_FmRtc,t_FmRtcAlarmParams * p_FmRtcAlarmParams)4550aeed3e9SJustin Hibbits t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
4560aeed3e9SJustin Hibbits {
4570aeed3e9SJustin Hibbits     t_FmRtc         *p_Rtc = (t_FmRtc *)h_FmRtc;
4580aeed3e9SJustin Hibbits     uint64_t        tmpAlarm;
459*852ba100SJustin Hibbits     bool            enable = FALSE;
4600aeed3e9SJustin Hibbits 
4610aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4620aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
4630aeed3e9SJustin Hibbits 
4640aeed3e9SJustin Hibbits     if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
4650aeed3e9SJustin Hibbits     {
4660aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
4670aeed3e9SJustin Hibbits     }
4680aeed3e9SJustin Hibbits 
4690aeed3e9SJustin Hibbits     if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
470*852ba100SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
471*852ba100SJustin Hibbits                      ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
472*852ba100SJustin Hibbits                       p_Rtc->clockPeriodNanoSec));
473*852ba100SJustin Hibbits     tmpAlarm = p_FmRtcAlarmParams->alarmTime;
474*852ba100SJustin Hibbits     if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
475*852ba100SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
476*852ba100SJustin Hibbits                      ("Alarm time must be a multiple of RTC period - %d nanoseconds",
477*852ba100SJustin Hibbits                       p_Rtc->clockPeriodNanoSec));
4780aeed3e9SJustin Hibbits 
4790aeed3e9SJustin Hibbits     if (p_FmRtcAlarmParams->f_AlarmCallback)
4800aeed3e9SJustin Hibbits     {
4810aeed3e9SJustin Hibbits         p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
4820aeed3e9SJustin Hibbits         p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
483*852ba100SJustin Hibbits         enable = TRUE;
4840aeed3e9SJustin Hibbits     }
4850aeed3e9SJustin Hibbits 
486*852ba100SJustin Hibbits     fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
487*852ba100SJustin Hibbits 
4880aeed3e9SJustin Hibbits     return E_OK;
4890aeed3e9SJustin Hibbits }
4900aeed3e9SJustin Hibbits 
4910aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc,t_FmRtcPeriodicPulseParams * p_FmRtcPeriodicPulseParams)4920aeed3e9SJustin Hibbits t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
4930aeed3e9SJustin Hibbits {
4940aeed3e9SJustin Hibbits     t_FmRtc         *p_Rtc = (t_FmRtc *)h_FmRtc;
495*852ba100SJustin Hibbits     bool            enable = FALSE;
4960aeed3e9SJustin Hibbits     uint64_t        tmpFiper;
4970aeed3e9SJustin Hibbits 
4980aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
4990aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
5000aeed3e9SJustin Hibbits 
5010aeed3e9SJustin Hibbits     if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
5020aeed3e9SJustin Hibbits     {
5030aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
5040aeed3e9SJustin Hibbits     }
505*852ba100SJustin Hibbits     if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
5060aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
5070aeed3e9SJustin Hibbits     if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
508*852ba100SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
509*852ba100SJustin Hibbits                      ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
510*852ba100SJustin Hibbits                       p_Rtc->clockPeriodNanoSec));
511*852ba100SJustin Hibbits     tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
512*852ba100SJustin Hibbits     if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
513*852ba100SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
514*852ba100SJustin Hibbits                      ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
515*852ba100SJustin Hibbits                       p_Rtc->clockPeriodNanoSec));
5160aeed3e9SJustin Hibbits     if (tmpFiper & 0xffffffff00000000LL)
517*852ba100SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
518*852ba100SJustin Hibbits                      ("Periodic pulse/RTC Period must be smaller than 4294967296",
519*852ba100SJustin Hibbits                       p_Rtc->clockPeriodNanoSec));
5200aeed3e9SJustin Hibbits 
5210aeed3e9SJustin Hibbits     if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
5220aeed3e9SJustin Hibbits     {
5230aeed3e9SJustin Hibbits         p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
5240aeed3e9SJustin Hibbits                                                                 p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
525*852ba100SJustin Hibbits         enable = TRUE;
5260aeed3e9SJustin Hibbits     }
527*852ba100SJustin Hibbits     fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
5280aeed3e9SJustin Hibbits     return E_OK;
5290aeed3e9SJustin Hibbits }
5300aeed3e9SJustin Hibbits 
5310aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc,uint8_t periodicPulseId)5320aeed3e9SJustin Hibbits t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
5330aeed3e9SJustin Hibbits {
5340aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
5350aeed3e9SJustin Hibbits 
5360aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
5370aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
5380aeed3e9SJustin Hibbits 
5390aeed3e9SJustin Hibbits     if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
5400aeed3e9SJustin Hibbits     {
5410aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
5420aeed3e9SJustin Hibbits     }
5430aeed3e9SJustin Hibbits 
5440aeed3e9SJustin Hibbits     p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
545*852ba100SJustin Hibbits     fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
5460aeed3e9SJustin Hibbits 
5470aeed3e9SJustin Hibbits     return E_OK;
5480aeed3e9SJustin Hibbits }
5490aeed3e9SJustin Hibbits 
5500aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetExternalTrigger(t_Handle h_FmRtc,t_FmRtcExternalTriggerParams * p_FmRtcExternalTriggerParams)5510aeed3e9SJustin Hibbits t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
5520aeed3e9SJustin Hibbits {
5530aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
554*852ba100SJustin Hibbits     bool        enable = FALSE;
5550aeed3e9SJustin Hibbits 
5560aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
5570aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
5580aeed3e9SJustin Hibbits 
5590aeed3e9SJustin Hibbits     if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
5600aeed3e9SJustin Hibbits     {
5610aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
5620aeed3e9SJustin Hibbits     }
5630aeed3e9SJustin Hibbits 
5640aeed3e9SJustin Hibbits     if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
5650aeed3e9SJustin Hibbits     {
5660aeed3e9SJustin Hibbits         p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
567*852ba100SJustin Hibbits         enable = TRUE;
5680aeed3e9SJustin Hibbits     }
5690aeed3e9SJustin Hibbits 
570*852ba100SJustin Hibbits     fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
5710aeed3e9SJustin Hibbits     return E_OK;
5720aeed3e9SJustin Hibbits }
5730aeed3e9SJustin Hibbits 
5740aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc,uint8_t externalTriggerId)5750aeed3e9SJustin Hibbits t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
5760aeed3e9SJustin Hibbits {
5770aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
5780aeed3e9SJustin Hibbits 
5790aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
5800aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
5810aeed3e9SJustin Hibbits 
5820aeed3e9SJustin Hibbits     if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
5830aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
5840aeed3e9SJustin Hibbits 
5850aeed3e9SJustin Hibbits     p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
5860aeed3e9SJustin Hibbits 
587*852ba100SJustin Hibbits     fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
5880aeed3e9SJustin Hibbits 
5890aeed3e9SJustin Hibbits     return E_OK;
5900aeed3e9SJustin Hibbits }
5910aeed3e9SJustin Hibbits 
5920aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,uint8_t triggerId,uint64_t * p_TimeStamp)5930aeed3e9SJustin Hibbits t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle             h_FmRtc,
5940aeed3e9SJustin Hibbits                                               uint8_t           triggerId,
5950aeed3e9SJustin Hibbits                                               uint64_t          *p_TimeStamp)
5960aeed3e9SJustin Hibbits {
5970aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
5980aeed3e9SJustin Hibbits 
5990aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
6000aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6010aeed3e9SJustin Hibbits 
6020aeed3e9SJustin Hibbits     if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
6030aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
6040aeed3e9SJustin Hibbits 
605*852ba100SJustin Hibbits     *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
6060aeed3e9SJustin Hibbits 
6070aeed3e9SJustin Hibbits     return E_OK;
6080aeed3e9SJustin Hibbits }
6090aeed3e9SJustin Hibbits 
6100aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_GetCurrentTime(t_Handle h_FmRtc,uint64_t * p_Ts)6110aeed3e9SJustin Hibbits t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
6120aeed3e9SJustin Hibbits {
6130aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
6140aeed3e9SJustin Hibbits 
6150aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
6160aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6170aeed3e9SJustin Hibbits 
618*852ba100SJustin Hibbits     *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
6190aeed3e9SJustin Hibbits 
6200aeed3e9SJustin Hibbits     return E_OK;
6210aeed3e9SJustin Hibbits }
6220aeed3e9SJustin Hibbits 
6230aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetCurrentTime(t_Handle h_FmRtc,uint64_t ts)6240aeed3e9SJustin Hibbits t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
6250aeed3e9SJustin Hibbits {
6260aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
6270aeed3e9SJustin Hibbits 
6280aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
6290aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6300aeed3e9SJustin Hibbits 
631*852ba100SJustin Hibbits     do_div(ts, p_Rtc->clockPeriodNanoSec);
632*852ba100SJustin Hibbits     fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
6330aeed3e9SJustin Hibbits 
6340aeed3e9SJustin Hibbits     return E_OK;
6350aeed3e9SJustin Hibbits }
6360aeed3e9SJustin Hibbits 
6370aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_GetFreqCompensation(t_Handle h_FmRtc,uint32_t * p_Compensation)6380aeed3e9SJustin Hibbits t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
6390aeed3e9SJustin Hibbits {
6400aeed3e9SJustin Hibbits     t_FmRtc     *p_Rtc = (t_FmRtc *)h_FmRtc;
6410aeed3e9SJustin Hibbits 
6420aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
6430aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6440aeed3e9SJustin Hibbits 
645*852ba100SJustin Hibbits     *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
6460aeed3e9SJustin Hibbits 
6470aeed3e9SJustin Hibbits     return E_OK;
6480aeed3e9SJustin Hibbits }
6490aeed3e9SJustin Hibbits 
6500aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_SetFreqCompensation(t_Handle h_FmRtc,uint32_t freqCompensation)6510aeed3e9SJustin Hibbits t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
6520aeed3e9SJustin Hibbits {
6530aeed3e9SJustin Hibbits     t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
6540aeed3e9SJustin Hibbits 
6550aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
6560aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6570aeed3e9SJustin Hibbits 
6580aeed3e9SJustin Hibbits     /* set the new freqCompensation */
659*852ba100SJustin Hibbits     fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
660*852ba100SJustin Hibbits 
661*852ba100SJustin Hibbits     return E_OK;
662*852ba100SJustin Hibbits }
663*852ba100SJustin Hibbits 
664*852ba100SJustin Hibbits #ifdef CONFIG_PTP_1588_CLOCK_DPAA
665*852ba100SJustin Hibbits /*****************************************************************************/
FM_RTC_EnableInterrupt(t_Handle h_FmRtc,uint32_t events)666*852ba100SJustin Hibbits t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
667*852ba100SJustin Hibbits {
668*852ba100SJustin Hibbits 	t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
669*852ba100SJustin Hibbits 
670*852ba100SJustin Hibbits 	SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
671*852ba100SJustin Hibbits 	SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
672*852ba100SJustin Hibbits 
673*852ba100SJustin Hibbits 	/* enable interrupt */
674*852ba100SJustin Hibbits 	fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
6750aeed3e9SJustin Hibbits 
6760aeed3e9SJustin Hibbits 	return E_OK;
6770aeed3e9SJustin Hibbits }
6780aeed3e9SJustin Hibbits 
6790aeed3e9SJustin Hibbits /*****************************************************************************/
FM_RTC_DisableInterrupt(t_Handle h_FmRtc,uint32_t events)680*852ba100SJustin Hibbits t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
6810aeed3e9SJustin Hibbits {
6820aeed3e9SJustin Hibbits 	t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
6830aeed3e9SJustin Hibbits 
684*852ba100SJustin Hibbits 	SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
685*852ba100SJustin Hibbits 	SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
6860aeed3e9SJustin Hibbits 
687*852ba100SJustin Hibbits 	/* disable interrupt */
688*852ba100SJustin Hibbits 	fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
6890aeed3e9SJustin Hibbits 
6900aeed3e9SJustin Hibbits 	return E_OK;
6910aeed3e9SJustin Hibbits }
692*852ba100SJustin Hibbits #endif
693