qdf_time.h 14 KB

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