1 /* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
2  *
3  * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
4  *the the People's Republic of China and other countries.
5  * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
6  *
7  * DISCLAIMER
8  * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
9  * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
10  * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
11  * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
12  * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
13  * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
14  * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
15  *
16  *
17  * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
18  * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
19  * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
20  * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
21  * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef __CLK_H__
33 #define __CLK_H__
34 
35 #include "common_ccmu.h"
36 //#include "platform_clk.h"
37 #include <hal_clk.h>
38 
39 #define clk_driver_version "v_1_0_2"
40 
41 typedef struct clk_base
42 {
43     hal_clk_id_t clk;
44     hal_clk_id_t parent;
45     u32 clk_rate;
46 } clk_base_t, *clk_base_pt;
47 
48 typedef struct clk_core
49 {
50     hal_clk_id_t clk;
51     hal_clk_type_t clk_type;
52     hal_clk_id_t current_parent;
53     hal_clk_type_t current_parent_type;
54     u32 clk_rate;
55     u32 parent_rate;
56     hal_clk_status_t clk_enbale;
57 } clk_core_t, *clk_core_pt;
58 
59 typedef struct clk_fix_factor
60 {
61     clk_core_t clk_core;
62     u32 clk_mult;
63     u32 clk_div;
64 } clk_fixed_factor_t, *clk_fixed_factor_pt ;
65 
66 typedef struct clk_factor
67 {
68     clk_core_t clk_core;
69     struct factor_init_data *factor_data ;
70 } clk_factor_t, *clk_factor_pt ;
71 
72 typedef struct clk_periph
73 {
74     clk_core_t clk_core;
75     hal_clk_id_t *parent_arry;
76     u32 parent_arry_size;
77     struct sunxi_clk_periph *config;
78 } clk_periph_t, *clk_periph_pt ;
79 
80 #define SETMASK(width, shift)   ((width?((-1U) >> (32-width)):0)  << (shift))
81 #define CLRMASK(width, shift)   (~(SETMASK(width, shift)))
82 
83 #define SET_BITS(shift, width, reg, val)    \
84     (((reg) & CLRMASK(width, shift)) | (val << (shift)))
85 
86 #define GET_BITS(shift, width, reg)     \
87     (((reg) & SETMASK(width, shift)) >> (shift))
88 
89 #define CLK_LOCKBIT(x) x
90 
91 #define do_div(n,base) ({                   \
92         u32 __base = (base);                \
93         u32 __rem;                      \
94         __rem = ((u64)(n)) % __base;            \
95         (n) = ((u64)(n)) / __base;              \
96         if (__rem > __base / 2) \
97             ++(n); \
98         __rem;                          \
99     })
100 
101 /************************************************************************************************
102 * Macro definition SUNXI_CLK_FIXED_SRC
103 * @Description: This definition used to defining a Soc fixed-src-clk type clock structure variable and statically initialized
104 *************************************************************************************************/
105 #define SUNXI_CLK_FIXED_SRC(_name, _clk, _current_parent, _current_parent_type, _clk_rate, _parent_rate) \
106     clk_core_t sunxi_clk_fixed_src_##_name  = { \
107                                                 .clk = _clk,    \
108                                                 .clk_type = HAL_CLK_FIXED_SRC,  \
109                                                 .current_parent = _current_parent,  \
110                                                 .current_parent_type = _current_parent_type, \
111                                                 .clk_rate = _clk_rate,      \
112                                                 .parent_rate = _parent_rate,    \
113                                                 .clk_enbale = HAL_CLK_STATUS_ENABLED,    \
114                                               }
115 
116 /************************************************************************************************
117 * Macro definition SUNXI_CLK_FIXED_FACTOR
118 * @Description: This definition used to defining a Soc fixed-factor-clk type clock structure variable and statically initialized
119 *************************************************************************************************/
120 #define SUNXI_CLK_FIXED_FACTOR(_name, _clk, _current_parent, _current_parent_type, _mult, _div) \
121     clk_fixed_factor_t sunxi_clk_fixed_factor_##_name  = {   \
122                                                              .clk_core = {   \
123                                                                              .clk = _clk,    \
124                                                                              .clk_type = HAL_CLK_FIXED_FACTOR,   \
125                                                                              .current_parent = _current_parent,  \
126                                                                              .current_parent_type = _current_parent_type, \
127                                                                              .clk_rate = 0,     \
128                                                                              .parent_rate = 0,      \
129                                                                              .clk_enbale = HAL_CLK_STATUS_DISABLED,   \
130                                                                          },  \
131                                                              .clk_mult = _mult,  \
132                                                              .clk_div = _div,    \
133                                                          }
134 
135 #define SUNXI_CLK_FACTOR_PERI1_MAX_FREQ (636000000U)
136 
137 /************************************************************************************************
138 * @Function: clk_udelay
139 * @Description: implement for seting delay time
140 * @Parameters:
141 * # us: delay time of us unit
142 * @Return values:
143 * # void: No parameters returned
144 * @Attention: .etc
145 *************************************************************************************************/
146 void clk_udelay(u32 us);
147 
148 /************************************************************************************************
149 * @Function: clk_get_core
150 * @Description: implement to find clock structure variable pointer of clock-id
151 * @Parameters:
152 * # clk: clock-id of soc specific clock
153 * @Return values:
154 * # NULL: input parameter of clock-id defined in hal but not defined by soc clock driver
155 * # others :  clk_core_pt structure variable pointer of clock-id
156 * @Attention: .etc
157 *************************************************************************************************/
158 clk_core_pt clk_get_core(hal_clk_id_t clk);
159 
160 
161 /************************************************************************************************
162 * @Function: clk_init
163 * @Description: implement for initialize soc clocks during the system power-on startup phase
164 * @Parameters:
165 * # void: No parameters required
166 * @Return values:
167 * # HAL_CLK_STATUS_OK: soc clocks initialize successed
168 * # others : soc clocks initialization may have some abnormal problems
169 * @Attention: clock initialize timing depands on specific soc platform clock design
170 *************************************************************************************************/
171 hal_clk_status_t clk_init(void);
172 
173 hal_clk_id_t clk_get(hal_clk_type_t type, hal_clk_id_t id);
174 
175 hal_clk_status_t clk_put(hal_clk_id_t id);
176 
177 /************************************************************************************************
178 * @Function: clk_get_rate
179 * @Description: implement for factor-clk, bus-clk and periph-clk get current rate cached witch may not current Runtime rate
180 * @Parameters:
181 * # clk: clock-id of soc specific clock
182 * @Return values:
183 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
184 * # 0 : input parameter of clock-id defined in hal but not defined by soc clock driver or clock disbaled
185 * # others: return rate cached successed
186 * @Attention: .etc
187 *************************************************************************************************/
188 hal_clk_status_t clk_get_rate(hal_clk_id_t clk, u32 *rate);
189 
190 
191 /************************************************************************************************
192 * @Function: clk_set_rate
193 * @Description: implement for bus-clk and periph-clk to set new rate
194 * @Parameters:
195 * # clk: clock-id of soc specific clock
196 * # rate: the new rate value
197 * @Return values:
198 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
199 * # HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED: fixed-clk and factor clk not allowed User to change rate because of stability
200 * # HAL_CLK_STATUS_ERROT_CLK_UNDEFINED: input parameter of clock-id defined in hal but not defined by soc clock driver
201 * # HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND: input parameter of clock-id defined in hal but not defined by soc clock driver
202 * # HAL_CLK_STATUS_OK: set new rate successed
203 * @Attention: .etc
204 *************************************************************************************************/
205 hal_clk_status_t clk_set_rate(hal_clk_id_t clk, u32 rate);
206 
207 
208 /************************************************************************************************
209 * @Function: clk_recalc_rate
210 * @Description: implement for factor-clk, bus-clk and periph-clk to recalculate current Runtime rate
211 * @Parameters:
212 * # clk: clock-id of soc specific clock
213 * @Return values:
214 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal
215 * # 0 : input parameter of clock-id defined in hal but not defined by soc clock driver or clock disbaled
216 * # others: return current clock rate successed
217 * @Attention: .etc
218 *************************************************************************************************/
219 hal_clk_status_t clk_recalc_rate(hal_clk_id_t clk, u32 *prate);
220 
221 
222 /************************************************************************************************
223 * @Function: clk_round_rate
224 * @Description: implement for for factor-clk, bus-clk and periph-clk round target rate to the most suitable rate
225 * @Parameters:
226 * # clk: clock-id of soc specific clock
227 * # rate: the target rate form API-User
228 * @Return values:
229 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
230 * # 0 : input parameter of clock-id defined in hal but not defined by soc clock driver or clock disbaled
231 * # others: return round rate successed
232 * @Attention: .etc
233 *************************************************************************************************/
234 hal_clk_status_t clk_round_rate(hal_clk_id_t clk, u32 rate, u32 *prate);
235 
236 
237 /************************************************************************************************
238 * @Function: clk_is_enabled
239 * @Description: implement for bus-clk and periph-clk to get clock enabled statue
240 * @Parameters:
241 * # clk: clock-id of soc specific clock
242 * @Return values:
243 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
244 * # HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED: fixed-clk and factor clk not allowed User to change rate because of stability
245 * # HAL_CLK_STATUS_ERROT_CLK_UNDEFINED: input parameter of clock-id defined in hal but not defined by soc clock driver
246 * # HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND: input parameter of clock-id defined in hal but not defined by soc clock driver
247 * # HAL_CLK_STATUS_ENABLED: clock current status is enabled
248 * # HAL_CLK_STATUS_DISABLED: clock current status is disabled
249 * @Attention: .etc
250 *************************************************************************************************/
251 hal_clk_status_t clk_is_enabled(hal_clk_id_t clk);
252 
253 
254 /************************************************************************************************
255 * @Function: clk_prepare_enable
256 * @Description: implement for bus-clk and periph-clk to enable clock
257 * @Parameters:
258 * # clk: clock-id of soc specific clock
259 * @Return values:
260 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
261 * # HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED: fixed-clk and factor clk not allowed User to change rate because of stability
262 * # HAL_CLK_STATUS_ERROT_CLK_UNDEFINED: input parameter of clock-id defined in hal but not defined by soc clock driver
263 * # HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND: input parameter of clock-id defined in hal but not defined by soc clock driver
264 * # HAL_CLK_STATUS_ENABLED: clock current status is enabled
265 * # HAL_CLK_STATUS_DISABLED: clock current status is disabled
266 * @Attention: .etc
267 *************************************************************************************************/
268 hal_clk_status_t clk_prepare_enable(hal_clk_id_t clk);
269 
270 
271 /************************************************************************************************
272 * @Function: clk_disable_unprepare
273 * @Description: implement for bus-clk and periph-clk to disable clock
274 * @Parameters:
275 * # clk: clock-id of soc specific clock
276 * @Return values:
277 * # HAL_CLK_STATUS_INVALID_PARAMETER: input parameter of clock-id undefined in hal ot rate value is invalid
278 * # HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED: fixed-clk and factor clk not allowed User to change rate because of stability
279 * # HAL_CLK_STATUS_ERROT_CLK_UNDEFINED: input parameter of clock-id defined in hal but not defined by soc clock driver
280 * # HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND: input parameter of clock-id defined in hal but not defined by soc clock driver
281 * # HAL_CLK_STATUS_OK: clock current status disabled successed
282 * @Attention: .etc
283 *************************************************************************************************/
284 hal_clk_status_t clk_disable_unprepare(hal_clk_id_t clk);
285 
286 
287 /************************************************************************************************
288 * @Function: clk_get_parent
289 * @Description: implement for factor-clk, bus-clk and periph-clk to select parent clock
290 * @Parameters:
291 * # clk: clock-id of soc specific clock witch nedds to adjust parent clock
292 * # parent: clock-id of soc specific clock's parent clock
293 * @Return values:
294 * # HAL_CLK_STATUS_OK: soc specific clock select and siwtch parent clock successed
295 * # others : soc specific clock select and siwtch parent clock may have some abnormal problems
296 * @Attention: soc specific clock and parent clock must be according to the SOC_User_Manual definition
297 *************************************************************************************************/
298 hal_clk_id_t clk_get_parent(hal_clk_id_t clk);
299 
300 
301 /************************************************************************************************
302 * @Function: clk_set_parent
303 * @Description: implement for factor-clk, bus-clk and periph-clk to select parent clock
304 * @Parameters:
305 * # clk: clock-id of soc specific clock witch nedds to adjust parent clock
306 * # parent: clock-id of soc specific clock's parent clock
307 * @Return values:
308 * # HAL_CLK_STATUS_OK: soc specific clock select and siwtch parent clock successed
309 * # others : soc specific clock select and siwtch parent clock may have some abnormal problems
310 * @Attention: soc specific clock and parent clock must be according to the SOC_User_Manual definition
311 *************************************************************************************************/
312 hal_clk_status_t clk_set_parent(hal_clk_id_t clk, hal_clk_id_t parent_clk);
313 
314 
315 #endif /* __HAL_CLOCK_H__ */
316 
317