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