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