xref: /rk3399_rockchip-uboot/include/bitfield.h (revision c69abd801b3600252726948e0763b2b3c3fe9e19)
1989ce049SDarwin Rambo /*
2989ce049SDarwin Rambo  * Copyright 2013 Broadcom Corporation.
3989ce049SDarwin Rambo  *
4989ce049SDarwin Rambo  * SPDX-License-Identifier:      GPL-2.0+
5989ce049SDarwin Rambo  */
6989ce049SDarwin Rambo 
7989ce049SDarwin Rambo /*
8989ce049SDarwin Rambo  * Bitfield operations
9989ce049SDarwin Rambo  *
10989ce049SDarwin Rambo  * These are generic bitfield operations which allow manipulation of variable
11989ce049SDarwin Rambo  * width bitfields within a word. One use of this would be to use data tables
12989ce049SDarwin Rambo  * to determine how to reprogram fields within R/W hardware registers.
13989ce049SDarwin Rambo  *
14989ce049SDarwin Rambo  * Example:
15989ce049SDarwin Rambo  *
16989ce049SDarwin Rambo  *            old_reg_val
17989ce049SDarwin Rambo  * +--------+----+---+--+-----+----------+
18989ce049SDarwin Rambo  * |        |    |   |  | old |          |
19989ce049SDarwin Rambo  * +--------+----+---+--+-----+----------+
20989ce049SDarwin Rambo  *
21989ce049SDarwin Rambo  *            new_reg_val
22989ce049SDarwin Rambo  * +--------+----+---+--+-----+----------+
23989ce049SDarwin Rambo  * |        |    |   |  | new |          |
24989ce049SDarwin Rambo  * +--------+----+---+--+-----+----------+
25989ce049SDarwin Rambo  *
26989ce049SDarwin Rambo  * mask = bitfield_mask(10, 5);
27989ce049SDarwin Rambo  * old = bitfield_extract(old_reg_val, 10, 5);
28989ce049SDarwin Rambo  * new_reg_val = bitfield_replace(old_reg_val, 10, 5, new);
29989ce049SDarwin Rambo  *
30989ce049SDarwin Rambo  * The numbers 10 and 5 could for example come from data
31989ce049SDarwin Rambo  * tables which describe all bitfields in all registers.
32989ce049SDarwin Rambo  */
33989ce049SDarwin Rambo 
34989ce049SDarwin Rambo #include <linux/types.h>
35989ce049SDarwin Rambo 
36989ce049SDarwin Rambo /* Produces a mask of set bits covering a range of a uint value */
37989ce049SDarwin Rambo static inline uint bitfield_mask(uint shift, uint width)
38989ce049SDarwin Rambo {
39989ce049SDarwin Rambo 	return ((1 << width) - 1) << shift;
40989ce049SDarwin Rambo }
41989ce049SDarwin Rambo 
42989ce049SDarwin Rambo /* Extract the value of a bitfield found within a given register value */
43989ce049SDarwin Rambo static inline uint bitfield_extract(uint reg_val, uint shift, uint width)
44989ce049SDarwin Rambo {
45989ce049SDarwin Rambo 	return (reg_val & bitfield_mask(shift, width)) >> shift;
46989ce049SDarwin Rambo }
47989ce049SDarwin Rambo 
48989ce049SDarwin Rambo /*
49989ce049SDarwin Rambo  * Replace the value of a bitfield found within a given register value
50989ce049SDarwin Rambo  * Returns the newly modified uint value with the replaced field.
51989ce049SDarwin Rambo  */
52989ce049SDarwin Rambo static inline uint bitfield_replace(uint reg_val, uint shift, uint width,
53989ce049SDarwin Rambo 				    uint bitfield_val)
54989ce049SDarwin Rambo {
55989ce049SDarwin Rambo 	uint mask = bitfield_mask(shift, width);
56989ce049SDarwin Rambo 
57*c69abd80SCodrin Ciubotariu 	return (reg_val & ~mask) | ((bitfield_val << shift) & mask);
58989ce049SDarwin Rambo }
59