1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2016 Intel Corporation. All rights reserved.
4 //
5 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6
7 /*
8 * Simple wait for event completion and signaling with timeouts.
9 */
10
11 #include <rtos/clk.h>
12 #include <sof/lib/io.h>
13 #include <sof/lib/uuid.h>
14 #include <rtos/wait.h>
15 #include <sof/platform.h>
16 #include <sof/schedule/schedule.h>
17 #include <sof/trace/trace.h>
18 #include <user/trace.h>
19 #include <errno.h>
20 #include <stdint.h>
21 #include <inttypes.h>
22
23 LOG_MODULE_REGISTER(wait, CONFIG_SOF_LOG_LEVEL);
24
25 /* 1028070e-04e8-46ab-8d81-10a0116ce738 */
26 DECLARE_SOF_UUID("wait", wait_uuid, 0x1028070e, 0x04e8, 0x46ab,
27 0x8d, 0x81, 0x10, 0xa0, 0x11, 0x6c, 0xe7, 0x38);
28
29 DECLARE_TR_CTX(wait_tr, SOF_UUID(wait_uuid), LOG_LEVEL_INFO);
30
31 #define DEFAULT_TRY_TIMES 8
32
poll_for_register_delay(uint32_t reg,uint32_t mask,uint32_t val,uint64_t us)33 int poll_for_register_delay(uint32_t reg, uint32_t mask,
34 uint32_t val, uint64_t us)
35 {
36 uint64_t tick = k_us_to_cyc_ceil64(us);
37 uint32_t tries = DEFAULT_TRY_TIMES;
38 uint64_t delta = tick / tries;
39
40 if (!delta) {
41 /*
42 * If we want to wait for less than DEFAULT_TRY_TIMES ticks then
43 * delta has to be set to 1 and number of tries to that of number
44 * of ticks.
45 */
46 delta = 1;
47 tries = tick;
48 }
49
50 while ((io_reg_read(reg) & mask) != val) {
51 if (!tries--) {
52 tr_err(&wait_tr, "poll timeout reg %u mask %u val %u us %u",
53 reg, mask, val, (uint32_t)us);
54 return -EIO;
55 }
56 wait_delay(delta);
57 }
58 return 0;
59 }
60
wait_delay(uint64_t number_of_clks)61 void wait_delay(uint64_t number_of_clks)
62 {
63 uint64_t timeout = sof_cycle_get_64() + number_of_clks;
64
65 while (sof_cycle_get_64() < timeout)
66 idelay(PLATFORM_DEFAULT_DELAY);
67 }
68
wait_delay_ms(uint64_t ms)69 void wait_delay_ms(uint64_t ms)
70 {
71 wait_delay(k_ms_to_cyc_ceil64(ms));
72 }
73
wait_delay_us(uint64_t us)74 void wait_delay_us(uint64_t us)
75 {
76 wait_delay(k_us_to_cyc_ceil64(us));
77 }
78