1 /* 2 * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 /** 29 * DOC: i_qdf_time 30 * This file provides OS dependent time API's. 31 */ 32 33 #ifndef _I_QDF_TIME_H 34 #define _I_QDF_TIME_H 35 36 #include <linux/jiffies.h> 37 #include <linux/delay.h> 38 #include <linux/ktime.h> 39 #include <linux/timekeeping.h> 40 #ifdef MSM_PLATFORM 41 #include <asm/arch_timer.h> 42 #endif 43 #ifdef CONFIG_CNSS 44 #include <net/cnss.h> 45 #endif 46 #include <linux/version.h> 47 48 typedef unsigned long __qdf_time_t; 49 typedef ktime_t __qdf_ktime_t; 50 51 /** 52 * __qdf_ns_to_ktime() - Converts nanoseconds to a ktime object 53 * @ns: time in nanoseconds 54 * 55 * Return: nanoseconds as ktime object 56 */ 57 static inline ktime_t __qdf_ns_to_ktime(uint64_t ns) 58 { 59 return ns_to_ktime(ns); 60 } 61 62 /** 63 * __qdf_ktime_add() - Adds two ktime objects and returns 64 * a ktime object 65 * @time1: time as ktime object 66 * @time2: time as ktime object 67 * 68 * Return: sum of ktime objects as ktime object 69 */ 70 static inline ktime_t __qdf_ktime_add(ktime_t ktime1, ktime_t ktime2) 71 { 72 return ktime_add(ktime1, ktime2); 73 } 74 75 /** 76 * __qdf_ktime_get() - Gets the current time as ktime object 77 * 78 * Return: current time as ktime object 79 */ 80 static inline ktime_t __qdf_ktime_get(void) 81 { 82 return ktime_get(); 83 } 84 85 /** 86 * __qdf_ktime_add_ns() - Adds ktime object and nanoseconds value and 87 * returns the ktime object 88 * 89 * Return: ktime object 90 */ 91 static inline ktime_t __qdf_ktime_add_ns(ktime_t ktime, int64_t ns) 92 { 93 return ktime_add_ns(ktime, ns); 94 } 95 96 /** 97 * __qdf_ktime_to_ns() - convert ktime to nanoseconds 98 * @ktime: time as ktime object 99 * @ns: time in nanoseconds 100 * 101 * Return: ktime in nanoseconds 102 */ 103 static inline int64_t __qdf_ktime_to_ns(ktime_t ktime) 104 { 105 return ktime_to_ns(ktime); 106 } 107 108 /** 109 * __qdf_ktime_to_ms() - convert ktime to milliseconds 110 * @ktime: time as ktime object 111 * 112 * Return: ktime in milliseconds 113 */ 114 static inline int64_t __qdf_ktime_to_ms(ktime_t ktime) 115 { 116 return ktime_to_ms(ktime); 117 } 118 119 120 /** 121 * __qdf_system_ticks() - get system ticks 122 * 123 * Return: system tick in jiffies 124 */ 125 static inline __qdf_time_t __qdf_system_ticks(void) 126 { 127 return jiffies; 128 } 129 130 /** 131 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds 132 * @ticks: System ticks 133 * 134 * Return: system tick converted into milli seconds 135 */ 136 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) 137 { 138 return jiffies_to_msecs(ticks); 139 } 140 141 /** 142 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks 143 * @msecs: Milli seconds 144 * 145 * Return: milli seconds converted into system ticks 146 */ 147 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) 148 { 149 return msecs_to_jiffies(msecs); 150 } 151 152 /** 153 * __qdf_get_system_uptime() - get system uptime 154 * 155 * Return: system uptime in jiffies 156 */ 157 static inline __qdf_time_t __qdf_get_system_uptime(void) 158 { 159 return jiffies; 160 } 161 162 static inline unsigned long __qdf_get_system_timestamp(void) 163 { 164 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); 165 } 166 167 #ifdef CONFIG_ARM 168 /** 169 * __qdf_udelay() - delay execution for given microseconds 170 * @usecs: Micro seconds to delay 171 * 172 * Return: none 173 */ 174 static inline void __qdf_udelay(uint32_t usecs) 175 { 176 /* 177 * This is in support of XScale build. They have a limit on the udelay 178 * value, so we have to make sure we don't approach the limit 179 */ 180 uint32_t mticks; 181 uint32_t leftover; 182 int i; 183 /* slice into 1024 usec chunks (simplifies calculation) */ 184 mticks = usecs >> 10; 185 leftover = usecs - (mticks << 10); 186 for (i = 0; i < mticks; i++) 187 udelay(1024); 188 udelay(leftover); 189 } 190 #else 191 static inline void __qdf_udelay(uint32_t usecs) 192 { 193 /* Normal Delay functions. Time specified in microseconds */ 194 udelay(usecs); 195 } 196 #endif 197 198 /** 199 * __qdf_mdelay() - delay execution for given milliseconds 200 * @usecs: Milliseconds to delay 201 * 202 * Return: none 203 */ 204 static inline void __qdf_mdelay(uint32_t msecs) 205 { 206 mdelay(msecs); 207 } 208 209 /** 210 * __qdf_system_time_after() - Check if a is later than b 211 * @a: Time stamp value a 212 * @b: Time stamp value b 213 * 214 * Return: 215 * true if a < b else false 216 */ 217 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) 218 { 219 return (long)(b) - (long)(a) < 0; 220 } 221 222 /** 223 * __qdf_system_time_before() - Check if a is before b 224 * @a: Time stamp value a 225 * @b: Time stamp value b 226 * 227 * Return: 228 * true if a is before b else false 229 */ 230 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) 231 { 232 return __qdf_system_time_after(b, a); 233 } 234 235 /** 236 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not 237 * later 238 * @a: Time stamp value a 239 * @b: Time stamp value b 240 * 241 * Return: 242 * true if a >= b else false 243 */ 244 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) 245 { 246 return (long)(a) - (long)(b) >= 0; 247 } 248 249 /** 250 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time 251 * This API is similar to qdf_get_system_boottime but it includes 252 * time spent in suspend. 253 * 254 * Return: Time in microseconds 255 */ 256 static inline uint64_t __qdf_get_monotonic_boottime(void) 257 { 258 struct timespec ts; 259 260 get_monotonic_boottime(&ts); 261 262 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 263 } 264 265 #if defined (QCA_WIFI_3_0_ADRASTEA) && defined (MSM_PLATFORM) 266 267 /** 268 * __qdf_get_log_timestamp() - get QTIMER 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(4, 4, 0)) 276 static inline uint64_t __qdf_get_log_timestamp(void) 277 { 278 return arch_counter_get_cntvct(); 279 } 280 #else 281 static inline uint64_t __qdf_get_log_timestamp(void) 282 { 283 return arch_counter_get_cntpct(); 284 } 285 #endif /* LINUX_VERSION_CODE */ 286 #else 287 288 /** 289 * __qdf_get_log_timestamp - get time stamp for logging 290 * For adrastea this API returns QTIMER tick which is needed to synchronize 291 * host and fw log timestamps 292 * For ROME and other discrete solution this API returns system boot time stamp 293 * 294 * Return: 295 * QTIMER ticks(19.2MHz) for adrastea 296 * System tick for rome and other future discrete solutions 297 */ 298 static inline uint64_t __qdf_get_log_timestamp(void) 299 { 300 struct timespec ts; 301 302 ktime_get_ts(&ts); 303 304 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 305 } 306 #endif /* QCA_WIFI_3_0_ADRASTEA */ 307 308 #endif 309