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