qdf_time.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /*
  2. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /**
  20. * DOC: qdf_time
  21. * This file abstracts time related functionality.
  22. */
  23. #ifndef _QDF_OS_TIME_H
  24. #define _QDF_OS_TIME_H
  25. #include <i_qdf_time.h>
  26. typedef __qdf_time_t qdf_time_t;
  27. typedef __qdf_ktime_t qdf_ktime_t;
  28. typedef __qdf_timespec_t qdf_timespec_t;
  29. typedef __qdf_work_struct_t qdf_work_struct_t;
  30. #define qdf_time_uint_to_ms(tu) (((tu) * 1024) / 1000)
  31. #ifdef ENHANCED_OS_ABSTRACTION
  32. /**
  33. * qdf_ns_to_ktime() - Converts nanoseconds to a qdf_ktime_t object
  34. * @ns: time in nanoseconds
  35. *
  36. * Return: nanoseconds as qdf_ktime_t object
  37. */
  38. qdf_ktime_t qdf_ns_to_ktime(uint64_t ns);
  39. /**
  40. * qdf_ktime_add() - Adds two qdf_ktime_t objects and returns
  41. * a qdf_ktime_t object
  42. * @ktime1: time as qdf_ktime_t object
  43. * @ktime2: time as qdf_ktime_t object
  44. *
  45. * Return: sum of both qdf_ktime_t as qdf_ktime_t object
  46. */
  47. qdf_ktime_t qdf_ktime_add(qdf_ktime_t ktime1, qdf_ktime_t ktime2);
  48. /**
  49. * qdf_ktime_get() - Gets the current time as qdf_ktime_t object
  50. *
  51. * Return: current time as qdf_ktime_t object
  52. */
  53. qdf_ktime_t qdf_ktime_get(void);
  54. /**
  55. * qdf_ktime_real_get() - Gets the current wall clock as qdf_ktime_t object
  56. *
  57. * Return: current wall clock as qdf_ktime_t object
  58. */
  59. qdf_ktime_t qdf_ktime_real_get(void);
  60. /**
  61. * qdf_ktime_add_ns() - Adds qdf_ktime_t object and nanoseconds value and
  62. * returns the qdf_ktime_t object
  63. * @ktime: time as qdf_ktime_t object
  64. * @ns: time in nanoseconds
  65. *
  66. * Return: qdf_ktime_t object
  67. */
  68. qdf_ktime_t qdf_ktime_add_ns(qdf_ktime_t ktime, int64_t ns);
  69. /**
  70. * qdf_ktime_to_ms() - Convert the qdf_ktime_t object into milliseconds
  71. * @ktime: time as qdf_ktime_t object
  72. *
  73. * Return: qdf_ktime_t in milliseconds
  74. */
  75. int64_t qdf_ktime_to_ms(qdf_ktime_t ktime);
  76. /**
  77. * qdf_ktime_to_us() - Convert the qdf_ktime_t object into microseconds
  78. * @ktime: time as qdf_ktime_t object
  79. *
  80. * Return: qdf_ktime_t in microseconds
  81. */
  82. int64_t qdf_ktime_to_us(qdf_ktime_t ktime);
  83. /**
  84. * qdf_ktime_to_ns() - Convert the qdf_ktime_t object into nanoseconds
  85. * @ktime: time as qdf_ktime_t object
  86. *
  87. * Return: qdf_ktime_t in nanoseconds
  88. */
  89. int64_t qdf_ktime_to_ns(qdf_ktime_t ktime);
  90. /**
  91. * qdf_system_ticks() - Count the number of ticks elapsed from the time when
  92. * the system booted
  93. *
  94. * Return: ticks
  95. */
  96. qdf_time_t qdf_system_ticks(void);
  97. #define qdf_system_ticks_per_sec __qdf_system_ticks_per_sec
  98. /**
  99. * qdf_system_ticks_to_msecs() - convert ticks to milliseconds
  100. * @clock_ticks: Number of ticks
  101. *
  102. * Return: unsigned int Time in milliseconds
  103. */
  104. uint32_t qdf_system_ticks_to_msecs(unsigned long clock_ticks);
  105. /**
  106. * qdf_system_ticks_to_nsecs() - convert ticks to nanoseconds
  107. * @clock_ticks: Number of ticks
  108. *
  109. * Return: unsigned int Time in nanoseconds
  110. */
  111. uint32_t qdf_system_ticks_to_nsecs(unsigned long clock_ticks);
  112. /**
  113. * qdf_system_msecs_to_ticks() - convert milliseconds to ticks
  114. * @msecs: Time in milliseconds
  115. *
  116. * Return: unsigned long number of ticks
  117. */
  118. qdf_time_t qdf_system_msecs_to_ticks(uint32_t msecs);
  119. /**
  120. * qdf_get_system_uptime() - Return a monotonically increasing time
  121. * This increments once per HZ ticks
  122. *
  123. * Return: qdf_time_t system up time in ticks
  124. */
  125. qdf_time_t qdf_get_system_uptime(void);
  126. /**
  127. * qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
  128. *
  129. * qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
  130. * that have elapsed since the system was booted. It also includes the time when
  131. * system was suspended.
  132. *
  133. * Return:
  134. * The time since system booted in nanoseconds
  135. */
  136. uint64_t qdf_get_bootbased_boottime_ns(void);
  137. /**
  138. * qdf_get_system_timestamp() - Return current timestamp
  139. *
  140. * Return: unsigned long timestamp in ms.
  141. */
  142. unsigned long qdf_get_system_timestamp(void);
  143. /**
  144. * qdf_udelay() - delay in microseconds
  145. * @usecs: Number of microseconds to delay
  146. *
  147. * Return: none
  148. */
  149. void qdf_udelay(int usecs);
  150. /**
  151. * qdf_mdelay() - Delay in milliseconds.
  152. * @msecs: Number of milliseconds to delay
  153. *
  154. * Return: none
  155. */
  156. void qdf_mdelay(int msecs);
  157. /**
  158. * qdf_system_time_after() - Check if a is later than b
  159. * @a: Time stamp value a
  160. * @b: Time stamp value b
  161. *
  162. * Return: true if a < b else false
  163. */
  164. bool qdf_system_time_after(qdf_time_t a, qdf_time_t b);
  165. /**
  166. * qdf_system_time_before() - Check if a is before b
  167. * @a: Time stamp value a
  168. * @b: Time stamp value b
  169. *
  170. * Return: true if a is before b else false
  171. */
  172. bool qdf_system_time_before(qdf_time_t a, qdf_time_t b);
  173. /**
  174. * qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
  175. * later
  176. * @a: Time stamp value a
  177. * @b: Time stamp value b
  178. *
  179. * Return: true if a >= b else false
  180. */
  181. bool qdf_system_time_after_eq(qdf_time_t a, qdf_time_t b);
  182. /**
  183. * enum qdf_timestamp_unit - what unit the qdf timestamp is in
  184. * @KERNEL_LOG: boottime time in uS (micro seconds)
  185. * @QTIMER: QTIME in (1/19200)S
  186. *
  187. * This enum is used to distinguish which timer source is used.
  188. */
  189. enum qdf_timestamp_unit {
  190. KERNEL_LOG,
  191. QTIMER,
  192. };
  193. #ifdef MSM_PLATFORM
  194. #define QDF_LOG_TIMESTAMP_UNIT QTIMER
  195. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
  196. #else
  197. #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
  198. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
  199. #endif /* end of MSM_PLATFORM */
  200. uint64_t qdf_log_timestamp_to_usecs(uint64_t time);
  201. /**
  202. * qdf_log_timestamp_to_secs() - get time stamp for logging in seconds
  203. * @time: logging timestamp
  204. * @secs: pointer to write seconds
  205. * @usecs: pointer to write microseconds
  206. *
  207. * Return: void. The normalized time is returned in @secs and @usecs
  208. */
  209. void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
  210. uint64_t *usecs);
  211. uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs);
  212. /**
  213. * qdf_get_log_timestamp() - get time stamp for logging
  214. * For adrastea this API returns QTIMER tick which is needed to synchronize
  215. * host and fw log timestamps
  216. * For ROME and other discrete solution this API returns system boot time stamp
  217. *
  218. * Return:
  219. * QTIMER ticks(19.2MHz) for adrastea
  220. * System tick for rome and other future discrete solutions
  221. */
  222. uint64_t qdf_get_log_timestamp(void);
  223. /**
  224. * qdf_get_log_timestamp_usecs() - get time stamp for logging in microseconds
  225. *
  226. * Return: The current logging timestamp normalized to microsecond precision
  227. */
  228. uint64_t qdf_get_log_timestamp_usecs(void);
  229. /**
  230. * qdf_get_monotonic_boottime() - get monotonic kernel boot time
  231. * This API is similar to qdf_get_system_boottime but it includes
  232. * time spent in suspend.
  233. *
  234. * Return: Time in microseconds
  235. */
  236. uint64_t qdf_get_monotonic_boottime(void);
  237. /**
  238. * qdf_time_ktime_get_real_time() - Get the time of day in qdf_timespec_t
  239. * @ts: pointer to the qdf_timespec_t
  240. *
  241. * Return: None
  242. */
  243. void qdf_time_ktime_get_real_time(qdf_timespec_t *ts);
  244. /**
  245. * qdf_time_sched_clock() - scheduler clock
  246. *
  247. * Return: current time in nanosec units.
  248. */
  249. unsigned long long qdf_time_sched_clock(void);
  250. #else
  251. static inline qdf_ktime_t qdf_ns_to_ktime(uint64_t ns)
  252. {
  253. return __qdf_ns_to_ktime(ns);
  254. }
  255. static inline qdf_ktime_t qdf_ktime_add(qdf_ktime_t ktime1, qdf_ktime_t ktime2)
  256. {
  257. return __qdf_ktime_add(ktime1, ktime2);
  258. }
  259. static inline qdf_ktime_t qdf_ktime_get(void)
  260. {
  261. return __qdf_ktime_get();
  262. }
  263. static inline qdf_ktime_t qdf_ktime_real_get(void)
  264. {
  265. return __qdf_ktime_real_get();
  266. }
  267. static inline qdf_ktime_t qdf_ktime_add_ns(qdf_ktime_t ktime, int64_t ns)
  268. {
  269. return __qdf_ktime_add_ns(ktime, ns);
  270. }
  271. static inline int64_t qdf_ktime_to_ms(qdf_ktime_t ktime)
  272. {
  273. return __qdf_ktime_to_ms(ktime);
  274. }
  275. static inline int64_t qdf_ktime_to_us(qdf_ktime_t ktime)
  276. {
  277. return __qdf_time_ktime_to_us(ktime);
  278. }
  279. static inline int64_t qdf_ktime_to_ns(qdf_ktime_t ktime)
  280. {
  281. return __qdf_ktime_to_ns(ktime);
  282. }
  283. static inline qdf_time_t qdf_system_ticks(void)
  284. {
  285. return __qdf_system_ticks();
  286. }
  287. #define qdf_system_ticks_per_sec __qdf_system_ticks_per_sec
  288. static inline uint32_t qdf_system_ticks_to_msecs(unsigned long clock_ticks)
  289. {
  290. return __qdf_system_ticks_to_msecs(clock_ticks);
  291. }
  292. static inline qdf_time_t qdf_system_msecs_to_ticks(uint32_t msecs)
  293. {
  294. return __qdf_system_msecs_to_ticks(msecs);
  295. }
  296. static inline qdf_time_t qdf_get_system_uptime(void)
  297. {
  298. return __qdf_get_system_uptime();
  299. }
  300. static inline uint64_t qdf_get_bootbased_boottime_ns(void)
  301. {
  302. return __qdf_get_bootbased_boottime_ns();
  303. }
  304. static inline unsigned long qdf_get_system_timestamp(void)
  305. {
  306. return __qdf_get_system_timestamp();
  307. }
  308. static inline void qdf_udelay(int usecs)
  309. {
  310. __qdf_udelay(usecs);
  311. }
  312. static inline void qdf_mdelay(int msecs)
  313. {
  314. __qdf_mdelay(msecs);
  315. }
  316. static inline bool qdf_system_time_after(qdf_time_t a, qdf_time_t b)
  317. {
  318. return __qdf_system_time_after(a, b);
  319. }
  320. static inline bool qdf_system_time_before(qdf_time_t a, qdf_time_t b)
  321. {
  322. return __qdf_system_time_before(a, b);
  323. }
  324. static inline bool qdf_system_time_after_eq(qdf_time_t a, qdf_time_t b)
  325. {
  326. return __qdf_system_time_after_eq(a, b);
  327. }
  328. /**
  329. * qdf_sched_clock() - use light weight timer to get timestamp for logging
  330. *
  331. * Return: timestamp in ns
  332. */
  333. static inline uint64_t qdf_sched_clock(void)
  334. {
  335. return __qdf_sched_clock();
  336. }
  337. /**
  338. * enum qdf_timestamp_unit - what unit the qdf timestamp is in
  339. * @KERNEL_LOG: boottime time in uS (micro seconds)
  340. * @QTIMER: QTIME in (1/19200)S
  341. *
  342. * This enum is used to distinguish which timer source is used.
  343. */
  344. enum qdf_timestamp_unit {
  345. KERNEL_LOG,
  346. QTIMER,
  347. };
  348. #ifdef MSM_PLATFORM
  349. #define QDF_LOG_TIMESTAMP_UNIT QTIMER
  350. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
  351. static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
  352. {
  353. /*
  354. * Try to preserve precision by multiplying by 10 first.
  355. * If that would cause a wrap around, divide first instead.
  356. */
  357. if (time * 10 < time) {
  358. do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
  359. return time * 10;
  360. }
  361. time = time * 10;
  362. do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
  363. return time;
  364. }
  365. /**
  366. * qdf_get_log_timestamp_lightweight() - get time stamp for logging
  367. * For adrastea this API returns QTIMER tick which is needed to synchronize
  368. * host and fw log timestamps
  369. * For ROME and other discrete solution this API returns system boot time stamp
  370. *
  371. * Return:
  372. * QTIMER ticks(19.2MHz) for adrastea
  373. * System tick for rome and other 3rd party platform solutions
  374. */
  375. static inline uint64_t qdf_get_log_timestamp_lightweight(void)
  376. {
  377. return __qdf_get_log_timestamp();
  378. }
  379. #else
  380. #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
  381. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
  382. static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
  383. {
  384. /* timestamps are already in micro seconds */
  385. return time;
  386. }
  387. static inline uint64_t qdf_get_log_timestamp_lightweight(void)
  388. {
  389. uint64_t timestamp_us;
  390. /* explicitly change to uint64_t, otherwise it will assign
  391. * uint32_t to timestamp_us, which lose high 32bits.
  392. * on 64bit platform, it will only use low 32bits jiffies in
  393. * jiffies_to_msecs.
  394. * eg: HZ=250, it will overflow every (0xffff ffff<<2==0x3fff ffff)
  395. * ticks. it is 1193 hours.
  396. */
  397. timestamp_us =
  398. (uint64_t)__qdf_system_ticks_to_msecs(qdf_system_ticks()) * 1000;
  399. return timestamp_us;
  400. }
  401. #endif /* end of MSM_PLATFORM */
  402. static inline void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
  403. uint64_t *usecs)
  404. {
  405. *secs = qdf_log_timestamp_to_usecs(time);
  406. *usecs = do_div(*secs, 1000000ul);
  407. }
  408. static inline uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs)
  409. {
  410. return (usecs * QDF_LOG_TIMESTAMP_CYCLES_PER_10_US) / 10;
  411. }
  412. static inline uint64_t qdf_get_log_timestamp(void)
  413. {
  414. return __qdf_get_log_timestamp();
  415. }
  416. static inline uint64_t qdf_get_log_timestamp_usecs(void)
  417. {
  418. return qdf_log_timestamp_to_usecs(qdf_get_log_timestamp());
  419. }
  420. static inline uint64_t qdf_get_monotonic_boottime(void)
  421. {
  422. return __qdf_get_monotonic_boottime();
  423. }
  424. static inline void qdf_time_ktime_get_real_time(qdf_timespec_t *ts)
  425. {
  426. return __qdf_time_ktime_get_real_time(ts);
  427. }
  428. static inline unsigned long long qdf_time_sched_clock(void)
  429. {
  430. return __qdf_time_sched_clock();
  431. }
  432. #endif
  433. #endif