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 #else 43 #include <linux/hrtimer.h> 44 #endif 45 #ifdef CONFIG_CNSS 46 #include <net/cnss.h> 47 #endif 48 #include <linux/version.h> 49 50 typedef unsigned long __qdf_time_t; 51 52 /** 53 * __qdf_system_ticks() - get system ticks 54 * 55 * Return: system tick in jiffies 56 */ 57 static inline __qdf_time_t __qdf_system_ticks(void) 58 { 59 return jiffies; 60 } 61 62 /** 63 * __qdf_system_ticks_to_msecs() - convert system ticks into milli seconds 64 * @ticks: System ticks 65 * 66 * Return: system tick converted into milli seconds 67 */ 68 static inline uint32_t __qdf_system_ticks_to_msecs(unsigned long ticks) 69 { 70 return jiffies_to_msecs(ticks); 71 } 72 73 /** 74 * __qdf_system_msecs_to_ticks() - convert milli seconds into system ticks 75 * @msecs: Milli seconds 76 * 77 * Return: milli seconds converted into system ticks 78 */ 79 static inline __qdf_time_t __qdf_system_msecs_to_ticks(uint32_t msecs) 80 { 81 return msecs_to_jiffies(msecs); 82 } 83 84 /** 85 * __qdf_get_system_uptime() - get system uptime 86 * 87 * Return: system uptime in jiffies 88 */ 89 static inline __qdf_time_t __qdf_get_system_uptime(void) 90 { 91 return jiffies; 92 } 93 94 static inline unsigned long __qdf_get_system_timestamp(void) 95 { 96 return (jiffies / HZ) * 1000 + (jiffies % HZ) * (1000 / HZ); 97 } 98 99 #ifdef CONFIG_ARM 100 /** 101 * __qdf_udelay() - delay execution for given microseconds 102 * @usecs: Micro seconds to delay 103 * 104 * Return: none 105 */ 106 static inline void __qdf_udelay(uint32_t usecs) 107 { 108 /* 109 * This is in support of XScale build. They have a limit on the udelay 110 * value, so we have to make sure we don't approach the limit 111 */ 112 uint32_t mticks; 113 uint32_t leftover; 114 int i; 115 /* slice into 1024 usec chunks (simplifies calculation) */ 116 mticks = usecs >> 10; 117 leftover = usecs - (mticks << 10); 118 for (i = 0; i < mticks; i++) 119 udelay(1024); 120 udelay(leftover); 121 } 122 #else 123 static inline void __qdf_udelay(uint32_t usecs) 124 { 125 /* Normal Delay functions. Time specified in microseconds */ 126 udelay(usecs); 127 } 128 #endif 129 130 /** 131 * __qdf_mdelay() - delay execution for given milliseconds 132 * @usecs: Milliseconds to delay 133 * 134 * Return: none 135 */ 136 static inline void __qdf_mdelay(uint32_t msecs) 137 { 138 mdelay(msecs); 139 } 140 141 /** 142 * __qdf_system_time_after() - Check if a is later than b 143 * @a: Time stamp value a 144 * @b: Time stamp value b 145 * 146 * Return: 147 * true if a < b else false 148 */ 149 static inline bool __qdf_system_time_after(__qdf_time_t a, __qdf_time_t b) 150 { 151 return (long)(b) - (long)(a) < 0; 152 } 153 154 /** 155 * __qdf_system_time_before() - Check if a is before b 156 * @a: Time stamp value a 157 * @b: Time stamp value b 158 * 159 * Return: 160 * true if a is before b else false 161 */ 162 static inline bool __qdf_system_time_before(__qdf_time_t a, __qdf_time_t b) 163 { 164 return __qdf_system_time_after(b, a); 165 } 166 167 /** 168 * __qdf_system_time_after_eq() - Check if a atleast as recent as b, if not 169 * later 170 * @a: Time stamp value a 171 * @b: Time stamp value b 172 * 173 * Return: 174 * true if a >= b else false 175 */ 176 static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) 177 { 178 return (long)(a) - (long)(b) >= 0; 179 } 180 181 /** 182 * __qdf_get_monotonic_boottime() - get monotonic kernel boot time 183 * This API is similar to qdf_get_system_boottime but it includes 184 * time spent in suspend. 185 * 186 * Return: Time in microseconds 187 */ 188 static inline uint64_t __qdf_get_monotonic_boottime(void) 189 { 190 struct timespec ts; 191 192 get_monotonic_boottime(&ts); 193 194 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 195 } 196 197 #ifdef QCA_WIFI_3_0_ADRASTEA 198 #include <asm/arch_timer.h> 199 200 /** 201 * __qdf_get_log_timestamp() - get QTIMER ticks 202 * 203 * Returns QTIMER(19.2 MHz) clock ticks. To convert it into seconds 204 * divide it by 19200. 205 * 206 * Return: QTIMER(19.2 MHz) clock ticks 207 */ 208 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 209 static inline uint64_t __qdf_get_log_timestamp(void) 210 { 211 return arch_counter_get_cntvct(); 212 } 213 #else 214 static inline uint64_t __qdf_get_log_timestamp(void) 215 { 216 return arch_counter_get_cntpct(); 217 } 218 #endif /* LINUX_VERSION_CODE */ 219 #else 220 221 /** 222 * __qdf_get_log_timestamp - get time stamp for logging 223 * For adrastea this API returns QTIMER tick which is needed to synchronize 224 * host and fw log timestamps 225 * For ROME and other discrete solution this API returns system boot time stamp 226 * 227 * Return: 228 * QTIMER ticks(19.2MHz) for adrastea 229 * System tick for rome and other future discrete solutions 230 */ 231 static inline uint64_t __qdf_get_log_timestamp(void) 232 { 233 struct timespec ts; 234 235 ktime_get_ts(&ts); 236 237 return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); 238 } 239 #endif /* QCA_WIFI_3_0_ADRASTEA */ 240 241 #endif 242