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