1 /*
2  * Copyright (c) 2022-2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef HPM_CLOCK_DRV_H
8 #define HPM_CLOCK_DRV_H
9 
10 #include "hpm_common.h"
11 #include "hpm_sysctl_drv.h"
12 #include "hpm_csr_drv.h"
13 
14 #define CLOCK_DIV_INVALID (~0UL)
15 
16 /**
17  * @brief Error codes for clock driver
18  */
19 enum {
20     status_clk_div_invalid = MAKE_STATUS(status_group_clk, 0),
21     status_clk_src_invalid = MAKE_STATUS(status_group_clk, 1),
22     status_clk_invalid = MAKE_STATUS(status_group_clk, 2),
23     status_clk_operation_unsupported = MAKE_STATUS(status_group_clk, 3),
24     status_clk_shared_ahb = MAKE_STATUS(status_group_clk, 4),
25     status_clk_shared_axis = MAKE_STATUS(status_group_clk, 5),
26     status_clk_shared_axic = MAKE_STATUS(status_group_clk, 6),
27     status_clk_shared_axiv = MAKE_STATUS(status_group_clk, 7),
28     status_clk_shared_axif = MAKE_STATUS(status_group_clk, 8),
29     status_clk_shared_axid = MAKE_STATUS(status_group_clk, 9),
30     status_clk_fixed = MAKE_STATUS(status_group_clk, 10),
31 
32 };
33 
34 
35 /**
36  * @brief Clock source group definitions
37  */
38 #define CLK_SRC_GROUP_COMMON            (0U)
39 #define CLK_SRC_GROUP_ADC               (1U)
40 #define CLK_SRC_GROUP_I2S               (2U)
41 #define CLK_SRC_GROUP_EWDG               (3U)
42 #define CLK_SRC_GROUP_PEWDG              (4U)
43 #define CLK_SRC_GROUP_PMIC              (5U)
44 #define CLK_SRC_GROUP_AXI_SOC           (6U)
45 #define CLK_SRC_GROUP_AXI_FAST          (7U)
46 #define CLK_SRC_GROUP_AXI_VIDEO         (8U)
47 #define CLK_SRC_GROUP_SRC               (9U)
48 #define CLK_SRC_GROUP_INVALID           (15U)
49 
50 #define MAKE_CLK_SRC(src_grp, index) (((uint8_t)(src_grp)<<4) | (index))
51 #define GET_CLK_SRC_GROUP(src) (((uint8_t)(src) >> 4) & 0x0FU)
52 #define GET_CLK_SRC_INDEX(src) ((uint8_t)(src) & 0x0FU)
53 
54 #define GET_CLOCK_SOURCE_FROM_CLK_SRC(clk_src) (clock_source_t)((uint32_t)(clk_src) & 0xFU)
55 
56 /**
57  * @brief Clock source definitions
58  */
59 typedef enum _clock_sources {
60     clk_src_osc24m = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 0),
61     clk_src_pll0_clk0 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 1),
62     clk_src_pll1_clk0 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 2),
63     clk_src_pll1_clk1 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 3),
64     clk_src_pll2_clk0 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 4),
65     clk_src_pll2_clk1 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 5),
66     clk_src_pll3_clk0 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 6),
67     clk_src_pll4_clk0 = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 7),
68     clk_src_osc32k = MAKE_CLK_SRC(CLK_SRC_GROUP_COMMON, 8),
69 
70     clk_adc_src_ana0 = MAKE_CLK_SRC(CLK_SRC_GROUP_ADC, 0),
71     clk_adc_src_ana1 = MAKE_CLK_SRC(CLK_SRC_GROUP_ADC, 0),
72     clk_adc_src_ahb0 = MAKE_CLK_SRC(CLK_SRC_GROUP_ADC, 1),
73 
74     clk_i2s_src_aud0 = MAKE_CLK_SRC(CLK_SRC_GROUP_I2S, 0),
75     clk_i2s_src_aud1 = MAKE_CLK_SRC(CLK_SRC_GROUP_I2S, 0),
76     clk_i2s_src_aud2 = MAKE_CLK_SRC(CLK_SRC_GROUP_I2S, 0),
77     clk_i2s_src_aud3 = MAKE_CLK_SRC(CLK_SRC_GROUP_I2S, 0),
78     clk_i2s_src_audx = MAKE_CLK_SRC(CLK_SRC_GROUP_I2S, 1),
79 
80     clk_wdg_src_ahb0 = MAKE_CLK_SRC(CLK_SRC_GROUP_EWDG, 0),
81     clk_wdg_src_osc32k = MAKE_CLK_SRC(CLK_SRC_GROUP_EWDG, 1),
82 
83     clk_pwdg_src_osc24m = MAKE_CLK_SRC(CLK_SRC_GROUP_PEWDG, 0),
84     clk_pwdg_src_osc32k = MAKE_CLK_SRC(CLK_SRC_GROUP_PEWDG, 1),
85 
86     clk_src_invalid = MAKE_CLK_SRC(CLK_SRC_GROUP_INVALID, 15),
87 } clk_src_t;
88 
89 
90 #define RESOURCE_INVALID (0xFFFFU)
91 #define RESOURCE_SHARED_AXI_SOC (0xFFFEU)
92 
93 /* Clock NAME related Macros */
94 #define MAKE_CLOCK_NAME(resource, src_type, node) (((uint32_t)(resource) << 16) | ((uint32_t)(src_type) << 8) | ((uint32_t)node))
95 #define GET_CLK_SRC_GROUP_FROM_NAME(name)  (((uint32_t)(name) >> 8) & 0xFFUL)
96 #define GET_CLK_NODE_FROM_NAME(name) ((uint32_t)(name) & 0xFFUL)
97 #define GET_CLK_RESOURCE_FROM_NAME(name) ((uint32_t)(name) >> 16)
98 
99 /**
100  * @brief Peripheral Clock Type Description
101  */
102 typedef enum _clock_name {
103     clock_axif = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_axif),
104     clock_axis = MAKE_CLOCK_NAME(sysctl_resource_axis, CLK_SRC_GROUP_COMMON, clock_node_axis),
105     clock_axic = MAKE_CLOCK_NAME(sysctl_resource_axic, CLK_SRC_GROUP_COMMON, clock_node_axic),
106     clock_axiv = MAKE_CLOCK_NAME(sysctl_resource_axiv, CLK_SRC_GROUP_COMMON, clock_node_axiv),
107     clock_axig = MAKE_CLOCK_NAME(sysctl_resource_axig, CLK_SRC_GROUP_COMMON, clock_node_gpu0),
108     clock_axid = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_axid),
109 
110     /* Software definition for compatibility */
111     clock_ahb = MAKE_CLOCK_NAME(RESOURCE_SHARED_AXI_SOC, CLK_SRC_GROUP_AXI_SOC, clock_node_axis),
112 
113     clock_cpu0 = MAKE_CLOCK_NAME(sysctl_resource_cpu0, CLK_SRC_GROUP_COMMON, clock_node_cpu0),
114     clock_mchtmr0 = MAKE_CLOCK_NAME(sysctl_resource_mchtmr0, CLK_SRC_GROUP_COMMON, clock_node_mchtmr0),
115     clock_gpu0 = MAKE_CLOCK_NAME(sysctl_resource_gpu0, CLK_SRC_GROUP_COMMON, clock_node_gpu0),
116 
117     clock_can0 = MAKE_CLOCK_NAME(sysctl_resource_can0, CLK_SRC_GROUP_COMMON, clock_node_can0),
118     clock_can1 = MAKE_CLOCK_NAME(sysctl_resource_can1, CLK_SRC_GROUP_COMMON, clock_node_can1),
119     clock_can2 = MAKE_CLOCK_NAME(sysctl_resource_can2, CLK_SRC_GROUP_COMMON, clock_node_can2),
120     clock_can3 = MAKE_CLOCK_NAME(sysctl_resource_can3, CLK_SRC_GROUP_COMMON, clock_node_can3),
121     clock_can4 = MAKE_CLOCK_NAME(sysctl_resource_can4, CLK_SRC_GROUP_COMMON, clock_node_can4),
122     clock_can5 = MAKE_CLOCK_NAME(sysctl_resource_can5, CLK_SRC_GROUP_COMMON, clock_node_can5),
123     clock_can6 = MAKE_CLOCK_NAME(sysctl_resource_can6, CLK_SRC_GROUP_COMMON, clock_node_can6),
124     clock_can7 = MAKE_CLOCK_NAME(sysctl_resource_can7, CLK_SRC_GROUP_COMMON, clock_node_can7),
125 
126     clock_lin0 = MAKE_CLOCK_NAME(sysctl_resource_lin0, CLK_SRC_GROUP_COMMON, clock_node_lin0),
127     clock_lin1 = MAKE_CLOCK_NAME(sysctl_resource_lin1, CLK_SRC_GROUP_COMMON, clock_node_lin1),
128     clock_lin2 = MAKE_CLOCK_NAME(sysctl_resource_lin2, CLK_SRC_GROUP_COMMON, clock_node_lin2),
129     clock_lin3 = MAKE_CLOCK_NAME(sysctl_resource_lin3, CLK_SRC_GROUP_COMMON, clock_node_lin3),
130     clock_lin4 = MAKE_CLOCK_NAME(sysctl_resource_lin4, CLK_SRC_GROUP_COMMON, clock_node_lin4),
131     clock_lin5 = MAKE_CLOCK_NAME(sysctl_resource_lin5, CLK_SRC_GROUP_COMMON, clock_node_lin5),
132     clock_lin6 = MAKE_CLOCK_NAME(sysctl_resource_lin6, CLK_SRC_GROUP_COMMON, clock_node_lin6),
133     clock_lin7 = MAKE_CLOCK_NAME(sysctl_resource_lin7, CLK_SRC_GROUP_COMMON, clock_node_lin7),
134 
135     clock_i2c0 = MAKE_CLOCK_NAME(sysctl_resource_i2c0, CLK_SRC_GROUP_COMMON, clock_node_i2c0),
136     clock_i2c1 = MAKE_CLOCK_NAME(sysctl_resource_i2c1, CLK_SRC_GROUP_COMMON, clock_node_i2c1),
137     clock_i2c2 = MAKE_CLOCK_NAME(sysctl_resource_i2c2, CLK_SRC_GROUP_COMMON, clock_node_i2c2),
138     clock_i2c3 = MAKE_CLOCK_NAME(sysctl_resource_i2c3, CLK_SRC_GROUP_COMMON, clock_node_i2c3),
139 
140     clock_spi0 = MAKE_CLOCK_NAME(sysctl_resource_spi0, CLK_SRC_GROUP_COMMON, clock_node_spi0),
141     clock_spi1 = MAKE_CLOCK_NAME(sysctl_resource_spi1, CLK_SRC_GROUP_COMMON, clock_node_spi1),
142     clock_spi2 = MAKE_CLOCK_NAME(sysctl_resource_spi2, CLK_SRC_GROUP_COMMON, clock_node_spi2),
143     clock_spi3 = MAKE_CLOCK_NAME(sysctl_resource_spi3, CLK_SRC_GROUP_COMMON, clock_node_spi3),
144 
145     clock_uart0 = MAKE_CLOCK_NAME(sysctl_resource_uart0, CLK_SRC_GROUP_COMMON, clock_node_uart0),
146     clock_uart1 = MAKE_CLOCK_NAME(sysctl_resource_uart1, CLK_SRC_GROUP_COMMON, clock_node_uart1),
147     clock_uart2 = MAKE_CLOCK_NAME(sysctl_resource_uart2, CLK_SRC_GROUP_COMMON, clock_node_uart2),
148     clock_uart3 = MAKE_CLOCK_NAME(sysctl_resource_uart3, CLK_SRC_GROUP_COMMON, clock_node_uart3),
149     clock_uart4 = MAKE_CLOCK_NAME(sysctl_resource_uart4, CLK_SRC_GROUP_COMMON, clock_node_uart4),
150     clock_uart5 = MAKE_CLOCK_NAME(sysctl_resource_uart5, CLK_SRC_GROUP_COMMON, clock_node_uart5),
151     clock_uart6 = MAKE_CLOCK_NAME(sysctl_resource_uart6, CLK_SRC_GROUP_COMMON, clock_node_uart6),
152     clock_uart7 = MAKE_CLOCK_NAME(sysctl_resource_uart7, CLK_SRC_GROUP_COMMON, clock_node_uart7),
153 
154     clock_gptmr0 = MAKE_CLOCK_NAME(sysctl_resource_gptmr0, CLK_SRC_GROUP_COMMON, clock_node_gptmr0),
155     clock_gptmr1 = MAKE_CLOCK_NAME(sysctl_resource_gptmr1, CLK_SRC_GROUP_COMMON, clock_node_gptmr1),
156     clock_gptmr2 = MAKE_CLOCK_NAME(sysctl_resource_gptmr2, CLK_SRC_GROUP_COMMON, clock_node_gptmr2),
157     clock_gptmr3 = MAKE_CLOCK_NAME(sysctl_resource_gptmr3, CLK_SRC_GROUP_COMMON, clock_node_gptmr3),
158     clock_gptmr4 = MAKE_CLOCK_NAME(sysctl_resource_gptmr4, CLK_SRC_GROUP_COMMON, clock_node_gptmr4),
159     clock_gptmr5 = MAKE_CLOCK_NAME(sysctl_resource_gptmr5, CLK_SRC_GROUP_COMMON, clock_node_gptmr5),
160     clock_gptmr6 = MAKE_CLOCK_NAME(sysctl_resource_gptmr6, CLK_SRC_GROUP_COMMON, clock_node_gptmr6),
161     clock_gptmr7 = MAKE_CLOCK_NAME(sysctl_resource_gptmr7, CLK_SRC_GROUP_COMMON, clock_node_gptmr7),
162 
163     clock_xpi0 = MAKE_CLOCK_NAME(sysctl_resource_xpi0, CLK_SRC_GROUP_COMMON, clock_node_xpi0),
164 
165     clock_xram = MAKE_CLOCK_NAME(sysctl_resource_xram, CLK_SRC_GROUP_COMMON, clock_node_xram),
166     clock_ddr0 = MAKE_CLOCK_NAME(sysctl_resource_ddr0, CLK_SRC_GROUP_AXI_FAST, clock_node_axif),
167 
168     clock_eth0 = MAKE_CLOCK_NAME(sysctl_resource_eth0, CLK_SRC_GROUP_COMMON, clock_node_eth0),
169 
170     clock_ptp0 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_ptp0),
171 
172     clock_sdxc0 = MAKE_CLOCK_NAME(sysctl_resource_sdc0, CLK_SRC_GROUP_COMMON, clock_node_sdc0),
173     clock_sdxc1 = MAKE_CLOCK_NAME(sysctl_resource_sdc1, CLK_SRC_GROUP_COMMON, clock_node_sdc1),
174 
175     clock_ntm0 = MAKE_CLOCK_NAME(sysctl_resource_ntm0, CLK_SRC_GROUP_COMMON, clock_node_ntm0),
176 
177     clock_ref0 = MAKE_CLOCK_NAME(sysctl_resource_ref0, CLK_SRC_GROUP_COMMON, clock_node_ref0),
178     clock_ref1 = MAKE_CLOCK_NAME(sysctl_resource_ref1, CLK_SRC_GROUP_COMMON, clock_node_ref1),
179 
180     clock_cam0 = MAKE_CLOCK_NAME(sysctl_resource_cam0, CLK_SRC_GROUP_COMMON, clock_node_cam0),
181     clock_cam1 = MAKE_CLOCK_NAME(sysctl_resource_cam1, CLK_SRC_GROUP_COMMON, clock_node_cam1),
182 
183     clock_lcd0 = MAKE_CLOCK_NAME(sysctl_resource_lcd0, CLK_SRC_GROUP_COMMON, clock_node_lcd0),
184     clock_lcd1 = MAKE_CLOCK_NAME(sysctl_resource_lcd1, CLK_SRC_GROUP_COMMON, clock_node_lcd1),
185 
186     clock_csi0 = MAKE_CLOCK_NAME(sysctl_resource_csi0, CLK_SRC_GROUP_COMMON, clock_node_csi0),
187     clock_csi1 = MAKE_CLOCK_NAME(sysctl_resource_csi1, CLK_SRC_GROUP_COMMON, clock_node_csi1),
188     clock_dsi0 = MAKE_CLOCK_NAME(sysctl_resource_dsi0, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
189     clock_dsi1 = MAKE_CLOCK_NAME(sysctl_resource_dsi1, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
190 
191     clock_gwc0 = MAKE_CLOCK_NAME(sysctl_resource_gwc0, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
192     clock_gwc1 = MAKE_CLOCK_NAME(sysctl_resource_gwc1, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
193 
194     clock_lvb = MAKE_CLOCK_NAME(sysctl_resource_lvb0, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
195     clock_lcb = MAKE_CLOCK_NAME(sysctl_resource_lcb0, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
196 
197     clock_ffa = MAKE_CLOCK_NAME(sysctl_resource_ffa0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
198     clock_tsns = MAKE_CLOCK_NAME(sysctl_resource_tsns, CLK_SRC_GROUP_PMIC, clock_node_invalid),
199 
200     clock_ptpc = MAKE_CLOCK_NAME(sysctl_resource_ptpc, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
201     clock_watchdog0 = MAKE_CLOCK_NAME(sysctl_resource_wdg0, CLK_SRC_GROUP_EWDG, 0),    /* 0 - instance */
202     clock_watchdog1 = MAKE_CLOCK_NAME(sysctl_resource_wdg1, CLK_SRC_GROUP_EWDG, 1),    /* 1 - instance */
203     clock_puart = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_PMIC, clock_node_invalid),
204     clock_ptmr = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_PMIC, clock_node_invalid),
205     clock_pwdg = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_PMIC, clock_node_invalid),
206     clock_sdp = MAKE_CLOCK_NAME(sysctl_resource_sdp0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
207     clock_xdma = MAKE_CLOCK_NAME(sysctl_resource_dma1, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
208     clock_rom = MAKE_CLOCK_NAME(sysctl_resource_rom0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
209     clock_usb0 = MAKE_CLOCK_NAME(sysctl_resource_usb0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
210     clock_jpeg = MAKE_CLOCK_NAME(sysctl_resource_jpeg, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
211     clock_pdma = MAKE_CLOCK_NAME(sysctl_resource_pdma, CLK_SRC_GROUP_AXI_VIDEO, clock_node_invalid),
212     clock_kman = MAKE_CLOCK_NAME(sysctl_resource_kman, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
213     clock_gpio = MAKE_CLOCK_NAME(sysctl_resource_gpio, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
214     clock_mbx0 = MAKE_CLOCK_NAME(sysctl_resource_mbx0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
215     clock_mbx1 = MAKE_CLOCK_NAME(sysctl_resource_mbx1, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
216     clock_hdma = MAKE_CLOCK_NAME(sysctl_resource_dma0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
217     clock_rng = MAKE_CLOCK_NAME(sysctl_resource_rng0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
218     clock_pdm = MAKE_CLOCK_NAME(sysctl_resource_pdm0, CLK_SRC_GROUP_I2S, clock_node_invalid),
219     clock_dao = MAKE_CLOCK_NAME(sysctl_resource_dao0, CLK_SRC_GROUP_I2S, clock_node_invalid),
220     clock_smix = MAKE_CLOCK_NAME(sysctl_resource_smix, CLK_SRC_GROUP_I2S, clock_node_invalid),
221 
222     /* For ADC, there are 2-stage clock source and divider configuration */
223     clock_ana0 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_ana0),
224     clock_ana1 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_ana1),
225     clock_adc0 = MAKE_CLOCK_NAME(sysctl_resource_adc0, CLK_SRC_GROUP_ADC, 0),    /* 0 - instance */
226     clock_adc1 = MAKE_CLOCK_NAME(sysctl_resource_adc1, CLK_SRC_GROUP_ADC, 1),    /* 1 - instance */
227 
228     clock_crc0 = MAKE_CLOCK_NAME(sysctl_resource_crc0, CLK_SRC_GROUP_AXI_SOC, clock_node_invalid),
229 
230     /* For I2S, there are 2-stage clock source and divider configuration */
231     clock_aud0 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_aud0),
232     clock_aud1 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_aud1),
233     clock_aud2 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_aud2),
234     clock_aud3 = MAKE_CLOCK_NAME(RESOURCE_INVALID, CLK_SRC_GROUP_COMMON, clock_node_aud3),
235     clock_i2s0 = MAKE_CLOCK_NAME(sysctl_resource_i2s0, CLK_SRC_GROUP_I2S, 0),    /* 0 - instance */
236     clock_i2s1 = MAKE_CLOCK_NAME(sysctl_resource_i2s1, CLK_SRC_GROUP_I2S, 1),    /* 1 - instance */
237     clock_i2s2 = MAKE_CLOCK_NAME(sysctl_resource_i2s2, CLK_SRC_GROUP_I2S, 2),    /* 2 - instance */
238     clock_i2s3 = MAKE_CLOCK_NAME(sysctl_resource_i2s3, CLK_SRC_GROUP_I2S, 3),    /* 3 - instance */
239 
240     /* Clock sources */
241     clk_osc0clk0 = MAKE_CLOCK_NAME(sysctl_resource_xtal, CLK_SRC_GROUP_SRC, 0),
242     clk_pll0clk0 = MAKE_CLOCK_NAME(sysctl_resource_clk0_pll0, CLK_SRC_GROUP_SRC, 1),
243     clk_pll1clk0 = MAKE_CLOCK_NAME(sysctl_resource_clk0_pll1, CLK_SRC_GROUP_SRC, 2),
244     clk_pll1clk1 = MAKE_CLOCK_NAME(sysctl_resource_clk1_pll1, CLK_SRC_GROUP_SRC, 3),
245     clk_pll2clk0 = MAKE_CLOCK_NAME(sysctl_resource_clk0_pll2, CLK_SRC_GROUP_SRC, 4),
246     clk_pll2clk1 = MAKE_CLOCK_NAME(sysctl_resource_clk1_pll2, CLK_SRC_GROUP_SRC, 5),
247     clk_pll3clk0 = MAKE_CLOCK_NAME(sysctl_resource_clk0_pll3, CLK_SRC_GROUP_SRC, 6),
248     clk_pll4clk0 = MAKE_CLOCK_NAME(sysctl_resource_clk0_pll4, CLK_SRC_GROUP_SRC, 7),
249 
250 } clock_name_t;
251 
252 extern uint32_t hpm_core_clock;
253 
254 #ifdef __cplusplus
255 extern "C" {
256 #endif
257 
258 /**
259  * @brief Get specified IP frequency
260  * @param[in] clock_name IP clock name
261  *
262  * @return IP clock frequency in Hz
263  */
264 uint32_t clock_get_frequency(clock_name_t clock_name);
265 
266 
267 /**
268  * @brief Get Clock frequency for selected clock source
269  * @param [in] source clock source
270  * @return clock frequency for selected clock source
271  */
272 uint32_t get_frequency_for_source(clock_source_t source);
273 
274 /**
275  * @brief Get the IP clock source
276  *        Note: This API return the direct clock source
277  * @param [in] clock_name clock name
278  * @return IP clock source
279  */
280 clk_src_t clock_get_source(clock_name_t clock_name);
281 
282 /**
283  * @brief Get the IP clock divider
284  *        Note:This API return the direct clock divider
285  * @param [in] clock_name clock name
286  * @return IP clock divider
287  */
288 uint32_t clock_get_divider(clock_name_t clock_name);
289 
290 /**
291  * @brief Set ADC clock source
292  * @param[in] clock_name ADC clock name
293  * @param[in] src ADC clock source
294  *
295  * @return #status_success Setting ADC clock source is successful
296  *         #status_clk_invalid Invalid ADC clock
297  *         #status_clk_src_invalid Invalid ADC clock source
298  */
299 hpm_stat_t clock_set_adc_source(clock_name_t clock_name, clk_src_t src);
300 
301 /**
302  * @brief Set I2S clock source
303  * @param[in] clock_name I2S clock name
304  * @param[in] src I2S clock source
305  *
306  * @return #status_success Setting DAC clock source is successful
307  *         #status_clk_invalid Invalid DAC clock
308  *         #status_clk_src_invalid Invalid DAC clock source
309  */
310 hpm_stat_t clock_set_i2s_source(clock_name_t clock_name, clk_src_t src);
311 
312 /**
313  * @brief Set the WDG clock source
314  * @param [in] clock_name WDG clock name
315  * @param [in] src WDG clock source
316  *
317  * @retval status_success Setting WDG clock source is successful
318  * @retval status_invalid_argument Invalid WDG or invalid clock source
319  */
320 hpm_stat_t clock_set_wdg_source(clock_name_t clock_name, clk_src_t src);
321 
322 /**
323  * @brief Set the IP clock source and divider
324  * @param[in] clock_name clock name
325  * @param[in] src clock source
326  * @param[in] div clock divider, valid range (1 - 256)
327  *
328  * @return #status_success Setting Clock source and divider is successful.
329  *         #status_clk_src_invalid clock source is invalid.
330  *         #status_clk_fixed clock source and divider is a fixed value
331  *         #status_clk_shared_ahb Clock is shared with the AHB clock
332  *         #status_clk_shared_axis Clock is shared with the AXI_SOC clock
333  *         #status_clk_shared_axic CLock is shared with the AXI_CONNECTIVITY clock
334  *         #status_clk_shared_axiv Clock is shared with the AXI_VIDEO clock
335  *         #status_clk_shared_axif Clock is shared with the AXI_FAST clock
336  *         #status_clk_shared_axid Clock is shared with the AXI_DISPLAY clock
337  */
338 hpm_stat_t clock_set_source_divider(clock_name_t clock_name, clk_src_t src, uint32_t div);
339 
340 /**
341  * @brief Enable IP clock
342  * @param[in] clock_name IP clock name
343  */
344 void clock_enable(clock_name_t clock_name);
345 
346 /**
347  * @brief Disable IP clock
348  * @param[in] clock_name IP clock name
349  */
350 void clock_disable(clock_name_t clock_name);
351 
352 /**
353  * @brief Add IP to specified group
354  * @param[in] clock_name IP clock name
355  * @param[in] group resource group index, valid value: 0/1/2/3
356  */
357 void clock_add_to_group(clock_name_t clock_name, uint32_t group);
358 
359 /**
360  * @brief Remove IP from specified group
361  * @param[in] clock_name IP clock name
362  * @param[in] group resource group index, valid value: 0/1/2/3
363  */
364 void clock_remove_from_group(clock_name_t clock_name, uint32_t group);
365 
366 /**
367  * @brief Check IP in specified group
368  * @param[in] clock_name IP clock name
369  * @return true if in group, false if not in group
370  */
371 bool clock_check_in_group(clock_name_t clock_name, uint32_t group);
372 
373 /**
374  * @brief Disconnect the clock group from specified CPU
375  * @param[in] group clock group index, value value is 0/1/2/3
376  * @param[in] cpu CPU index, valid value is 0/1
377  */
378 void clock_connect_group_to_cpu(uint32_t group, uint32_t cpu);
379 
380 /**
381  * @brief Disconnect the clock group from specified CPU
382  * @param[in] group clock group index, value value is 0/1/2/3
383  * @param[in] cpu CPU index, valid value is 0/1
384  */
385 void clock_disconnect_group_from_cpu(uint32_t group, uint32_t cpu);
386 
387 /**
388  * @brief Delay specified microseconds
389  *
390  * @param [in] us expected delay interval in microseconds
391  */
392 void clock_cpu_delay_us(uint32_t us);
393 
394 /**
395  * @brief Delay specified milliseconds
396  *
397  * @param [in] ms expected delay interval in milliseconds
398  */
399 void clock_cpu_delay_ms(uint32_t ms);
400 
401 /**
402  * @brief Update the Core clock frequency
403  */
404 void clock_update_core_clock(void);
405 
406 
407 #ifdef __cplusplus
408 }
409 #endif
410 
411 #endif /* HPM_CLOCK_DRV_H */
412