xref: /freebsd/sys/contrib/alpine-hal/al_hal_reg_utils.h (revision f4b37ed0f8b307b1f3f0f630ca725d68f1dff30d)
1*f4b37ed0SZbigniew Bodek /*-
2*f4b37ed0SZbigniew Bodek ********************************************************************************
3*f4b37ed0SZbigniew Bodek Copyright (C) 2015 Annapurna Labs Ltd.
4*f4b37ed0SZbigniew Bodek 
5*f4b37ed0SZbigniew Bodek This file may be licensed under the terms of the Annapurna Labs Commercial
6*f4b37ed0SZbigniew Bodek License Agreement.
7*f4b37ed0SZbigniew Bodek 
8*f4b37ed0SZbigniew Bodek Alternatively, this file can be distributed under the terms of the GNU General
9*f4b37ed0SZbigniew Bodek Public License V2 as published by the Free Software Foundation and can be
10*f4b37ed0SZbigniew Bodek found at http://www.gnu.org/licenses/gpl-2.0.html
11*f4b37ed0SZbigniew Bodek 
12*f4b37ed0SZbigniew Bodek Alternatively, redistribution and use in source and binary forms, with or
13*f4b37ed0SZbigniew Bodek without modification, are permitted provided that the following conditions are
14*f4b37ed0SZbigniew Bodek met:
15*f4b37ed0SZbigniew Bodek 
16*f4b37ed0SZbigniew Bodek     *     Redistributions of source code must retain the above copyright notice,
17*f4b37ed0SZbigniew Bodek this list of conditions and the following disclaimer.
18*f4b37ed0SZbigniew Bodek 
19*f4b37ed0SZbigniew Bodek     *     Redistributions in binary form must reproduce the above copyright
20*f4b37ed0SZbigniew Bodek notice, this list of conditions and the following disclaimer in
21*f4b37ed0SZbigniew Bodek the documentation and/or other materials provided with the
22*f4b37ed0SZbigniew Bodek distribution.
23*f4b37ed0SZbigniew Bodek 
24*f4b37ed0SZbigniew Bodek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25*f4b37ed0SZbigniew Bodek ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26*f4b37ed0SZbigniew Bodek WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*f4b37ed0SZbigniew Bodek DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28*f4b37ed0SZbigniew Bodek ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*f4b37ed0SZbigniew Bodek (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*f4b37ed0SZbigniew Bodek LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*f4b37ed0SZbigniew Bodek ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*f4b37ed0SZbigniew Bodek (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*f4b37ed0SZbigniew Bodek SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*f4b37ed0SZbigniew Bodek 
35*f4b37ed0SZbigniew Bodek *******************************************************************************/
36*f4b37ed0SZbigniew Bodek 
37*f4b37ed0SZbigniew Bodek /**
38*f4b37ed0SZbigniew Bodek  * @defgroup group_common HAL Common Layer
39*f4b37ed0SZbigniew Bodek  *  @{
40*f4b37ed0SZbigniew Bodek  * @file   al_hal_reg_utils.h
41*f4b37ed0SZbigniew Bodek  *
42*f4b37ed0SZbigniew Bodek  * @brief  Register utilities used by HALs and platform layer
43*f4b37ed0SZbigniew Bodek  *
44*f4b37ed0SZbigniew Bodek  *
45*f4b37ed0SZbigniew Bodek  */
46*f4b37ed0SZbigniew Bodek 
47*f4b37ed0SZbigniew Bodek #ifndef __AL_HAL_REG_UTILS_H__
48*f4b37ed0SZbigniew Bodek #define __AL_HAL_REG_UTILS_H__
49*f4b37ed0SZbigniew Bodek 
50*f4b37ed0SZbigniew Bodek #include "al_hal_plat_types.h"
51*f4b37ed0SZbigniew Bodek #include "al_hal_plat_services.h"
52*f4b37ed0SZbigniew Bodek 
53*f4b37ed0SZbigniew Bodek /* *INDENT-OFF* */
54*f4b37ed0SZbigniew Bodek #ifdef __cplusplus
55*f4b37ed0SZbigniew Bodek extern "C" {
56*f4b37ed0SZbigniew Bodek #endif
57*f4b37ed0SZbigniew Bodek /* *INDENT-ON* */
58*f4b37ed0SZbigniew Bodek 
59*f4b37ed0SZbigniew Bodek #define AL_BIT(b)	(1UL << (b))
60*f4b37ed0SZbigniew Bodek 
61*f4b37ed0SZbigniew Bodek #define AL_ADDR_LOW(x)	((uint32_t)((al_phys_addr_t)(x)))
62*f4b37ed0SZbigniew Bodek #define AL_ADDR_HIGH(x)	((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16))
63*f4b37ed0SZbigniew Bodek 
64*f4b37ed0SZbigniew Bodek /** get field out of 32 bit register */
65*f4b37ed0SZbigniew Bodek #define AL_REG_FIELD_GET(reg, mask, shift)  (((reg) & (mask)) >> (shift))
66*f4b37ed0SZbigniew Bodek 
67*f4b37ed0SZbigniew Bodek /** set field of 32 bit register */
68*f4b37ed0SZbigniew Bodek #define AL_REG_FIELD_SET(reg, mask, shift, val)			\
69*f4b37ed0SZbigniew Bodek 	(reg) =							\
70*f4b37ed0SZbigniew Bodek 		(((reg) & (~(mask))) |				\
71*f4b37ed0SZbigniew Bodek 		((((unsigned)(val)) << (shift)) & (mask)))
72*f4b37ed0SZbigniew Bodek 
73*f4b37ed0SZbigniew Bodek /** set field of 64 bit register */
74*f4b37ed0SZbigniew Bodek #define AL_REG_FIELD_SET_64(reg, mask, shift, val)		\
75*f4b37ed0SZbigniew Bodek 	((reg) =						\
76*f4b37ed0SZbigniew Bodek 		(((reg) & (~(mask))) |				\
77*f4b37ed0SZbigniew Bodek 		((((uint64_t)(val)) << (shift)) & (mask))))
78*f4b37ed0SZbigniew Bodek 
79*f4b37ed0SZbigniew Bodek /** get single bit out of 32 bit register */
80*f4b37ed0SZbigniew Bodek #define AL_REG_BIT_GET(reg, shift)				\
81*f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_GET(reg, AL_BIT(shift), shift)
82*f4b37ed0SZbigniew Bodek 
83*f4b37ed0SZbigniew Bodek #define AL_REG_BITS_FIELD(shift, val)				\
84*f4b37ed0SZbigniew Bodek 		(((unsigned)(val)) << (shift))
85*f4b37ed0SZbigniew Bodek 
86*f4b37ed0SZbigniew Bodek /** set single bit field of 32 bit register to a given value */
87*f4b37ed0SZbigniew Bodek #define AL_REG_BIT_VAL_SET(reg, shift, val)				\
88*f4b37ed0SZbigniew Bodek 	AL_REG_FIELD_SET(reg, AL_BIT(shift), shift, val)
89*f4b37ed0SZbigniew Bodek 
90*f4b37ed0SZbigniew Bodek /** set single bit of 32 bit register to 1 */
91*f4b37ed0SZbigniew Bodek #define AL_REG_BIT_SET(reg, shift)				\
92*f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, shift, 1)
93*f4b37ed0SZbigniew Bodek 
94*f4b37ed0SZbigniew Bodek /** clear single bit of 32 bit register */
95*f4b37ed0SZbigniew Bodek #define AL_REG_BIT_CLEAR(reg, shift)				\
96*f4b37ed0SZbigniew Bodek 	AL_REG_BIT_VAL_SET(reg, shift, 0)
97*f4b37ed0SZbigniew Bodek 
98*f4b37ed0SZbigniew Bodek 
99*f4b37ed0SZbigniew Bodek #define AL_BIT_MASK(n)						\
100*f4b37ed0SZbigniew Bodek 	(AL_BIT(n) - 1)
101*f4b37ed0SZbigniew Bodek 
102*f4b37ed0SZbigniew Bodek #define AL_FIELD_MASK(msb, lsb)					\
103*f4b37ed0SZbigniew Bodek 	(AL_BIT(msb) + AL_BIT_MASK(msb) - AL_BIT_MASK(lsb))
104*f4b37ed0SZbigniew Bodek 
105*f4b37ed0SZbigniew Bodek /** clear bits specified by clear_mask */
106*f4b37ed0SZbigniew Bodek #define AL_REG_MASK_CLEAR(reg, clear_mask)			\
107*f4b37ed0SZbigniew Bodek 	((reg) = (((reg) & (~(clear_mask)))))
108*f4b37ed0SZbigniew Bodek 
109*f4b37ed0SZbigniew Bodek /** set bits specified by clear_mask */
110*f4b37ed0SZbigniew Bodek #define AL_REG_MASK_SET(reg, clear_mask)			\
111*f4b37ed0SZbigniew Bodek 	((reg) = (((reg) | (clear_mask))))
112*f4b37ed0SZbigniew Bodek 
113*f4b37ed0SZbigniew Bodek 
114*f4b37ed0SZbigniew Bodek /** clear bits specified by clear_mask, and set bits specified by set_mask */
115*f4b37ed0SZbigniew Bodek #define AL_REG_CLEAR_AND_SET(reg, clear_mask, set_mask)			\
116*f4b37ed0SZbigniew Bodek 	(reg) =	(((reg) & (~(clear_mask))) | (set_mask))
117*f4b37ed0SZbigniew Bodek 
118*f4b37ed0SZbigniew Bodek #define AL_ALIGN_UP(val, size)					\
119*f4b37ed0SZbigniew Bodek 	((size) * (((val) + (size) - 1) / (size)))
120*f4b37ed0SZbigniew Bodek 
121*f4b37ed0SZbigniew Bodek /** take bits selected by mask from one data, the rest from background */
122*f4b37ed0SZbigniew Bodek #define AL_MASK_VAL(mask, data, background)		\
123*f4b37ed0SZbigniew Bodek 	(((mask) & (data)) | ((~mask) & (background)))
124*f4b37ed0SZbigniew Bodek 
125*f4b37ed0SZbigniew Bodek /**
126*f4b37ed0SZbigniew Bodek  * 8 bits register masked write
127*f4b37ed0SZbigniew Bodek  *
128*f4b37ed0SZbigniew Bodek  * @param	reg
129*f4b37ed0SZbigniew Bodek  *	register address
130*f4b37ed0SZbigniew Bodek  * @param	mask
131*f4b37ed0SZbigniew Bodek  *	bits not selected (1) by mask will be left unchanged
132*f4b37ed0SZbigniew Bodek  * @param	data
133*f4b37ed0SZbigniew Bodek  *	data to write. bits not selected by mask ignored.
134*f4b37ed0SZbigniew Bodek  */
135*f4b37ed0SZbigniew Bodek static inline void
136*f4b37ed0SZbigniew Bodek al_reg_write8_masked(uint8_t __iomem *reg, uint8_t mask, uint8_t data)
137*f4b37ed0SZbigniew Bodek {
138*f4b37ed0SZbigniew Bodek 	uint8_t temp;
139*f4b37ed0SZbigniew Bodek 	temp = al_reg_read8(reg);
140*f4b37ed0SZbigniew Bodek 	al_reg_write8(reg, AL_MASK_VAL(mask, data, temp));
141*f4b37ed0SZbigniew Bodek }
142*f4b37ed0SZbigniew Bodek 
143*f4b37ed0SZbigniew Bodek 
144*f4b37ed0SZbigniew Bodek /**
145*f4b37ed0SZbigniew Bodek  * 16 bits register masked write
146*f4b37ed0SZbigniew Bodek  *
147*f4b37ed0SZbigniew Bodek  * @param	reg
148*f4b37ed0SZbigniew Bodek  *	register address
149*f4b37ed0SZbigniew Bodek  * @param	mask
150*f4b37ed0SZbigniew Bodek  *	bits not selected (1) by mask will be left unchanged
151*f4b37ed0SZbigniew Bodek  * @param	data
152*f4b37ed0SZbigniew Bodek  *	data to write. bits not selected by mask ignored.
153*f4b37ed0SZbigniew Bodek  */
154*f4b37ed0SZbigniew Bodek static inline void
155*f4b37ed0SZbigniew Bodek al_reg_write16_masked(uint16_t __iomem *reg, uint16_t mask, uint16_t data)
156*f4b37ed0SZbigniew Bodek {
157*f4b37ed0SZbigniew Bodek 	uint16_t temp;
158*f4b37ed0SZbigniew Bodek 	temp = al_reg_read16(reg);
159*f4b37ed0SZbigniew Bodek 	al_reg_write16(reg, AL_MASK_VAL(mask, data, temp));
160*f4b37ed0SZbigniew Bodek }
161*f4b37ed0SZbigniew Bodek 
162*f4b37ed0SZbigniew Bodek 
163*f4b37ed0SZbigniew Bodek /**
164*f4b37ed0SZbigniew Bodek  * 32 bits register masked write
165*f4b37ed0SZbigniew Bodek  *
166*f4b37ed0SZbigniew Bodek  * @param	reg
167*f4b37ed0SZbigniew Bodek  *	register address
168*f4b37ed0SZbigniew Bodek  * @param	mask
169*f4b37ed0SZbigniew Bodek  *	bits not selected (1) by mask will be left unchanged
170*f4b37ed0SZbigniew Bodek  * @param	data
171*f4b37ed0SZbigniew Bodek  *	data to write. bits not selected by mask ignored.
172*f4b37ed0SZbigniew Bodek  */
173*f4b37ed0SZbigniew Bodek static inline void
174*f4b37ed0SZbigniew Bodek al_reg_write32_masked(uint32_t __iomem *reg, uint32_t mask, uint32_t data)
175*f4b37ed0SZbigniew Bodek {
176*f4b37ed0SZbigniew Bodek 	uint32_t temp;
177*f4b37ed0SZbigniew Bodek 	temp = al_reg_read32(reg);
178*f4b37ed0SZbigniew Bodek 	al_reg_write32(reg, AL_MASK_VAL(mask, data, temp));
179*f4b37ed0SZbigniew Bodek }
180*f4b37ed0SZbigniew Bodek 
181*f4b37ed0SZbigniew Bodek /* *INDENT-OFF* */
182*f4b37ed0SZbigniew Bodek #ifdef __cplusplus
183*f4b37ed0SZbigniew Bodek }
184*f4b37ed0SZbigniew Bodek #endif
185*f4b37ed0SZbigniew Bodek /* *INDENT-ON* */
186*f4b37ed0SZbigniew Bodek /** @} end of Common group */
187*f4b37ed0SZbigniew Bodek #endif
188*f4b37ed0SZbigniew Bodek 
189