• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include "device_resource_if.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "watchdog_if.h"
23 #include "watchdog_core.h"
24 #include "hpm_ewdg_drv.h"
25 #include "hpm_soc.h"
26 
27 #define HDF_LOG_TAG HPMICRO_WATCHDOG_HDF
28 #define EWDG_CNT_CLK_FREQ 32768UL
29 
30 struct HPMWatchdogDevice {
31     uint32_t id;
32     uint32_t base;
33     int32_t status;
34     uint32_t timeoutSeconds;
35 };
36 
GetStatus(struct WatchdogCntlr * wdt,int32_t * status)37 static int32_t GetStatus(struct WatchdogCntlr *wdt, int32_t *status)
38 {
39     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
40     *status = hpmDev->status;
41     HDF_LOGD("ID: %u, GetStatus: %d\n", hpmDev->id, *status);
42     return HDF_SUCCESS;
43 }
44 
SetTimeout(struct WatchdogCntlr * wdt,uint32_t seconds)45 static int32_t SetTimeout(struct WatchdogCntlr *wdt, uint32_t seconds)
46 {
47     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
48 
49     hpmDev->timeoutSeconds = seconds;
50     HDF_LOGD("ID: %u, SetTimeout: %d\n",hpmDev->id, seconds);
51     return HDF_SUCCESS;
52 }
53 
GetTimeout(struct WatchdogCntlr * wdt,uint32_t * seconds)54 static int32_t GetTimeout(struct WatchdogCntlr *wdt, uint32_t *seconds)
55 {
56     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
57 
58     *seconds = hpmDev->timeoutSeconds;
59     HDF_LOGD("ID: %u, GetTimeout: %d\n",hpmDev->id, *seconds);
60     return HDF_SUCCESS;
61 }
62 
Start(struct WatchdogCntlr * wdt)63 static int32_t Start(struct WatchdogCntlr *wdt)
64 {
65     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
66     EWDG_Type *base = (EWDG_Type *)hpmDev->base;
67 
68     ewdg_config_t config;
69     ewdg_get_default_config(base, &config);
70 
71     config.enable_watchdog = true;
72     config.int_rst_config.enable_timeout_reset = true;
73     config.ctrl_config.use_lowlevel_timeout = false;
74     uint32_t ewdg_src_clk_freq = EWDG_CNT_CLK_FREQ;
75     config.ctrl_config.cnt_clk_sel = ewdg_cnt_clk_src_ext_osc_clk;
76 
77     /* Set the EWDG reset timeout to 1 second */
78     config.cnt_src_freq = ewdg_src_clk_freq;
79     config.ctrl_config.timeout_reset_us = hpmDev->timeoutSeconds *1000000;
80 
81     /* Initialize the WDG */
82     hpm_stat_t status = ewdg_init(base, &config);
83     if (status != status_success) {
84         printf(" EWDG initialization failed, error_code=%d\n", status);
85     }
86 
87     hpmDev->status = WATCHDOG_START;
88     HDF_LOGD("ID: %u, Start", hpmDev->id);
89     return HDF_SUCCESS;
90 }
91 
Stop(struct WatchdogCntlr * wdt)92 static int32_t Stop(struct WatchdogCntlr *wdt)
93 {
94     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
95     EWDG_Type *base = (EWDG_Type *)hpmDev->base;
96     ewdg_disable(base);
97     hpmDev->status = WATCHDOG_STOP;
98     HDF_LOGD("ID: %u, Stop", hpmDev->id);
99     return HDF_SUCCESS;
100 }
101 
Feed(struct WatchdogCntlr * wdt)102 static int32_t Feed(struct WatchdogCntlr *wdt)
103 {
104     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
105     EWDG_Type *base = (EWDG_Type *)hpmDev->base;
106     ewdg_refresh(base);
107     return HDF_SUCCESS;
108 }
109 
110 static struct WatchdogMethod watchdogOps = {
111     .getStatus = GetStatus,
112     .setTimeout = SetTimeout,
113     .getTimeout = GetTimeout,
114     .start = Start,
115     .stop = Stop,
116     .feed = Feed,
117 };
118 
WatchdogDriverBind(struct HdfDeviceObject * device)119 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device)
120 {
121     int32_t ret = HDF_SUCCESS;
122     struct WatchdogCntlr *watchdogCntlr;
123 
124     if (device == NULL) {
125         ret = HDF_FAILURE;
126         HDF_LOGE("Bind: HdfDeviceObject null\n");
127         return ret;
128     }
129 
130     watchdogCntlr = (struct WatchdogCntlr *)OsalMemCalloc(sizeof(struct WatchdogCntlr));
131     if (watchdogCntlr == NULL) {
132         ret = HDF_ERR_MALLOC_FAIL;
133         HDF_LOGE("Bind: Services malloc Failed!!!\n");
134         return ret;
135     }
136 
137     watchdogCntlr->device = device;
138     watchdogCntlr->ops = &watchdogOps;
139 
140     ret = WatchdogCntlrAdd(watchdogCntlr);
141     if (ret) {
142         HDF_LOGE("Bind: WatchdogCntlrAdd Failed: %d!!!\n", ret);
143         OsalMemFree(watchdogCntlr);
144         return ret;
145     }
146 
147     HDF_LOGI("Bind: successed\n");
148     return ret;
149 }
150 
WatchdogDriverInit(struct HdfDeviceObject * device)151 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device)
152 {
153     int32_t ret = HDF_SUCCESS;
154 
155     struct WatchdogCntlr *watchdogCntlr = WatchdogCntlrFromDevice(device);
156     if (watchdogCntlr == NULL) {
157         ret = HDF_FAILURE;
158         HDF_LOGE("Init: get WatchdogCntlr Failed!!!\n");
159         goto ERROR1;
160     }
161 
162     struct HPMWatchdogDevice *hpmWdtDev = (struct HPMWatchdogDevice *)OsalMemCalloc(
163                                         sizeof(struct HPMWatchdogDevice));
164     if (hpmWdtDev == NULL) {
165         ret = HDF_ERR_MALLOC_FAIL;
166         HDF_LOGE("Init: HPMWatchdogDevice malloc Failed!!!\n");
167         goto ERROR1;
168     }
169 
170     struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
171     if (dri == NULL) {
172         ret = HDF_FAILURE;
173         HDF_LOGE("Init: get DeviceResourceIface Failed!!!\n");
174         goto ERROR2;
175     }
176 
177     dri->GetUint32(device->property, "id", &hpmWdtDev->id, 0);
178     dri->GetUint32(device->property, "base", &hpmWdtDev->base, 0);
179     HDF_LOGI("Init: hpmWdtDev->id: %u\n", hpmWdtDev->id);
180     HDF_LOGI("Init: hpmWdtDev->base: 0x%X\n", hpmWdtDev->base);
181 
182     watchdogCntlr->wdtId = hpmWdtDev->id;
183     watchdogCntlr->priv = hpmWdtDev;
184 
185     return ret;
186 
187 ERROR2:
188     OsalMemFree(hpmWdtDev);
189 ERROR1:
190     return ret;
191 }
192 
WatchdogDriverRelease(struct HdfDeviceObject * device)193 static void WatchdogDriverRelease(struct HdfDeviceObject *device)
194 {
195     if (device == NULL) {
196         return;
197     }
198 
199     struct WatchdogCntlr *watchdogCntlr = WatchdogCntlrFromDevice(device);
200     if (watchdogCntlr) {
201         OsalMemFree(watchdogCntlr);
202     }
203     HDF_LOGI("Release");
204     return;
205 }
206 
207 
208 struct HdfDriverEntry g_watchdogDriverEntry = {
209     .moduleVersion = 1,
210     .moduleName = "HPMICRO_WATCHDOG_MODULE_HDF",
211     .Bind = WatchdogDriverBind,
212     .Init = WatchdogDriverInit,
213     .Release = WatchdogDriverRelease,
214 };
215 
216 HDF_INIT(g_watchdogDriverEntry);