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