qdf_time.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /*
  2. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022 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. #ifdef ENHANCED_OS_ABSTRACTION
  31. /**
  32. * qdf_ns_to_ktime - Converts nanoseconds to a qdf_ktime_t object
  33. * @ns: time in nanoseconds
  34. *
  35. * Return: nanoseconds as qdf_ktime_t object
  36. */
  37. qdf_ktime_t qdf_ns_to_ktime(uint64_t ns);
  38. /**
  39. * qdf_ktime_add - Adds two qdf_ktime_t objects and returns
  40. * a qdf_ktime_t object
  41. * @ktime1: time as qdf_ktime_t object
  42. * @ktime2: time as qdf_ktime_t object
  43. *
  44. * Return: sum of both qdf_ktime_t as qdf_ktime_t object
  45. */
  46. qdf_ktime_t qdf_ktime_add(qdf_ktime_t ktime1, qdf_ktime_t ktime2);
  47. /**
  48. * qdf_ktime_get - Gets the current time as qdf_ktime_t object
  49. *
  50. * Return: current time as qdf_ktime_t object
  51. */
  52. qdf_ktime_t qdf_ktime_get(void);
  53. /**
  54. * qdf_ktime_real_get - Gets the current wall clock as qdf_ktime_t object
  55. *
  56. * Return: current wall clock as qdf_ktime_t object
  57. */
  58. qdf_ktime_t qdf_ktime_real_get(void);
  59. /**
  60. * qdf_ktime_add_ns - Adds qdf_ktime_t object and nanoseconds value and
  61. * returns the qdf_ktime_t object
  62. * @ktime: time as qdf_ktime_t object
  63. * @ns: time in nanoseconds
  64. *
  65. * Return: qdf_ktime_t object
  66. */
  67. qdf_ktime_t qdf_ktime_add_ns(qdf_ktime_t ktime, int64_t ns);
  68. /**
  69. * qdf_ktime_to_ms - Convert the qdf_ktime_t object into milliseconds
  70. * @ktime: time as qdf_ktime_t object
  71. *
  72. * Return: qdf_ktime_t in milliseconds
  73. */
  74. int64_t qdf_ktime_to_ms(qdf_ktime_t ktime);
  75. /**
  76. * qdf_ktime_to_ns - Convert the qdf_ktime_t object into nanoseconds
  77. * @ktime: time as qdf_ktime_t object
  78. *
  79. * Return: qdf_ktime_t in nanoseconds
  80. */
  81. int64_t qdf_ktime_to_ns(qdf_ktime_t ktime);
  82. /**
  83. * qdf_system_ticks - Count the number of ticks elapsed from the time when
  84. * the system booted
  85. *
  86. * Return: ticks
  87. */
  88. qdf_time_t qdf_system_ticks(void);
  89. #define qdf_system_ticks_per_sec __qdf_system_ticks_per_sec
  90. /**
  91. * qdf_system_ticks_to_msecs - convert ticks to milliseconds
  92. * @clock_ticks: Number of ticks
  93. *
  94. * Return: unsigned int Time in milliseconds
  95. */
  96. uint32_t qdf_system_ticks_to_msecs(unsigned long clock_ticks);
  97. /**
  98. * qdf_system_msecs_to_ticks - convert milliseconds to ticks
  99. * @msec: Time in milliseconds
  100. *
  101. * Return: unsigned long number of ticks
  102. */
  103. qdf_time_t qdf_system_msecs_to_ticks(uint32_t msecs);
  104. /**
  105. * qdf_get_system_uptime - Return a monotonically increasing time
  106. * This increments once per HZ ticks
  107. *
  108. * Return: qdf_time_t system up time in ticks
  109. */
  110. qdf_time_t qdf_get_system_uptime(void);
  111. /**
  112. * qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
  113. *
  114. * qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
  115. * that have elapsed since the system was booted. It also includes the time when
  116. * system was suspended.
  117. *
  118. * Return:
  119. * The time since system booted in nanoseconds
  120. */
  121. uint64_t qdf_get_bootbased_boottime_ns(void);
  122. /**
  123. * qdf_get_system_timestamp - Return current timestamp
  124. *
  125. * Return: unsigned long timestamp in ms.
  126. */
  127. unsigned long qdf_get_system_timestamp(void);
  128. /**
  129. * qdf_udelay - delay in microseconds
  130. * @usecs: Number of microseconds to delay
  131. *
  132. * Return: none
  133. */
  134. void qdf_udelay(int usecs);
  135. /**
  136. * qdf_mdelay - Delay in milliseconds.
  137. * @msec: Number of milliseconds to delay
  138. *
  139. * Return: none
  140. */
  141. void qdf_mdelay(int msecs);
  142. /**
  143. * qdf_system_time_after() - Check if a is later than b
  144. * @a: Time stamp value a
  145. * @b: Time stamp value b
  146. *
  147. * Return: true if a < b else false
  148. */
  149. bool qdf_system_time_after(qdf_time_t a, qdf_time_t b);
  150. /**
  151. * qdf_system_time_before() - Check if a is before b
  152. * @a: Time stamp value a
  153. * @b: Time stamp value b
  154. *
  155. * Return: true if a is before b else false
  156. */
  157. bool qdf_system_time_before(qdf_time_t a, qdf_time_t b);
  158. /**
  159. * qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
  160. * later
  161. * @a: Time stamp value a
  162. * @b: Time stamp value b
  163. *
  164. * Return: true if a >= b else false
  165. */
  166. bool qdf_system_time_after_eq(qdf_time_t a, qdf_time_t b);
  167. /**
  168. * enum qdf_timestamp_unit - what unit the qdf timestamp is in
  169. * @KERNEL_LOG: boottime time in uS (micro seconds)
  170. * @QTIMER: QTIME in (1/19200)S
  171. *
  172. * This enum is used to distinguish which timer source is used.
  173. */
  174. enum qdf_timestamp_unit {
  175. KERNEL_LOG,
  176. QTIMER,
  177. };
  178. #ifdef MSM_PLATFORM
  179. #define QDF_LOG_TIMESTAMP_UNIT QTIMER
  180. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
  181. #else
  182. #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
  183. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
  184. #endif /* end of MSM_PLATFORM */
  185. uint64_t qdf_log_timestamp_to_usecs(uint64_t time);
  186. /**
  187. * qdf_get_log_timestamp_to_secs() - get time stamp for logging in seconds
  188. *
  189. * Return: The current logging timestamp normalized to second precision
  190. */
  191. void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
  192. uint64_t *usecs);
  193. uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs);
  194. /**
  195. * qdf_get_log_timestamp - get time stamp for logging
  196. * For adrastea this API returns QTIMER tick which is needed to synchronize
  197. * host and fw log timestamps
  198. * For ROME and other discrete solution this API returns system boot time stamp
  199. *
  200. * Return:
  201. * QTIMER ticks(19.2MHz) for adrastea
  202. * System tick for rome and other future discrete solutions
  203. */
  204. uint64_t qdf_get_log_timestamp(void);
  205. /**
  206. * qdf_get_log_timestamp_usecs() - get time stamp for logging in microseconds
  207. *
  208. * Return: The current logging timestamp normalized to microsecond precision
  209. */
  210. uint64_t qdf_get_log_timestamp_usecs(void);
  211. /**
  212. * qdf_get_monotonic_boottime - get monotonic kernel boot time
  213. * This API is similar to qdf_get_system_boottime but it includes
  214. * time spent in suspend.
  215. *
  216. * Return: Time in microseconds
  217. */
  218. uint64_t qdf_get_monotonic_boottime(void);
  219. /**
  220. * qdf_time_ktime_get_real_time() - Get the time of day in qdf_timespec_t
  221. * @ts: pointer to the qdf_timespec_t
  222. *
  223. * Return: None
  224. */
  225. void qdf_time_ktime_get_real_time(qdf_timespec_t *ts);
  226. /**
  227. * qdf_time_sched_clock - scheduler clock
  228. *
  229. * Return: current time in nanosec units.
  230. */
  231. unsigned long long qdf_time_sched_clock(void);
  232. #else
  233. /**
  234. * qdf_ns_to_ktime - Converts nanoseconds to a qdf_ktime_t object
  235. * @ns: time in nanoseconds
  236. *
  237. * Return: nanoseconds as qdf_ktime_t object
  238. */
  239. static inline qdf_ktime_t qdf_ns_to_ktime(uint64_t ns)
  240. {
  241. return __qdf_ns_to_ktime(ns);
  242. }
  243. /**
  244. * qdf_ktime_add - Adds two qdf_ktime_t objects and returns
  245. * a qdf_ktime_t object
  246. * @ktime1: time as qdf_ktime_t object
  247. * @ktime2: time as qdf_ktime_t object
  248. *
  249. * Return: sum of both qdf_ktime_t as qdf_ktime_t object
  250. */
  251. static inline qdf_ktime_t qdf_ktime_add(qdf_ktime_t ktime1, qdf_ktime_t ktime2)
  252. {
  253. return __qdf_ktime_add(ktime1, ktime2);
  254. }
  255. /**
  256. * qdf_ktime_get - Gets the current time as qdf_ktime_t object
  257. *
  258. * Return: current time as qdf_ktime_t object
  259. */
  260. static inline qdf_ktime_t qdf_ktime_get(void)
  261. {
  262. return __qdf_ktime_get();
  263. }
  264. /**
  265. * qdf_ktime_real_get - Gets the current wall clock as qdf_ktime_t object
  266. *
  267. * Return: current wall clock as qdf_ktime_t object
  268. */
  269. static inline qdf_ktime_t qdf_ktime_real_get(void)
  270. {
  271. return __qdf_ktime_real_get();
  272. }
  273. /**
  274. * qdf_ktime_add_ns - Adds qdf_ktime_t object and nanoseconds value and
  275. * returns the qdf_ktime_t object
  276. * @ktime: time as qdf_ktime_t object
  277. * @ns: time in nanoseconds
  278. *
  279. * Return: qdf_ktime_t object
  280. */
  281. static inline qdf_ktime_t qdf_ktime_add_ns(qdf_ktime_t ktime, int64_t ns)
  282. {
  283. return __qdf_ktime_add_ns(ktime, ns);
  284. }
  285. /**
  286. * qdf_ktime_to_ms - Convert the qdf_ktime_t object into milliseconds
  287. * @ktime: time as qdf_ktime_t object
  288. *
  289. * Return: qdf_ktime_t in milliseconds
  290. */
  291. static inline int64_t qdf_ktime_to_ms(qdf_ktime_t ktime)
  292. {
  293. return __qdf_ktime_to_ms(ktime);
  294. }
  295. /**
  296. * qdf_ktime_to_us - Convert the qdf_ktime_t object into microseconds
  297. * @ktime: time as qdf_ktime_t object
  298. *
  299. * Return: qdf_ktime_t in microseconds
  300. */
  301. static inline int64_t qdf_ktime_to_us(qdf_ktime_t ktime)
  302. {
  303. return __qdf_time_ktime_to_us(ktime);
  304. }
  305. /**
  306. * qdf_ktime_to_ns - Convert the qdf_ktime_t object into nanoseconds
  307. * @ktime: time as qdf_ktime_t object
  308. *
  309. * Return: qdf_ktime_t in nanoseconds
  310. */
  311. static inline int64_t qdf_ktime_to_ns(qdf_ktime_t ktime)
  312. {
  313. return __qdf_ktime_to_ns(ktime);
  314. }
  315. /**
  316. * qdf_system_ticks - Count the number of ticks elapsed from the time when
  317. * the system booted
  318. *
  319. * Return: ticks
  320. */
  321. static inline qdf_time_t qdf_system_ticks(void)
  322. {
  323. return __qdf_system_ticks();
  324. }
  325. #define qdf_system_ticks_per_sec __qdf_system_ticks_per_sec
  326. /**
  327. * qdf_system_ticks_to_msecs - convert ticks to milliseconds
  328. * @clock_ticks: Number of ticks
  329. *
  330. * Return: unsigned int Time in milliseconds
  331. */
  332. static inline uint32_t qdf_system_ticks_to_msecs(unsigned long clock_ticks)
  333. {
  334. return __qdf_system_ticks_to_msecs(clock_ticks);
  335. }
  336. /**
  337. * qdf_system_msecs_to_ticks - convert milliseconds to ticks
  338. * @msec: Time in milliseconds
  339. *
  340. * Return: unsigned long number of ticks
  341. */
  342. static inline qdf_time_t qdf_system_msecs_to_ticks(uint32_t msecs)
  343. {
  344. return __qdf_system_msecs_to_ticks(msecs);
  345. }
  346. /**
  347. * qdf_get_system_uptime - Return a monotonically increasing time
  348. * This increments once per HZ ticks
  349. *
  350. * Return: qdf_time_t system up time in ticks
  351. */
  352. static inline qdf_time_t qdf_get_system_uptime(void)
  353. {
  354. return __qdf_get_system_uptime();
  355. }
  356. /**
  357. * qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
  358. *
  359. * qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
  360. * that have elapsed since the system was booted. It also includes the time when
  361. * system was suspended.
  362. *
  363. * Return:
  364. * The time since system booted in nanoseconds
  365. */
  366. static inline uint64_t qdf_get_bootbased_boottime_ns(void)
  367. {
  368. return __qdf_get_bootbased_boottime_ns();
  369. }
  370. /**
  371. * qdf_get_system_timestamp - Return current timestamp
  372. *
  373. * Return: unsigned long timestamp in ms.
  374. */
  375. static inline unsigned long qdf_get_system_timestamp(void)
  376. {
  377. return __qdf_get_system_timestamp();
  378. }
  379. /**
  380. * qdf_udelay - delay in microseconds
  381. * @usecs: Number of microseconds to delay
  382. *
  383. * Return: none
  384. */
  385. static inline void qdf_udelay(int usecs)
  386. {
  387. __qdf_udelay(usecs);
  388. }
  389. /**
  390. * qdf_mdelay - Delay in milliseconds.
  391. * @msec: Number of milliseconds to delay
  392. *
  393. * Return: none
  394. */
  395. static inline void qdf_mdelay(int msecs)
  396. {
  397. __qdf_mdelay(msecs);
  398. }
  399. /**
  400. * qdf_system_time_after() - Check if a is later than b
  401. * @a: Time stamp value a
  402. * @b: Time stamp value b
  403. *
  404. * Return:
  405. * true if a < b else false
  406. */
  407. static inline bool qdf_system_time_after(qdf_time_t a, qdf_time_t b)
  408. {
  409. return __qdf_system_time_after(a, b);
  410. }
  411. /**
  412. * qdf_system_time_before() - Check if a is before b
  413. * @a: Time stamp value a
  414. * @b: Time stamp value b
  415. *
  416. * Return:
  417. * true if a is before b else false
  418. */
  419. static inline bool qdf_system_time_before(qdf_time_t a, qdf_time_t b)
  420. {
  421. return __qdf_system_time_before(a, b);
  422. }
  423. /**
  424. * qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
  425. * later
  426. * @a: Time stamp value a
  427. * @b: Time stamp value b
  428. *
  429. * Return:
  430. * true if a >= b else false
  431. */
  432. static inline bool qdf_system_time_after_eq(qdf_time_t a, qdf_time_t b)
  433. {
  434. return __qdf_system_time_after_eq(a, b);
  435. }
  436. /**
  437. * qdf_sched_clock() - use light weight timer to get timestamp for logging
  438. *
  439. * Return: timestamp in ns
  440. */
  441. static inline uint64_t qdf_sched_clock(void)
  442. {
  443. return __qdf_sched_clock();
  444. }
  445. /**
  446. * enum qdf_timestamp_unit - what unit the qdf timestamp is in
  447. * @KERNEL_LOG: boottime time in uS (micro seconds)
  448. * @QTIMER: QTIME in (1/19200)S
  449. *
  450. * This enum is used to distinguish which timer source is used.
  451. */
  452. enum qdf_timestamp_unit {
  453. KERNEL_LOG,
  454. QTIMER,
  455. };
  456. #ifdef MSM_PLATFORM
  457. #define QDF_LOG_TIMESTAMP_UNIT QTIMER
  458. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
  459. static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
  460. {
  461. /*
  462. * Try to preserve precision by multiplying by 10 first.
  463. * If that would cause a wrap around, divide first instead.
  464. */
  465. if (time * 10 < time) {
  466. do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
  467. return time * 10;
  468. }
  469. time = time * 10;
  470. do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
  471. return time;
  472. }
  473. /**
  474. * qdf_get_log_timestamp_lightweight - get time stamp for logging
  475. * For adrastea this API returns QTIMER tick which is needed to synchronize
  476. * host and fw log timestamps
  477. * For ROME and other discrete solution this API returns system boot time stamp
  478. *
  479. * Return:
  480. * QTIMER ticks(19.2MHz) for adrastea
  481. * System tick for rome and other 3rd party platform solutions
  482. */
  483. static inline uint64_t qdf_get_log_timestamp_lightweight(void)
  484. {
  485. return __qdf_get_log_timestamp();
  486. }
  487. #else
  488. #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
  489. #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
  490. static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
  491. {
  492. /* timestamps are already in micro seconds */
  493. return time;
  494. }
  495. static inline uint64_t qdf_get_log_timestamp_lightweight(void)
  496. {
  497. uint64_t timestamp_us;
  498. /* explicitly change to uint64_t, otherwise it will assign
  499. * uint32_t to timestamp_us, which lose high 32bits.
  500. * on 64bit platform, it will only use low 32bits jiffies in
  501. * jiffies_to_msecs.
  502. * eg: HZ=250, it will overflow every (0xffff ffff<<2==0x3fff ffff)
  503. * ticks. it is 1193 hours.
  504. */
  505. timestamp_us =
  506. (uint64_t)__qdf_system_ticks_to_msecs(qdf_system_ticks()) * 1000;
  507. return timestamp_us;
  508. }
  509. #endif /* end of MSM_PLATFORM */
  510. static inline void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
  511. uint64_t *usecs)
  512. {
  513. *secs = qdf_log_timestamp_to_usecs(time);
  514. *usecs = do_div(*secs, 1000000ul);
  515. }
  516. static inline uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs)
  517. {
  518. return (usecs * QDF_LOG_TIMESTAMP_CYCLES_PER_10_US) / 10;
  519. }
  520. /**
  521. * qdf_get_log_timestamp - get time stamp for logging
  522. * For adrastea this API returns QTIMER tick which is needed to synchronize
  523. * host and fw log timestamps
  524. * For ROME and other discrete solution this API returns system boot time stamp
  525. *
  526. * Return:
  527. * QTIMER ticks(19.2MHz) for adrastea
  528. * System tick for rome and other future discrete solutions
  529. */
  530. static inline uint64_t qdf_get_log_timestamp(void)
  531. {
  532. return __qdf_get_log_timestamp();
  533. }
  534. /**
  535. * qdf_get_log_timestamp_usecs() - get time stamp for logging in microseconds
  536. *
  537. * Return: The current logging timestamp normalized to microsecond precision
  538. */
  539. static inline uint64_t qdf_get_log_timestamp_usecs(void)
  540. {
  541. return qdf_log_timestamp_to_usecs(qdf_get_log_timestamp());
  542. }
  543. /**
  544. * qdf_get_monotonic_boottime - get monotonic kernel boot time
  545. * This API is similar to qdf_get_system_boottime but it includes
  546. * time spent in suspend.
  547. *
  548. * Return: Time in microseconds
  549. */
  550. static inline uint64_t qdf_get_monotonic_boottime(void)
  551. {
  552. return __qdf_get_monotonic_boottime();
  553. }
  554. static inline void qdf_time_ktime_get_real_time(qdf_timespec_t *ts)
  555. {
  556. return __qdf_time_ktime_get_real_time(ts);
  557. }
  558. static inline unsigned long long qdf_time_sched_clock(void)
  559. {
  560. return __qdf_time_sched_clock();
  561. }
  562. #endif
  563. #endif