1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 #include "timer_hi35xx.h"
16 #include "device_resource_if.h"
17 #include "hdf_base.h"
18 #include "hdf_log.h"
19 #include "osal_mem.h"
20 #include "osal_io.h"
21 #include "osal_irq.h"
22
23 #define HDF_LOG_TAG timer_hi35xx
24
TimerHi35xxRegWrite(uint32_t value,volatile uint8_t * addr)25 static int32_t TimerHi35xxRegWrite(uint32_t value, volatile uint8_t *addr)
26 {
27 CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT);
28
29 OSAL_WRITEL(value, addr);
30 return HDF_SUCCESS;
31 }
32
TimerHi35xxRegRead(volatile uint8_t * addr)33 static uint32_t TimerHi35xxRegRead(volatile uint8_t *addr)
34 {
35 CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT);
36
37 uint32_t val = OSAL_READL(addr);
38 return val;
39 }
40
TimerHi35xxEnable(struct TimerHi35xxInfo * info,bool enable)41 static int32_t TimerHi35xxEnable(struct TimerHi35xxInfo *info, bool enable)
42 {
43 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
44 uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
45 if (enable) {
46 value &= ~TIMERx_CONTROL_TIMEREN;
47 value |= (0x1 << TIMERx_CONTROL_TIMEREN_SHIFT);
48 } else {
49 value &= ~TIMERx_CONTROL_TIMEREN;
50 value |= (0x0 << TIMERx_CONTROL_TIMEREN_SHIFT);
51 }
52 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
53 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
54 return HDF_SUCCESS;
55 }
56
57 // once or period
TimerHi35xxSetMode(struct TimerHi35xxInfo * info,uint16_t mode)58 static int32_t TimerHi35xxSetMode(struct TimerHi35xxInfo *info, uint16_t mode)
59 {
60 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
61 uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
62 if ((mode == TIMERx_CONTROL_TIMERMODE_PERIOD) || (mode == TIMERx_CONTROL_TIMERMODE_FREE)) {
63 value &= ~TIMERx_CONTROL_TIMERMODE;
64 value |= (mode << TIMERx_CONTROL_TIMERMODE_SHIFT);
65 } else { // one shot
66 value &= ~TIMERx_CONTROL_ONESHOT;
67 value |= (TIMERx_CONTROL_TIMERMODE_ONESHOT_ONE << TIMERx_CONTROL_ONESHOT_SHIFT);
68 }
69
70 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
71 return HDF_SUCCESS;
72 }
73
74 // divide frequence
TimerHi35xxSetPre(struct TimerHi35xxInfo * info,uint16_t pre)75 static int32_t TimerHi35xxSetPre(struct TimerHi35xxInfo *info, uint16_t pre)
76 {
77 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
78 uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
79 uint32_t tmpVal;
80 switch (pre) {
81 case TIMERx_CONTROL_TIMERPRE_NOT:
82 tmpVal = TIMERx_CONTROL_TIMERPRE_NOT;
83 break;
84 case TIMERx_CONTROL_TIMERPRE_4_LEVEL:
85 tmpVal = TIMERx_CONTROL_TIMERPRE_4_LEVEL;
86 break;
87 case TIMERx_CONTROL_TIMERPRE_8_LEVEL:
88 case TIMERx_CONTROL_TIMERPRE_UNDEFINE:
89 tmpVal = TIMERx_CONTROL_TIMERPRE_8_LEVEL;
90 break;
91 default:
92 HDF_LOGE("%s: unsupported pre [%u]", __func__, pre);
93 return HDF_ERR_INVALID_PARAM;
94 }
95 value &= ~TIMERx_CONTROL_TIMERPRE;
96 value |= (tmpVal << TIMERx_CONTROL_TIMERPRE_SHIFT);
97 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
98 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
99 return HDF_SUCCESS;
100 }
101
102 // mask interrupts true:not mask; false mask
TimerHi35xxIntEnable(struct TimerHi35xxInfo * info,bool enable)103 static int32_t TimerHi35xxIntEnable(struct TimerHi35xxInfo *info, bool enable)
104 {
105 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
106 uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
107 if (enable) {
108 value &= ~TIMERx_CONTROL_INTENABLE;
109 value |= (0x1 << TIMERx_CONTROL_INTENABLE_SHIFT);
110 } else {
111 value &= ~TIMERx_CONTROL_INTENABLE;
112 value |= (0x0 << TIMERx_CONTROL_INTENABLE_SHIFT);
113 }
114 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
115 return HDF_SUCCESS;
116 }
117
118 // clear timer interrupt
TimerHi35xxIntClear(struct TimerHi35xxInfo * info)119 static int32_t TimerHi35xxIntClear(struct TimerHi35xxInfo *info)
120 {
121 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
122 TimerHi35xxRegWrite(0x0, info->regBase + HI35XX_TIMERx_INTCLR);
123 return HDF_SUCCESS;
124 }
125
TimerHi35xxTimerSize(struct TimerHi35xxInfo * info,bool is32Bit)126 static int32_t TimerHi35xxTimerSize(struct TimerHi35xxInfo *info, bool is32Bit)
127 {
128 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
129 uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
130 if (is32Bit) { // 1:32 bit
131 value &= ~TIMERx_CONTROL_TIMERSIZE;
132 value |= (0x1 << TIMERx_CONTROL_TIMERSIZE_SHIFT);
133 } else { // 0:16 bit
134 value &= ~TIMERx_CONTROL_TIMERSIZE;
135 value |= (0x0 << TIMERx_CONTROL_TIMERSIZE_SHIFT);
136 }
137 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
138 return HDF_SUCCESS;
139 }
140
141 // timer count value
TimerHi35xxTimerLoadSet(struct TimerHi35xxInfo * info,uint32_t value)142 static int32_t TimerHi35xxTimerLoadSet(struct TimerHi35xxInfo *info, uint32_t value)
143 {
144 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
145
146 TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_LOAD);
147 return HDF_SUCCESS;
148 }
149
TimerHi35xxTimerGetAllReg(struct TimerHi35xxInfo * info)150 static void TimerHi35xxTimerGetAllReg(struct TimerHi35xxInfo *info)
151 {
152 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_LOAD);
153 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_VALUE);
154 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
155 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_INTCLR);
156 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_RIS);
157 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_MIS);
158 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_BGLOAD);
159 }
160
161 // timer count clk
TimerHi35xxScCtrlSet(void)162 static void TimerHi35xxScCtrlSet(void)
163 {
164 volatile uint8_t *regBase =
165 (volatile void *)OsalIoRemap((uintptr_t)HI35XX_SC_CTRL_REG, TIMER_MAX_REG_SIZE);
166 if (regBase == NULL) {
167 HDF_LOGE("%s:OsalIoRemap fail", __func__);
168 return;
169 }
170 uint32_t value = TimerHi35xxRegRead(regBase);
171 value &= ~HI35XX_SC_CTRL_TIMEREN0OV;
172 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN0OV_SHIFT);
173 value &= ~HI35XX_SC_CTRL_TIMEREN1OV;
174 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN1OV_SHIFT);
175 value &= ~HI35XX_SC_CTRL_TIMEREN2OV;
176 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN2OV_SHIFT);
177 value &= ~HI35XX_SC_CTRL_TIMEREN3OV;
178 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN3OV_SHIFT);
179 value &= ~HI35XX_SC_CTRL_TIMEREN4OV;
180 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN4OV_SHIFT);
181 value &= ~HI35XX_SC_CTRL_TIMEREN5OV;
182 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN5OV_SHIFT);
183 value &= ~HI35XX_SC_CTRL_TIMEREN6OV;
184 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN6OV_SHIFT);
185 value &= ~HI35XX_SC_CTRL_TIMEREN7OV;
186 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN7OV_SHIFT);
187 TimerHi35xxRegWrite(value, regBase);
188 TimerHi35xxRegRead(regBase);
189 OsalIoUnmap((void*)regBase);
190 regBase = NULL;
191 }
192
TimerHi35xxIrqHandle(uint32_t irqId,void * data)193 static uint32_t TimerHi35xxIrqHandle(uint32_t irqId, void *data)
194 {
195 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_OBJECT);
196 struct TimerHi35xxInfo *info = NULL;
197 info = (struct TimerHi35xxInfo *)data;
198
199 HDF_LOGD("------------->%s[%s]: timer[%u], irqId [%u] in ",
200 __func__, __TIME__, info->number, irqId);
201
202 // clear interrupt
203 TimerHi35xxIntClear(info);
204
205 CHECK_NULL_PTR_RETURN_VALUE(info->cb, HDF_ERR_INVALID_OBJECT);
206 info->cb();
207 HDF_LOGD("------------->%s: timer[%u], irqId [%u] process success", __func__, info->number, irqId);
208 return HDF_SUCCESS;
209 }
210
TimerHi35xxSet(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)211 static int32_t TimerHi35xxSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
212 {
213 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
214 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
215 CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
216
217 cntrl->info.useconds = useconds;
218 cntrl->info.cb = cb;
219 cntrl->info.isPeriod = true;
220
221 struct TimerHi35xxInfo *info = cntrl->priv;
222 info->cb = cb;
223 info->isPeriod = true;
224 HDF_LOGD("%s: timer[%u][%d][%d] ",
225 __func__, info->number, cntrl->info.useconds, cntrl->info.isPeriod);
226
227 if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD) != HDF_SUCCESS) {
228 HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
229 return HDF_FAILURE;
230 }
231 return HDF_SUCCESS;
232 }
233
TimerHi35xxSetOnce(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)234 static int32_t TimerHi35xxSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
235 {
236 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
237 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
238 CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
239
240 cntrl->info.useconds = useconds;
241 cntrl->info.cb = cb;
242 cntrl->info.isPeriod = false;
243
244 struct TimerHi35xxInfo *info = cntrl->priv;
245 info->cb = cb;
246 info->isPeriod = false;
247 if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_ONESHOT) != HDF_SUCCESS) {
248 HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
249 return HDF_FAILURE;
250 }
251 return HDF_SUCCESS;
252 }
253
TimerHi35xxSetTimeout(struct TimerCntrl * cntrl)254 static int32_t TimerHi35xxSetTimeout(struct TimerCntrl *cntrl)
255 {
256 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
257 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
258 unsigned int value;
259 unsigned int maxCnt = ~0x00; /* 32 bit counter */
260 unsigned int maxSeconds = maxCnt / HI35XX_TIMERx_CLOCK_HZ;
261
262 if (cntrl->info.useconds == 0 || (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) > maxSeconds) {
263 value = maxCnt;
264 } else {
265 value = (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) * HI35XX_TIMERx_CLOCK_HZ;
266 }
267
268 struct TimerHi35xxInfo *info = cntrl->priv;
269 OSAL_WRITEL(value, info->regBase + HI35XX_TIMERx_LOAD);
270
271 HDF_LOGD("%s: timer[%u] [%d][%d][%d] ", __func__, info->number, maxSeconds, value, cntrl->info.useconds);
272
273 return HDF_SUCCESS;
274 }
275
TimerHi35xxIrqRegister(struct TimerHi35xxInfo * info)276 static int32_t TimerHi35xxIrqRegister(struct TimerHi35xxInfo *info)
277 {
278 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
279
280 if (OsalRegisterIrq(info->irq, 0, TimerHi35xxIrqHandle, "timer_alarm", (void*)info) != HDF_SUCCESS) {
281 HDF_LOGE("%s: OsalRegisterIrq[%u][%u] fail!", __func__, info->irq, info->number);
282 return HDF_FAILURE;
283 }
284 info->isIrqReg = true;
285 return HDF_SUCCESS;
286 }
287
TimerHi35xxIrqUnregister(struct TimerHi35xxInfo * info)288 static int32_t TimerHi35xxIrqUnregister(struct TimerHi35xxInfo *info)
289 {
290 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
291
292 (void)OsalUnregisterIrq(info->irq, (void *)info);
293 info->isIrqReg = false;
294 return HDF_SUCCESS;
295 }
296
TimerHi35xxStart(struct TimerCntrl * cntrl)297 static int32_t TimerHi35xxStart(struct TimerCntrl *cntrl)
298 {
299 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
300 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
301 struct TimerHi35xxInfo *info = cntrl->priv;
302
303 int ret = TimerHi35xxIrqRegister(info);
304 if (ret != HDF_SUCCESS) {
305 HDF_LOGE("%s: TimerHi35xxIrqRegister fail!", __func__);
306 return HDF_FAILURE;
307 }
308
309 // not mask interrupt
310 ret = TimerHi35xxIntEnable(info, true);
311 if (ret != HDF_SUCCESS) {
312 HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
313 return HDF_FAILURE;
314 }
315
316 ret = TimerHi35xxSetTimeout(cntrl);
317 if (ret != HDF_SUCCESS) {
318 HDF_LOGE("%s: TimerHi35xxSetTimeout fail!", __func__);
319 return HDF_FAILURE;
320 }
321
322 ret = TimerHi35xxEnable(info, true);
323 if (ret != HDF_SUCCESS) {
324 HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
325 return HDF_FAILURE;
326 }
327 TimerHi35xxTimerGetAllReg(info);
328 return HDF_SUCCESS;
329 }
330
TimerHi35xxStop(struct TimerCntrl * cntrl)331 static int32_t TimerHi35xxStop(struct TimerCntrl *cntrl)
332 {
333 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
334 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
335 struct TimerHi35xxInfo *info = cntrl->priv;
336 int ret = TimerHi35xxEnable(info, false);
337 if (ret != HDF_SUCCESS) {
338 HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
339 return HDF_FAILURE;
340 }
341
342 ret = TimerHi35xxIntEnable(info, false);
343 if (ret != HDF_SUCCESS) {
344 HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
345 return HDF_FAILURE;
346 }
347
348 ret = TimerHi35xxIrqUnregister(info);
349 if (ret != HDF_SUCCESS) {
350 HDF_LOGE("%s: TimerHi35xxIrqUnregister fail!", __func__);
351 return HDF_FAILURE;
352 }
353 return HDF_SUCCESS;
354 }
355
TimerHi35xxOpen(struct TimerCntrl * cntrl)356 static int32_t TimerHi35xxOpen(struct TimerCntrl *cntrl)
357 {
358 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
359 return HDF_SUCCESS;
360 }
361
TimerHi35xxClose(struct TimerCntrl * cntrl)362 static int32_t TimerHi35xxClose(struct TimerCntrl *cntrl)
363 {
364 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
365 TimerHi35xxStop(cntrl);
366 return HDF_SUCCESS;
367 }
368
TimerHi35xxRemove(struct TimerCntrl * cntrl)369 static int32_t TimerHi35xxRemove(struct TimerCntrl *cntrl)
370 {
371 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
372 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
373 struct TimerHi35xxInfo *info = cntrl->priv;
374
375 TimerHi35xxStop(cntrl);
376 if (info->regBase != NULL) {
377 OsalIoUnmap((void*)info->regBase);
378 info->regBase = NULL;
379 }
380
381 OsalMemFree(cntrl->priv);
382 cntrl->priv = NULL;
383 return HDF_SUCCESS;
384 }
385
386 static struct TimerCntrlMethod g_timerCntlrMethod = {
387 .Remove = TimerHi35xxRemove,
388 .Open = TimerHi35xxOpen,
389 .Close = TimerHi35xxClose,
390 .Set = TimerHi35xxSet,
391 .SetOnce = TimerHi35xxSetOnce,
392 .Start = TimerHi35xxStart,
393 .Stop = TimerHi35xxStop,
394 };
395
TimerHi35xxInitRegSet(struct TimerHi35xxInfo * info)396 static int32_t TimerHi35xxInitRegSet(struct TimerHi35xxInfo *info)
397 {
398 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
399 TimerHi35xxScCtrlSet();
400 TimerHi35xxEnable(info, false);
401 TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD);
402 TimerHi35xxIntEnable(info, false);
403 TimerHi35xxSetPre(info, TIMERx_CONTROL_TIMERPRE_NOT);
404 TimerHi35xxTimerSize(info, true);
405 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
406
407 TimerHi35xxTimerLoadSet(info, HI35XX_TIMERx_LOAD_INIT_VAL);
408 return HDF_SUCCESS;
409 }
410
TimerHi35xxReadHcs(struct TimerHi35xxInfo * info,const struct DeviceResourceNode * node)411 static int32_t TimerHi35xxReadHcs(struct TimerHi35xxInfo *info, const struct DeviceResourceNode *node)
412 {
413 int32_t ret;
414 uint32_t tmp;
415 struct DeviceResourceIface *iface = NULL;
416
417 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
418 if (iface == NULL || iface->GetUint32 == NULL) {
419 HDF_LOGE("%s: invalid drs ops fail!", __func__);
420 return HDF_FAILURE;
421 }
422
423 ret = iface->GetUint32(node, "number", &info->number, 0);
424 if (ret != HDF_SUCCESS) {
425 HDF_LOGE("%s: read id fail!", __func__);
426 return HDF_FAILURE;
427 }
428
429 ret = iface->GetUint32(node, "bus_clock", &info->busClock, 0);
430 if (ret != HDF_SUCCESS) {
431 HDF_LOGE("%s: read [%u] bus_clock fail!", __func__, info->number);
432 return HDF_FAILURE;
433 }
434
435 ret = iface->GetUint32(node, "mode", &info->mode, 0);
436 if (ret != HDF_SUCCESS) {
437 HDF_LOGE("%s: read [%u] mode fail!", __func__, info->number);
438 return HDF_FAILURE;
439 }
440
441 ret = iface->GetUint32(node, "init_count_val", &info->initCountVal, 0);
442 if (ret != HDF_SUCCESS) {
443 HDF_LOGE("%s: read [%u] init_count_val fail!", __func__, info->number);
444 return HDF_FAILURE;
445 }
446
447 ret = iface->GetUint32(node, "irq", &info->irq, 0);
448 if (ret != HDF_SUCCESS) {
449 HDF_LOGE("%s: read [%u] irq fail!", __func__, info->number);
450 return HDF_FAILURE;
451 }
452
453 if (iface->GetUint32(node, "reg_base", &tmp, 0) != HDF_SUCCESS) {
454 HDF_LOGE("%s: read [%u] reg_base fail", __func__, info->number);
455 return HDF_FAILURE;
456 }
457 info->regBase = OsalIoRemap(tmp, TIMER_MAX_REG_SIZE);
458 if (info->regBase == NULL) {
459 HDF_LOGE("%s:OsalIoRemap fail", __func__);
460 return HDF_FAILURE;
461 }
462 HDF_LOGD("%s:regBase[0x%x][%px]", __func__, tmp, info->regBase);
463
464 HDF_LOGD("%s:number[%u], bus_clock[%d], mode[%d], init_count_val[%d] irq[%u]", __func__,
465 info->number, info->busClock, info->mode, info->initCountVal, info->irq);
466
467 return HDF_SUCCESS;
468 }
469
TimerHi35xxInitHandle(const struct DeviceResourceNode * node,struct TimerHi35xxInfo * info)470 static int32_t TimerHi35xxInitHandle(const struct DeviceResourceNode *node, struct TimerHi35xxInfo *info)
471 {
472 CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
473 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
474
475 int32_t ret = TimerHi35xxReadHcs(info, node);
476 if (ret != HDF_SUCCESS) {
477 HDF_LOGE("%s: TimerHi35xxReadHcs fail!", __func__);
478 return ret;
479 }
480
481 ret = TimerHi35xxInitRegSet(info);
482 if (ret != HDF_SUCCESS) {
483 HDF_LOGE("%s: TimerHi35xxInitRegSet fail!", __func__);
484 return ret;
485 }
486 info->isIrqReg = false;
487
488 return HDF_SUCCESS;
489 }
490
TimerHi35xxInfoFree(struct TimerCntrl * cntrl)491 static void TimerHi35xxInfoFree(struct TimerCntrl *cntrl)
492 {
493 CHECK_NULL_PTR_RETURN(cntrl);
494 if (cntrl->priv != NULL) {
495 OsalMemFree(cntrl->priv);
496 cntrl->priv = NULL;
497 }
498
499 if (cntrl != NULL) {
500 OsalMemFree(cntrl);
501 }
502 }
TimerHi35xxParseAndInit(struct HdfDeviceObject * device,const struct DeviceResourceNode * node)503 static int32_t TimerHi35xxParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
504 {
505 int32_t ret;
506 struct TimerCntrl *cntrl = NULL;
507 struct TimerHi35xxInfo *info = NULL;
508 (void)device;
509
510 cntrl = (struct TimerCntrl *)OsalMemCalloc(sizeof(*cntrl));
511 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
512
513 info = (struct TimerHi35xxInfo *)OsalMemCalloc(sizeof(*info));
514 if (cntrl == NULL) {
515 HDF_LOGE("%s: malloc info fail!", __func__);
516 TimerHi35xxInfoFree(cntrl);
517 return HDF_ERR_MALLOC_FAIL;
518 }
519 cntrl->priv = (void *)info;
520
521 ret = TimerHi35xxInitHandle(node, info);
522 if (ret != HDF_SUCCESS) {
523 HDF_LOGE("%s: TimerHi35xxInitHandle fail!", __func__);
524 TimerHi35xxInfoFree(cntrl);
525 return ret;
526 }
527
528 cntrl->info.number = info->number;
529 cntrl->ops = &g_timerCntlrMethod;
530 ret = TimerCntrlAdd(cntrl);
531 if (ret != HDF_SUCCESS) {
532 HDF_LOGE("%s: TimerCntrlAdd fail!", __func__);
533 TimerHi35xxInfoFree(cntrl);
534 return ret;
535 }
536 return HDF_SUCCESS;
537 }
538
TimerHi35xxDeviceInit(struct HdfDeviceObject * device)539 static int32_t TimerHi35xxDeviceInit(struct HdfDeviceObject *device)
540 {
541 int32_t ret;
542 const struct DeviceResourceNode *childNode = NULL;
543 if (device == NULL || device->property == NULL) {
544 HDF_LOGE("%s: device or property is NULL", __func__);
545 return HDF_ERR_INVALID_OBJECT;
546 }
547
548 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
549 ret = TimerHi35xxParseAndInit(device, childNode);
550 if (ret != HDF_SUCCESS) {
551 HDF_LOGE("%s:TimerHi35xxParseAndInit fail", __func__);
552 return HDF_FAILURE;
553 }
554 }
555 HDF_LOGD("%s: success", __func__);
556 return HDF_SUCCESS;
557 }
558
TimerHi35xxDeviceBind(struct HdfDeviceObject * device)559 static int32_t TimerHi35xxDeviceBind(struct HdfDeviceObject *device)
560 {
561 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT);
562 HDF_LOGD("%s: success", __func__);
563 return HDF_SUCCESS;
564 }
565
TimerHi35xxRemoveById(const struct DeviceResourceNode * node)566 static void TimerHi35xxRemoveById(const struct DeviceResourceNode *node)
567 {
568 int32_t ret;
569 uint32_t timerId;
570 struct DeviceResourceIface *drsOps = NULL;
571
572 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
573 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
574 HDF_LOGE("%s: invalid drs ops fail!", __func__);
575 return;
576 }
577
578 ret = drsOps->GetUint32(node, "id", (uint32_t *)&timerId, 0);
579 if (ret != HDF_SUCCESS) {
580 HDF_LOGE("%s: read id fail!", __func__);
581 return;
582 }
583
584 TimerCntrlRemoveByNumber(timerId);
585 return;
586 }
587
TimerHi35xxDeviceRelease(struct HdfDeviceObject * device)588 static void TimerHi35xxDeviceRelease(struct HdfDeviceObject *device)
589 {
590 const struct DeviceResourceNode *childNode = NULL;
591 HDF_LOGD("%s: in", __func__);
592 if (device == NULL || device->property == NULL) {
593 HDF_LOGE("%s: device is NULL", __func__);
594 return;
595 }
596
597 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
598 TimerHi35xxRemoveById(childNode);
599 }
600
601 HDF_LOGD("%s: success", __func__);
602 }
603
604 struct HdfDriverEntry g_hdfTimerDevice = {
605 .moduleVersion = 1,
606 .moduleName = "hi35xx_timer_driver",
607 .Bind = TimerHi35xxDeviceBind,
608 .Init = TimerHi35xxDeviceInit,
609 .Release = TimerHi35xxDeviceRelease,
610 };
611
612 HDF_INIT(g_hdfTimerDevice);
613