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 /** 126 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds 127 * @ticks: System ticks 128 * 129 * Return: system tick converted into milli seconds 130 */ 131 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) 132 { 133 return jiffies_to_msecs(ticks); 134 } 135 136 /** 137 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks 138 * @msecs: Milli seconds 139 * 140 * Return: milli seconds converted into system ticks 141 */ 142 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) 143 { 144 return msecs_to_jiffies(msecs); 145 } 146 147 /** 148 * __qdf_get_system_uptime() - get system uptime 149 * 150 * Return: system uptime in jiffies 151 */ 152 static inline __qdf_time_t __qdf_get_system_uptime(void) 153 { 154 return jiffies; 155 } 156 157 static inline unsigned long __qdf_get_system_timestamp(void) 158 { 159 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); 160 } 161 162 #ifdef CONFIG_ARM 163 /** 164 * __qdf_udelay() - delay execution for given microseconds 165 * @usecs: Micro seconds to delay 166 * 167 * Return: none 168 */ 169 static inline void __qdf_udelay(uint32_t usecs) 170 { 171 /* 172 * This is in support of XScale build. They have a limit on the udelay 173 * value, so we have to make sure we don't approach the limit 174 */ 175 uint32_t mticks; 176 uint32_t leftover; 177 int i; 178 /* slice into 1024 usec chunks (simplifies calculation) */ 179 mticks = usecs >> 10; 180 leftover = usecs - (mticks << 10); 181 for (i = 0; i < mticks; i++) 182 udelay(1024); 183 udelay(leftover); 184 } 185 #else 186 static inline void __qdf_udelay(uint32_t usecs) 187 { 188 /* Normal Delay functions. Time specified in microseconds */ 189 udelay(usecs); 190 } 191 #endif 192 193 /** 194 * __qdf_mdelay() - delay execution for given milliseconds 195 * @usecs: Milliseconds to delay 196 * 197 * Return: none 198 */ 199 static inline void __qdf_mdelay(uint32_t msecs) 200 { 201 mdelay(msecs); 202 } 203 204 /** 205 * __qdf_system_time_after() - Check if a is later than b 206 * @a: Time stamp value a 207 * @b: Time stamp value b 208 * 209 * Return: 210 * true if a < b else false 211 */ 212 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) 213 { 214 return (long)(b) - (long)(a) < 0; 215 } 216 217 /** 218 * __qdf_system_time_before() - Check if a is before b 219 * @a: Time stamp value a 220 * @b: Time stamp value b 221 * 222 * Return: 223 * true if a is before b else false 224 */ 225 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) 226 { 227 return __qdf_system_time_after(b, a); 228 } 229 230 /** 231 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not 232 * later 233 * @a: Time stamp value a 234 * @b: Time stamp value b 235 * 236 * Return: 237 * true if a >= b else false 238 */ 239 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) 240 { 241 return (long)(a) - (long)(b) >= 0; 242 } 243 244 /** 245 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time 246 * This API is similar to qdf_get_system_boottime but it includes 247 * time spent in suspend. 248 * 249 * Return: Time in microseconds 250 */ 251 static inline uint64_t __qdf_get_monotonic_boottime(void) 252 { 253 struct timespec ts; 254 255 get_monotonic_boottime(&ts); 256 257 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 258 } 259 260 #if defined (QCA_WIFI_3_0_ADRASTEA) && defined (MSM_PLATFORM) 261 262 /** 263 * __qdf_get_log_timestamp() - get QTIMER ticks 264 * 265 * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds 266 * divide it by 19200. 267 * 268 * Return: QTIMER(19.2 MHz) clock ticks 269 */ 270 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 271 static inline uint64_t __qdf_get_log_timestamp(void) 272 { 273 return arch_counter_get_cntvct(); 274 } 275 #else 276 static inline uint64_t __qdf_get_log_timestamp(void) 277 { 278 return arch_counter_get_cntpct(); 279 } 280 #endif /* LINUX_VERSION_CODE */ 281 #else 282 283 /** 284 * __qdf_get_log_timestamp - get time stamp for logging 285 * For adrastea this API returns QTIMER tick which is needed to synchronize 286 * host and fw log timestamps 287 * For ROME and other discrete solution this API returns system boot time stamp 288 * 289 * Return: 290 * QTIMER ticks(19.2MHz) for adrastea 291 * System tick for rome and other future discrete solutions 292 */ 293 static inline uint64_t __qdf_get_log_timestamp(void) 294 { 295 struct timespec ts; 296 297 ktime_get_ts(&ts); 298 299 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 300 } 301 #endif /* QCA_WIFI_3_0_ADRASTEA */ 302 303 /** 304 * __qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds 305 * 306 * __qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds 307 * that have elapsed since the system was booted. It also includes the time when 308 * system was suspended. 309 * 310 * Return: 311 * The time since system booted in nanoseconds 312 */ 313 314 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) 315 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 316 { 317 return ktime_get_boot_ns(); 318 } 319 320 #else 321 static inline uint64_t __qdf_get_bootbased_boottime_ns(void) 322 { 323 return ktime_to_ns(ktime_get_boottime()); 324 } 325 #endif 326 327 #endif 328