qdf_time.h 16 KB

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