xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h (revision 839714c413056bc9b82af766295b4ffabe28bbbf)
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  */
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  */
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  */
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  */
101 static inline ktime_t __qdf_ktime_real_get(void)
102 {
103 	return ktime_get_real();
104 }
105 
106 /**
107  * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and
108  *                        returns the ktime object
109  * @ktime: time as ktime object
110  * @ns: time in nanoseconds
111  *
112  * Return: ktime object
113  */
114 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns)
115 {
116 	return ktime_add_ns(ktime, ns);
117 }
118 
119 /**
120  * __qdf_ktime_to_ns() - convert ktime to nanoseconds
121  * @ktime: time as ktime object
122  *
123  * Return: ktime in nanoseconds
124  */
125 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime)
126 {
127 	return ktime_to_ns(ktime);
128 }
129 
130 /**
131  * __qdf_ktime_to_ms() - convert ktime to milliseconds
132  * @ktime: time as ktime object
133  *
134  * Return: ktime in milliseconds
135  */
136 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime)
137 {
138 	return ktime_to_ms(ktime);
139 }
140 
141 
142 /**
143  * __qdf_system_ticks() - get system ticks
144  *
145  * Return: system tick in jiffies
146  */
147 static inline __qdf_time_t __qdf_system_ticks(void)
148 {
149 	return jiffies;
150 }
151 
152 #define __qdf_system_ticks_per_sec HZ
153 
154 /**
155  * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds
156  * @ticks: System ticks
157  *
158  * Return: system tick converted into milli seconds
159  */
160 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks)
161 {
162 	return jiffies_to_msecs(ticks);
163 }
164 
165 /**
166  * __qdf_system_ticks_to_nsecs() - convert system ticks into nano seconds
167  * @ticks: System ticks
168  *
169  * Return: system tick converted into nano seconds
170  */
171 static inline uint32_t __qdf_system_ticks_to_nsecs(unsigned long ticks)
172 {
173 	return jiffies_to_nsecs(ticks);
174 }
175 
176 /**
177  * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks
178  * @msecs: Milli seconds
179  *
180  * Return: milli seconds converted into system ticks
181  */
182 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs)
183 {
184 	return msecs_to_jiffies(msecs);
185 }
186 
187 /**
188  * __qdf_get_system_uptime() - get system uptime
189  *
190  * Return: system uptime in jiffies
191  */
192 static inline __qdf_time_t __qdf_get_system_uptime(void)
193 {
194 	return jiffies;
195 }
196 
197 static inline unsigned long __qdf_get_system_timestamp(void)
198 {
199 	return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ);
200 }
201 
202 #ifdef CONFIG_ARM
203 /**
204  * __qdf_udelay() - delay execution for given microseconds
205  * @usecs: Micro seconds to delay
206  *
207  * Return: none
208  */
209 static inline void __qdf_udelay(uint32_t usecs)
210 {
211 	/*
212 	 * This is in support of XScale build.  They have a limit on the udelay
213 	 * value, so we have to make sure we don't approach the limit
214 	 */
215 	uint32_t mticks;
216 	uint32_t leftover;
217 	int i;
218 	/* slice into 1024 usec chunks (simplifies calculation) */
219 	mticks = usecs >> 10;
220 	leftover = usecs - (mticks << 10);
221 	for (i = 0; i < mticks; i++)
222 		udelay(1024);
223 	udelay(leftover);
224 }
225 #else
226 static inline void __qdf_udelay(uint32_t usecs)
227 {
228 	/* Normal Delay functions. Time specified in microseconds */
229 	udelay(usecs);
230 }
231 #endif
232 
233 /**
234  * __qdf_mdelay() - delay execution for given milliseconds
235  * @msecs: Milliseconds to delay
236  *
237  * Return: none
238  */
239 static inline void __qdf_mdelay(uint32_t msecs)
240 {
241 	mdelay(msecs);
242 }
243 
244 /**
245  * __qdf_system_time_after() - Check if a is later than b
246  * @a: Time stamp value a
247  * @b: Time stamp value b
248  *
249  * Return:
250  * true if a < b else false
251  */
252 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b)
253 {
254 	return (long)(b) - (long)(a) < 0;
255 }
256 
257 /**
258  * __qdf_system_time_before() - Check if a is before b
259  * @a: Time stamp value a
260  * @b: Time stamp value b
261  *
262  * Return:
263  * true if a is before b else false
264  */
265 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b)
266 {
267 	return __qdf_system_time_after(b, a);
268 }
269 
270 /**
271  * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
272  * later
273  * @a: Time stamp value a
274  * @b: Time stamp value b
275  *
276  * Return:
277  * true if a >= b else false
278  */
279 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b)
280 {
281 	return (long)(a) - (long)(b) >= 0;
282 }
283 
284 /**
285  * __qdf_sched_clock() - use light weight timer to get timestamp
286  *
287  * Return: timestamp in ns
288  */
289 static inline uint64_t __qdf_sched_clock(void)
290 {
291 	return sched_clock();
292 }
293 
294 /**
295  * __qdf_get_monotonic_boottime() - get monotonic kernel boot time
296  * This API is similar to qdf_get_system_boottime but it includes
297  * time spent in suspend.
298  *
299  * Return: Time in microseconds
300  */
301 static inline uint64_t __qdf_get_monotonic_boottime(void)
302 {
303 	return (uint64_t)ktime_to_us(ktime_get_boottime());
304 }
305 
306 #if defined (MSM_PLATFORM)
307 
308 /**
309  * __qdf_get_log_timestamp() - get msm timer ticks
310  *
311  * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds
312  * divide it by 19200.
313  *
314  * Return: QTIMER(19.2 MHz) clock ticks
315  */
316 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
317 static inline uint64_t __qdf_get_log_timestamp(void)
318 {
319 	return __arch_counter_get_cntvct();
320 }
321 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
322 static inline uint64_t __qdf_get_log_timestamp(void)
323 {
324 	return arch_counter_get_cntvct();
325 }
326 #else
327 static inline uint64_t __qdf_get_log_timestamp(void)
328 {
329 	return arch_counter_get_cntpct();
330 }
331 #endif /* LINUX_VERSION_CODE */
332 #else
333 
334 /**
335  * __qdf_get_log_timestamp - get time stamp for logging
336  *
337  * Return: system tick for non MSM platforms
338  */
339 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
340 static inline uint64_t __qdf_get_log_timestamp(void)
341 {
342 	struct timespec64 ts;
343 
344 	ktime_get_ts64(&ts);
345 
346 	return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
347 }
348 #else
349 static inline uint64_t __qdf_get_log_timestamp(void)
350 {
351 	struct timespec ts;
352 
353 	ktime_get_ts(&ts);
354 
355 	return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
356 }
357 #endif
358 #endif
359 
360 /**
361  * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
362  *
363  * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
364  * that have elapsed since the system was booted. It also includes the time when
365  * system was suspended.
366  *
367  * Return:
368  * The time since system booted in nanoseconds
369  */
370 
371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
372 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
373 {
374 	return ktime_get_boottime_ns();
375 }
376 
377 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
378 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
379 {
380 	return ktime_get_boot_ns();
381 }
382 
383 #else
384 static inline uint64_t __qdf_get_bootbased_boottime_ns(void)
385 {
386 	return ktime_to_ns(ktime_get_boottime());
387 }
388 #endif
389 
390 /**
391  * __qdf_time_ms_to_ktime() - Converts milliseconds to a ktime object
392  * @ms: time in milliseconds
393  *
394  * Return: milliseconds as ktime object
395  */
396 static inline ktime_t __qdf_time_ms_to_ktime(uint64_t ms)
397 {
398 	return ms_to_ktime(ms);
399 }
400 
401 /**
402  * __qdf_time_ktime_real_get() - Gets the current wall clock as ktime object
403  *
404  * Return: current wall clock as ktime object
405  */
406 static inline ktime_t __qdf_time_ktime_real_get(void)
407 {
408 	return ktime_get_real();
409 }
410 
411 /**
412  * __qdf_time_sched_clock() - schedule clock
413  *
414  * Return: returns current time in nanosec units.
415  */
416 static inline unsigned long long __qdf_time_sched_clock(void)
417 {
418 	return sched_clock();
419 }
420 
421 /**
422  * __qdf_time_ktime_sub() - Subtract two ktime objects and returns
423  * a ktime object
424  * @ktime1: time as ktime object
425  * @ktime2: time as ktime object
426  *
427  * Return: subtraction of ktime objects as ktime object
428  */
429 static inline ktime_t __qdf_time_ktime_sub(ktime_t ktime1, ktime_t ktime2)
430 {
431 	return ktime_sub(ktime1, ktime2);
432 }
433 
434 /**
435  * __qdf_time_ktime_set() - Set a ktime_t variable from a seconds/nanoseconds
436  * value
437  * @secs: seconds to set
438  * @nsecs: nanoseconds to set
439  *
440  * Return: The ktime_t representation of the value.
441  */
442 static inline ktime_t __qdf_time_ktime_set(const s64 secs,
443 					   const unsigned long nsecs)
444 {
445 	return ktime_set(secs, nsecs);
446 }
447 
448 /**
449  * __qdf_time_ktime_to_us() - Convert the ktime_t object into microseconds
450  * @ktime: time as ktime_t object
451  *
452  * Return: ktime_t in microseconds
453  */
454 static inline int64_t __qdf_time_ktime_to_us(ktime_t ktime)
455 {
456 	return ktime_to_us(ktime);
457 }
458 
459 /**
460  * __qdf_time_ktime_get_real_time() - Get the time of day in qdf_timespec_t
461  * @ts: pointer to the qdf_timespec_t to be set
462  *
463  * Return: none
464  */
465 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
466 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts)
467 {
468 	ktime_get_real_ts64(ts);
469 }
470 #else
471 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts)
472 {
473 	do_gettimeofday(ts);
474 }
475 #endif
476 
477 #endif
478