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