• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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