qdf_time.h 15 KB

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