1 /*******************************************************************************
2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 *
25 * PolarFire SoC (MPFS) Microprocessor Subsystem Watchdog bare metal software
26 * driver public API.
27 *
28 *
29 */
30 /*=========================================================================*//**
31 @mainpage PolarFire SoC MSS Watchdog Bare Metal Driver
32
33 ==============================================================================
34 Introduction
35 ==============================================================================
36 The PolarFire SoC Microprocessor SubSystem (MSS) includes five instances of
37 watchdog timer hardware blocks used to detect system lockups. This software
38 driver provides a set of functions for controlling the MSS watchdog as part of
39 a bare metal system where no operating system is available. The driver can be
40 adapted for use as part of an operating system, but the implementation of the
41 adaptation layer between the driver and the operating system's driver model is
42 outside the scope of the driver.
43
44 The MSS watchdog driver provides support for the following features:
45 - Initialization of the MSS watchdog
46 - Reading the current value and status of the watchdog timer
47 - Refreshing the watchdog timer value
48 - Enabling, disabling and clearing timeout and MVRP interrupts.
49
50 ==============================================================================
51 Hardware Flow Dependencies
52 ==============================================================================
53 The configuration of all the features of the PolarFire SoC MSS watchdog is
54 covered by this driver. Besides, this driver does not require any other
55 configuration.
56
57 On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
58 masters and multiple slaves. Five RISC-V CPUs connect to the Master ports
59 M10 to M14 of the AXI switch. By default, all the APB peripherals are
60 accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
61 bridges (referred as main APB bus). However, to support logical separation in
62 the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
63 can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
64 APB bridges (referred as the AMP APB bus).
65
66 Application must make sure that the desired MSS Watchdog instance is
67 appropriately configured on one of the APB slaves described above by
68 configuring the PolarFire SoC system registers (SYSREG) as per the application
69 need and that the appropriate data structures are provided to this driver as
70 parameter to the functions provided by this driver.
71
72 The base address and register addresses are defined in this driver as
73 constants. The interrupt number assignment for the MSS Watchdog peripherals
74 are defined as constants in the MPFS HAL. You must ensure that the latest MPFS
75 HAL is included in the project settings of the SoftConsole tool chain and that
76 it is generated into your project.
77
78 ==============================================================================
79 Theory of Operation
80 ==============================================================================
81 The MSS watchdog driver functions are grouped into the following categories:
82 - Initialization and configuration
83 - Reading the current value and status of the watchdog timer
84 - Refreshing the watchdog timer value
85 - Support for enabling, disabling and clearing time-out and MVRP interrupts.
86
87 --------------------------------
88 Initialization and Configuration
89 --------------------------------
90 The MSS Watchdog driver provides the MSS_WD_configure() function to configure
91 the MSS Watchdog with desired configuration values. It also provides the
92 MSS_WD_get_config() function to read back the current configurations of the
93 MSS Watchdog. You can use this function to retrieve the current configurations
94 and then overwrite them with the application specific values, such as initial
95 watchdog timer value, Maximum Value (up to which) Refresh (is) Permitted,
96 watchdog time-out value, enable/disable forbidden region, enable/disable
97 MVRP interrupt and interrupt type.
98
99 The occurrence of a time out event before the system reset can be detected
100 using the MSS_WD_timeout_occured() function. This function would typically be
101 used at the start of the application to detect whether the application is
102 starting as a result of a power-on reset or a watchdog reset. The time out
103 event must be cleared through a call to function MSS_WD_clear_timeout_event()
104 in order to allow the detection of subsequent time out events or
105 differentiating between a RISC-V initiated system reset and watchdog reset.
106
107 --------------------------------------------
108 Reading the Watchdog Timer Value and Status
109 --------------------------------------------
110 MSS Watchdog is a down counter. A refresh forbidden window can be created by
111 configuring the watchdog Maximum Value up to which Refresh is Permitted (MVRP).
112 When the current value of the watchdog timer is greater than the MVRP value,
113 refreshing the watchdog is forbidden. Attempting to refresh the watchdog timer
114 in the forbidden window will assert a timeout interrupt. The
115 MSS_WD_forbidden_status() function can be used to know whether the watchdog
116 timer is in forbidden window or has crossed it. By default, the forbidden
117 window is disabled. It can be enabled by providing an appropriate value as
118 parameter to the MSS_WD_configure() function. When the forbidden window is
119 disabled, any attempt to refresh the watchdog timer is ignored and the counter
120 keeps on down counting.
121
122 The current value of the watchdog timer can be read using the
123 MSS_WD_current_value() function. This function can be called at any time.
124
125 --------------------------------------------
126 Refreshing the Watchdog Timer Value
127 --------------------------------------------
128 The watchdog timer value is refreshed using the MSS_WD_reload() function. The
129 value reloaded into the watchdog timer down-counter is specified at the
130 configuration time with an appropriate value as parameter to the
131 MSS_WD_get_config() function.
132
133 --------------------------------------------
134 Interrupt Control
135 --------------------------------------------
136 The PolarFire SoC MSS Watchdog generates two interrupts, The MVRP interrupt and
137 the timeout interrupt.
138 The MVRP interrupt is generated when the watchdog down-counter crosses the
139 Maximum Value up to which Refresh is Permitted (MVRP). Following functions to
140 control MVRP interrupt:
141 - MSS_WD_enable_mvrp_irq
142 - MSS_WD_disable_mvrp_irq
143 - MSS_WD_clear_mvrp_irq
144
145 The timeout interrupt is generated when the watchdog down-counter crosses the
146 watchdog timeout value. The timeout value is a non-zero value and it can be
147 set to a maximum of MSS_WDOG_TRIGGER_MAX. The non-maskable interrupt is
148 generated when the watchdog crosses this timeout value, the down counter
149 keeps on down counting and a reset signal is generated when reaches zero.
150 Following functions to control timeout interrupt:
151 - MSS_WD_enable_timeout_irq
152 - MSS_WD_disable_timeout_irq
153 - MSS_WD_clear_timeout_irq
154
155 *//*=========================================================================*/
156
157 #ifndef MSS_WATCHDOG_H_
158 #define MSS_WATCHDOG_H_
159
160 #ifdef __cplusplus
161 extern "C" {
162 #endif
163
164 #include <stdint.h>
165
166 /*
167 The following constants can be used to configure the MSS Watchdog where a
168 zero or non-zero value such as enable or disable is to be provided as input
169 parameter as shown below:
170 wd0lo_config.forbidden_en = MSS_WDOG_DISABLE;
171 MSS_WD_configure(MSS_WDOG0_LO, &wd0lo_config);
172 */
173 #define MSS_WDOG_ENABLE 1u
174 #define MSS_WDOG_DISABLE 0u
175
176
177 /***************************************************************************//**
178 The mss_watchdog_num_t is the Watchdog module number enumeration.
179 The MSS_WDOG0_LO to MSS_WDOG4_LO Correspond to the Watchdog module number
180 0 to 4 when the appear on the AXI switch Slave 5.
181 The MSS_WDOG0_HI to MSS_WDOG4_HI Correspond to the Watchdog module number
182 0 to 4 when the appear on the AXI switch Slave 6.
183 */
184 typedef enum mss_watchdog_num{
185 MSS_WDOG0_LO = 0,
186 MSS_WDOG1_LO = 1,
187 MSS_WDOG2_LO = 2,
188 MSS_WDOG3_LO = 3,
189 MSS_WDOG4_LO = 4,
190 MSS_WDOG0_HI = 5,
191 MSS_WDOG1_HI = 6,
192 MSS_WDOG2_HI = 7,
193 MSS_WDOG3_HI = 8,
194 MSS_WDOG4_HI = 9,
195
196 } mss_watchdog_num_t;
197
198
199 /***************************************************************************//**
200 The mss_watchdog_config_t type for the watchdog Configuration structure. This
201 type is used as a parameter for the MSS_WD_configure() and the
202 MSS_WD_get_config() functions.
203
204 Following are the values as part of this structure
205 | Parameter | Description |
206 |------------------|-----------------------------------------------------------|
207 | time_val | The value from which the watchdog timer counts down |
208 | mvrp_val | The Watchdog MVRP value |
209 | timeout_val | The watchdog timeout value |
210 | forbidden_en | Enable/disable the forbidden window |
211 | | When set, if a refresh occurs in the forbidden window, |
212 | | the watchdog timeout interrupt will be generated. |
213
214
215 Time calculation example:
216
217 time_val = 0xFFFFF0u
218 mvrp_val = 0x989680u
219 timeout_val = 0x3e8u
220
221 A presaclar = 256 is used on the MSS AXI clock.
222 Considering AXI clock = 25Mhz
223
224 The MVRP interrupt will happen after
225 (0xFFFFF0 - 0x989680) * ( 1/25MHz/256)
226 mvrp interrupt will happen after 69 sec. after system reset
227
228 (0xFFFFF0 - 0x3e8) * ( 1/25MHz/256)
229 timeout interrupt will happen after 171 sec. after system reset
230
231 */
232
233 typedef struct mss_watchdog_config{
234 uint32_t time_val;
235 uint32_t mvrp_val;
236 uint32_t timeout_val;
237 uint8_t forbidden_en;
238 uint8_t intr_type;
239
240 } mss_watchdog_config_t;
241
242 /***************************************************************************//**
243 Internal constants and types
244 *******************************************************************************/
245 #define MSS_WDOG_INTEN_MVRP 0u
246 #define MSS_WDOG_INTEN_TRIG 1u
247 #define MSS_WDOG_INTEN_SLEEP 2u
248 #define MSS_WDOG_ACTIVE_SLEEP 3u
249 #define MSS_WDOG_ENA_FORBIDDEN 4u
250
251 #define MSS_WDOG_INTEN_MVRP_MASK ( 1u << MSS_WDOG_INTEN_MVRP)
252 #define MSS_WDOG_INTEN_TRIG_MASK ( 1u << MSS_WDOG_INTEN_TRIG)
253 #define MSS_WDOG_INTEN_SLEEP_MASK ( 1u << MSS_WDOG_INTEN_SLEEP)
254 #define MSS_WDOG_ACTIVE_SLEEP_MASK ( 1u << MSS_WDOG_ACTIVE_SLEEP)
255 #define MSS_WDOG_ENA_FORBIDDEN_MASK ( 1u << MSS_WDOG_ENA_FORBIDDEN)
256
257 #define MSS_WDOG_MVRP_TRIPPED 0u
258 #define MSS_WDOG_WDOG_TRIPPED 1u
259 #define MSS_WDOG_FORBIDDEN 2u
260 #define MSS_WDOG_TRIGGERED 3u
261 #define MSS_WDOG_LOCKED 4u
262 #define MSS_WDOG_DEVRST 5u
263
264 #define MSS_WDOG_MVRP_TRIPPED_MASK ( 1u << MSS_WDOG_MVRP_TRIPPED)
265 #define MSS_WDOG_WDOG_TRIPPED_MASK ( 1u << MSS_WDOG_WDOG_TRIPPED)
266 #define MSS_WDOG_FORBIDDEN_MASK ( 1u << MSS_WDOG_FORBIDDEN)
267 #define MSS_WDOG_TRIGGERED_MASK ( 1u << MSS_WDOG_TRIGGERED)
268 #define MSS_WDOG_LOCKED_MASK ( 1u << MSS_WDOG_LOCKED)
269 #define MSS_WDOG_DEVRST_MASK ( 1u << MSS_WDOG_DEVRST)
270
271 #define MSS_WDOG_TRIGGER_MAX 4095u
272 #define MSS_WDOG_TIMER_MAX 16777200u /*0xFFFFFFu*/
273
274 /*
275 The WATCHDOG_TypeDef is the hardware register structure for the PolarFire SoC
276 MSS Watchdog.
277 */
278 typedef struct
279 {
280 volatile uint32_t REFRESH;
281 volatile uint32_t CONTROL;
282 volatile uint32_t STATUS;
283 volatile uint32_t TIME;
284 volatile uint32_t MSVP;
285 volatile uint32_t TRIGGER;
286 volatile uint32_t FORCE;
287 } WATCHDOG_TypeDef;
288
289 extern WATCHDOG_TypeDef* wdog_hw_base[10];
290
291 /***************************************************************************//**
292 The MSS_WDOG_REFRESH_KEY macro holds the magic value which will cause a reload
293 of the watchdog's down counter when written to the watchdog's WDOGREFRESH
294 register.
295 */
296 #define MSS_WDOG_REFRESH_KEY (uint32_t)0xDEADC0DEU
297
298 /***************************************************************************//**
299 The MSS_WDOG_FORCE_RESET_KEY macro holds the magic value which will force a
300 reset if the Watchdog is already timed out (gone past the timeout value).
301 Writing Any other value or writing TRIGGER register at other times will trigger
302 the watchdog NMI sequence (i.e Raise the timeout interrupt).
303 */
304 #define MSS_WDOG_FORCE_RESET_KEY (uint32_t)0xDEADU
305
306 /***************************************************************************//**
307 The MSS_WD_get_config() function returns the current configurations of the
308 PolarFire SoC MSS Watchdog. The MSS Watchdog is pre-initialized by the flash
309 bits at the design time. When used for the first time before calling the
310 MSS_WD_configure() function, this function will return the default
311 configurations as configured at the design time. You can reconfigure the
312 MSS Watchdog using MSS_WD_configure() function. A call to MSS_WD_get_config()
313 function will then return the current configuration values set by a previous
314 call to MSS_WD_configure() function. You may not need to use this function if
315 you do not want to know what the current configurations are. In that case, you
316 can directly use the MSS_WD_configure() function to configure the MSS Watchdog
317 to the values of your choice.
318
319 @param wd_num
320 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
321 on which the operation needs to be performed. The Watchdog module number can
322 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
323 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
324 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI Correspond to the Watchdog
325 module number 0 to 5 when they appear on the AXI switch Slave 6.
326
327 @param config
328 The config parameter is the return parameter in which the current
329 configurations of the watchdog module will be stored.
330
331 Please see the description of mss_watchdog_config_t for details.
332
333 @return
334 This function does not return any value.
335
336
337 Example:
338 @code
339 #include "mss_watchdog.h"
340 mss_watchdog_config_t wd0lo_config;
341
342 void e51( void )
343 {
344 MSS_WD_get_config(MSS_WDOG0_LO, &wd0lo_config);
345
346 wd0lo_config.forbidden_en = WDOG_ENABLE;
347 wd0lo_config.mvrp_val = 0xFFFF000u;
348
349 MSS_WD_configure(MSS_WDOG0_LO, &wd0lo_config);
350
351 for(;;)
352 {
353 main_task();
354 }
355 }
356 */
357 void MSS_WD_get_config
358 (
359 mss_watchdog_num_t wd_num,
360 mss_watchdog_config_t* config
361 );
362
363 /***************************************************************************//**
364 The MSS_WD_configure() function configures the desired watchdog module. The
365 Watchdog module is pre-initialized by the flash bits at the design time to the
366 default values. You can reconfigure the Watchdog module using
367 MSS_WD_configure() function.
368
369 Note that the MSS_WD_configure() function can be used only once, as it writes
370 into the TIME register. After a write into the TIME register, the TIME, TRIGGER
371 and MSVP register values are frozen and can't be altered again unless a system
372 reset happens.
373
374 Note also that the MSS Watchdog is not enabled at reset, calling this function
375 will start the watchdog, it cannot then be disabled and must be refreshed
376 periodically.
377
378 @param wd_num
379 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
380 on which the operation needs to be performed. The Watchdog module number can
381 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
382 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
383 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
384 module number 0 to 5 when the appear on the AXI switch Slave 6.
385
386 @param config
387 The config parameter is the input parameter in which the configurations to be
388 applied to the watchdog module are provided by the application.
389 Please see the description of mss_watchdog_config_t for details.
390
391 @return
392 This function returns a zero value when executed successfully. A non-zero
393 value is returned when the configuration values are out of bound.
394
395 Example:
396 @code
397 #include "mss_watchdog.h"
398 mss_watchdog_config_t wd0lo_config;
399
400 void e51( void )
401 {
402 MSS_WD_get_config(MSS_WDOG0_LO, &wd0lo_config);
403
404 wd0lo_config.forbidden_en = WDOG_ENABLE;
405 wd0lo_config.mvrp_val = 0xFFFF000u;
406
407 MSS_WD_configure(MSS_WDOG0_LO, &wd0lo_config);
408
409 for(;;)
410 {
411 main_task();
412 }
413 }
414 */
415 uint8_t MSS_WD_configure
416 (
417 mss_watchdog_num_t wd_num,
418 const mss_watchdog_config_t * config
419 );
420
421 /***************************************************************************//**
422 The MSS_WD_reload() function causes the watchdog to reload its down-counter
423 timer with the load value configured through the MSS configurator in the
424 hardware flow. This function must be called regularly to avoid a system reset
425 or a watchdog interrupt.
426
427 Note that the MSS Watchdog is not enabled at reset, calling this function
428 will start the watchdog, it cannot then be disabled and must be refreshed
429 periodically.
430
431 @param wd_num
432 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
433 on which the operation needs to be performed. The Watchdog module number can
434 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
435 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
436 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
437 module number 0 to 5 when they appear on the AXI switch Slave 6.
438
439 @return
440 This function does not return a value.
441 */
MSS_WD_reload(mss_watchdog_num_t wd_num)442 static inline void MSS_WD_reload(mss_watchdog_num_t wd_num)
443 {
444 if ((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
445 {
446 wdog_hw_base[wd_num]->REFRESH = MSS_WDOG_REFRESH_KEY;
447 }
448 }
449
450 /***************************************************************************//**
451 The MSS_WD_current_value() function returns the current value of the
452 watchdog's down-counter.
453
454 @param wd_num
455 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
456 on which the operation needs to be performed. The Watchdog module number can
457 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
458 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
459 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
460 module number 0 to 5 when the appear on the AXI switch Slave 6.
461
462 @return
463 This function returns the current value of the watchdog’s down-counter as
464 a 32-bit unsigned integer.
465 */
MSS_WD_current_value(mss_watchdog_num_t wd_num)466 static inline uint32_t MSS_WD_current_value(mss_watchdog_num_t wd_num)
467 {
468 return wdog_hw_base[wd_num]->REFRESH;
469 }
470
471 /***************************************************************************//**
472 The MSS_WD_forbidden_status() function returns the refresh status of the
473 MSS Watchdog.
474
475 @param wd_num
476 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
477 on which the operation needs to be performed. The Watchdog module number can
478 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
479 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
480 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
481 module number 0 to 5 when the appear on the AXI switch Slave 6.
482
483 @return
484 This function returns the refresh status of the watchdog. A value of 1
485 indicates that watchdog's down-counter is within the forbidden window and
486 that a reload should not be done. A value of 0 indicates that the watchdog's
487 down counter is within the permitted window and that a reload is allowed.
488 */
MSS_WD_forbidden_status(mss_watchdog_num_t wd_num)489 static inline uint32_t MSS_WD_forbidden_status(mss_watchdog_num_t wd_num)
490 {
491 return ((wdog_hw_base[wd_num]->STATUS & MSS_WDOG_FORBIDDEN_MASK) >>
492 MSS_WDOG_FORBIDDEN);
493 }
494
495 /***************************************************************************//**
496 The MSS_WD_enable_mvrp_irq() function enables the MVRP interrupt.
497 The MSS Watchdog 0 to 4 generate a local MVRP interrupt to HART0 to 4
498 respectively. At the same time these interrupts are also available over the
499 PLIC. This function allows you to choose which interrupt type should be
500 enabled for each interrupt. The corresponding interrupt handler gets called
501 when the interrupt asserts.
502
503 Note: The Watchdog MVRP interrupt handler default implementations are
504 weakly defined in the PolarFire SoC HAL. You must provide your own
505 implementation of these functions, which will override the default
506 implementation, to suit your application. Please refer mss_ints.h in the
507 MPFS HAL for the actual names and the prototypes of these functions.
508
509 Note: This function must be called from appropriate HART context.
510
511 @param wd_num
512 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
513 on which the operation needs to be performed. The Watchdog module number can
514 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
515 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
516 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
517 module number 0 to 5 when the appear on the AXI switch Slave 6.
518
519 @param intr_type
520 The intr_type parameter indicates the type of interrupt that must be enabled.
521 The MVRP interrupt for each hart can either be local interrupt to that hart
522 or it can be accessed as a PLIC interrupt.
523
524 @return
525 This function does not return a value.
526
527 Example:
528 @code
529 #include "mss_watchdog.h"
530 void e51( void )
531 {
532
533 MSS_WD_enable_mvrp_irq(wd_num);
534 for (;;)
535 {
536 main_task();
537 cortex_sleep();
538 }
539 }
540
541 void wdog0_mvrp_E51_local_IRQHandler_10(void)
542 {
543 process_timeout();
544 MSS_WD_clear_mvrp_irq();
545 }
546 @endcode
547 */
548 static inline void
MSS_WD_enable_mvrp_irq(mss_watchdog_num_t wd_num)549 MSS_WD_enable_mvrp_irq
550 (
551 mss_watchdog_num_t wd_num
552 )
553 {
554 if ((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
555 {
556 wdog_hw_base[wd_num]->CONTROL |= MSS_WDOG_INTEN_MVRP_MASK;
557 }
558 }
559
560 /***************************************************************************//**
561 The MSS_WD_disable_mvrp_irq() function disables the generation of the
562 MVRP interrupt.
563
564 Note: This function must be called from appropriate HART context.
565
566 @param wd_num
567 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
568 on which the operation needs to be performed. The Watchdog module number can
569 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
570 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
571 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
572 module number 0 to 5 when the appear on the AXI switch Slave 6.
573
574 @return
575 This function does not return a value.
576 */
577 static __inline void
MSS_WD_disable_mvrp_irq(mss_watchdog_num_t wd_num)578 MSS_WD_disable_mvrp_irq
579 (
580 mss_watchdog_num_t wd_num
581 )
582 {
583 if ((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
584 {
585 wdog_hw_base[wd_num]->CONTROL &= ~(MSS_WDOG_INTEN_MVRP_MASK);
586 }
587 }
588
589 /***************************************************************************//**
590 The MSS_WD_clear_timeout_irq() function clears the watchdog’s timeout
591 interrupt which is connected to the RISC-V NMI interrupt. Calling
592 MSS_WD_clear_timeout_irq() results in clearing the RISC-V NMI interrupt.
593 Note: You must call the MSS_WD_clear_timeout_irq() function as part of your
594 implementation of the wdog0_tout_u51_local_IRQHandler_9() timeout
595 interrupt service routine (ISR) in order to prevent the same interrupt
596 event re-triggering a call to the timeout ISR.
597
598 Note: This function must be called from appropriate HART context.
599
600 Note: The MSS_WD_enable_timeout_irq() and MSS_WD_disable_timeout_irq() are
601 removed as in the PolarFire SoC MSS Watchdog the timeout interrupt is
602 permanently enabled by default and it can not be disabled.
603
604 @param wd_num
605 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
606 on which the operation needs to be performed. The Watchdog module number can
607 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
608 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
609 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
610 module number 0 to 5 when the appear on the AXI switch Slave 6.
611
612 @return
613 This function does not return any value.
614
615 */
MSS_WD_clear_timeout_irq(mss_watchdog_num_t wd_num)616 static inline void MSS_WD_clear_timeout_irq(mss_watchdog_num_t wd_num)
617 {
618 if ((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
619 {
620 wdog_hw_base[wd_num]->STATUS |= MSS_WDOG_WDOG_TRIPPED_MASK;
621 /*
622 * Perform a second write to ensure that the first write completed before
623 * returning from this function. This is to account for posted writes across
624 * the AHB matrix. The second write ensures that the first write has
625 * completed and that the interrupt line has been de-asserted by the time
626 * the function returns. Omitting the second write may result in a delay
627 * in the de-assertion of the interrupt line going to the RISC-V and a
628 * retriggering of the interrupt.
629 */
630 wdog_hw_base[wd_num]->STATUS |= MSS_WDOG_WDOG_TRIPPED_MASK;
631 }
632 }
633
634 /***************************************************************************//**
635 The MSS_WD_clear_mvrp_irq() function clears the mvrp interrupt. This
636 function also clears the interrupt in the RISC-V interrupt controller
637 through a call to NVIC_ClearPendingIRQ().
638 Note: You must call the MSS_WD_clear_mvrp_irq() function as part of your
639 implementation of the wdog0_msvp_u51_local_IRQHandler_10() mvrp interrupt service
640 routine (ISR) in order to prevent the same interrupt event re-triggering
641 a call to the mvrp ISR.
642
643 @param wd_num
644 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
645 on which the operation needs to be performed. The Watchdog module number can
646 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
647 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
648 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
649 module number 0 to 5 when the appear on the AXI switch Slave 6.
650
651 @return
652 This function does not return a value.
653
654 */
MSS_WD_clear_mvrp_irq(mss_watchdog_num_t wd_num)655 static inline void MSS_WD_clear_mvrp_irq(mss_watchdog_num_t wd_num)
656 {
657 if ((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
658 {
659 wdog_hw_base[wd_num]->STATUS |= MSS_WDOG_MVRP_TRIPPED_MASK;
660 /*
661 * Perform a second write to ensure that the first write completed before
662 * returning from this function. This is to account for posted writes across
663 * the AHB matrix. The second write ensures that the first write has
664 * completed and that the interrupt line has been de-asserted by the time
665 * the function returns. Omitting the second write may result in a delay
666 * in the de-assertion of the interrupt line going to the RISC-V and a
667 * re-triggering of the interrupt.
668 */
669 wdog_hw_base[wd_num]->STATUS |= MSS_WDOG_MVRP_TRIPPED_MASK;
670 }
671 }
672
673 /***************************************************************************//**
674 The MSS_WD_timeout_occured() function reports the occurrence of a timeout
675 event.
676
677 @param wd_num
678 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
679 on which the operation needs to be performed. The Watchdog module number can
680 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
681 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
682 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
683 module number 0 to 5 when the appear on the AXI switch Slave 6.
684
685 @return
686 A zero value indicates no watchdog timeout event occurred. A value of 1
687 indicates that a timeout event occurred.
688
689 Example:
690 @code
691 #include "mss_watchdog.h"
692 void e51( void )
693 {
694 uint32_t wdg_reset;
695
696 wdg_reset = MSS_WD_timeout_occured();
697 if (wdg_reset)
698 {
699 log_watchdog_event();
700 MSS_WD_clear_timeout_event();
701 }
702
703 for(;;)
704 {
705 main_task();
706 }
707 }
708 */
MSS_WD_timeout_occured(mss_watchdog_num_t wd_num)709 static inline uint32_t MSS_WD_timeout_occured(mss_watchdog_num_t wd_num)
710 {
711 return((wdog_hw_base[wd_num]->STATUS & MSS_WDOG_TRIGGERED_MASK) >>
712 MSS_WDOG_TRIGGERED);
713 }
714
715 /***************************************************************************//**
716 The MSS_WD_force_reset() function is used to force an immediate reset
717 if the watchdog has already triggered. Writing any value in this condition
718 will cause an NMI sequence. Moreover any attempt to force reset when the
719 watchdog is not in triggered condition will also cause an NMI sequence.
720
721 @param wd_num
722 The wd_num parameter is the Watchdog module number in the PolarFire SoC MSS
723 on which the operation needs to be performed. The Watchdog module number can
724 be chosen using mss_watchdog_num_t. The MSS_WDOG0_LO to MSS_WDOG4_LO
725 correspond to the Watchdog module number 0 to 5 when the appear on the AXI
726 switch Slave 5. The MSS_WDOG0_HI to MSS_WDOG4_HI correspond to the watchdog
727 module number 0 to 5 when the appear on the AXI switch Slave 6.
728
729 @return
730 This function does not return a value.
731 */
MSS_WD_force_reset(mss_watchdog_num_t wd_num)732 static inline void MSS_WD_force_reset(mss_watchdog_num_t wd_num)
733 {
734 if (MSS_WDOG_TRIGGERED_MASK ==
735 (uint32_t)(wdog_hw_base[wd_num]->STATUS |
736 MSS_WDOG_TRIGGERED_MASK))
737 {
738 wdog_hw_base[wd_num]->FORCE = 0xDEADu;
739 }
740 else
741 {
742 wdog_hw_base[wd_num]->FORCE = 0x0u;
743 }
744 }
745
746 #ifdef __cplusplus
747 }
748 #endif
749
750 #endif /* MSS_WATCHDOG_H_ */
751