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 <sof/lib/clk.h>
12 #include <sof/lib/io.h>
13 #include <sof/lib/uuid.h>
14 #include <sof/lib/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 /* 1028070e-04e8-46ab-8d81-10a0116ce738 */
24 DECLARE_SOF_UUID("wait", wait_uuid, 0x1028070e, 0x04e8, 0x46ab,
25 0x8d, 0x81, 0x10, 0xa0, 0x11, 0x6c, 0xe7, 0x38);
26
27 DECLARE_TR_CTX(wait_tr, SOF_UUID(wait_uuid), LOG_LEVEL_INFO);
28
29 #define DEFAULT_TRY_TIMES 8
30
poll_for_register_delay(uint32_t reg,uint32_t mask,uint32_t val,uint64_t us)31 int poll_for_register_delay(uint32_t reg, uint32_t mask,
32 uint32_t val, uint64_t us)
33 {
34 uint64_t tick = clock_us_to_ticks(PLATFORM_DEFAULT_CLOCK, us);
35 uint32_t tries = DEFAULT_TRY_TIMES;
36 uint64_t delta = tick / tries;
37
38 if (!delta) {
39 delta = us;
40 tries = 1;
41 }
42
43 while ((io_reg_read(reg) & mask) != val) {
44 if (!tries--) {
45 tr_err(&wait_tr, "poll timeout reg %u mask %u val %u us %u",
46 reg, mask, val, (uint32_t)us);
47 return -EIO;
48 }
49 wait_delay(delta);
50 }
51 return 0;
52 }
53
wait_delay(uint64_t number_of_clks)54 void wait_delay(uint64_t number_of_clks)
55 {
56 struct timer *timer = timer_get();
57 uint64_t current = platform_timer_get(timer);
58
59 while ((platform_timer_get(timer) - current) < number_of_clks)
60 idelay(PLATFORM_DEFAULT_DELAY);
61 }
62