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