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