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);