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