]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/clk/imx/clk-imx8qxp.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / clk / imx / clk-imx8qxp.c
CommitLineData
98c63a78
PF
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2018 NXP
4 * Peng Fan <peng.fan@nxp.com>
5 */
6
d678a59d 7#include <common.h>
98c63a78
PF
8#include <clk-uclass.h>
9#include <dm.h>
f7ae49fc 10#include <log.h>
99ac6c76 11#include <firmware/imx/sci/sci.h>
98c63a78
PF
12#include <asm/arch/clock.h>
13#include <dt-bindings/clock/imx8qxp-clock.h>
14#include <dt-bindings/soc/imx_rsrc.h>
15#include <misc.h>
16
17#include "clk-imx8.h"
18
8dd86205 19#if IS_ENABLED(CONFIG_CMD_CLK)
98c63a78
PF
20struct imx8_clks imx8_clk_names[] = {
21 { IMX8QXP_A35_DIV, "A35_DIV" },
22 { IMX8QXP_I2C0_CLK, "I2C0" },
23 { IMX8QXP_I2C1_CLK, "I2C1" },
24 { IMX8QXP_I2C2_CLK, "I2C2" },
25 { IMX8QXP_I2C3_CLK, "I2C3" },
26 { IMX8QXP_UART0_CLK, "UART0" },
27 { IMX8QXP_UART1_CLK, "UART1" },
28 { IMX8QXP_UART2_CLK, "UART2" },
29 { IMX8QXP_UART3_CLK, "UART3" },
30 { IMX8QXP_SDHC0_CLK, "SDHC0" },
31 { IMX8QXP_SDHC1_CLK, "SDHC1" },
32 { IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
33 { IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
34 { IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
35 { IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
36 { IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
37 { IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
38 { IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
39 { IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
40};
41
42int num_clks = ARRAY_SIZE(imx8_clk_names);
43#endif
44
45ulong imx8_clk_get_rate(struct clk *clk)
46{
47 sc_pm_clk_t pm_clk;
48 ulong rate;
49 u16 resource;
50 int ret;
51
52 debug("%s(#%lu)\n", __func__, clk->id);
53
54 switch (clk->id) {
55 case IMX8QXP_A35_DIV:
56 resource = SC_R_A35;
57 pm_clk = SC_PM_CLK_CPU;
58 break;
59 case IMX8QXP_I2C0_CLK:
f35237e1 60 case IMX8QXP_I2C0_IPG_CLK:
98c63a78
PF
61 resource = SC_R_I2C_0;
62 pm_clk = SC_PM_CLK_PER;
63 break;
64 case IMX8QXP_I2C1_CLK:
f35237e1 65 case IMX8QXP_I2C1_IPG_CLK:
98c63a78
PF
66 resource = SC_R_I2C_1;
67 pm_clk = SC_PM_CLK_PER;
68 break;
69 case IMX8QXP_I2C2_CLK:
f35237e1 70 case IMX8QXP_I2C2_IPG_CLK:
98c63a78
PF
71 resource = SC_R_I2C_2;
72 pm_clk = SC_PM_CLK_PER;
73 break;
74 case IMX8QXP_I2C3_CLK:
f35237e1 75 case IMX8QXP_I2C3_IPG_CLK:
98c63a78
PF
76 resource = SC_R_I2C_3;
77 pm_clk = SC_PM_CLK_PER;
78 break;
79 case IMX8QXP_SDHC0_IPG_CLK:
80 case IMX8QXP_SDHC0_CLK:
81 case IMX8QXP_SDHC0_DIV:
82 resource = SC_R_SDHC_0;
83 pm_clk = SC_PM_CLK_PER;
84 break;
85 case IMX8QXP_SDHC1_IPG_CLK:
86 case IMX8QXP_SDHC1_CLK:
87 case IMX8QXP_SDHC1_DIV:
88 resource = SC_R_SDHC_1;
89 pm_clk = SC_PM_CLK_PER;
90 break;
98c63a78 91 case IMX8QXP_UART0_CLK:
bcbd1364 92 case IMX8QXP_UART0_IPG_CLK:
98c63a78
PF
93 resource = SC_R_UART_0;
94 pm_clk = SC_PM_CLK_PER;
95 break;
96 case IMX8QXP_UART1_CLK:
bcbd1364 97 case IMX8QXP_UART1_IPG_CLK:
98c63a78
PF
98 resource = SC_R_UART_1;
99 pm_clk = SC_PM_CLK_PER;
100 break;
101 case IMX8QXP_UART2_CLK:
bcbd1364 102 case IMX8QXP_UART2_IPG_CLK:
98c63a78
PF
103 resource = SC_R_UART_2;
104 pm_clk = SC_PM_CLK_PER;
105 break;
106 case IMX8QXP_UART3_CLK:
bcbd1364 107 case IMX8QXP_UART3_IPG_CLK:
98c63a78
PF
108 resource = SC_R_UART_3;
109 pm_clk = SC_PM_CLK_PER;
110 break;
111 case IMX8QXP_ENET0_IPG_CLK:
112 case IMX8QXP_ENET0_AHB_CLK:
113 case IMX8QXP_ENET0_REF_DIV:
114 case IMX8QXP_ENET0_PTP_CLK:
115 resource = SC_R_ENET_0;
116 pm_clk = SC_PM_CLK_PER;
117 break;
118 case IMX8QXP_ENET1_IPG_CLK:
119 case IMX8QXP_ENET1_AHB_CLK:
120 case IMX8QXP_ENET1_REF_DIV:
121 case IMX8QXP_ENET1_PTP_CLK:
122 resource = SC_R_ENET_1;
123 pm_clk = SC_PM_CLK_PER;
124 break;
125 default:
126 if (clk->id < IMX8QXP_UART0_IPG_CLK ||
127 clk->id >= IMX8QXP_CLK_END) {
128 printf("%s(Invalid clk ID #%lu)\n",
129 __func__, clk->id);
130 return -EINVAL;
131 }
9042bf6f 132 return -EINVAL;
98c63a78
PF
133 };
134
135 ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
136 (sc_pm_clock_rate_t *)&rate);
137 if (ret) {
138 printf("%s err %d\n", __func__, ret);
139 return ret;
140 }
141
142 return rate;
143}
144
145ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
146{
147 sc_pm_clk_t pm_clk;
148 u32 new_rate = rate;
149 u16 resource;
150 int ret;
151
152 debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
153
154 switch (clk->id) {
155 case IMX8QXP_I2C0_CLK:
f35237e1 156 case IMX8QXP_I2C0_IPG_CLK:
98c63a78
PF
157 resource = SC_R_I2C_0;
158 pm_clk = SC_PM_CLK_PER;
159 break;
160 case IMX8QXP_I2C1_CLK:
f35237e1 161 case IMX8QXP_I2C1_IPG_CLK:
98c63a78
PF
162 resource = SC_R_I2C_1;
163 pm_clk = SC_PM_CLK_PER;
164 break;
165 case IMX8QXP_I2C2_CLK:
f35237e1 166 case IMX8QXP_I2C2_IPG_CLK:
98c63a78
PF
167 resource = SC_R_I2C_2;
168 pm_clk = SC_PM_CLK_PER;
169 break;
170 case IMX8QXP_I2C3_CLK:
f35237e1 171 case IMX8QXP_I2C3_IPG_CLK:
98c63a78
PF
172 resource = SC_R_I2C_3;
173 pm_clk = SC_PM_CLK_PER;
174 break;
175 case IMX8QXP_UART0_CLK:
bcbd1364 176 case IMX8QXP_UART0_IPG_CLK:
98c63a78
PF
177 resource = SC_R_UART_0;
178 pm_clk = SC_PM_CLK_PER;
179 break;
180 case IMX8QXP_UART1_CLK:
bcbd1364 181 case IMX8QXP_UART1_IPG_CLK:
98c63a78
PF
182 resource = SC_R_UART_1;
183 pm_clk = SC_PM_CLK_PER;
184 break;
185 case IMX8QXP_UART2_CLK:
bcbd1364 186 case IMX8QXP_UART2_IPG_CLK:
98c63a78
PF
187 resource = SC_R_UART_2;
188 pm_clk = SC_PM_CLK_PER;
189 break;
190 case IMX8QXP_UART3_CLK:
bcbd1364 191 case IMX8QXP_UART3_IPG_CLK:
98c63a78
PF
192 resource = SC_R_UART_3;
193 pm_clk = SC_PM_CLK_PER;
194 break;
195 case IMX8QXP_SDHC0_IPG_CLK:
196 case IMX8QXP_SDHC0_CLK:
197 case IMX8QXP_SDHC0_DIV:
198 resource = SC_R_SDHC_0;
199 pm_clk = SC_PM_CLK_PER;
200 break;
201 case IMX8QXP_SDHC1_SEL:
202 case IMX8QXP_SDHC0_SEL:
203 return 0;
204 case IMX8QXP_SDHC1_IPG_CLK:
205 case IMX8QXP_SDHC1_CLK:
206 case IMX8QXP_SDHC1_DIV:
207 resource = SC_R_SDHC_1;
208 pm_clk = SC_PM_CLK_PER;
209 break;
210 case IMX8QXP_ENET0_IPG_CLK:
211 case IMX8QXP_ENET0_AHB_CLK:
212 case IMX8QXP_ENET0_REF_DIV:
213 case IMX8QXP_ENET0_PTP_CLK:
214 resource = SC_R_ENET_0;
215 pm_clk = SC_PM_CLK_PER;
216 break;
217 case IMX8QXP_ENET1_IPG_CLK:
218 case IMX8QXP_ENET1_AHB_CLK:
219 case IMX8QXP_ENET1_REF_DIV:
220 case IMX8QXP_ENET1_PTP_CLK:
221 resource = SC_R_ENET_1;
222 pm_clk = SC_PM_CLK_PER;
223 break;
224 default:
225 if (clk->id < IMX8QXP_UART0_IPG_CLK ||
226 clk->id >= IMX8QXP_CLK_END) {
227 printf("%s(Invalid clk ID #%lu)\n",
228 __func__, clk->id);
229 return -EINVAL;
230 }
9042bf6f 231 return -EINVAL;
98c63a78
PF
232 };
233
234 ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
235 if (ret) {
236 printf("%s err %d\n", __func__, ret);
237 return ret;
238 }
239
240 return new_rate;
241}
242
243int __imx8_clk_enable(struct clk *clk, bool enable)
244{
245 sc_pm_clk_t pm_clk;
246 u16 resource;
247 int ret;
248
249 debug("%s(#%lu)\n", __func__, clk->id);
250
251 switch (clk->id) {
252 case IMX8QXP_I2C0_CLK:
f35237e1 253 case IMX8QXP_I2C0_IPG_CLK:
98c63a78
PF
254 resource = SC_R_I2C_0;
255 pm_clk = SC_PM_CLK_PER;
256 break;
257 case IMX8QXP_I2C1_CLK:
f35237e1 258 case IMX8QXP_I2C1_IPG_CLK:
98c63a78
PF
259 resource = SC_R_I2C_1;
260 pm_clk = SC_PM_CLK_PER;
261 break;
262 case IMX8QXP_I2C2_CLK:
f35237e1 263 case IMX8QXP_I2C2_IPG_CLK:
98c63a78
PF
264 resource = SC_R_I2C_2;
265 pm_clk = SC_PM_CLK_PER;
266 break;
267 case IMX8QXP_I2C3_CLK:
f35237e1 268 case IMX8QXP_I2C3_IPG_CLK:
98c63a78
PF
269 resource = SC_R_I2C_3;
270 pm_clk = SC_PM_CLK_PER;
271 break;
272 case IMX8QXP_UART0_CLK:
bcbd1364 273 case IMX8QXP_UART0_IPG_CLK:
98c63a78
PF
274 resource = SC_R_UART_0;
275 pm_clk = SC_PM_CLK_PER;
276 break;
277 case IMX8QXP_UART1_CLK:
bcbd1364 278 case IMX8QXP_UART1_IPG_CLK:
98c63a78
PF
279 resource = SC_R_UART_1;
280 pm_clk = SC_PM_CLK_PER;
281 break;
282 case IMX8QXP_UART2_CLK:
bcbd1364 283 case IMX8QXP_UART2_IPG_CLK:
98c63a78
PF
284 resource = SC_R_UART_2;
285 pm_clk = SC_PM_CLK_PER;
286 break;
287 case IMX8QXP_UART3_CLK:
bcbd1364 288 case IMX8QXP_UART3_IPG_CLK:
98c63a78
PF
289 resource = SC_R_UART_3;
290 pm_clk = SC_PM_CLK_PER;
291 break;
292 case IMX8QXP_SDHC0_IPG_CLK:
293 case IMX8QXP_SDHC0_CLK:
294 case IMX8QXP_SDHC0_DIV:
295 resource = SC_R_SDHC_0;
296 pm_clk = SC_PM_CLK_PER;
297 break;
298 case IMX8QXP_SDHC1_IPG_CLK:
299 case IMX8QXP_SDHC1_CLK:
300 case IMX8QXP_SDHC1_DIV:
301 resource = SC_R_SDHC_1;
302 pm_clk = SC_PM_CLK_PER;
303 break;
304 case IMX8QXP_ENET0_IPG_CLK:
305 case IMX8QXP_ENET0_AHB_CLK:
306 case IMX8QXP_ENET0_REF_DIV:
307 case IMX8QXP_ENET0_PTP_CLK:
308 resource = SC_R_ENET_0;
309 pm_clk = SC_PM_CLK_PER;
310 break;
311 case IMX8QXP_ENET1_IPG_CLK:
312 case IMX8QXP_ENET1_AHB_CLK:
313 case IMX8QXP_ENET1_REF_DIV:
314 case IMX8QXP_ENET1_PTP_CLK:
315 resource = SC_R_ENET_1;
316 pm_clk = SC_PM_CLK_PER;
317 break;
318 default:
319 if (clk->id < IMX8QXP_UART0_IPG_CLK ||
320 clk->id >= IMX8QXP_CLK_END) {
321 printf("%s(Invalid clk ID #%lu)\n",
322 __func__, clk->id);
323 return -EINVAL;
324 }
9042bf6f 325 return -EINVAL;
98c63a78
PF
326 }
327
328 ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
329 if (ret) {
330 printf("%s err %d\n", __func__, ret);
331 return ret;
332 }
333
334 return 0;
335}