1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2017-2020 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * o Redistributions of source code must retain the above copyright notice, this list
11  *   of conditions and the following disclaimer.
12  *
13  * o Redistributions in binary form must reproduce the above copyright notice, this
14  *   list of conditions and the following disclaimer in the documentation and/or
15  *   other materials provided with the distribution.
16  *
17  * o Neither the name of the copyright holder nor the names of its
18  *   contributors may be used to endorse or promote products derived from this
19  *   software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22  * ANY 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25  * ANY 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 ON
28  * 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 /*!
34  * Header file containing the public API for the System Controller (SC)
35  * Timer function.
36  *
37  * @addtogroup TIMER_SVC TIMER: Timer Service
38  *
39  * Module for the Timer service. This includes support for the watchdog, RTC,
40  * and system counter. Note every resource partition has a watchdog it can
41  * use.
42  *
43  * @{
44  */
45 
46 #ifndef SC_TIMER_API_H
47 #define SC_TIMER_API_H
48 
49 /* Includes */
50 
51 #include "main/types.h"
52 #include "svc/rm/rm_api.h"
53 
54 /* Defines */
55 
56 /*!
57  * @name Defines for type widths
58  */
59 /*@{*/
60 #define SC_TIMER_ACTION_W   3U      /*!< Width of sc_timer_wdog_action_t */
61 /*@}*/
62 
63 /*!
64  * @name Defines for sc_timer_wdog_action_t
65  */
66 /*@{*/
67 #define SC_TIMER_WDOG_ACTION_PARTITION      0U   /*!< Reset partition */
68 #define SC_TIMER_WDOG_ACTION_WARM           1U   /*!< Warm reset system */
69 #define SC_TIMER_WDOG_ACTION_COLD           2U   /*!< Cold reset system */
70 #define SC_TIMER_WDOG_ACTION_BOARD          3U   /*!< Reset board */
71 #define SC_TIMER_WDOG_ACTION_IRQ            4U   /*!< Only generate IRQs */
72 /*@}*/
73 
74 /* Types */
75 
76 /*!
77  * This type is used to configure the watchdog action.
78  */
79 typedef uint8_t sc_timer_wdog_action_t;
80 
81 /*!
82  * This type is used to declare a watchdog time value in milliseconds.
83  */
84 typedef uint32_t sc_timer_wdog_time_t;
85 
86 /* Functions */
87 
88 /*!
89  * @name Watchdog Functions
90  * @{
91  */
92 
93 /*!
94  * This function sets the watchdog timeout in milliseconds. If not
95  * set then the timeout defaults to the max. Once locked this value
96  * cannot be changed.
97  *
98  * @param[in]     ipc         IPC handle
99  * @param[in]     timeout     timeout period for the watchdog
100  *
101  * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
102  *         = locked).
103  */
104 sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc,
105     sc_timer_wdog_time_t timeout);
106 
107 /*!
108  * This function sets the watchdog pre-timeout in milliseconds. If not
109  * set then the pre-timeout defaults to the max. Once locked this value
110  * cannot be changed.
111  *
112  * @param[in]     ipc          IPC handle
113  * @param[in]     pre_timeout  pre-timeout period for the watchdog
114  *
115  * When the pre-timout expires an IRQ will be generated. Note this timeout
116  * clears when the IRQ is triggered. An IRQ is generated for the failing
117  * partition and all of its child partitions.
118  *
119  * @return Returns an error code (SC_ERR_NONE = success).
120  */
121 sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
122     sc_timer_wdog_time_t pre_timeout);
123 
124 /*!
125  * This function sets the watchdog window in milliseconds. If not
126  * set then the window defaults to the 0. Once locked this value
127  * cannot be changed.
128  *
129  * @param[in]     ipc         IPC handle
130  * @param[in]     window      window period for the watchdog
131  *
132  * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
133  *         = locked).
134  *
135  * Calling sc_timer_ping_wdog() before the window time has expired will
136  * result in the watchdog action being taken.
137  */
138 sc_err_t sc_timer_set_wdog_window(sc_ipc_t ipc,
139     sc_timer_wdog_time_t window);
140 
141 /*!
142  * This function starts the watchdog.
143  *
144  * @param[in]     ipc         IPC handle
145  * @param[in]     lock        boolean indicating the lock status
146  *
147  * @return Returns an error code (SC_ERR_NONE = success).
148  *
149  * Return errors:
150  * - SC_ERR_NOACCESS if caller's partition is not isolated,
151  * - SC_ERR_BUSY if already started
152  *
153  * If \a lock is set then the watchdog cannot be stopped or the timeout
154  * period changed.
155  *
156  * If the calling partition is not isolated then the wdog cannot be used.
157  * This is always the case if a non-secure partition is running on the same
158  * CPU as a secure partition (e.g. Linux under TZ). See sc_rm_partition_alloc().
159  */
160 sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock);
161 
162 /*!
163  * This function stops the watchdog if it is not locked.
164  *
165  * @param[in]     ipc         IPC handle
166  *
167  * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
168  *         = locked).
169  */
170 sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc);
171 
172 /*!
173  * This function pings (services, kicks) the watchdog resetting the time
174  * before expiration back to the timeout.
175  *
176  * @param[in]     ipc         IPC handle
177  *
178  * @return Returns an error code (SC_ERR_NONE = success).
179  */
180 sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc);
181 
182 /*!
183  * This function gets the status of the watchdog. All arguments are
184  * in milliseconds.
185  *
186  * @param[in]     ipc             IPC handle
187  * @param[out]    timeout         pointer to return the timeout
188  * @param[out]    max_timeout     pointer to return the max timeout
189  * @param[out]    remaining_time  pointer to return the time remaining
190  *                                until trigger
191  *
192  * @return Returns an error code (SC_ERR_NONE = success).
193  */
194 sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
195     sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *max_timeout,
196     sc_timer_wdog_time_t *remaining_time);
197 
198 /*!
199  * This function gets the status of the watchdog of a partition. All
200  * arguments are in milliseconds.
201  *
202  * @param[in]     ipc             IPC handle
203  * @param[in]     pt              partition to query
204  * @param[out]    enb             pointer to return enable status
205  * @param[out]    timeout         pointer to return the timeout
206  * @param[out]    remaining_time  pointer to return the time remaining
207  *                                until trigger
208  *
209  * @return Returns an error code (SC_ERR_NONE = success).
210  */
211 sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt, sc_bool_t *enb,
212     sc_timer_wdog_time_t *timeout, sc_timer_wdog_time_t *remaining_time);
213 
214 /*!
215  * This function configures the action to be taken when a watchdog
216  * expires.
217  *
218  * @param[in]     ipc         IPC handle
219  * @param[in]     pt          partition to affect
220  * @param[in]     action      action to take
221  *
222  * Default action is inherited from the parent.
223  *
224  * @return Returns an error code (SC_ERR_NONE = success).
225  *
226  * Return errors:
227  * - SC_ERR_PARM if invalid parameters,
228  * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner,
229  * - SC_ERR_LOCKED if the watchdog is locked
230  */
231 sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
232     sc_rm_pt_t pt, sc_timer_wdog_action_t action);
233 
234 /* @} */
235 
236 /*!
237  * @name Real-Time Clock (RTC) Functions
238  * @{
239  */
240 
241 /*!
242  * This function sets the RTC time. Only the owner of the SC_R_SYSTEM
243  * resource or a partition with access permissions to SC_R_SYSTEM can
244  * set the time.
245  *
246  * @param[in]     ipc         IPC handle
247  * @param[in]     year        year (min 1970)
248  * @param[in]     mon         month (1-12)
249  * @param[in]     day         day of the month (1-31)
250  * @param[in]     hour        hour (0-23)
251  * @param[in]     min         minute (0-59)
252  * @param[in]     sec         second (0-59)
253  *
254  * @return Returns an error code (SC_ERR_NONE = success).
255  *
256  * Return errors:
257  * - SC_ERR_PARM if invalid time/date parameters,
258  * - SC_ERR_NOACCESS if caller's partition cannot access SC_R_SYSTEM
259  */
260 sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
261     uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
262 
263 /*!
264  * This function gets the RTC time.
265  *
266  * @param[in]     ipc         IPC handle
267  * @param[out]    year        pointer to return year (min 1970)
268  * @param[out]    mon         pointer to return month (1-12)
269  * @param[out]    day         pointer to return day of the month (1-31)
270  * @param[out]    hour        pointer to return hour (0-23)
271  * @param[out]    min         pointer to return minute (0-59)
272  * @param[out]    sec         pointer to return second (0-59)
273  *
274  * @return Returns an error code (SC_ERR_NONE = success).
275  */
276 sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
277     uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec);
278 
279 /*!
280  * This function gets the RTC time in seconds since 1/1/1970.
281  *
282  * @param[in]     ipc         IPC handle
283  * @param[out]    sec         pointer to return seconds
284  *
285  * @return Returns an error code (SC_ERR_NONE = success).
286  */
287 sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec);
288 
289 /*!
290  * This function sets the RTC alarm.
291  *
292  * @param[in]     ipc         IPC handle
293  * @param[in]     year        year (min 1970)
294  * @param[in]     mon         month (1-12)
295  * @param[in]     day         day of the month (1-31)
296  * @param[in]     hour        hour (0-23)
297  * @param[in]     min         minute (0-59)
298  * @param[in]     sec         second (0-59)
299  *
300  * Note this alarm setting clears when the alarm is triggered. This is an
301  * absolute time.
302  *
303  * @return Returns an error code (SC_ERR_NONE = success).
304  *
305  * Return errors:
306  * - SC_ERR_PARM if invalid time/date parameters
307  */
308 sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
309     uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
310 
311 /*!
312  * This function sets the RTC alarm (periodic mode).
313  *
314  * @param[in]     ipc         IPC handle
315  * @param[in]     sec         period in seconds
316  *
317  * @return Returns an error code (SC_ERR_NONE = success).
318  *
319  * Note this is a relative time.
320  *
321  * Return errors:
322  * - SC_ERR_PARM if invalid time/date parameters
323  */
324 sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec);
325 
326 /*!
327  * This function cancels the RTC alarm.
328  *
329  * @param[in]     ipc         IPC handle
330  *
331  * Note this alarm setting clears when the alarm is triggered.
332  *
333  * @return Returns an error code (SC_ERR_NONE = success).
334  *
335  * Return errors:
336  * - SC_ERR_PARM if invalid time/date parameters
337  */
338 sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc);
339 
340 /*!
341  * This function sets the RTC calibration value. Only the owner of the SC_R_SYSTEM
342  * resource or a partition with access permissions to SC_R_SYSTEM can set the
343  * calibration.
344  *
345  * @param[in]     ipc         IPC handle
346  * @param[in]     count       calibration count (-16 to 15)
347  *
348  * The calibration value is a 5-bit value including the sign bit, which is
349  * implemented in 2's complement. It is added or subtracted from the RTC on
350  * a periodic basis, once per 32768 cycles of the RTC clock.
351  *
352  * @return Returns an error code (SC_ERR_NONE = success).
353  */
354 sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count);
355 
356 /* @} */
357 
358 /*!
359  * @name System Counter (SYSCTR) Functions
360  * @{
361  */
362 
363 /*!
364  * This function sets the SYSCTR alarm.
365  *
366  * @param[in]     ipc         IPC handle
367  * @param[in]     ticks       number of 8MHz cycles
368  *
369  * Note the \a ticks parameter is an absolute time. This alarm
370  * setting clears when the alarm is triggered.
371  *
372  * @return Returns an error code (SC_ERR_NONE = success).
373  *
374  * Return errors:
375  * - SC_ERR_PARM if invalid time/date parameters
376  */
377 sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks);
378 
379 /*!
380  * This function sets the SYSCTR alarm (periodic mode).
381  *
382  * @param[in]     ipc          IPC handle
383  * @param[in]     ticks        number of 8MHz cycles
384  *
385  * Note the \a ticks parameter is a relative time.
386  *
387  * @return Returns an error code (SC_ERR_NONE = success).
388  *
389  * Return errors:
390  * - SC_ERR_PARM if invalid time/date parameters
391  */
392 sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc,
393     uint64_t ticks);
394 
395 /*!
396  * This function cancels the SYSCTR alarm.
397  *
398  * @param[in]     ipc         IPC handle
399  *
400  * Note this alarm setting clears when the alarm is triggered.
401  *
402  * @return Returns an error code (SC_ERR_NONE = success).
403  *
404  * Return errors:
405  * - SC_ERR_PARM if invalid time/date parameters
406  */
407 sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc);
408 
409 /* @} */
410 
411 #endif /* SC_TIMER_API_H */
412 
413 /**@}*/
414 
415