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_io.h"
20 #include "osal_irq.h"
21 #include "osal_mem.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 [%hu]", __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
TimerDumperAddDatas(struct TimerHi35xxInfo * info)161 static void TimerDumperAddDatas(struct TimerHi35xxInfo *info)
162 {
163 struct PlatformDumperData datas[] = {
164 {"HI35XX_TIMERx_LOAD", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_LOAD)},
165 {"HI35XX_TIMERx_VALUE", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_VALUE)},
166 {"HI35XX_TIMERx_CONTROL", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_CONTROL)},
167 {"HI35XX_TIMERx_INTCLR", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_INTCLR)},
168 {"HI35XX_TIMERx_RIS", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_RIS)},
169 {"HI35XX_TIMERx_MIS", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_MIS)},
170 {"HI35XX_TIMERx_BGLOAD", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_BGLOAD)},
171 };
172 if (info->dumper == NULL) {
173 return;
174 }
175
176 PlatformDumperAddDatas(info->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData));
177 }
178
179 // timer count clk
TimerHi35xxScCtrlSet(void)180 static void TimerHi35xxScCtrlSet(void)
181 {
182 volatile uint8_t *regBase =
183 (volatile void *)OsalIoRemap((uintptr_t)HI35XX_SC_CTRL_REG, TIMER_MAX_REG_SIZE);
184 if (regBase == NULL) {
185 HDF_LOGE("%s:OsalIoRemap fail", __func__);
186 return;
187 }
188 uint32_t value = TimerHi35xxRegRead(regBase);
189 value &= ~HI35XX_SC_CTRL_TIMEREN0OV;
190 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN0OV_SHIFT);
191 value &= ~HI35XX_SC_CTRL_TIMEREN1OV;
192 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN1OV_SHIFT);
193 value &= ~HI35XX_SC_CTRL_TIMEREN2OV;
194 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN2OV_SHIFT);
195 value &= ~HI35XX_SC_CTRL_TIMEREN3OV;
196 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN3OV_SHIFT);
197 value &= ~HI35XX_SC_CTRL_TIMEREN4OV;
198 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN4OV_SHIFT);
199 value &= ~HI35XX_SC_CTRL_TIMEREN5OV;
200 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN5OV_SHIFT);
201 value &= ~HI35XX_SC_CTRL_TIMEREN6OV;
202 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN6OV_SHIFT);
203 value &= ~HI35XX_SC_CTRL_TIMEREN7OV;
204 value |= (0x0 << HI35XX_SC_CTRL_TIMEREN7OV_SHIFT);
205 TimerHi35xxRegWrite(value, regBase);
206 TimerHi35xxRegRead(regBase);
207 OsalIoUnmap((void *)regBase);
208 regBase = NULL;
209 }
210
TimerHi35xxIrqHandle(uint32_t irqId,void * data)211 static uint32_t TimerHi35xxIrqHandle(uint32_t irqId, void *data)
212 {
213 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_OBJECT);
214 struct TimerHi35xxInfo *info = NULL;
215 info = (struct TimerHi35xxInfo *)data;
216
217 HDF_LOGD("------------->%s[%s]: timer[%u], irqId [%u] in ",
218 __func__, __TIME__, info->number, irqId);
219
220 // clear interrupt
221 TimerHi35xxIntClear(info);
222
223 CHECK_NULL_PTR_RETURN_VALUE(info->cb, HDF_ERR_INVALID_OBJECT);
224 info->cb(info->number);
225 HDF_LOGD("------------->%s: timer[%u], irqId [%u] process success", __func__, info->number, irqId);
226 return HDF_SUCCESS;
227 }
228
TimerHi35xxSet(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)229 static int32_t TimerHi35xxSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
230 {
231 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
232 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
233 CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
234
235 cntrl->info.useconds = useconds;
236 cntrl->info.cb = cb;
237 cntrl->info.isPeriod = true;
238
239 struct TimerHi35xxInfo *info = cntrl->priv;
240 info->cb = cb;
241 info->isPeriod = true;
242 HDF_LOGD("%s: timer[%u][%u][%d] ",
243 __func__, info->number, cntrl->info.useconds, cntrl->info.isPeriod);
244
245 if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD) != HDF_SUCCESS) {
246 HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
247 return HDF_FAILURE;
248 }
249 return HDF_SUCCESS;
250 }
251
TimerHi35xxSetOnce(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)252 static int32_t TimerHi35xxSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
253 {
254 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
255 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
256 CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
257
258 cntrl->info.useconds = useconds;
259 cntrl->info.cb = cb;
260 cntrl->info.isPeriod = false;
261
262 struct TimerHi35xxInfo *info = cntrl->priv;
263 info->cb = cb;
264 info->isPeriod = false;
265 if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_ONESHOT) != HDF_SUCCESS) {
266 HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
267 return HDF_FAILURE;
268 }
269 return HDF_SUCCESS;
270 }
271
TimerHi35xxSetTimeout(struct TimerCntrl * cntrl)272 static int32_t TimerHi35xxSetTimeout(struct TimerCntrl *cntrl)
273 {
274 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
275 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
276 unsigned int value;
277 unsigned int maxCnt = ~0x00; /* 32 bit counter */
278 unsigned int maxSeconds = maxCnt / HI35XX_TIMERx_CLOCK_HZ;
279
280 if (cntrl->info.useconds == 0 || (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) > maxSeconds) {
281 value = maxCnt;
282 } else {
283 value = (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) * HI35XX_TIMERx_CLOCK_HZ;
284 }
285
286 struct TimerHi35xxInfo *info = cntrl->priv;
287 OSAL_WRITEL(value, info->regBase + HI35XX_TIMERx_LOAD);
288
289 HDF_LOGD("%s: timer[%u] [%u][%u][%u] ", __func__, info->number, maxSeconds, value, cntrl->info.useconds);
290
291 return HDF_SUCCESS;
292 }
293
TimerHi35xxIrqRegister(struct TimerHi35xxInfo * info)294 static int32_t TimerHi35xxIrqRegister(struct TimerHi35xxInfo *info)
295 {
296 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
297
298 if (OsalRegisterIrq(info->irq, 0, TimerHi35xxIrqHandle, "timer_alarm", (void *)info) != HDF_SUCCESS) {
299 HDF_LOGE("%s: OsalRegisterIrq[%u][%u] fail!", __func__, info->irq, info->number);
300 return HDF_FAILURE;
301 }
302 info->isIrqReg = true;
303 return HDF_SUCCESS;
304 }
305
TimerHi35xxIrqUnregister(struct TimerHi35xxInfo * info)306 static int32_t TimerHi35xxIrqUnregister(struct TimerHi35xxInfo *info)
307 {
308 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
309
310 (void)OsalUnregisterIrq(info->irq, (void *)info);
311 info->isIrqReg = false;
312 return HDF_SUCCESS;
313 }
314
TimerHi35xxStart(struct TimerCntrl * cntrl)315 static int32_t TimerHi35xxStart(struct TimerCntrl *cntrl)
316 {
317 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
318 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
319 struct TimerHi35xxInfo *info = cntrl->priv;
320
321 int ret = TimerHi35xxIrqRegister(info);
322 if (ret != HDF_SUCCESS) {
323 HDF_LOGE("%s: TimerHi35xxIrqRegister fail!", __func__);
324 return HDF_FAILURE;
325 }
326
327 // not mask interrupt
328 ret = TimerHi35xxIntEnable(info, true);
329 if (ret != HDF_SUCCESS) {
330 HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
331 return HDF_FAILURE;
332 }
333
334 ret = TimerHi35xxSetTimeout(cntrl);
335 if (ret != HDF_SUCCESS) {
336 HDF_LOGE("%s: TimerHi35xxSetTimeout fail!", __func__);
337 return HDF_FAILURE;
338 }
339
340 ret = TimerHi35xxEnable(info, true);
341 if (ret != HDF_SUCCESS) {
342 HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
343 return HDF_FAILURE;
344 }
345 TimerHi35xxTimerGetAllReg(info);
346 TimerDumperAddDatas(info);
347 PlatformDumperDump(info->dumper);
348 return HDF_SUCCESS;
349 }
350
TimerHi35xxStop(struct TimerCntrl * cntrl)351 static int32_t TimerHi35xxStop(struct TimerCntrl *cntrl)
352 {
353 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
354 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
355 struct TimerHi35xxInfo *info = cntrl->priv;
356 int ret = TimerHi35xxEnable(info, false);
357 if (ret != HDF_SUCCESS) {
358 HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
359 return HDF_FAILURE;
360 }
361
362 ret = TimerHi35xxIntEnable(info, false);
363 if (ret != HDF_SUCCESS) {
364 HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
365 return HDF_FAILURE;
366 }
367
368 ret = TimerHi35xxIrqUnregister(info);
369 if (ret != HDF_SUCCESS) {
370 HDF_LOGE("%s: TimerHi35xxIrqUnregister fail!", __func__);
371 return HDF_FAILURE;
372 }
373 PlatformDumperDump(info->dumper);
374 return HDF_SUCCESS;
375 }
376
TimerHi35xxOpen(struct TimerCntrl * cntrl)377 static int32_t TimerHi35xxOpen(struct TimerCntrl *cntrl)
378 {
379 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
380 return HDF_SUCCESS;
381 }
382
TimerHi35xxClose(struct TimerCntrl * cntrl)383 static int32_t TimerHi35xxClose(struct TimerCntrl *cntrl)
384 {
385 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
386 TimerHi35xxStop(cntrl);
387 return HDF_SUCCESS;
388 }
389
TimerHi35xxRemove(struct TimerCntrl * cntrl)390 static int32_t TimerHi35xxRemove(struct TimerCntrl *cntrl)
391 {
392 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
393 CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
394 struct TimerHi35xxInfo *info = cntrl->priv;
395
396 TimerHi35xxStop(cntrl);
397 if (info->regBase != NULL) {
398 OsalIoUnmap((void *)info->regBase);
399 info->regBase = NULL;
400 }
401 PlatformDumperDestroy(info->dumper);
402 OsalMemFree(info->dumperName);
403
404 OsalMemFree(cntrl->priv);
405 cntrl->priv = NULL;
406 return HDF_SUCCESS;
407 }
408
409 static struct TimerCntrlMethod g_timerCntlrMethod = {
410 .Remove = TimerHi35xxRemove,
411 .Open = TimerHi35xxOpen,
412 .Close = TimerHi35xxClose,
413 .Set = TimerHi35xxSet,
414 .SetOnce = TimerHi35xxSetOnce,
415 .Start = TimerHi35xxStart,
416 .Stop = TimerHi35xxStop,
417 };
418
TimerHi35xxInitRegSet(struct TimerHi35xxInfo * info)419 static int32_t TimerHi35xxInitRegSet(struct TimerHi35xxInfo *info)
420 {
421 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
422 TimerHi35xxScCtrlSet();
423 TimerHi35xxEnable(info, false);
424 TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD);
425 TimerHi35xxIntEnable(info, false);
426 TimerHi35xxSetPre(info, TIMERx_CONTROL_TIMERPRE_NOT);
427 TimerHi35xxTimerSize(info, true);
428 TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
429
430 TimerHi35xxTimerLoadSet(info, HI35XX_TIMERx_LOAD_INIT_VAL);
431 return HDF_SUCCESS;
432 }
433
TimerHi35xxReadHcs(struct TimerHi35xxInfo * info,const struct DeviceResourceNode * node)434 static int32_t TimerHi35xxReadHcs(struct TimerHi35xxInfo *info, const struct DeviceResourceNode *node)
435 {
436 int32_t ret;
437 uint32_t tmp;
438 struct DeviceResourceIface *iface = NULL;
439
440 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
441 if (iface == NULL || iface->GetUint32 == NULL) {
442 HDF_LOGE("%s: invalid drs ops fail!", __func__);
443 return HDF_FAILURE;
444 }
445
446 ret = iface->GetUint32(node, "number", &info->number, 0);
447 if (ret != HDF_SUCCESS) {
448 HDF_LOGE("%s: read id fail!", __func__);
449 return HDF_FAILURE;
450 }
451
452 ret = iface->GetUint32(node, "bus_clock", &info->busClock, 0);
453 if (ret != HDF_SUCCESS) {
454 HDF_LOGE("%s: read [%u] bus_clock fail!", __func__, info->number);
455 return HDF_FAILURE;
456 }
457
458 ret = iface->GetUint32(node, "mode", &info->mode, 0);
459 if (ret != HDF_SUCCESS) {
460 HDF_LOGE("%s: read [%u] mode fail!", __func__, info->number);
461 return HDF_FAILURE;
462 }
463
464 ret = iface->GetUint32(node, "init_count_val", &info->initCountVal, 0);
465 if (ret != HDF_SUCCESS) {
466 HDF_LOGE("%s: read [%u] init_count_val fail!", __func__, info->number);
467 return HDF_FAILURE;
468 }
469
470 ret = iface->GetUint32(node, "irq", &info->irq, 0);
471 if (ret != HDF_SUCCESS) {
472 HDF_LOGE("%s: read [%u] irq fail!", __func__, info->number);
473 return HDF_FAILURE;
474 }
475
476 if (iface->GetUint32(node, "reg_base", &tmp, 0) != HDF_SUCCESS) {
477 HDF_LOGE("%s: read [%u] reg_base fail", __func__, info->number);
478 return HDF_FAILURE;
479 }
480 info->regBase = OsalIoRemap(tmp, TIMER_MAX_REG_SIZE);
481 if (info->regBase == NULL) {
482 HDF_LOGE("%s:OsalIoRemap fail", __func__);
483 return HDF_FAILURE;
484 }
485
486 HDF_LOGD("%s:number[%u], bus_clock[%u], mode[%u], init_count_val[%u] irq[%u]", __func__,
487 info->number, info->busClock, info->mode, info->initCountVal, info->irq);
488
489 return HDF_SUCCESS;
490 }
491
TimerHi35xxInitHandle(const struct DeviceResourceNode * node,struct TimerHi35xxInfo * info)492 static int32_t TimerHi35xxInitHandle(const struct DeviceResourceNode *node, struct TimerHi35xxInfo *info)
493 {
494 CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
495 CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
496
497 int32_t ret = TimerHi35xxReadHcs(info, node);
498 if (ret != HDF_SUCCESS) {
499 HDF_LOGE("%s: TimerHi35xxReadHcs fail!", __func__);
500 return ret;
501 }
502
503 ret = TimerHi35xxInitRegSet(info);
504 if (ret != HDF_SUCCESS) {
505 HDF_LOGE("%s: TimerHi35xxInitRegSet fail!", __func__);
506 return ret;
507 }
508 info->isIrqReg = false;
509
510 return HDF_SUCCESS;
511 }
512
TimerHi35xxInfoFree(struct TimerCntrl * cntrl)513 static void TimerHi35xxInfoFree(struct TimerCntrl *cntrl)
514 {
515 CHECK_NULL_PTR_RETURN(cntrl);
516 if (cntrl->priv != NULL) {
517 OsalMemFree(cntrl->priv);
518 cntrl->priv = NULL;
519 }
520
521 if (cntrl != NULL) {
522 OsalMemFree(cntrl);
523 }
524 }
525
TimerDumperGet(struct TimerHi35xxInfo * info)526 static void TimerDumperGet(struct TimerHi35xxInfo *info)
527 {
528 struct PlatformDumper *dumper = NULL;
529 char *name = (char *)OsalMemAlloc(TIMER_DUMPER_NAME_LEN);
530 if (name == NULL) {
531 return;
532 }
533 if (snprintf_s(name, TIMER_DUMPER_NAME_LEN, TIMER_DUMPER_NAME_LEN - 1, "%s%d",
534 TIMER_DUMPER_NAME_PREFIX, info->number) < 0) {
535 HDF_LOGE("%s: snprintf_s name fail!", __func__);
536 OsalMemFree(name);
537 return;
538 }
539 dumper = PlatformDumperCreate(name);
540 if (dumper == NULL) {
541 HDF_LOGE("%s: get dumper for %s fail!", __func__, name);
542 OsalMemFree(name);
543 return;
544 }
545 info->dumperName = name;
546 info->dumper = dumper;
547 }
548
TimerHi35xxParseAndInit(struct HdfDeviceObject * device,const struct DeviceResourceNode * node)549 static int32_t TimerHi35xxParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
550 {
551 int32_t ret;
552 struct TimerCntrl *cntrl = NULL;
553 struct TimerHi35xxInfo *info = NULL;
554 (void)device;
555
556 cntrl = (struct TimerCntrl *)OsalMemCalloc(sizeof(*cntrl));
557 CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
558
559 info = (struct TimerHi35xxInfo *)OsalMemCalloc(sizeof(*info));
560 if (cntrl == NULL) {
561 HDF_LOGE("%s: malloc info fail!", __func__);
562 TimerHi35xxInfoFree(cntrl);
563 return HDF_ERR_MALLOC_FAIL;
564 }
565 cntrl->priv = (void *)info;
566
567 ret = TimerHi35xxInitHandle(node, info);
568 if (ret != HDF_SUCCESS) {
569 HDF_LOGE("%s: TimerHi35xxInitHandle fail!", __func__);
570 TimerHi35xxInfoFree(cntrl);
571 return ret;
572 }
573
574 cntrl->info.number = info->number;
575 cntrl->ops = &g_timerCntlrMethod;
576 TimerDumperGet(info);
577 ret = TimerCntrlAdd(cntrl);
578 if (ret != HDF_SUCCESS) {
579 HDF_LOGE("%s: TimerCntrlAdd fail!", __func__);
580 TimerHi35xxInfoFree(cntrl);
581 return ret;
582 }
583 return HDF_SUCCESS;
584 }
585
TimerHi35xxDeviceInit(struct HdfDeviceObject * device)586 static int32_t TimerHi35xxDeviceInit(struct HdfDeviceObject *device)
587 {
588 int32_t ret;
589 const struct DeviceResourceNode *childNode = NULL;
590 if (device == NULL || device->property == NULL) {
591 HDF_LOGE("%s: device or property is NULL", __func__);
592 return HDF_ERR_INVALID_OBJECT;
593 }
594
595 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
596 ret = TimerHi35xxParseAndInit(device, childNode);
597 if (ret != HDF_SUCCESS) {
598 HDF_LOGE("%s:TimerHi35xxParseAndInit fail", __func__);
599 return HDF_FAILURE;
600 }
601 }
602 HDF_LOGD("%s: success", __func__);
603 return HDF_SUCCESS;
604 }
605
TimerHi35xxDeviceBind(struct HdfDeviceObject * device)606 static int32_t TimerHi35xxDeviceBind(struct HdfDeviceObject *device)
607 {
608 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT);
609 HDF_LOGI("%s: success", __func__);
610 return HDF_SUCCESS;
611 }
612
TimerHi35xxRemoveById(const struct DeviceResourceNode * node)613 static void TimerHi35xxRemoveById(const struct DeviceResourceNode *node)
614 {
615 int32_t ret;
616 uint32_t timerId;
617 struct DeviceResourceIface *drsOps = NULL;
618
619 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
620 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
621 HDF_LOGE("%s: invalid drs ops fail!", __func__);
622 return;
623 }
624
625 ret = drsOps->GetUint32(node, "id", (uint32_t *)&timerId, 0);
626 if (ret != HDF_SUCCESS) {
627 HDF_LOGE("%s: read id fail!", __func__);
628 return;
629 }
630
631 TimerCntrlRemoveByNumber(timerId);
632 return;
633 }
634
TimerHi35xxDeviceRelease(struct HdfDeviceObject * device)635 static void TimerHi35xxDeviceRelease(struct HdfDeviceObject *device)
636 {
637 const struct DeviceResourceNode *childNode = NULL;
638
639 HDF_LOGD("%s: in", __func__);
640 if (device == NULL || device->property == NULL) {
641 HDF_LOGE("%s: device is NULL", __func__);
642 return;
643 }
644
645 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
646 TimerHi35xxRemoveById(childNode);
647 }
648 }
649
650 struct HdfDriverEntry g_hdfTimerDevice = {
651 .moduleVersion = 1,
652 .moduleName = "hi35xx_timer_driver",
653 .Bind = TimerHi35xxDeviceBind,
654 .Init = TimerHi35xxDeviceInit,
655 .Release = TimerHi35xxDeviceRelease,
656 };
657
658 HDF_INIT(g_hdfTimerDevice);
659