xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
2  * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * DOC: i_qdf_time
30  * This file provides OS dependent time API's.
31  */
32 
33 #ifndef _I_QDF_TIME_H
34 #define _I_QDF_TIME_H
35 
36 #include <linux/jiffies.h>
37 #include <linux/delay.h>
38 #include <linux/ktime.h>
39 #include <linux/timekeeping.h>
40 #ifdef MSM_PLATFORM
41 #include <asm/arch_timer.h>
42 #endif
43 #ifdef CONFIG_CNSS
44 #include <net/cnss.h>
45 #endif
46 #include <linux/version.h>
47 
48 typedef unsigned long __qdf_time_t;
49 typedef ktime_t  __qdf_ktime_t;
50 
51 /**
52  * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object
53  * @ns: time in nanoseconds
54  *
55  * Return: nanoseconds as ktime object
56  */
57 static inline ktime_t __qdf_ns_to_ktime(uint64_t ns)
58 {
59 	return ns_to_ktime(ns);
60 }
61 
62 /**
63  * __qdf_ktime_add() - Adds two ktime objects and returns
64  * a ktime object
65  * @time1: time as ktime object
66  * @time2: time as ktime object
67  *
68  * Return: sum of ktime objects as ktime object
69  */
70 static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2)
71 {
72 	return ktime_add(ktime1, ktime2);
73 }
74 
75 /**
76  * __qdf_ktime_get() - Gets the current time as ktime object
77  *
78  * Return: current time as ktime object
79  */
80 static inline ktime_t __qdf_ktime_get(void)
81 {
82 	return ktime_get();
83 }
84 
85 /**
86  * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and
87  * returns the ktime object
88  *
89  * Return: ktime object
90  */
91 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns)
92 {
93 	return ktime_add_ns(ktime, ns);
94 }
95 
96 /**
97  * __qdf_ktime_to_ns() - convert ktime to nanoseconds
98  * @ktime: time as ktime object
99  * @ns: time in nanoseconds
100  *
101  * Return: ktime in nanoseconds
102  */
103 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime)
104 {
105 	return ktime_to_ns(ktime);
106 }
107 
108 /**
109  * __qdf_ktime_to_ms() - convert ktime to milliseconds
110  * @ktime: time as ktime object
111  *
112  * Return: ktime in milliseconds
113  */
114 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime)
115 {
116 	return ktime_to_ms(ktime);
117 }
118 
119 
120 /**
121  * __qdf_system_ticks() - get system ticks
122  *
123  * Return: system tick in jiffies
124  */
125 static inline __qdf_time_t __qdf_system_ticks(void)
126 {
127 	return jiffies;
128 }
129 
130 /**
131  * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds
132  * @ticks: System ticks
133  *
134  * Return: system tick converted into milli seconds
135  */
136 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks)
137 {
138 	return jiffies_to_msecs(ticks);
139 }
140 
141 /**
142  * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks
143  * @msecs: Milli seconds
144  *
145  * Return: milli seconds converted into system ticks
146  */
147 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs)
148 {
149 	return msecs_to_jiffies(msecs);
150 }
151 
152 /**
153  * __qdf_get_system_uptime() - get system uptime
154  *
155  * Return: system uptime in jiffies
156  */
157 static inline __qdf_time_t __qdf_get_system_uptime(void)
158 {
159 	return jiffies;
160 }
161 
162 static inline unsigned long __qdf_get_system_timestamp(void)
163 {
164 	return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ);
165 }
166 
167 #ifdef CONFIG_ARM
168 /**
169  * __qdf_udelay() - delay execution for given microseconds
170  * @usecs: Micro seconds to delay
171  *
172  * Return: none
173  */
174 static inline void __qdf_udelay(uint32_t usecs)
175 {
176 	/*
177 	 * This is in support of XScale build.  They have a limit on the udelay
178 	 * value, so we have to make sure we don't approach the limit
179 	 */
180 	uint32_t mticks;
181 	uint32_t leftover;
182 	int i;
183 	/* slice into 1024 usec chunks (simplifies calculation) */
184 	mticks = usecs >> 10;
185 	leftover = usecs - (mticks << 10);
186 	for (i = 0; i < mticks; i++)
187 		udelay(1024);
188 	udelay(leftover);
189 }
190 #else
191 static inline void __qdf_udelay(uint32_t usecs)
192 {
193 	/* Normal Delay functions. Time specified in microseconds */
194 	udelay(usecs);
195 }
196 #endif
197 
198 /**
199  * __qdf_mdelay() - delay execution for given milliseconds
200  * @usecs: Milliseconds to delay
201  *
202  * Return: none
203  */
204 static inline void __qdf_mdelay(uint32_t msecs)
205 {
206 	mdelay(msecs);
207 }
208 
209 /**
210  * __qdf_system_time_after() - Check if a is later than b
211  * @a: Time stamp value a
212  * @b: Time stamp value b
213  *
214  * Return:
215  * true if a < b else false
216  */
217 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b)
218 {
219 	return (long)(b) - (long)(a) < 0;
220 }
221 
222 /**
223  * __qdf_system_time_before() - Check if a is before b
224  * @a: Time stamp value a
225  * @b: Time stamp value b
226  *
227  * Return:
228  * true if a is before b else false
229  */
230 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b)
231 {
232 	return __qdf_system_time_after(b, a);
233 }
234 
235 /**
236  * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
237  * later
238  * @a: Time stamp value a
239  * @b: Time stamp value b
240  *
241  * Return:
242  * true if a >= b else false
243  */
244 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b)
245 {
246 	return (long)(a) - (long)(b) >= 0;
247 }
248 
249 /**
250  * __qdf_get_monotonic_boottime() - get monotonic kernel boot time
251  * This API is similar to qdf_get_system_boottime but it includes
252  * time spent in suspend.
253  *
254  * Return: Time in microseconds
255  */
256 static inline uint64_t __qdf_get_monotonic_boottime(void)
257 {
258 	struct timespec ts;
259 
260 	get_monotonic_boottime(&ts);
261 
262 	return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
263 }
264 
265 #if defined (QCA_WIFI_3_0_ADRASTEA) && defined (MSM_PLATFORM)
266 
267 /**
268  * __qdf_get_log_timestamp() - get QTIMER ticks
269  *
270  * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds
271  * divide it by 19200.
272  *
273  * Return: QTIMER(19.2 MHz) clock ticks
274  */
275 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
276 static inline uint64_t __qdf_get_log_timestamp(void)
277 {
278 	return arch_counter_get_cntvct();
279 }
280 #else
281 static inline uint64_t __qdf_get_log_timestamp(void)
282 {
283 	return arch_counter_get_cntpct();
284 }
285 #endif /* LINUX_VERSION_CODE */
286 #else
287 
288 /**
289  * __qdf_get_log_timestamp - get time stamp for logging
290  * For adrastea this API returns QTIMER tick which is needed to synchronize
291  * host and fw log timestamps
292  * For ROME and other discrete solution this API returns system boot time stamp
293  *
294  * Return:
295  * QTIMER ticks(19.2MHz) for adrastea
296  * System tick for rome and other future discrete solutions
297  */
298 static inline uint64_t __qdf_get_log_timestamp(void)
299 {
300 	struct timespec ts;
301 
302 	ktime_get_ts(&ts);
303 
304 	return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
305 }
306 #endif /* QCA_WIFI_3_0_ADRASTEA */
307 
308 #endif
309