xref: /linux/drivers/gpu/drm/xe/xe_sleep.h (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
194a2ceb1SMichal Wajdeczko /* SPDX-License-Identifier: MIT */
294a2ceb1SMichal Wajdeczko /*
394a2ceb1SMichal Wajdeczko  * Copyright © 2026 Intel Corporation
494a2ceb1SMichal Wajdeczko  */
594a2ceb1SMichal Wajdeczko 
694a2ceb1SMichal Wajdeczko #ifndef _XE_SLEEP_H_
794a2ceb1SMichal Wajdeczko #define _XE_SLEEP_H_
894a2ceb1SMichal Wajdeczko 
994a2ceb1SMichal Wajdeczko #include <linux/delay.h>
1094a2ceb1SMichal Wajdeczko #include <linux/math64.h>
1194a2ceb1SMichal Wajdeczko 
1294a2ceb1SMichal Wajdeczko /**
1394a2ceb1SMichal Wajdeczko  * xe_sleep_relaxed_ms() - Sleep for an approximate time.
1494a2ceb1SMichal Wajdeczko  * @delay_ms: time in msec to sleep
1594a2ceb1SMichal Wajdeczko  *
1694a2ceb1SMichal Wajdeczko  * For smaller timeouts, sleep with 0.5ms accuracy.
1794a2ceb1SMichal Wajdeczko  */
1894a2ceb1SMichal Wajdeczko static inline void xe_sleep_relaxed_ms(unsigned int delay_ms)
1994a2ceb1SMichal Wajdeczko {
2094a2ceb1SMichal Wajdeczko 	unsigned long min_us, max_us;
2194a2ceb1SMichal Wajdeczko 
2294a2ceb1SMichal Wajdeczko 	if (!delay_ms)
2394a2ceb1SMichal Wajdeczko 		return;
2494a2ceb1SMichal Wajdeczko 
2594a2ceb1SMichal Wajdeczko 	if (delay_ms > 20) {
2694a2ceb1SMichal Wajdeczko 		msleep(delay_ms);
2794a2ceb1SMichal Wajdeczko 		return;
2894a2ceb1SMichal Wajdeczko 	}
2994a2ceb1SMichal Wajdeczko 
3094a2ceb1SMichal Wajdeczko 	min_us = mul_u32_u32(delay_ms, 1000);
3194a2ceb1SMichal Wajdeczko 	max_us = min_us + 500;
3294a2ceb1SMichal Wajdeczko 
3394a2ceb1SMichal Wajdeczko 	usleep_range(min_us, max_us);
3494a2ceb1SMichal Wajdeczko }
3594a2ceb1SMichal Wajdeczko 
36*eec43f36SMichal Wajdeczko /**
37*eec43f36SMichal Wajdeczko  * xe_sleep_exponential_ms() - Sleep for a exponentially increased time.
38*eec43f36SMichal Wajdeczko  * @sleep_period_ms: current time in msec to sleep
39*eec43f36SMichal Wajdeczko  * @max_sleep_ms: maximum time in msec to sleep
40*eec43f36SMichal Wajdeczko  *
41*eec43f36SMichal Wajdeczko  * Sleep for the @sleep_period_ms and exponentially increase this time for the
42*eec43f36SMichal Wajdeczko  * next loop, unless reaching the @max_sleep_ms limit.
43*eec43f36SMichal Wajdeczko  *
44*eec43f36SMichal Wajdeczko  * Return: approximate time in msec the task was delayed.
45*eec43f36SMichal Wajdeczko  */
46*eec43f36SMichal Wajdeczko static inline unsigned int xe_sleep_exponential_ms(unsigned int *sleep_period_ms,
47*eec43f36SMichal Wajdeczko 						   unsigned int max_sleep_ms)
48*eec43f36SMichal Wajdeczko {
49*eec43f36SMichal Wajdeczko 	unsigned int delay_ms = *sleep_period_ms;
50*eec43f36SMichal Wajdeczko 	unsigned int next_delay_ms = 2 * delay_ms;
51*eec43f36SMichal Wajdeczko 
52*eec43f36SMichal Wajdeczko 	xe_sleep_relaxed_ms(delay_ms);
53*eec43f36SMichal Wajdeczko 	*sleep_period_ms = min(next_delay_ms, max_sleep_ms);
54*eec43f36SMichal Wajdeczko 	return delay_ms;
55*eec43f36SMichal Wajdeczko }
56*eec43f36SMichal Wajdeczko 
5794a2ceb1SMichal Wajdeczko #endif
58