1 /*
2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: i_qdf_time
22 * This file provides OS dependent time API's.
23 */
24
25 #ifndef _I_QDF_TIME_H
26 #define _I_QDF_TIME_H
27
28 #include <linux/version.h>
29 #include <linux/jiffies.h>
30 #include <linux/delay.h>
31 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
32 #include <linux/sched/clock.h>
33 #else
34 #include <linux/sched.h>
35 #endif
36 #include <linux/ktime.h>
37 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
38 #include <linux/timekeeping.h>
39 #else
40 #include <linux/hrtimer.h>
41 #endif
42 #ifdef MSM_PLATFORM
43 #include <asm/arch_timer.h>
44 #endif
45 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
46 #include <linux/sched/clock.h>
47 #else
48 #include <linux/sched.h>
49 #endif
50
51 typedef unsigned long __qdf_time_t;
52 typedef ktime_t __qdf_ktime_t;
53
54 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
55 typedef struct timespec64 __qdf_timespec_t;
56 #else
57 typedef struct timeval __qdf_timespec_t;
58 #endif
59
60 typedef struct work_struct __qdf_work_struct_t;
61
62 /**
63 * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object
64 * @ns: time in nanoseconds
65 *
66 * Return: nanoseconds as ktime object
67 */
__qdf_ns_to_ktime(uint64_t ns)68 static inline ktime_t __qdf_ns_to_ktime(uint64_t ns)
69 {
70 return ns_to_ktime(ns);
71 }
72
73 /**
74 * __qdf_ktime_add() - Adds two ktime objects and returns
75 * a ktime object
76 * @ktime1: time as ktime object
77 * @ktime2: time as ktime object
78 *
79 * Return: sum of ktime objects as ktime object
80 */
__qdf_ktime_add(ktime_t ktime1,ktime_t ktime2)81 static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2)
82 {
83 return ktime_add(ktime1, ktime2);
84 }
85
86 /**
87 * __qdf_ktime_get() - Gets the current time as ktime object
88 *
89 * Return: current time as ktime object
90 */
__qdf_ktime_get(void)91 static inline ktime_t __qdf_ktime_get(void)
92 {
93 return ktime_get();
94 }
95
96 /**
97 * __qdf_ktime_real_get() - Gets the current wall clock as ktime object
98 *
99 * Return: current wall clock as ktime object
100 */
__qdf_ktime_real_get(void)101 static inline ktime_t __qdf_ktime_real_get(void)
102 {
103 return ktime_get_real();
104 }
105
106 /**
107 * __qdf_ktime_get_ns() - Gets the current time nano seconds
108 *
109 * Return: ktime in nano sec
110 */
__qdf_ktime_get_ns(void)111 static inline ktime_t __qdf_ktime_get_ns(void)
112 {
113 return ktime_get_ns();
114 }
115
116 /**
117 * __qdf_ktime_get_real_ns() - Gets the current time in ns using UTC
118 *
119 * Return: ktime in nano sec
120 */
__qdf_ktime_get_real_ns(void)121 static inline ktime_t __qdf_ktime_get_real_ns(void)
122 {
123 return ktime_get_real_ns();
124 }
125
126 /**
127 * __qdf_ktime_compare - compare two qdf_ktime_t objects
128 * @ktime1: time as qdf_ktime_t object
129 * @ktime2: time as qdf_ktime_t object
130 *
131 * Return:
132 * * ktime1 < ktime2 - return <0
133 * * ktime1 == ktime2 - return 0
134 * * ktime1 > ktime2 - return >0
135 */
__qdf_ktime_compare(ktime_t ktime1,ktime_t ktime2)136 static inline int __qdf_ktime_compare(ktime_t ktime1, ktime_t ktime2)
137 {
138 return ktime_compare(ktime1, ktime2);
139 }
140
141 /**
142 * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and
143 * returns the ktime object
144 * @ktime: time as ktime object
145 * @ns: time in nanoseconds
146 *
147 * Return: ktime object
148 */
__qdf_ktime_add_ns(ktime_t ktime,int64_t ns)149 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns)
150 {
151 return ktime_add_ns(ktime, ns);
152 }
153
154 /**
155 * __qdf_ktime_to_ns() - convert ktime to nanoseconds
156 * @ktime: time as ktime object
157 *
158 * Return: ktime in nanoseconds
159 */
__qdf_ktime_to_ns(ktime_t ktime)160 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime)
161 {
162 return ktime_to_ns(ktime);
163 }
164
165 /**
166 * __qdf_ktime_to_ms() - convert ktime to milliseconds
167 * @ktime: time as ktime object
168 *
169 * Return: ktime in milliseconds
170 */
__qdf_ktime_to_ms(ktime_t ktime)171 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime)
172 {
173 return ktime_to_ms(ktime);
174 }
175
176 /**
177 * __qdf_system_ticks() - get system ticks
178 *
179 * Return: system tick in jiffies
180 */
__qdf_system_ticks(void)181 static inline __qdf_time_t __qdf_system_ticks(void)
182 {
183 return jiffies;
184 }
185
186 #define __qdf_system_ticks_per_sec HZ
187 /**
188 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds
189 * @ticks: System ticks
190 *
191 * Return: system tick converted into milli seconds
192 */
__qdf_system_ticks_to_msecs(unsigned long ticks)193 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks)
194 {
195 return jiffies_to_msecs(ticks);
196 }
197
198 /**
199 * __qdf_system_ticks_to_nsecs() - convert system ticks into nano seconds
200 * @ticks: System ticks
201 *
202 * Return: system tick converted into nano seconds
203 */
__qdf_system_ticks_to_nsecs(unsigned long ticks)204 static inline uint32_t __qdf_system_ticks_to_nsecs(unsigned long ticks)
205 {
206 return jiffies_to_nsecs(ticks);
207 }
208
209 /**
210 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks
211 * @msecs: Milli seconds
212 *
213 * Return: milli seconds converted into system ticks
214 */
__qdf_system_msecs_to_ticks(uint32_t msecs)215 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs)
216 {
217 return msecs_to_jiffies(msecs);
218 }
219
220 /**
221 * __qdf_get_system_uptime() - get system uptime
222 *
223 * Return: system uptime in jiffies
224 */
__qdf_get_system_uptime(void)225 static inline __qdf_time_t __qdf_get_system_uptime(void)
226 {
227 return jiffies;
228 }
229
__qdf_get_system_timestamp(void)230 static inline unsigned long __qdf_get_system_timestamp(void)
231 {
232 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ);
233 }
234
235 #ifdef CONFIG_ARM
236 /**
237 * __qdf_udelay() - delay execution for given microseconds
238 * @usecs: Micro seconds to delay
239 *
240 * Return: none
241 */
__qdf_udelay(uint32_t usecs)242 static inline void __qdf_udelay(uint32_t usecs)
243 {
244 /*
245 * This is in support of XScale build. They have a limit on the udelay
246 * value, so we have to make sure we don't approach the limit
247 */
248 uint32_t mticks;
249 uint32_t leftover;
250 int i;
251 /* slice into 1024 usec chunks (simplifies calculation) */
252 mticks = usecs >> 10;
253 leftover = usecs - (mticks << 10);
254 for (i = 0; i < mticks; i++)
255 udelay(1024);
256 udelay(leftover);
257 }
258 #else
__qdf_udelay(uint32_t usecs)259 static inline void __qdf_udelay(uint32_t usecs)
260 {
261 /* Normal Delay functions. Time specified in microseconds */
262 udelay(usecs);
263 }
264 #endif
265
266 /**
267 * __qdf_mdelay() - delay execution for given milliseconds
268 * @msecs: Milliseconds to delay
269 *
270 * Return: none
271 */
__qdf_mdelay(uint32_t msecs)272 static inline void __qdf_mdelay(uint32_t msecs)
273 {
274 mdelay(msecs);
275 }
276
277 /**
278 * __qdf_system_time_after() - Check if a is later than b
279 * @a: Time stamp value a
280 * @b: Time stamp value b
281 *
282 * Return:
283 * true if a > b else false
284 */
__qdf_system_time_after(__qdf_time_t a,__qdf_time_t b)285 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b)
286 {
287 return (long)((b) - (a)) < 0;
288 }
289
290 /**
291 * __qdf_system_time_before() - Check if a is before b
292 * @a: Time stamp value a
293 * @b: Time stamp value b
294 *
295 * Return:
296 * true if a is before b else false
297 */
__qdf_system_time_before(__qdf_time_t a,__qdf_time_t b)298 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b)
299 {
300 return __qdf_system_time_after(b, a);
301 }
302
303 /**
304 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
305 * later
306 * @a: Time stamp value a
307 * @b: Time stamp value b
308 *
309 * Return:
310 * true if a >= b else false
311 */
__qdf_system_time_after_eq(__qdf_time_t a,__qdf_time_t b)312 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b)
313 {
314 return (long)((a) - (b)) >= 0;
315 }
316
317 /**
318 * __qdf_sched_clock() - use light weight timer to get timestamp
319 *
320 * Return: timestamp in ns
321 */
__qdf_sched_clock(void)322 static inline uint64_t __qdf_sched_clock(void)
323 {
324 return sched_clock();
325 }
326
327 /**
328 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time
329 * This API is similar to qdf_get_system_boottime but it includes
330 * time spent in suspend.
331 *
332 * Return: Time in microseconds
333 */
__qdf_get_monotonic_boottime(void)334 static inline uint64_t __qdf_get_monotonic_boottime(void)
335 {
336 return (uint64_t)ktime_to_us(ktime_get_boottime());
337 }
338
339 #if defined (MSM_PLATFORM)
340 /**
341 * __qdf_get_log_timestamp() - get msm timer ticks
342 *
343 * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds
344 * divide it by 19200.
345 *
346 * Return: QTIMER(19.2 MHz) clock ticks
347 */
348 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
__qdf_get_log_timestamp(void)349 static inline uint64_t __qdf_get_log_timestamp(void)
350 {
351 return __arch_counter_get_cntvct();
352 }
353 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
__qdf_get_log_timestamp(void)354 static inline uint64_t __qdf_get_log_timestamp(void)
355 {
356 return arch_counter_get_cntvct();
357 }
358 #else
__qdf_get_log_timestamp(void)359 static inline uint64_t __qdf_get_log_timestamp(void)
360 {
361 return arch_counter_get_cntpct();
362 }
363 #endif /* LINUX_VERSION_CODE */
364 #else
365
366 /**
367 * __qdf_get_log_timestamp - get time stamp for logging
368 *
369 * Return: system tick for non MSM platforms
370 */
371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
__qdf_get_log_timestamp(void)372 static inline uint64_t __qdf_get_log_timestamp(void)
373 {
374 struct timespec64 ts;
375
376 ktime_get_ts64(&ts);
377
378 return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
379 }
380 #else
__qdf_get_log_timestamp(void)381 static inline uint64_t __qdf_get_log_timestamp(void)
382 {
383 struct timespec ts;
384
385 ktime_get_ts(&ts);
386
387 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
388 }
389 #endif
390 #endif
391
392 /**
393 * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
394 *
395 * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
396 * that have elapsed since the system was booted. It also includes the time when
397 * system was suspended.
398 *
399 * Return:
400 * The time since system booted in nanoseconds
401 */
402
403 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
__qdf_get_bootbased_boottime_ns(void)404 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
405 {
406 return ktime_get_boottime_ns();
407 }
408
409 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
__qdf_get_bootbased_boottime_ns(void)410 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
411 {
412 return ktime_get_boot_ns();
413 }
414
415 #else
__qdf_get_bootbased_boottime_ns(void)416 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
417 {
418 return ktime_to_ns(ktime_get_boottime());
419 }
420 #endif
421
422 /**
423 * __qdf_time_ms_to_ktime() - Converts milliseconds to a ktime object
424 * @ms: time in milliseconds
425 *
426 * Return: milliseconds as ktime object
427 */
__qdf_time_ms_to_ktime(uint64_t ms)428 static inline ktime_t __qdf_time_ms_to_ktime(uint64_t ms)
429 {
430 return ms_to_ktime(ms);
431 }
432
433 /**
434 * __qdf_time_ktime_real_get() - Gets the current wall clock as ktime object
435 *
436 * Return: current wall clock as ktime object
437 */
__qdf_time_ktime_real_get(void)438 static inline ktime_t __qdf_time_ktime_real_get(void)
439 {
440 return ktime_get_real();
441 }
442
443 /**
444 * __qdf_time_sched_clock() - schedule clock
445 *
446 * Return: returns current time in nanosec units.
447 */
__qdf_time_sched_clock(void)448 static inline unsigned long long __qdf_time_sched_clock(void)
449 {
450 return sched_clock();
451 }
452
453 /**
454 * __qdf_time_ktime_sub() - Subtract two ktime objects and returns
455 * a ktime object
456 * @ktime1: time as ktime object
457 * @ktime2: time as ktime object
458 *
459 * Return: subtraction of ktime objects as ktime object
460 */
__qdf_time_ktime_sub(ktime_t ktime1,ktime_t ktime2)461 static inline ktime_t __qdf_time_ktime_sub(ktime_t ktime1, ktime_t ktime2)
462 {
463 return ktime_sub(ktime1, ktime2);
464 }
465
466 /**
467 * __qdf_time_ktime_set() - Set a ktime_t variable from a seconds/nanoseconds
468 * value
469 * @secs: seconds to set
470 * @nsecs: nanoseconds to set
471 *
472 * Return: The ktime_t representation of the value.
473 */
__qdf_time_ktime_set(const s64 secs,const unsigned long nsecs)474 static inline ktime_t __qdf_time_ktime_set(const s64 secs,
475 const unsigned long nsecs)
476 {
477 return ktime_set(secs, nsecs);
478 }
479
480 /**
481 * __qdf_time_ktime_to_us() - Convert the ktime_t object into microseconds
482 * @ktime: time as ktime_t object
483 *
484 * Return: ktime_t in microseconds
485 */
__qdf_time_ktime_to_us(ktime_t ktime)486 static inline int64_t __qdf_time_ktime_to_us(ktime_t ktime)
487 {
488 return ktime_to_us(ktime);
489 }
490
491 /**
492 * __qdf_time_ktime_get_real_time() - Get the time of day in qdf_timespec_t
493 * @ts: pointer to the qdf_timespec_t to be set
494 *
495 * Return: none
496 */
497 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
__qdf_time_ktime_get_real_time(__qdf_timespec_t * ts)498 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts)
499 {
500 ktime_get_real_ts64(ts);
501 }
502 #else
__qdf_time_ktime_get_real_time(__qdf_timespec_t * ts)503 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts)
504 {
505 do_gettimeofday(ts);
506 }
507 #endif
508
__qdf_usleep_range(unsigned long min,unsigned long max)509 static inline void __qdf_usleep_range(unsigned long min, unsigned long max)
510 {
511 usleep_range(min, max);
512 }
513 #endif
514