1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  */
5 
6 #include <common.h>
7 #include <clk-uclass.h>
8 #include <dm.h>
9 #include <asm/io.h>
10 #include <dm/lists.h>
11 #include <linux/delay.h>
12 #include <asm/arch/scu_ast2600.h>
13 #include <asm/global_data.h>
14 #include <dt-bindings/clock/ast2600-clock.h>
15 #include <dt-bindings/reset/ast2600-reset.h>
16 
17 DECLARE_GLOBAL_DATA_PTR;
18 
19 #define CLKIN_25M 25000000UL
20 
21 /* MAC Clock Delay settings */
22 #define MAC12_DEF_DELAY_1G		0x0041b75d
23 #define MAC12_DEF_DELAY_100M	0x00417410
24 #define MAC12_DEF_DELAY_10M		0x00417410
25 #define MAC34_DEF_DELAY_1G		0x0010438a
26 #define MAC34_DEF_DELAY_100M	0x00104208
27 #define MAC34_DEF_DELAY_10M		0x00104208
28 
29 /*
30  * 3-bit encode of CPU freqeucy
31  * Some code is duplicated
32  */
33 enum ast2600_cpu_freq {
34 	CPU_FREQ_1200M_1,
35 	CPU_FREQ_1600M_1,
36 	CPU_FREQ_1200M_2,
37 	CPU_FREQ_1600M_2,
38 	CPU_FREQ_800M_1,
39 	CPU_FREQ_800M_2,
40 	CPU_FREQ_800M_3,
41 	CPU_FREQ_800M_4,
42 };
43 
44 struct ast2600_clk_priv {
45 	struct ast2600_scu *scu;
46 };
47 
48 /*
49  * Clock divider/multiplier configuration struct.
50  * For H-PLL and M-PLL the formula is
51  * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
52  * M - Numerator
53  * N - Denumerator
54  * P - Post Divider
55  * They have the same layout in their control register.
56  *
57  * D-PLL and D2-PLL have extra divider (OD + 1), which is not
58  * yet needed and ignored by clock configurations.
59  */
60 union ast2600_pll_reg {
61 	uint32_t w;
62 	struct {
63 		unsigned int m : 13;
64 		unsigned int n : 6;
65 		unsigned int p : 4;
66 		unsigned int off : 1;
67 		unsigned int bypass : 1;
68 		unsigned int reset : 1;
69 		unsigned int reserved : 6;
70 	} b;
71 };
72 
73 struct ast2600_pll_cfg {
74 	union ast2600_pll_reg reg;
75 	unsigned int ext_reg;
76 };
77 
78 struct ast2600_pll_desc {
79 	uint32_t in;
80 	uint32_t out;
81 	struct ast2600_pll_cfg cfg;
82 };
83 
84 static const struct ast2600_pll_desc ast2600_pll_lookup[] = {
85 	{
86 		.in = CLKIN_25M,
87 		.out = 400000000,
88 		.cfg.reg.b.m = 95,
89 		.cfg.reg.b.n = 2,
90 		.cfg.reg.b.p = 1,
91 		.cfg.ext_reg = 0x31,
92 	},
93 	{
94 		.in = CLKIN_25M,
95 		.out = 200000000,
96 		.cfg.reg.b.m = 127,
97 		.cfg.reg.b.n = 0,
98 		.cfg.reg.b.p = 15,
99 		.cfg.ext_reg = 0x3f,
100 	},
101 	{
102 		.in = CLKIN_25M,
103 		.out = 334000000,
104 		.cfg.reg.b.m = 667,
105 		.cfg.reg.b.n = 4,
106 		.cfg.reg.b.p = 9,
107 		.cfg.ext_reg = 0x14d,
108 	},
109 	{
110 		.in = CLKIN_25M,
111 		.out = 1000000000,
112 		.cfg.reg.b.m = 119,
113 		.cfg.reg.b.n = 2,
114 		.cfg.reg.b.p = 0,
115 		.cfg.ext_reg = 0x3d,
116 	},
117 	{
118 		.in = CLKIN_25M,
119 		.out = 50000000,
120 		.cfg.reg.b.m = 95,
121 		.cfg.reg.b.n = 2,
122 		.cfg.reg.b.p = 15,
123 		.cfg.ext_reg = 0x31,
124 	},
125 };
126 
127 /* divisor tables */
128 static uint32_t axi_ahb_div0_table[] = {
129 	3, 2, 3, 4,
130 };
131 
132 static uint32_t axi_ahb_div1_table[] = {
133 	3, 4, 6, 8,
134 };
135 
136 static uint32_t axi_ahb_default_table[] = {
137 	3, 4, 3, 4, 2, 2, 2, 2,
138 };
139 
ast2600_get_pll_rate(struct ast2600_scu * scu,int pll_idx)140 extern uint32_t ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx)
141 {
142 	union ast2600_pll_reg pll_reg;
143 	uint32_t hwstrap1;
144 	uint32_t cpu_freq;
145 	uint32_t mul = 1, div = 1;
146 
147 	switch (pll_idx) {
148 	case ASPEED_CLK_APLL:
149 		pll_reg.w = readl(&scu->apll);
150 		break;
151 	case ASPEED_CLK_DPLL:
152 		pll_reg.w = readl(&scu->dpll);
153 		break;
154 	case ASPEED_CLK_EPLL:
155 		pll_reg.w = readl(&scu->epll);
156 		break;
157 	case ASPEED_CLK_HPLL:
158 		pll_reg.w = readl(&scu->hpll);
159 		break;
160 	case ASPEED_CLK_MPLL:
161 		pll_reg.w = readl(&scu->mpll);
162 		break;
163 	}
164 
165 	if (!pll_reg.b.bypass) {
166 		/* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)
167 		 * HPLL Numerator (M) = fix 0x5F when SCU500[10]=1
168 		 * Fixed 0xBF when SCU500[10]=0 and SCU500[8]=1
169 		 * SCU200[12:0] (default 0x8F) when SCU510[10]=0 and SCU510[8]=0
170 		 * HPLL Denumerator (N) =	SCU200[18:13] (default 0x2)
171 		 * HPLL Divider (P)	 =	SCU200[22:19] (default 0x0)
172 		 * HPLL Bandwidth Adj (NB) =  fix 0x2F when SCU500[10]=1
173 		 * Fixed 0x5F when SCU500[10]=0 and SCU500[8]=1
174 		 * SCU204[11:0] (default 0x31) when SCU500[10]=0 and SCU500[8]=0
175 		 */
176 		if (pll_idx == ASPEED_CLK_HPLL) {
177 			hwstrap1 = readl(&scu->hwstrap1);
178 			cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
179 				    SCU_HWSTRAP1_CPU_FREQ_SHIFT;
180 
181 			switch (cpu_freq) {
182 			case CPU_FREQ_800M_1:
183 			case CPU_FREQ_800M_2:
184 			case CPU_FREQ_800M_3:
185 			case CPU_FREQ_800M_4:
186 				pll_reg.b.m = 0x5f;
187 				break;
188 			case CPU_FREQ_1600M_1:
189 			case CPU_FREQ_1600M_2:
190 				pll_reg.b.m = 0xbf;
191 				break;
192 			default:
193 				pll_reg.b.m = 0x8f;
194 				break;
195 			}
196 		}
197 
198 		mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
199 		div = (pll_reg.b.p + 1);
200 	}
201 
202 	return ((CLKIN_25M * mul) / div);
203 }
204 
ast2600_get_hclk_rate(struct ast2600_scu * scu)205 static uint32_t ast2600_get_hclk_rate(struct ast2600_scu *scu)
206 {
207 	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
208 	uint32_t axi_div, ahb_div;
209 	uint32_t hwstrap1 = readl(&scu->hwstrap1);
210 	uint32_t cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
211 			     SCU_HWSTRAP1_CPU_FREQ_SHIFT;
212 	uint32_t axi_ahb_ratio = (hwstrap1 & SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK) >>
213 				  SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT;
214 
215 	if (hwstrap1 & SCU_HWSTRAP1_CPU_AXI_CLK_RATIO) {
216 		axi_ahb_div1_table[0] = axi_ahb_default_table[cpu_freq] * 2;
217 		axi_div = 1;
218 		ahb_div = axi_ahb_div1_table[axi_ahb_ratio];
219 	} else {
220 		axi_ahb_div0_table[0] = axi_ahb_default_table[cpu_freq];
221 		axi_div = 2;
222 		ahb_div = axi_ahb_div0_table[axi_ahb_ratio];
223 	}
224 
225 	return (rate / axi_div / ahb_div);
226 }
227 
ast2600_get_bclk_rate(struct ast2600_scu * scu)228 static uint32_t ast2600_get_bclk_rate(struct ast2600_scu *scu)
229 {
230 	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
231 	uint32_t clksrc1 = readl(&scu->clksrc1);
232 	uint32_t bclk_div = (clksrc1 & SCU_CLKSRC1_BCLK_DIV_MASK) >>
233 			     SCU_CLKSRC1_BCLK_DIV_SHIFT;
234 
235 	return (rate / ((bclk_div + 1) * 4));
236 }
237 
ast2600_get_pclk1_rate(struct ast2600_scu * scu)238 static uint32_t ast2600_get_pclk1_rate(struct ast2600_scu *scu)
239 {
240 	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
241 	uint32_t clksrc1 = readl(&scu->clksrc1);
242 	uint32_t pclk_div = (clksrc1 & SCU_CLKSRC1_PCLK_DIV_MASK) >>
243 			     SCU_CLKSRC1_PCLK_DIV_SHIFT;
244 
245 	return (rate / ((pclk_div + 1) * 4));
246 }
247 
ast2600_get_pclk2_rate(struct ast2600_scu * scu)248 static uint32_t ast2600_get_pclk2_rate(struct ast2600_scu *scu)
249 {
250 	uint32_t rate = ast2600_get_hclk_rate(scu);
251 	uint32_t clksrc4 = readl(&scu->clksrc4);
252 	uint32_t pclk_div = (clksrc4 & SCU_CLKSRC4_PCLK_DIV_MASK) >>
253 			     SCU_CLKSRC4_PCLK_DIV_SHIFT;
254 
255 	return (rate / ((pclk_div + 1) * 2));
256 }
257 
ast2600_get_uxclk_in_rate(struct ast2600_scu * scu)258 static uint32_t ast2600_get_uxclk_in_rate(struct ast2600_scu *scu)
259 {
260 	uint32_t rate = 0;
261 	uint32_t clksrc5 = readl(&scu->clksrc5);
262 	uint32_t uxclk = (clksrc5 & SCU_CLKSRC5_UXCLK_MASK) >>
263 			  SCU_CLKSRC5_UXCLK_SHIFT;
264 
265 	switch (uxclk) {
266 	case 0:
267 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
268 		break;
269 	case 1:
270 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
271 		break;
272 	case 2:
273 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
274 		break;
275 	case 3:
276 		rate = ast2600_get_hclk_rate(scu);
277 		break;
278 	}
279 
280 	return rate;
281 }
282 
ast2600_get_huxclk_in_rate(struct ast2600_scu * scu)283 static uint32_t ast2600_get_huxclk_in_rate(struct ast2600_scu *scu)
284 {
285 	uint32_t rate = 0;
286 	uint32_t clksrc5 = readl(&scu->clksrc5);
287 	uint32_t huxclk = (clksrc5 & SCU_CLKSRC5_HUXCLK_MASK) >>
288 			   SCU_CLKSRC5_HUXCLK_SHIFT;
289 
290 	switch (huxclk) {
291 	case 0:
292 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
293 		break;
294 	case 1:
295 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
296 		break;
297 	case 2:
298 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
299 		break;
300 	case 3:
301 		rate = ast2600_get_hclk_rate(scu);
302 		break;
303 	}
304 
305 	return rate;
306 }
307 
ast2600_get_uart_uxclk_rate(struct ast2600_scu * scu)308 static uint32_t ast2600_get_uart_uxclk_rate(struct ast2600_scu *scu)
309 {
310 	uint32_t rate = ast2600_get_uxclk_in_rate(scu);
311 	uint32_t uart_clkgen = readl(&scu->uart_clkgen);
312 	uint32_t n = (uart_clkgen & SCU_UART_CLKGEN_N_MASK) >>
313 		      SCU_UART_CLKGEN_N_SHIFT;
314 	uint32_t r = (uart_clkgen & SCU_UART_CLKGEN_R_MASK) >>
315 		      SCU_UART_CLKGEN_R_SHIFT;
316 
317 	return ((rate * r) / (n * 2));
318 }
319 
ast2600_get_uart_huxclk_rate(struct ast2600_scu * scu)320 static uint32_t ast2600_get_uart_huxclk_rate(struct ast2600_scu *scu)
321 {
322 	uint32_t rate = ast2600_get_huxclk_in_rate(scu);
323 	uint32_t huart_clkgen = readl(&scu->huart_clkgen);
324 	uint32_t n = (huart_clkgen & SCU_HUART_CLKGEN_N_MASK) >>
325 		      SCU_HUART_CLKGEN_N_SHIFT;
326 	uint32_t r = (huart_clkgen & SCU_HUART_CLKGEN_R_MASK) >>
327 		      SCU_HUART_CLKGEN_R_SHIFT;
328 
329 	return ((rate * r) / (n * 2));
330 }
331 
ast2600_get_sdio_clk_rate(struct ast2600_scu * scu)332 static uint32_t ast2600_get_sdio_clk_rate(struct ast2600_scu *scu)
333 {
334 	uint32_t rate = 0;
335 	uint32_t clksrc4 = readl(&scu->clksrc4);
336 	uint32_t sdio_div = (clksrc4 & SCU_CLKSRC4_SDIO_DIV_MASK) >>
337 			     SCU_CLKSRC4_SDIO_DIV_SHIFT;
338 
339 	if (clksrc4 & SCU_CLKSRC4_SDIO)
340 		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
341 	else
342 		rate = ast2600_get_hclk_rate(scu);
343 
344 	return (rate / ((sdio_div + 1) * 2));
345 }
346 
ast2600_get_emmc_clk_rate(struct ast2600_scu * scu)347 static uint32_t ast2600_get_emmc_clk_rate(struct ast2600_scu *scu)
348 {
349 	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
350 	uint32_t clksrc1 = readl(&scu->clksrc1);
351 	uint32_t emmc_div = (clksrc1 & SCU_CLKSRC1_EMMC_DIV_MASK) >>
352 			     SCU_CLKSRC1_EMMC_DIV_SHIFT;
353 
354 	return (rate / ((emmc_div + 1) * 4));
355 }
356 
ast2600_get_uart_clk_rate(struct ast2600_scu * scu,int uart_idx)357 static uint32_t ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx)
358 {
359 	uint32_t rate = 0;
360 	uint32_t uart5_clk = 0;
361 	uint32_t clksrc2 = readl(&scu->clksrc2);
362 	uint32_t clksrc4 = readl(&scu->clksrc4);
363 	uint32_t clksrc5 = readl(&scu->clksrc5);
364 	uint32_t misc_ctrl1 = readl(&scu->misc_ctrl1);
365 
366 	switch (uart_idx) {
367 	case 1:
368 	case 2:
369 	case 3:
370 	case 4:
371 	case 6:
372 		if (clksrc4 & BIT(uart_idx - 1))
373 			rate = ast2600_get_uart_huxclk_rate(scu);
374 		else
375 			rate = ast2600_get_uart_uxclk_rate(scu);
376 		break;
377 	case 5:
378 		/*
379 		 * SCU0C[12] and SCU304[14] together decide
380 		 * the UART5 clock generation
381 		 */
382 		if (misc_ctrl1 & SCU_MISC_CTRL1_UART5_DIV)
383 			uart5_clk = 0x1 << 1;
384 
385 		if (clksrc2 & SCU_CLKSRC2_UART5)
386 			uart5_clk |= 0x1;
387 
388 		switch (uart5_clk) {
389 		case 0:
390 			rate = 24000000;
391 			break;
392 		case 1:
393 			rate = 192000000;
394 			break;
395 		case 2:
396 			rate = 24000000 / 13;
397 			break;
398 		case 3:
399 			rate = 192000000 / 13;
400 			break;
401 		}
402 
403 		break;
404 	case 7:
405 	case 8:
406 	case 9:
407 	case 10:
408 	case 11:
409 	case 12:
410 	case 13:
411 		if (clksrc5 & BIT(uart_idx - 1))
412 			rate = ast2600_get_uart_huxclk_rate(scu);
413 		else
414 			rate = ast2600_get_uart_uxclk_rate(scu);
415 		break;
416 	}
417 
418 	return rate;
419 }
420 
ast2600_clk_get_rate(struct clk * clk)421 static ulong ast2600_clk_get_rate(struct clk *clk)
422 {
423 	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
424 	ulong rate = 0;
425 
426 	switch (clk->id) {
427 	case ASPEED_CLK_HPLL:
428 	case ASPEED_CLK_EPLL:
429 	case ASPEED_CLK_DPLL:
430 	case ASPEED_CLK_MPLL:
431 	case ASPEED_CLK_APLL:
432 		rate = ast2600_get_pll_rate(priv->scu, clk->id);
433 		break;
434 	case ASPEED_CLK_AHB:
435 		rate = ast2600_get_hclk_rate(priv->scu);
436 		break;
437 	case ASPEED_CLK_APB1:
438 		rate = ast2600_get_pclk1_rate(priv->scu);
439 		break;
440 	case ASPEED_CLK_APB2:
441 		rate = ast2600_get_pclk2_rate(priv->scu);
442 		break;
443 	case ASPEED_CLK_GATE_UART1CLK:
444 		rate = ast2600_get_uart_clk_rate(priv->scu, 1);
445 		break;
446 	case ASPEED_CLK_GATE_UART2CLK:
447 		rate = ast2600_get_uart_clk_rate(priv->scu, 2);
448 		break;
449 	case ASPEED_CLK_GATE_UART3CLK:
450 		rate = ast2600_get_uart_clk_rate(priv->scu, 3);
451 		break;
452 	case ASPEED_CLK_GATE_UART4CLK:
453 		rate = ast2600_get_uart_clk_rate(priv->scu, 4);
454 		break;
455 	case ASPEED_CLK_GATE_UART5CLK:
456 		rate = ast2600_get_uart_clk_rate(priv->scu, 5);
457 		break;
458 	case ASPEED_CLK_BCLK:
459 		rate = ast2600_get_bclk_rate(priv->scu);
460 		break;
461 	case ASPEED_CLK_SDIO:
462 		rate = ast2600_get_sdio_clk_rate(priv->scu);
463 		break;
464 	case ASPEED_CLK_EMMC:
465 		rate = ast2600_get_emmc_clk_rate(priv->scu);
466 		break;
467 	case ASPEED_CLK_UARTX:
468 		rate = ast2600_get_uart_uxclk_rate(priv->scu);
469 		break;
470 	case ASPEED_CLK_HUARTX:
471 		rate = ast2600_get_uart_huxclk_rate(priv->scu);
472 		break;
473 	default:
474 		debug("can't get clk rate\n");
475 		return -ENOENT;
476 	}
477 
478 	return rate;
479 }
480 
481 /**
482  * @brief	lookup PLL divider config by input/output rate
483  * @param[in]	*pll - PLL descriptor
484  * @return	true - if PLL divider config is found, false - else
485  * The function caller shall fill "pll->in" and "pll->out",
486  * then this function will search the lookup table
487  * to find a valid PLL divider configuration.
488  */
ast2600_search_clock_config(struct ast2600_pll_desc * pll)489 static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll)
490 {
491 	uint32_t i;
492 	const struct ast2600_pll_desc *def_desc;
493 	bool is_found = false;
494 
495 	for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) {
496 		def_desc = &ast2600_pll_lookup[i];
497 
498 		if (def_desc->in == pll->in && def_desc->out == pll->out) {
499 			is_found = true;
500 			pll->cfg.reg.w = def_desc->cfg.reg.w;
501 			pll->cfg.ext_reg = def_desc->cfg.ext_reg;
502 			break;
503 		}
504 	}
505 	return is_found;
506 }
507 
ast2600_configure_pll(struct ast2600_scu * scu,struct ast2600_pll_cfg * p_cfg,int pll_idx)508 static uint32_t ast2600_configure_pll(struct ast2600_scu *scu,
509 				 struct ast2600_pll_cfg *p_cfg, int pll_idx)
510 {
511 	uint32_t addr, addr_ext;
512 	uint32_t reg;
513 
514 	switch (pll_idx) {
515 	case ASPEED_CLK_HPLL:
516 		addr = (uint32_t)(&scu->hpll);
517 		addr_ext = (uint32_t)(&scu->hpll_ext);
518 		break;
519 	case ASPEED_CLK_MPLL:
520 		addr = (uint32_t)(&scu->mpll);
521 		addr_ext = (uint32_t)(&scu->mpll_ext);
522 		break;
523 	case ASPEED_CLK_DPLL:
524 		addr = (uint32_t)(&scu->dpll);
525 		addr_ext = (uint32_t)(&scu->dpll_ext);
526 		break;
527 	case ASPEED_CLK_EPLL:
528 		addr = (uint32_t)(&scu->epll);
529 		addr_ext = (uint32_t)(&scu->epll_ext);
530 		break;
531 	case ASPEED_CLK_APLL:
532 		addr = (uint32_t)(&scu->apll);
533 		addr_ext = (uint32_t)(&scu->apll_ext);
534 		break;
535 	default:
536 		debug("unknown PLL index\n");
537 		return 1;
538 	}
539 
540 	p_cfg->reg.b.bypass = 0;
541 	p_cfg->reg.b.off = 1;
542 	p_cfg->reg.b.reset = 1;
543 
544 	reg = readl(addr);
545 	reg &= ~GENMASK(25, 0);
546 	reg |= p_cfg->reg.w;
547 	writel(reg, addr);
548 
549 	/* write extend parameter */
550 	writel(p_cfg->ext_reg, addr_ext);
551 	udelay(100);
552 	p_cfg->reg.b.off = 0;
553 	p_cfg->reg.b.reset = 0;
554 	reg &= ~GENMASK(25, 0);
555 	reg |= p_cfg->reg.w;
556 	writel(reg, addr);
557 	while (!(readl(addr_ext) & BIT(31)))
558 		;
559 
560 	return 0;
561 }
562 
ast2600_configure_ddr(struct ast2600_scu * scu,ulong rate)563 static uint32_t ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate)
564 {
565 	struct ast2600_pll_desc mpll;
566 
567 	mpll.in = CLKIN_25M;
568 	mpll.out = rate;
569 	if (ast2600_search_clock_config(&mpll) == false) {
570 		printf("error!! unable to find valid DDR clock setting\n");
571 		return 0;
572 	}
573 	ast2600_configure_pll(scu, &mpll.cfg, ASPEED_CLK_MPLL);
574 
575 	return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
576 }
577 
ast2600_clk_set_rate(struct clk * clk,ulong rate)578 static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate)
579 {
580 	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
581 	ulong new_rate;
582 
583 	switch (clk->id) {
584 	case ASPEED_CLK_MPLL:
585 		new_rate = ast2600_configure_ddr(priv->scu, rate);
586 		break;
587 	default:
588 		return -ENOENT;
589 	}
590 
591 	return new_rate;
592 }
593 
ast2600_configure_mac12_clk(struct ast2600_scu * scu)594 static uint32_t ast2600_configure_mac12_clk(struct ast2600_scu *scu)
595 {
596 	/* scu340[25:0]: 1G default delay */
597 	clrsetbits_le32(&scu->mac12_clk_delay, GENMASK(25, 0),
598 			MAC12_DEF_DELAY_1G);
599 
600 	/* set 100M/10M default delay */
601 	writel(MAC12_DEF_DELAY_100M, &scu->mac12_clk_delay_100M);
602 	writel(MAC12_DEF_DELAY_10M, &scu->mac12_clk_delay_10M);
603 
604 	/* MAC AHB = HPLL / 6 */
605 	clrsetbits_le32(&scu->clksrc1, SCU_CLKSRC1_MAC_DIV_MASK,
606 			(0x2 << SCU_CLKSRC1_MAC_DIV_SHIFT));
607 
608 	return 0;
609 }
610 
ast2600_configure_mac34_clk(struct ast2600_scu * scu)611 static uint32_t ast2600_configure_mac34_clk(struct ast2600_scu *scu)
612 {
613 	/*
614 	 * scu350[31]   RGMII 125M source: 0 = from IO pin
615 	 * scu350[25:0] MAC 1G delay
616 	 */
617 	clrsetbits_le32(&scu->mac34_clk_delay, (BIT(31) | GENMASK(25, 0)),
618 			MAC34_DEF_DELAY_1G);
619 	writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M);
620 	writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M);
621 
622 	/*
623 	 * clock source seletion and divider
624 	 * scu310[26:24] : MAC AHB bus clock = HCLK / 2
625 	 * scu310[18:16] : RMII 50M = HCLK_200M / 4
626 	 */
627 	clrsetbits_le32(&scu->clksrc4,
628 			(SCU_CLKSRC4_MAC_DIV_MASK | SCU_CLKSRC4_RMII34_DIV_MASK),
629 			((0x0 << SCU_CLKSRC4_MAC_DIV_SHIFT)
630 			 | (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT)));
631 
632 	/*
633 	 * set driving strength
634 	 * scu458[3:2] : MAC4 driving strength
635 	 * scu458[1:0] : MAC3 driving strength
636 	 */
637 	clrsetbits_le32(&scu->pinmux16,
638 			SCU_PINCTRL16_MAC4_DRIVING_MASK | SCU_PINCTRL16_MAC3_DRIVING_MASK,
639 			(0x3 << SCU_PINCTRL16_MAC4_DRIVING_SHIFT)
640 			 | (0x3 << SCU_PINCTRL16_MAC3_DRIVING_SHIFT));
641 
642 	return 0;
643 }
644 
645 /**
646  * ast2600 RGMII clock source tree
647  * 125M from external PAD -------->|\
648  * HPLL -->|\                      | |---->RGMII 125M for MAC#1 & MAC#2
649  *         | |---->| divider |---->|/                             +
650  * EPLL -->|/                                                     |
651  *                                                                |
652  * +---------<-----------|RGMIICK PAD output enable|<-------------+
653  * |
654  * +--------------------------->|\
655  *                              | |----> RGMII 125M for MAC#3 & MAC#4
656  * HCLK 200M ---->|divider|---->|/
657  * To simplify the control flow:
658  * 1. RGMII 1/2 always use EPLL as the internal clock source
659  * 2. RGMII 3/4 always use RGMIICK pad as the RGMII 125M source
660  * 125M from external PAD -------->|\
661  *                                 | |---->RGMII 125M for MAC#1 & MAC#2
662  *         EPLL---->| divider |--->|/                             +
663  *                                                                |
664  * +<--------------------|RGMIICK PAD output enable|<-------------+
665  * |
666  * +--------------------------->RGMII 125M for MAC#3 & MAC#4
667  */
668 #define RGMIICK_SRC_PAD		0
669 #define RGMIICK_SRC_EPLL	1 /* recommended */
670 #define RGMIICK_SRC_HPLL	2
671 
672 #define RGMIICK_DIV2	1
673 #define RGMIICK_DIV3	2
674 #define RGMIICK_DIV4	3
675 #define RGMIICK_DIV5	4
676 #define RGMIICK_DIV6	5
677 #define RGMIICK_DIV7	6
678 #define RGMIICK_DIV8	7 /* recommended */
679 
680 #define RMIICK_DIV4		0
681 #define RMIICK_DIV8		1
682 #define RMIICK_DIV12	2
683 #define RMIICK_DIV16	3
684 #define RMIICK_DIV20	4 /* recommended */
685 #define RMIICK_DIV24	5
686 #define RMIICK_DIV28	6
687 #define RMIICK_DIV32	7
688 
689 struct ast2600_mac_clk_div {
690 	uint32_t src; /* 0=external PAD, 1=internal PLL */
691 	uint32_t fin; /* divider input speed */
692 	uint32_t n; /* 0=div2, 1=div2, 2=div3, 3=div4,...,7=div8 */
693 	uint32_t fout; /* fout = fin / n */
694 };
695 
696 struct ast2600_mac_clk_div rgmii_clk_defconfig = {
697 	.src = ASPEED_CLK_EPLL,
698 	.fin = 1000000000,
699 	.n = RGMIICK_DIV8,
700 	.fout = 125000000,
701 };
702 
703 struct ast2600_mac_clk_div rmii_clk_defconfig = {
704 	.src = ASPEED_CLK_EPLL,
705 	.fin = 1000000000,
706 	.n = RMIICK_DIV20,
707 	.fout = 50000000,
708 };
709 
ast2600_init_mac_pll(struct ast2600_scu * p_scu,struct ast2600_mac_clk_div * p_cfg)710 static void ast2600_init_mac_pll(struct ast2600_scu *p_scu,
711 				 struct ast2600_mac_clk_div *p_cfg)
712 {
713 	struct ast2600_pll_desc pll;
714 
715 	pll.in = CLKIN_25M;
716 	pll.out = p_cfg->fin;
717 	if (ast2600_search_clock_config(&pll) == false) {
718 		pr_err("unable to find valid ETHNET MAC clock setting\n");
719 		return;
720 	}
721 	ast2600_configure_pll(p_scu, &pll.cfg, p_cfg->src);
722 }
723 
ast2600_init_rgmii_clk(struct ast2600_scu * p_scu,struct ast2600_mac_clk_div * p_cfg)724 static void ast2600_init_rgmii_clk(struct ast2600_scu *p_scu,
725 				   struct ast2600_mac_clk_div *p_cfg)
726 {
727 	uint32_t reg_304 = readl(&p_scu->clksrc2);
728 	uint32_t reg_340 = readl(&p_scu->mac12_clk_delay);
729 	uint32_t reg_350 = readl(&p_scu->mac34_clk_delay);
730 
731 	reg_340 &= ~GENMASK(31, 29);
732 	/* scu340[28]: RGMIICK PAD output enable (to MAC 3/4) */
733 	reg_340 |= BIT(28);
734 	if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
735 		/*
736 		 * re-init PLL if the current PLL output frequency doesn't match
737 		 * the divider setting
738 		 */
739 		if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
740 			ast2600_init_mac_pll(p_scu, p_cfg);
741 		/* scu340[31]: select RGMII 125M from internal source */
742 		reg_340 |= BIT(31);
743 	}
744 
745 	reg_304 &= ~GENMASK(23, 20);
746 
747 	/* set clock divider */
748 	reg_304 |= (p_cfg->n & 0x7) << 20;
749 
750 	/* select internal clock source */
751 	if (p_cfg->src == ASPEED_CLK_HPLL)
752 		reg_304 |= BIT(23);
753 
754 	/* RGMII 3/4 clock source select */
755 	reg_350 &= ~BIT(31);
756 
757 	writel(reg_304, &p_scu->clksrc2);
758 	writel(reg_340, &p_scu->mac12_clk_delay);
759 	writel(reg_350, &p_scu->mac34_clk_delay);
760 }
761 
762 /**
763  * ast2600 RMII/NCSI clock source tree
764  * HPLL -->|\
765  *         | |---->| divider |----> RMII 50M for MAC#1 & MAC#2
766  * EPLL -->|/
767  * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4
768  */
ast2600_init_rmii_clk(struct ast2600_scu * p_scu,struct ast2600_mac_clk_div * p_cfg)769 static void ast2600_init_rmii_clk(struct ast2600_scu *p_scu,
770 				  struct ast2600_mac_clk_div *p_cfg)
771 {
772 	uint32_t clksrc2 = readl(&p_scu->clksrc2);
773 	uint32_t clksrc4 = readl(&p_scu->clksrc4);
774 
775 	if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
776 		/*
777 		 * re-init PLL if the current PLL output frequency doesn't match
778 		 * the divider setting
779 		 */
780 		if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
781 			ast2600_init_mac_pll(p_scu, p_cfg);
782 	}
783 
784 	clksrc2 &= ~(SCU_CLKSRC2_RMII12 | SCU_CLKSRC2_RMII12_DIV_MASK);
785 
786 	/* set RMII 1/2 clock divider */
787 	clksrc2 |= (p_cfg->n & 0x7) << 16;
788 
789 	/* RMII clock source selection */
790 	if (p_cfg->src == ASPEED_CLK_HPLL)
791 		clksrc2 |= SCU_CLKSRC2_RMII12;
792 
793 	/* set RMII 3/4 clock divider */
794 	clksrc4 &= ~SCU_CLKSRC4_RMII34_DIV_MASK;
795 	clksrc4 |= (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT);
796 
797 	writel(clksrc2, &p_scu->clksrc2);
798 	writel(clksrc4, &p_scu->clksrc4);
799 }
800 
ast2600_configure_mac(struct ast2600_scu * scu,int index)801 static uint32_t ast2600_configure_mac(struct ast2600_scu *scu, int index)
802 {
803 	uint32_t reset_bit;
804 	uint32_t clkgate_bit;
805 
806 	switch (index) {
807 	case 1:
808 		reset_bit = BIT(ASPEED_RESET_MAC1);
809 		clkgate_bit = SCU_CLKGATE1_MAC1;
810 		writel(reset_bit, &scu->modrst_ctrl1);
811 		udelay(100);
812 		writel(clkgate_bit, &scu->clkgate_clr1);
813 		mdelay(10);
814 		writel(reset_bit, &scu->modrst_clr1);
815 		break;
816 	case 2:
817 		reset_bit = BIT(ASPEED_RESET_MAC2);
818 		clkgate_bit = SCU_CLKGATE1_MAC2;
819 		writel(reset_bit, &scu->modrst_ctrl1);
820 		udelay(100);
821 		writel(clkgate_bit, &scu->clkgate_clr1);
822 		mdelay(10);
823 		writel(reset_bit, &scu->modrst_clr1);
824 		break;
825 	case 3:
826 		reset_bit = BIT(ASPEED_RESET_MAC3 - 32);
827 		clkgate_bit = SCU_CLKGATE2_MAC3;
828 		writel(reset_bit, &scu->modrst_ctrl2);
829 		udelay(100);
830 		writel(clkgate_bit, &scu->clkgate_clr2);
831 		mdelay(10);
832 		writel(reset_bit, &scu->modrst_clr2);
833 		break;
834 	case 4:
835 		reset_bit = BIT(ASPEED_RESET_MAC4 - 32);
836 		clkgate_bit = SCU_CLKGATE2_MAC4;
837 		writel(reset_bit, &scu->modrst_ctrl2);
838 		udelay(100);
839 		writel(clkgate_bit, &scu->clkgate_clr2);
840 		mdelay(10);
841 		writel(reset_bit, &scu->modrst_clr2);
842 		break;
843 	default:
844 		return -EINVAL;
845 	}
846 
847 	return 0;
848 }
849 
ast2600_configure_rsa_ecc_clk(struct ast2600_scu * scu)850 static void ast2600_configure_rsa_ecc_clk(struct ast2600_scu *scu)
851 {
852 	uint32_t clksrc1 = readl(&scu->clksrc1);
853 
854 	/* Configure RSA clock = HPLL/3 */
855 	clksrc1 |= SCU_CLKSRC1_ECC_RSA;
856 	clksrc1 &= ~SCU_CLKSRC1_ECC_RSA_DIV_MASK;
857 	clksrc1 |= (2 << SCU_CLKSRC1_ECC_RSA_DIV_SHIFT);
858 
859 	writel(clksrc1, &scu->clksrc1);
860 }
861 
ast2600_enable_sdclk(struct ast2600_scu * scu)862 static ulong ast2600_enable_sdclk(struct ast2600_scu *scu)
863 {
864 	uint32_t reset_bit;
865 	uint32_t clkgate_bit;
866 
867 	reset_bit = BIT(ASPEED_RESET_SD - 32);
868 	clkgate_bit = SCU_CLKGATE2_SDIO;
869 
870 	writel(reset_bit, &scu->modrst_ctrl2);
871 	udelay(100);
872 	writel(clkgate_bit, &scu->clkgate_clr2);
873 	mdelay(10);
874 	writel(reset_bit, &scu->modrst_clr2);
875 
876 	return 0;
877 }
878 
ast2600_enable_extsdclk(struct ast2600_scu * scu)879 static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu)
880 {
881 	int i = 0;
882 	uint32_t div = 0;
883 	uint32_t rate = 0;
884 	uint32_t clksrc4 = readl(&scu->clksrc4);
885 
886 	/*
887 	 * ast2600 SD controller max clk is 200Mhz
888 	 * use apll for clock source 800/4 = 200
889 	 * controller max is 200mhz
890 	 */
891 	rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
892 	for (i = 0; i < 8; i++) {
893 		div = (i + 1) * 2;
894 		if ((rate / div) <= 200000000)
895 			break;
896 	}
897 	clksrc4 &= ~SCU_CLKSRC4_SDIO_DIV_MASK;
898 	clksrc4 |= (i << SCU_CLKSRC4_SDIO_DIV_SHIFT);
899 	clksrc4 |= SCU_CLKSRC4_SDIO;
900 	writel(clksrc4, &scu->clksrc4);
901 
902 	setbits_le32(&scu->clksrc4, SCU_CLKSRC4_SDIO_EN);
903 
904 	return 0;
905 }
906 
ast2600_enable_emmcclk(struct ast2600_scu * scu)907 static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu)
908 {
909 	uint32_t reset_bit;
910 	uint32_t clkgate_bit;
911 
912 	reset_bit = BIT(ASPEED_RESET_EMMC);
913 	clkgate_bit = SCU_CLKGATE1_EMMC;
914 
915 	writel(reset_bit, &scu->modrst_ctrl1);
916 	udelay(100);
917 	writel(clkgate_bit, &scu->clkgate_clr1);
918 	mdelay(10);
919 	writel(reset_bit, &scu->modrst_clr1);
920 
921 	return 0;
922 }
923 
ast2600_enable_extemmcclk(struct ast2600_scu * scu)924 static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu)
925 {
926 	int i = 0;
927 	uint32_t div = 0;
928 	uint32_t rate = 0;
929 	uint32_t clksrc1 = readl(&scu->clksrc1);
930 
931 	/*
932 	 * ast2600 eMMC controller max clk is 200Mhz
933 	 * HPll->1/2->|\
934 	 *				|->SCU300[11]->SCU300[14:12][1/N] +
935 	 * MPLL------>|/								  |
936 	 * +----------------------------------------------+
937 	 * |
938 	 * +---------> EMMC12C[15:8][1/N]-> eMMC clk
939 	 */
940 	rate = ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
941 	for (i = 0; i < 8; i++) {
942 		div = (i + 1) * 2;
943 		if ((rate / div) <= 200000000)
944 			break;
945 	}
946 
947 	clksrc1 &= ~SCU_CLKSRC1_EMMC_DIV_MASK;
948 	clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
949 	clksrc1 |= SCU_CLKSRC1_EMMC;
950 	writel(clksrc1, &scu->clksrc1);
951 
952 	setbits_le32(&scu->clksrc1, SCU_CLKSRC1_EMMC_EN);
953 
954 	return 0;
955 }
956 
ast2600_enable_fsiclk(struct ast2600_scu * scu)957 static ulong ast2600_enable_fsiclk(struct ast2600_scu *scu)
958 {
959 	uint32_t reset_bit;
960 	uint32_t clkgate_bit;
961 
962 	reset_bit = BIT(ASPEED_RESET_FSI % 32);
963 	clkgate_bit = SCU_CLKGATE2_FSI;
964 
965 	/* The FSI clock is shared between masters. If it's already on
966 	 * don't touch it, as that will reset the existing master.
967 	 */
968 	if (!(readl(&scu->clkgate_ctrl2) & clkgate_bit)) {
969 		debug("%s: already running, not touching it\n", __func__);
970 		return 0;
971 	}
972 
973 	writel(reset_bit, &scu->modrst_ctrl2);
974 	udelay(100);
975 	writel(clkgate_bit, &scu->clkgate_clr2);
976 	mdelay(10);
977 	writel(reset_bit, &scu->modrst_clr2);
978 
979 	return 0;
980 }
981 
ast2600_enable_usbahclk(struct ast2600_scu * scu)982 static ulong ast2600_enable_usbahclk(struct ast2600_scu *scu)
983 {
984 	uint32_t reset_bit;
985 	uint32_t clkgate_bit;
986 
987 	reset_bit = BIT(ASPEED_RESET_EHCI_P1);
988 	clkgate_bit = SCU_CLKGATE1_USB_HUB;
989 
990 	writel(reset_bit, &scu->modrst_ctrl1);
991 	udelay(100);
992 	writel(clkgate_bit, &scu->clkgate_ctrl1);
993 	mdelay(20);
994 	writel(reset_bit, &scu->modrst_clr1);
995 
996 	return 0;
997 }
998 
ast2600_enable_usbbhclk(struct ast2600_scu * scu)999 static ulong ast2600_enable_usbbhclk(struct ast2600_scu *scu)
1000 {
1001 	uint32_t reset_bit;
1002 	uint32_t clkgate_bit;
1003 
1004 	reset_bit = BIT(ASPEED_RESET_EHCI_P2);
1005 	clkgate_bit = SCU_CLKGATE1_USB_HOST2;
1006 
1007 	writel(reset_bit, &scu->modrst_ctrl1);
1008 	udelay(100);
1009 	writel(clkgate_bit, &scu->clkgate_clr1);
1010 	mdelay(20);
1011 	writel(reset_bit, &scu->modrst_clr1);
1012 
1013 	return 0;
1014 }
1015 
ast2600_clk_enable(struct clk * clk)1016 static int ast2600_clk_enable(struct clk *clk)
1017 {
1018 	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
1019 
1020 	switch (clk->id) {
1021 	case ASPEED_CLK_GATE_MAC1CLK:
1022 		ast2600_configure_mac(priv->scu, 1);
1023 		break;
1024 	case ASPEED_CLK_GATE_MAC2CLK:
1025 		ast2600_configure_mac(priv->scu, 2);
1026 		break;
1027 	case ASPEED_CLK_GATE_MAC3CLK:
1028 		ast2600_configure_mac(priv->scu, 3);
1029 		break;
1030 	case ASPEED_CLK_GATE_MAC4CLK:
1031 		ast2600_configure_mac(priv->scu, 4);
1032 		break;
1033 	case ASPEED_CLK_GATE_SDCLK:
1034 		ast2600_enable_sdclk(priv->scu);
1035 		break;
1036 	case ASPEED_CLK_GATE_SDEXTCLK:
1037 		ast2600_enable_extsdclk(priv->scu);
1038 		break;
1039 	case ASPEED_CLK_GATE_EMMCCLK:
1040 		ast2600_enable_emmcclk(priv->scu);
1041 		break;
1042 	case ASPEED_CLK_GATE_EMMCEXTCLK:
1043 		ast2600_enable_extemmcclk(priv->scu);
1044 		break;
1045 	case ASPEED_CLK_GATE_FSICLK:
1046 		ast2600_enable_fsiclk(priv->scu);
1047 		break;
1048 	case ASPEED_CLK_GATE_USBPORT1CLK:
1049 		ast2600_enable_usbahclk(priv->scu);
1050 		break;
1051 	case ASPEED_CLK_GATE_USBPORT2CLK:
1052 		ast2600_enable_usbbhclk(priv->scu);
1053 		break;
1054 	default:
1055 		pr_err("can't enable clk\n");
1056 		return -ENOENT;
1057 	}
1058 
1059 	return 0;
1060 }
1061 
1062 struct clk_ops ast2600_clk_ops = {
1063 	.get_rate = ast2600_clk_get_rate,
1064 	.set_rate = ast2600_clk_set_rate,
1065 	.enable = ast2600_clk_enable,
1066 };
1067 
ast2600_clk_probe(struct udevice * dev)1068 static int ast2600_clk_probe(struct udevice *dev)
1069 {
1070 	struct ast2600_clk_priv *priv = dev_get_priv(dev);
1071 
1072 	priv->scu = devfdt_get_addr_ptr(dev);
1073 	if (IS_ERR(priv->scu))
1074 		return PTR_ERR(priv->scu);
1075 
1076 	ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
1077 	ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
1078 	ast2600_configure_mac12_clk(priv->scu);
1079 	ast2600_configure_mac34_clk(priv->scu);
1080 	ast2600_configure_rsa_ecc_clk(priv->scu);
1081 
1082 	return 0;
1083 }
1084 
ast2600_clk_bind(struct udevice * dev)1085 static int ast2600_clk_bind(struct udevice *dev)
1086 {
1087 	int ret;
1088 
1089 	/* The reset driver does not have a device node, so bind it here */
1090 	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
1091 	if (ret)
1092 		debug("Warning: No reset driver: ret=%d\n", ret);
1093 
1094 	return 0;
1095 }
1096 
1097 struct aspeed_clks {
1098 	ulong id;
1099 	const char *name;
1100 };
1101 
1102 static struct aspeed_clks aspeed_clk_names[] = {
1103 	{ ASPEED_CLK_HPLL, "hpll" },
1104 	{ ASPEED_CLK_MPLL, "mpll" },
1105 	{ ASPEED_CLK_APLL, "apll" },
1106 	{ ASPEED_CLK_EPLL, "epll" },
1107 	{ ASPEED_CLK_DPLL, "dpll" },
1108 	{ ASPEED_CLK_AHB, "hclk" },
1109 	{ ASPEED_CLK_APB1, "pclk1" },
1110 	{ ASPEED_CLK_APB2, "pclk2" },
1111 	{ ASPEED_CLK_BCLK, "bclk" },
1112 	{ ASPEED_CLK_UARTX, "uxclk" },
1113 	{ ASPEED_CLK_HUARTX, "huxclk" },
1114 };
1115 
soc_clk_dump(void)1116 int soc_clk_dump(void)
1117 {
1118 	struct udevice *dev;
1119 	struct clk clk;
1120 	unsigned long rate;
1121 	int i, ret;
1122 
1123 	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu),
1124 					  &dev);
1125 	if (ret)
1126 		return ret;
1127 
1128 	printf("Clk\t\tHz\n");
1129 
1130 	for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) {
1131 		clk.id = aspeed_clk_names[i].id;
1132 		ret = clk_request(dev, &clk);
1133 		if (ret < 0) {
1134 			debug("%s clk_request() failed: %d\n", __func__, ret);
1135 			continue;
1136 		}
1137 
1138 		ret = clk_get_rate(&clk);
1139 		rate = ret;
1140 
1141 		clk_free(&clk);
1142 
1143 		if (ret == -EINVAL) {
1144 			printf("clk ID %lu not supported yet\n",
1145 			       aspeed_clk_names[i].id);
1146 			continue;
1147 		}
1148 		if (ret < 0) {
1149 			printf("%s %lu: get_rate err: %d\n", __func__,
1150 			       aspeed_clk_names[i].id, ret);
1151 			continue;
1152 		}
1153 
1154 		printf("%s(%3lu):\t%lu\n", aspeed_clk_names[i].name,
1155 		       aspeed_clk_names[i].id, rate);
1156 	}
1157 
1158 	return 0;
1159 }
1160 
1161 static const struct udevice_id ast2600_clk_ids[] = {
1162 	{ .compatible = "aspeed,ast2600-scu", },
1163 	{ },
1164 };
1165 
1166 U_BOOT_DRIVER(aspeed_ast2600_scu) = {
1167 	.name = "aspeed_ast2600_scu",
1168 	.id = UCLASS_CLK,
1169 	.of_match = ast2600_clk_ids,
1170 	.priv_auto = sizeof(struct ast2600_clk_priv),
1171 	.ops = &ast2600_clk_ops,
1172 	.bind = ast2600_clk_bind,
1173 	.probe = ast2600_clk_probe,
1174 };
1175