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_get_ns() - Gets the current time nano seconds 108 * 109 * Return: ktime in nano sec 110 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 225 static inline __qdf_time_t __qdf_get_system_uptime(void) 226 { 227 return jiffies; 228 } 229 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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)) 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)) 354 static inline uint64_t __qdf_get_log_timestamp(void) 355 { 356 return arch_counter_get_cntvct(); 357 } 358 #else 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)) 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 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)) 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)) 410 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 411 { 412 return ktime_get_boot_ns(); 413 } 414 415 #else 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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) 498 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts) 499 { 500 ktime_get_real_ts64(ts); 501 } 502 #else 503 static inline void __qdf_time_ktime_get_real_time(__qdf_timespec_t *ts) 504 { 505 do_gettimeofday(ts); 506 } 507 #endif 508 509 static inline void __qdf_usleep_range(unsigned long min, unsigned long max) 510 { 511 usleep_range(min, max); 512 } 513 #endif 514