1 /* 2 * Copyright (c) 2014-2020 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 #include <linux/ktime.h> 31 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 32 #include <linux/timekeeping.h> 33 #else 34 #include <linux/hrtimer.h> 35 #endif 36 #ifdef MSM_PLATFORM 37 #include <asm/arch_timer.h> 38 #endif 39 40 typedef unsigned long __qdf_time_t; 41 typedef ktime_t __qdf_ktime_t; 42 43 /** 44 * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object 45 * @ns: time in nanoseconds 46 * 47 * Return: nanoseconds as ktime object 48 */ 49 static inline ktime_t __qdf_ns_to_ktime(uint64_t ns) 50 { 51 return ns_to_ktime(ns); 52 } 53 54 /** 55 * __qdf_ktime_add() - Adds two ktime objects and returns 56 * a ktime object 57 * @time1: time as ktime object 58 * @time2: time as ktime object 59 * 60 * Return: sum of ktime objects as ktime object 61 */ 62 static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2) 63 { 64 return ktime_add(ktime1, ktime2); 65 } 66 67 /** 68 * __qdf_ktime_get() - Gets the current time as ktime object 69 * 70 * Return: current time as ktime object 71 */ 72 static inline ktime_t __qdf_ktime_get(void) 73 { 74 return ktime_get(); 75 } 76 77 /** 78 * __qdf_ktime_real_get() - Gets the current wall clock as ktime object 79 * 80 * Return: current wall clock as ktime object 81 */ 82 static inline ktime_t __qdf_ktime_real_get(void) 83 { 84 return ktime_get_real(); 85 } 86 87 /** 88 * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and 89 * returns the ktime object 90 * 91 * Return: ktime object 92 */ 93 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns) 94 { 95 return ktime_add_ns(ktime, ns); 96 } 97 98 /** 99 * __qdf_ktime_to_ns() - convert ktime to nanoseconds 100 * @ktime: time as ktime object 101 * @ns: time in nanoseconds 102 * 103 * Return: ktime in nanoseconds 104 */ 105 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime) 106 { 107 return ktime_to_ns(ktime); 108 } 109 110 /** 111 * __qdf_ktime_to_ms() - convert ktime to milliseconds 112 * @ktime: time as ktime object 113 * 114 * Return: ktime in milliseconds 115 */ 116 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime) 117 { 118 return ktime_to_ms(ktime); 119 } 120 121 122 /** 123 * __qdf_system_ticks() - get system ticks 124 * 125 * Return: system tick in jiffies 126 */ 127 static inline __qdf_time_t __qdf_system_ticks(void) 128 { 129 return jiffies; 130 } 131 132 #define __qdf_system_ticks_per_sec HZ 133 134 /** 135 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds 136 * @ticks: System ticks 137 * 138 * Return: system tick converted into milli seconds 139 */ 140 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) 141 { 142 return jiffies_to_msecs(ticks); 143 } 144 145 /** 146 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks 147 * @msecs: Milli seconds 148 * 149 * Return: milli seconds converted into system ticks 150 */ 151 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) 152 { 153 return msecs_to_jiffies(msecs); 154 } 155 156 /** 157 * __qdf_get_system_uptime() - get system uptime 158 * 159 * Return: system uptime in jiffies 160 */ 161 static inline __qdf_time_t __qdf_get_system_uptime(void) 162 { 163 return jiffies; 164 } 165 166 static inline unsigned long __qdf_get_system_timestamp(void) 167 { 168 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); 169 } 170 171 #ifdef CONFIG_ARM 172 /** 173 * __qdf_udelay() - delay execution for given microseconds 174 * @usecs: Micro seconds to delay 175 * 176 * Return: none 177 */ 178 static inline void __qdf_udelay(uint32_t usecs) 179 { 180 /* 181 * This is in support of XScale build. They have a limit on the udelay 182 * value, so we have to make sure we don't approach the limit 183 */ 184 uint32_t mticks; 185 uint32_t leftover; 186 int i; 187 /* slice into 1024 usec chunks (simplifies calculation) */ 188 mticks = usecs >> 10; 189 leftover = usecs - (mticks << 10); 190 for (i = 0; i < mticks; i++) 191 udelay(1024); 192 udelay(leftover); 193 } 194 #else 195 static inline void __qdf_udelay(uint32_t usecs) 196 { 197 /* Normal Delay functions. Time specified in microseconds */ 198 udelay(usecs); 199 } 200 #endif 201 202 /** 203 * __qdf_mdelay() - delay execution for given milliseconds 204 * @usecs: Milliseconds to delay 205 * 206 * Return: none 207 */ 208 static inline void __qdf_mdelay(uint32_t msecs) 209 { 210 mdelay(msecs); 211 } 212 213 /** 214 * __qdf_system_time_after() - Check if a is later than b 215 * @a: Time stamp value a 216 * @b: Time stamp value b 217 * 218 * Return: 219 * true if a < b else false 220 */ 221 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) 222 { 223 return (long)(b) - (long)(a) < 0; 224 } 225 226 /** 227 * __qdf_system_time_before() - Check if a is before b 228 * @a: Time stamp value a 229 * @b: Time stamp value b 230 * 231 * Return: 232 * true if a is before b else false 233 */ 234 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) 235 { 236 return __qdf_system_time_after(b, a); 237 } 238 239 /** 240 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not 241 * later 242 * @a: Time stamp value a 243 * @b: Time stamp value b 244 * 245 * Return: 246 * true if a >= b else false 247 */ 248 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) 249 { 250 return (long)(a) - (long)(b) >= 0; 251 } 252 253 /** 254 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time 255 * This API is similar to qdf_get_system_boottime but it includes 256 * time spent in suspend. 257 * 258 * Return: Time in microseconds 259 */ 260 static inline uint64_t __qdf_get_monotonic_boottime(void) 261 { 262 return (uint64_t)ktime_to_us(ktime_get_boottime()); 263 } 264 265 #if defined (MSM_PLATFORM) 266 267 /** 268 * __qdf_get_log_timestamp() - get msm timer 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(5, 2, 0)) 276 static inline uint64_t __qdf_get_log_timestamp(void) 277 { 278 return __arch_counter_get_cntvct(); 279 } 280 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 281 static inline uint64_t __qdf_get_log_timestamp(void) 282 { 283 return arch_counter_get_cntvct(); 284 } 285 #else 286 static inline uint64_t __qdf_get_log_timestamp(void) 287 { 288 return arch_counter_get_cntpct(); 289 } 290 #endif /* LINUX_VERSION_CODE */ 291 #else 292 293 /** 294 * __qdf_get_log_timestamp - get time stamp for logging 295 * 296 * Return: system tick for non MSM platfroms 297 */ 298 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 299 static inline uint64_t __qdf_get_log_timestamp(void) 300 { 301 struct timespec64 ts; 302 303 ktime_get_real_ts64(&ts); 304 305 return ((uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 306 } 307 #else 308 static inline uint64_t __qdf_get_log_timestamp(void) 309 { 310 struct timespec ts; 311 312 ktime_get_ts(&ts); 313 314 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 315 } 316 #endif 317 #endif 318 319 /** 320 * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds 321 * 322 * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds 323 * that have elapsed since the system was booted. It also includes the time when 324 * system was suspended. 325 * 326 * Return: 327 * The time since system booted in nanoseconds 328 */ 329 330 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) 331 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 332 { 333 return ktime_get_boottime_ns(); 334 } 335 336 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 337 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 338 { 339 return ktime_get_boot_ns(); 340 } 341 342 #else 343 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 344 { 345 return ktime_to_ns(ktime_get_boottime()); 346 } 347 #endif 348 349 #endif 350