1 /***************************************************************************//**
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * PolarFire SoC (MPFS) Microprocessor SubSystem Watchdog bare metal software
7  * driver implementation.
8  *
9  *
10  */
11 
12 #include "mpfs_hal/mss_hal.h"
13 #include "mss_watchdog.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 WATCHDOG_TypeDef* wdog_hw_base[10] = {(WATCHDOG_TypeDef*)0x20001000,
20                                       (WATCHDOG_TypeDef*)0x20101000,
21                                       (WATCHDOG_TypeDef*)0x20103000,
22                                       (WATCHDOG_TypeDef*)0x20105000,
23                                       (WATCHDOG_TypeDef*)0x20107000,
24                                       (WATCHDOG_TypeDef*)0x28001000,
25                                       (WATCHDOG_TypeDef*)0x28101000,
26                                       (WATCHDOG_TypeDef*)0x28103000,
27                                       (WATCHDOG_TypeDef*)0x28105000,
28                                       (WATCHDOG_TypeDef*)0x28107000};
29 
30 /***************************************************************************//**
31  * See mss_watchdog.h for details of how to use this function.
32  */
MSS_WD_configure(mss_watchdog_num_t wd_num,const mss_watchdog_config_t * config)33 uint8_t MSS_WD_configure
34 (
35     mss_watchdog_num_t wd_num,
36     const mss_watchdog_config_t * config
37 )
38 {
39     uint8_t error = 0u;
40 
41     /* Note that the MSVP register value must always be <= TIMER register value.
42       After any write to register from offset 0x00 to 0x0c the TRIGGER,MSVP and
43       TIME registers are locked. Hence write them in proper sequence.
44      */
45     if (config->timeout_val <= MSS_WDOG_TRIGGER_MAX)
46     {
47         wdog_hw_base[wd_num]->TRIGGER = config->timeout_val;
48     }
49     else
50     {
51         error = 1u;
52     }
53 
54     if (config->time_val <= MSS_WDOG_TIMER_MAX)
55     {
56         wdog_hw_base[wd_num]->MSVP = config->mvrp_val;
57     }
58     else
59     {
60         error = 1u;
61     }
62 
63     if (config->time_val <= MSS_WDOG_TIMER_MAX)
64     {
65         wdog_hw_base[wd_num]->TIME = config->time_val;
66     }
67     else
68     {
69         error = 1u;
70     }
71 
72     wdog_hw_base[wd_num]->CONTROL =  (uint32_t)(config->forbidden_en <<
73                                                          MSS_WDOG_ENA_FORBIDDEN);
74 
75     /* Reload watchdog with new load if it is not in forbidden window. */
76     if (!(MSS_WDOG_FORBIDDEN_MASK & wdog_hw_base[wd_num]->STATUS))
77     {
78         wdog_hw_base[wd_num]->REFRESH = MSS_WDOG_REFRESH_KEY;
79     }
80     else
81     {
82         error = 1u;
83     }
84 
85     return(error);
86 }
87 
88 /***************************************************************************//**
89  * See mss_watchdog.h for details of how to use this function.
90  */
MSS_WD_get_config(mss_watchdog_num_t wd_num,mss_watchdog_config_t * config)91 void MSS_WD_get_config
92 (
93     mss_watchdog_num_t wd_num, mss_watchdog_config_t* config
94 )
95 {
96     if((WATCHDOG_TypeDef*)0 != wdog_hw_base[wd_num])
97     {
98         config->time_val = wdog_hw_base[wd_num]->TIME;
99         config->timeout_val = wdog_hw_base[wd_num]->TRIGGER;
100         config->mvrp_val = wdog_hw_base[wd_num]->MSVP;
101 
102         config->forbidden_en = (uint8_t)((wdog_hw_base[wd_num]->CONTROL &
103                                 MSS_WDOG_ENA_FORBIDDEN_MASK)
104                                                         >> MSS_WDOG_ENA_FORBIDDEN);
105     }
106 }
107 
108 #ifdef __cplusplus
109 }
110 #endif
111 
112