xref: /linux-6.15/drivers/gpu/drm/lib/drm_random.c (revision a33d42dd)
1*a33d42ddSChris Wilson #include <linux/bitops.h>
2*a33d42ddSChris Wilson #include <linux/kernel.h>
3*a33d42ddSChris Wilson #include <linux/random.h>
4*a33d42ddSChris Wilson #include <linux/slab.h>
5*a33d42ddSChris Wilson #include <linux/types.h>
6*a33d42ddSChris Wilson 
7*a33d42ddSChris Wilson #include "drm_random.h"
8*a33d42ddSChris Wilson 
9*a33d42ddSChris Wilson static inline u32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
10*a33d42ddSChris Wilson {
11*a33d42ddSChris Wilson 	return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
12*a33d42ddSChris Wilson }
13*a33d42ddSChris Wilson 
14*a33d42ddSChris Wilson void drm_random_reorder(unsigned int *order, unsigned int count,
15*a33d42ddSChris Wilson 			struct rnd_state *state)
16*a33d42ddSChris Wilson {
17*a33d42ddSChris Wilson 	unsigned int i, j;
18*a33d42ddSChris Wilson 
19*a33d42ddSChris Wilson 	for (i = 0; i < count; ++i) {
20*a33d42ddSChris Wilson 		BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
21*a33d42ddSChris Wilson 		j = drm_prandom_u32_max_state(count, state);
22*a33d42ddSChris Wilson 		swap(order[i], order[j]);
23*a33d42ddSChris Wilson 	}
24*a33d42ddSChris Wilson }
25*a33d42ddSChris Wilson EXPORT_SYMBOL(drm_random_reorder);
26*a33d42ddSChris Wilson 
27*a33d42ddSChris Wilson unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
28*a33d42ddSChris Wilson {
29*a33d42ddSChris Wilson 	unsigned int *order, i;
30*a33d42ddSChris Wilson 
31*a33d42ddSChris Wilson 	order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY);
32*a33d42ddSChris Wilson 	if (!order)
33*a33d42ddSChris Wilson 		return order;
34*a33d42ddSChris Wilson 
35*a33d42ddSChris Wilson 	for (i = 0; i < count; i++)
36*a33d42ddSChris Wilson 		order[i] = i;
37*a33d42ddSChris Wilson 
38*a33d42ddSChris Wilson 	drm_random_reorder(order, count, state);
39*a33d42ddSChris Wilson 	return order;
40*a33d42ddSChris Wilson }
41*a33d42ddSChris Wilson EXPORT_SYMBOL(drm_random_order);
42