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 <asm/arch/scu_ast2600.h> 12 #include <dt-bindings/clock/ast2600-clock.h> 13 #include <dt-bindings/reset/ast2600-reset.h> 14 15 /* 16 * MAC Clock Delay settings, taken from Aspeed SDK 17 */ 18 #define RGMII_TXCLK_ODLY 8 19 #define RMII_RXCLK_IDLY 2 20 21 #define MAC_DEF_DELAY_1G 0x00410410 22 #define MAC_DEF_DELAY_100M 0x00410410 23 #define MAC_DEF_DELAY_10M 0x00410410 24 25 #define MAC34_DEF_DELAY_1G 0x00104208 26 #define MAC34_DEF_DELAY_100M 0x00104208 27 #define MAC34_DEF_DELAY_10M 0x00104208 28 29 /* 30 * TGMII Clock Duty constants, taken from Aspeed SDK 31 */ 32 #define RGMII2_TXCK_DUTY 0x66 33 #define RGMII1_TXCK_DUTY 0x64 34 35 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000) 36 37 DECLARE_GLOBAL_DATA_PTR; 38 39 /* 40 * Clock divider/multiplier configuration struct. 41 * For H-PLL and M-PLL the formula is 42 * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1) 43 * M - Numerator 44 * N - Denumerator 45 * P - Post Divider 46 * They have the same layout in their control register. 47 * 48 * D-PLL and D2-PLL have extra divider (OD + 1), which is not 49 * yet needed and ignored by clock configurations. 50 */ 51 union ast2600_pll_reg { 52 unsigned int w; 53 struct { 54 unsigned int m : 13; /* 12:0 */ 55 unsigned int n : 6; /* 18:13 */ 56 unsigned int p : 4; /* 22:19 */ 57 unsigned int reserved : 9; /* 31:20 */ 58 } b; 59 }; 60 61 struct ast2600_pll_cfg { 62 union ast2600_pll_reg reg; 63 unsigned int ext_reg; 64 }; 65 66 struct ast2600_pll_desc { 67 u32 in; 68 u32 out; 69 struct ast2600_pll_cfg cfg; 70 }; 71 72 static const struct ast2600_pll_desc ast2600_pll_lookup[] = { 73 {.in = AST2600_CLK_IN, .out = 400000000, 74 .cfg.reg.b.m = 95, .cfg.reg.b.n = 2, .cfg.reg.b.p = 1, 75 .cfg.ext_reg = 0x31, 76 }, 77 {.in = AST2600_CLK_IN, .out = 200000000, 78 .cfg.reg.b.m = 127, .cfg.reg.b.n = 0, .cfg.reg.b.p = 15, 79 .cfg.ext_reg = 0x3f 80 }, 81 {.in = AST2600_CLK_IN, .out = 334000000, 82 .cfg.reg.b.m = 667, .cfg.reg.b.n = 4, .cfg.reg.b.p = 9, 83 .cfg.ext_reg = 0x14d 84 }, 85 86 {.in = AST2600_CLK_IN, .out = 1000000000, 87 .cfg.reg.b.m = 119, .cfg.reg.b.n = 2, .cfg.reg.b.p = 0, 88 .cfg.ext_reg = 0x3d 89 }, 90 91 {.in = AST2600_CLK_IN, .out = 50000000, 92 .cfg.reg.b.m = 95, .cfg.reg.b.n = 2, .cfg.reg.b.p = 15, 93 .cfg.ext_reg = 0x31 94 }, 95 }; 96 97 extern u32 ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx) 98 { 99 u32 clkin = AST2600_CLK_IN; 100 u32 pll_reg = 0; 101 unsigned int mult, div = 1; 102 103 switch(pll_idx) { 104 case ASPEED_CLK_HPLL: 105 pll_reg = readl(&scu->h_pll_param); 106 break; 107 case ASPEED_CLK_MPLL: 108 pll_reg = readl(&scu->m_pll_param); 109 break; 110 case ASPEED_CLK_DPLL: 111 pll_reg = readl(&scu->d_pll_param); 112 break; 113 case ASPEED_CLK_EPLL: 114 pll_reg = readl(&scu->e_pll_param); 115 break; 116 117 } 118 if (pll_reg & BIT(24)) { 119 /* Pass through mode */ 120 mult = div = 1; 121 } else { 122 /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1) */ 123 union ast2600_pll_reg reg; 124 reg.w = pll_reg; 125 mult = (reg.b.m + 1) / (reg.b.n + 1); 126 div = (reg.b.p + 1); 127 } 128 return ((clkin * mult)/div); 129 130 } 131 132 extern u32 ast2600_get_apll_rate(struct ast2600_scu *scu) 133 { 134 u32 clkin = AST2600_CLK_IN; 135 u32 apll_reg = readl(&scu->a_pll_param); 136 unsigned int mult, div = 1; 137 138 if (apll_reg & BIT(20)) { 139 /* Pass through mode */ 140 mult = div = 1; 141 } else { 142 /* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */ 143 u32 m = (apll_reg >> 5) & 0x3f; 144 u32 od = (apll_reg >> 4) & 0x1; 145 u32 n = apll_reg & 0xf; 146 147 mult = (2 - od) * (m + 2); 148 div = n + 1; 149 } 150 return ((clkin * mult)/div); 151 } 152 153 static u32 ast2600_a0_axi_ahb_div_table[] = { 154 2, 2, 3, 5, 155 }; 156 157 static u32 ast2600_a1_axi_ahb_div_table[] = { 158 4, 6, 2, 4, 159 }; 160 161 static u32 ast2600_get_hclk(struct ast2600_scu *scu) 162 { 163 u32 hw_rev = readl(&scu->chip_id0); 164 u32 hwstrap1 = readl(&scu->hwstrap1); 165 u32 axi_div = 1; 166 u32 ahb_div = 0; 167 u32 rate = 0; 168 169 if(hwstrap1 & BIT(16)) 170 axi_div = 1; 171 else 172 axi_div = 2; 173 174 if (hw_rev & BIT(16)) 175 ahb_div = ast2600_a1_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 176 else 177 ahb_div = ast2600_a0_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 178 179 rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); 180 181 return (rate / axi_div / ahb_div); 182 } 183 184 static u32 ast2600_hpll_pclk1_div_table[] = { 185 4, 8, 12, 16, 20, 24, 28, 32, 186 }; 187 188 static u32 ast2600_hpll_pclk2_div_table[] = { 189 2, 4, 6, 8, 10, 12, 14, 16, 190 }; 191 192 static u32 ast2600_get_pclk1(struct ast2600_scu *scu) 193 { 194 u32 clk_sel1 = readl(&scu->clk_sel1); 195 u32 apb_div = ast2600_hpll_pclk1_div_table[((clk_sel1 >> 23) & 0x7)]; 196 u32 rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); 197 198 return (rate / apb_div); 199 } 200 201 static u32 ast2600_get_pclk2(struct ast2600_scu *scu) 202 { 203 u32 clk_sel4 = readl(&scu->clk_sel4); 204 u32 apb_div = ast2600_hpll_pclk2_div_table[((clk_sel4 >> 9) & 0x7)]; 205 u32 rate = ast2600_get_hclk(scu); 206 207 return (rate / apb_div); 208 } 209 210 static u32 ast2600_get_uxclk_rate(struct ast2600_scu *scu) 211 { 212 u32 clk_in = 0; 213 u32 uxclk_sel = readl(&scu->clk_sel4); 214 215 uxclk_sel &= 0x3; 216 switch(uxclk_sel) { 217 case 0: 218 clk_in = ast2600_get_apll_rate(scu) / 4; 219 break; 220 case 1: 221 clk_in = ast2600_get_apll_rate(scu) / 2; 222 break; 223 case 2: 224 clk_in = ast2600_get_apll_rate(scu); 225 break; 226 case 3: 227 clk_in = ast2600_get_hclk(scu); 228 break; 229 } 230 231 return clk_in; 232 } 233 234 static u32 ast2600_get_huxclk_rate(struct ast2600_scu *scu) 235 { 236 u32 clk_in = 0; 237 u32 huclk_sel = readl(&scu->clk_sel4); 238 239 huclk_sel = ((huclk_sel >> 3) & 0x3); 240 switch(huclk_sel) { 241 case 0: 242 clk_in = ast2600_get_apll_rate(scu) / 4; 243 break; 244 case 1: 245 clk_in = ast2600_get_apll_rate(scu) / 2; 246 break; 247 case 2: 248 clk_in = ast2600_get_apll_rate(scu); 249 break; 250 case 3: 251 clk_in = ast2600_get_hclk(scu); 252 break; 253 } 254 255 return clk_in; 256 } 257 258 static u32 ast2600_get_uart_from_uxclk_rate(struct ast2600_scu *scu) 259 { 260 u32 clk_in = ast2600_get_uxclk_rate(scu); 261 u32 div_reg = readl(&scu->uart_24m_ref_uxclk); 262 unsigned int mult, div; 263 264 u32 n = (div_reg >> 8) & 0x3ff; 265 u32 r = div_reg & 0xff; 266 267 mult = r; 268 div = (n * 4); 269 return (clk_in * mult)/div; 270 } 271 272 static u32 ast2600_get_uart_from_huxclk_rate(struct ast2600_scu *scu) 273 { 274 u32 clk_in = ast2600_get_huxclk_rate(scu); 275 u32 div_reg = readl(&scu->uart_24m_ref_huxclk); 276 277 unsigned int mult, div; 278 279 u32 n = (div_reg >> 8) & 0x3ff; 280 u32 r = div_reg & 0xff; 281 282 mult = r; 283 div = (n * 4); 284 return (clk_in * mult)/div; 285 } 286 287 static u32 ast2600_get_sdio_clk_rate(struct ast2600_scu *scu) 288 { 289 u32 clkin = 0; 290 u32 clk_sel = readl(&scu->clk_sel4); 291 u32 div = (clk_sel >> 28) & 0x7; 292 293 if(clk_sel & BIT(8)) { 294 clkin = ast2600_get_apll_rate(scu); 295 } else { 296 clkin = ast2600_get_hclk(scu); 297 } 298 div = (div + 1) << 1; 299 300 return (clkin / div); 301 } 302 303 static u32 ast2600_get_emmc_clk_rate(struct ast2600_scu *scu) 304 { 305 u32 clkin = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); 306 u32 clk_sel = readl(&scu->clk_sel1); 307 u32 div = (clk_sel >> 12) & 0x7; 308 309 div = (div + 1) << 2; 310 311 return (clkin / div); 312 } 313 314 static u32 ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx) 315 { 316 u32 uart_sel = readl(&scu->clk_sel4); 317 u32 uart_sel5 = readl(&scu->clk_sel5); 318 ulong uart_clk = 0; 319 320 switch(uart_idx) { 321 case 1: 322 case 2: 323 case 3: 324 case 4: 325 case 6: 326 if(uart_sel & BIT(uart_idx - 1)) 327 uart_clk = ast2600_get_uart_from_uxclk_rate(scu)/13 ; 328 else 329 uart_clk = ast2600_get_uart_from_huxclk_rate(scu)/13 ; 330 break; 331 case 5: //24mhz is come form usb phy 48Mhz 332 { 333 u8 uart5_clk_sel = 0; 334 //high bit 335 if (readl(&scu->misc_ctrl1) & BIT(12)) 336 uart5_clk_sel = 0x2; 337 else 338 uart5_clk_sel = 0x0; 339 340 if (readl(&scu->clk_sel2) & BIT(14)) 341 uart5_clk_sel |= 0x1; 342 343 switch(uart5_clk_sel) { 344 case 0: 345 uart_clk = 24000000; 346 break; 347 case 1: 348 uart_clk = 0; 349 break; 350 case 2: 351 uart_clk = 24000000/13; 352 break; 353 case 3: 354 uart_clk = 192000000/13; 355 break; 356 } 357 } 358 break; 359 case 7: 360 case 8: 361 case 9: 362 case 10: 363 case 11: 364 case 12: 365 case 13: 366 if(uart_sel5 & BIT(uart_idx - 1)) 367 uart_clk = ast2600_get_uart_from_uxclk_rate(scu)/13 ; 368 else 369 uart_clk = ast2600_get_uart_from_huxclk_rate(scu)/13 ; 370 break; 371 } 372 373 return uart_clk; 374 } 375 376 static ulong ast2600_clk_get_rate(struct clk *clk) 377 { 378 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 379 ulong rate = 0; 380 381 switch (clk->id) { 382 case ASPEED_CLK_HPLL: 383 case ASPEED_CLK_EPLL: 384 case ASPEED_CLK_DPLL: 385 case ASPEED_CLK_MPLL: 386 rate = ast2600_get_pll_rate(priv->scu, clk->id); 387 break; 388 case ASPEED_CLK_AHB: 389 rate = ast2600_get_hclk(priv->scu); 390 break; 391 case ASPEED_CLK_APB1: 392 rate = ast2600_get_pclk1(priv->scu); 393 break; 394 case ASPEED_CLK_APB2: 395 rate = ast2600_get_pclk2(priv->scu); 396 break; 397 case ASPEED_CLK_APLL: 398 rate = ast2600_get_apll_rate(priv->scu); 399 break; 400 case ASPEED_CLK_GATE_UART1CLK: 401 rate = ast2600_get_uart_clk_rate(priv->scu, 1); 402 break; 403 case ASPEED_CLK_GATE_UART2CLK: 404 rate = ast2600_get_uart_clk_rate(priv->scu, 2); 405 break; 406 case ASPEED_CLK_GATE_UART3CLK: 407 rate = ast2600_get_uart_clk_rate(priv->scu, 3); 408 break; 409 case ASPEED_CLK_GATE_UART4CLK: 410 rate = ast2600_get_uart_clk_rate(priv->scu, 4); 411 break; 412 case ASPEED_CLK_GATE_UART5CLK: 413 rate = ast2600_get_uart_clk_rate(priv->scu, 5); 414 break; 415 case ASPEED_CLK_SDIO: 416 rate = ast2600_get_sdio_clk_rate(priv->scu); 417 break; 418 case ASPEED_CLK_EMMC: 419 rate = ast2600_get_emmc_clk_rate(priv->scu); 420 break; 421 default: 422 pr_debug("can't get clk rate \n"); 423 return -ENOENT; 424 break; 425 } 426 427 return rate; 428 } 429 430 /** 431 * @brief lookup PLL divider config by input/output rate 432 * @param[in] *pll - PLL descriptor 433 * @return true - if PLL divider config is found, false - else 434 * 435 * The function caller shall fill "pll->in" and "pll->out", then this function 436 * will search the lookup table to find a valid PLL divider configuration. 437 */ 438 static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll) 439 { 440 u32 i; 441 bool is_found = false; 442 443 for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) { 444 const struct ast2600_pll_desc *def_cfg = &ast2600_pll_lookup[i]; 445 if ((def_cfg->in == pll->in) && (def_cfg->out == pll->out)) { 446 is_found = true; 447 pll->cfg.reg.w = def_cfg->cfg.reg.w; 448 pll->cfg.ext_reg = def_cfg->cfg.ext_reg; 449 break; 450 } 451 } 452 return is_found; 453 } 454 455 static u32 ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate) 456 { 457 u32 mpll_reg; 458 struct ast2600_pll_desc mpll; 459 460 mpll.in = AST2600_CLK_IN; 461 mpll.out = rate; 462 if (false == ast2600_search_clock_config(&mpll)) { 463 printf("error!! unable to find valid DDR clock setting\n"); 464 return 0; 465 } 466 467 mpll_reg = readl(&scu->m_pll_param); 468 mpll_reg &= ~GENMASK(22, 0); 469 mpll_reg |= mpll.cfg.reg.w; 470 writel(mpll_reg, &scu->m_pll_param); 471 472 /* write extend parameter */ 473 writel(mpll.cfg.ext_reg, &scu->m_pll_ext_param); 474 475 return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL); 476 } 477 478 static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate) 479 { 480 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 481 482 ulong new_rate; 483 switch (clk->id) { 484 case ASPEED_CLK_MPLL: 485 new_rate = ast2600_configure_ddr(priv->scu, rate); 486 break; 487 default: 488 return -ENOENT; 489 } 490 491 return new_rate; 492 } 493 494 #define SCU_CLKSTOP_MAC1 (20) 495 #define SCU_CLKSTOP_MAC2 (21) 496 #define SCU_CLKSTOP_MAC3 (20) 497 #define SCU_CLKSTOP_MAC4 (21) 498 499 static u32 ast2600_configure_mac12_clk(struct ast2600_scu *scu) 500 { 501 u32 epll_reg; 502 u32 clksel; 503 u32 clkdelay; 504 505 struct ast2600_pll_desc epll; 506 507 epll.in = AST2600_CLK_IN; 508 epll.out = 1000000000; 509 if (false == ast2600_search_clock_config(&epll)) { 510 printf( 511 "error!! unable to find valid ETHNET MAC clock setting\n"); 512 debug("%s: epll cfg = 0x%08x 0x%08x\n", __func__, 513 epll.cfg.reg.w, epll.cfg.ext_reg); 514 debug("%s: epll cfg = %02x %02x %02x\n", __func__, 515 epll.cfg.reg.b.m, epll.cfg.reg.b.n, epll.cfg.reg.b.p); 516 return 0; 517 } 518 519 epll_reg = readl(&scu->e_pll_param); 520 epll_reg &= ~GENMASK(22, 0); 521 epll_reg |= epll.cfg.reg.w; 522 writel(epll_reg, &scu->e_pll_param); 523 524 /* write extend parameter */ 525 writel(epll.cfg.ext_reg, &scu->e_pll_ext_param); 526 527 /* select MAC#1 and MAC#2 clock source = EPLL / 8 */ 528 clksel = readl(&scu->clk_sel2); 529 clksel &= ~BIT(23); 530 clksel |= 0x7 << 20; 531 writel(clksel, &scu->clk_sel2); 532 533 /* 534 BIT(31): select RGMII 125M from internal source 535 BIT(28): RGMII 125M output enable 536 BIT(25:0): 1G default delay 537 */ 538 clkdelay = MAC_DEF_DELAY_1G | BIT(31) | BIT(28); 539 writel(clkdelay, &scu->mac12_clk_delay); 540 541 /* set 100M/10M default delay */ 542 writel(MAC_DEF_DELAY_100M, &scu->mac12_clk_delay_100M); 543 writel(MAC_DEF_DELAY_10M, &scu->mac12_clk_delay_10M); 544 545 /* MAC AHB = HPLL / 6 */ 546 clksel = readl(&scu->clk_sel1); 547 clksel &= ~GENMASK(18, 16); 548 clksel |= 0x2 << 16; 549 writel(clksel, &scu->clk_sel1); 550 551 return 0; 552 } 553 554 static u32 ast2600_configure_mac34_clk(struct ast2600_scu *scu) 555 { 556 u32 reg; 557 558 ast2600_configure_mac12_clk(scu); 559 560 /* 561 BIT[31] RGMII 125M source: 0 = from IO pin 562 BIT[25:0] MAC 1G delay 563 */ 564 reg = readl(&scu->mac34_clk_delay); 565 reg &= ~(BIT(31) | GENMASK(25, 0)); 566 reg |= MAC34_DEF_DELAY_1G; 567 writel(reg, &scu->mac34_clk_delay); 568 writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M); 569 writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M); 570 571 /* clock source seletion and divider */ 572 reg = readl(&scu->clk_sel4); 573 reg &= ~GENMASK(26, 24); /* MAC AHB = HCLK / 2 */ 574 reg &= ~GENMASK(18, 16); 575 reg |= 0x3 << 16; /* RMII 50M = SLICLK_200M / 4 */ 576 writel(reg, &scu->clk_sel4); 577 578 /* set driving strength */ 579 reg = readl(&scu->pinmux_ctrl16); 580 reg &= GENMASK(3, 0); 581 reg |= (0x2 << 0) | (0x2 << 2); 582 writel(reg, &scu->pinmux_ctrl16); 583 584 return 0; 585 } 586 #if 0 587 /** 588 * ast2600 RGMII clock source tree 589 * 590 * 125M from external PAD -------->|\ 591 * HPLL -->|\ | |---->RGMII 125M for MAC#1 & MAC#2 592 * | |---->| divider |---->|/ + 593 * EPLL -->|/ | 594 * | 595 * +---------<-----------|PAD output enable|<---------------------+ 596 * | 597 * +--->|PAD input enable|----->|\ 598 * | |----> RGMII 125M for MAC#3 & MAC#4 599 * SLICLK 200M -->|divider|---->|/ 600 * 601 * 602 * ast2600 RMII/NCSI clock source tree 603 * 604 * HPLL -->|\ 605 * | |---->| divider |----> RMII 50M for MAC#1 & MAC#2 606 * EPLL -->|/ 607 * 608 * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4 609 */ 610 struct ast2600_rgmii_clk_config { 611 u32 mac_1_2_src; /* 0=external PAD, 1=internal PLL */ 612 u32 int_clk_src; /* 0=EPLL, 1=HPLL */ 613 u32 int_clk_div; 614 615 u32 mac_3_4_src; /* 0=external PAD, 1=SLICLK */ 616 u32 sli_clk_div; /* reserved */ 617 }; 618 619 static void ast2600_init_rgmii_clk(struct ast2600_scu *scu, int index) 620 { 621 debug("%s not ready\n", __func__); 622 } 623 624 static void ast2600_init_rmii_clk(struct ast2600_scu *scu, int index) 625 { 626 debug("%s not ready\n", __func__); 627 } 628 #endif 629 static u32 ast2600_configure_mac(struct ast2600_scu *scu, int index) 630 { 631 u32 reset_bit; 632 u32 clkstop_bit; 633 634 if (index < 3) 635 ast2600_configure_mac12_clk(scu); 636 else 637 ast2600_configure_mac34_clk(scu); 638 639 switch (index) { 640 case 1: 641 reset_bit = BIT(ASPEED_RESET_MAC1); 642 clkstop_bit = BIT(SCU_CLKSTOP_MAC1); 643 writel(reset_bit, &scu->sysreset_ctrl1); 644 udelay(100); 645 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 646 mdelay(10); 647 writel(reset_bit, &scu->sysreset_clr_ctrl1); 648 649 break; 650 case 2: 651 reset_bit = BIT(ASPEED_RESET_MAC2); 652 clkstop_bit = BIT(SCU_CLKSTOP_MAC2); 653 writel(reset_bit, &scu->sysreset_ctrl1); 654 udelay(100); 655 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 656 mdelay(10); 657 writel(reset_bit, &scu->sysreset_clr_ctrl1); 658 break; 659 case 3: 660 reset_bit = BIT(ASPEED_RESET_MAC3 - 32); 661 clkstop_bit = BIT(SCU_CLKSTOP_MAC3); 662 writel(reset_bit, &scu->sysreset_ctrl2); 663 udelay(100); 664 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 665 mdelay(10); 666 writel(reset_bit, &scu->sysreset_clr_ctrl2); 667 break; 668 case 4: 669 reset_bit = BIT(ASPEED_RESET_MAC4 - 32); 670 clkstop_bit = BIT(SCU_CLKSTOP_MAC4); 671 writel(reset_bit, &scu->sysreset_ctrl2); 672 udelay(100); 673 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 674 mdelay(10); 675 writel(reset_bit, &scu->sysreset_clr_ctrl2); 676 break; 677 default: 678 return -EINVAL; 679 } 680 681 return 0; 682 } 683 684 #define SCU_CLKSTOP_SDIO 4 685 static ulong ast2600_enable_sdclk(struct ast2600_scu *scu) 686 { 687 u32 reset_bit; 688 u32 clkstop_bit; 689 690 reset_bit = BIT(ASPEED_RESET_SD - 32); 691 clkstop_bit = BIT(SCU_CLKSTOP_SDIO); 692 693 writel(reset_bit, &scu->sysreset_clr_ctrl2); 694 udelay(100); 695 //enable clk 696 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 697 mdelay(10); 698 writel(reset_bit, &scu->sysreset_ctrl2); 699 700 return 0; 701 } 702 703 #define SCU_CLKSTOP_EXTSD 31 704 #define SCU_CLK_SD_MASK (0x7 << 28) 705 #define SCU_CLK_SD_DIV(x) (x << 28) 706 707 static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu) 708 { 709 u32 clk_sel = readl(&scu->clk_sel4); 710 u32 enableclk_bit; 711 712 enableclk_bit = BIT(SCU_CLKSTOP_EXTSD); 713 714 //default use apll for clock source 800/2 = 400 715 clk_sel &= ~SCU_CLK_SD_MASK; 716 clk_sel |= SCU_CLK_SD_DIV(0) | BIT(8); 717 writel(clk_sel, &scu->clk_sel4); 718 719 //enable clk 720 setbits_le32(&scu->clk_sel4, enableclk_bit); 721 722 return 0; 723 } 724 725 #define SCU_CLKSTOP_EMMC 27 726 static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu) 727 { 728 u32 reset_bit; 729 u32 clkstop_bit; 730 731 reset_bit = BIT(ASPEED_RESET_EMMC); 732 clkstop_bit = BIT(SCU_CLKSTOP_EMMC); 733 734 writel(reset_bit, &scu->sysreset_clr_ctrl1); 735 udelay(100); 736 //enable clk 737 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 738 mdelay(10); 739 writel(reset_bit, &scu->sysreset_ctrl2); 740 741 return 0; 742 } 743 744 #define SCU_CLKSTOP_EXTEMMC 15 745 #define SCU_CLK_EMMC_MASK (0x7 << 12) 746 #define SCU_CLK_EMMC_DIV(x) (x << 12) 747 748 static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu) 749 { 750 u32 clk_sel = readl(&scu->clk_sel1); 751 u32 enableclk_bit; 752 753 enableclk_bit = BIT(SCU_CLKSTOP_EXTEMMC); 754 755 clk_sel &= ~SCU_CLK_SD_MASK; 756 clk_sel |= SCU_CLK_SD_DIV(1); 757 writel(clk_sel, &scu->clk_sel1); 758 759 //enable clk 760 setbits_le32(&scu->clk_sel1, enableclk_bit); 761 762 return 0; 763 } 764 765 static int ast2600_clk_enable(struct clk *clk) 766 { 767 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 768 769 switch (clk->id) { 770 case ASPEED_CLK_GATE_MAC1CLK: 771 ast2600_configure_mac(priv->scu, 1); 772 break; 773 case ASPEED_CLK_GATE_MAC2CLK: 774 ast2600_configure_mac(priv->scu, 2); 775 break; 776 case ASPEED_CLK_GATE_MAC3CLK: 777 ast2600_configure_mac(priv->scu, 3); 778 break; 779 case ASPEED_CLK_GATE_MAC4CLK: 780 ast2600_configure_mac(priv->scu, 4); 781 break; 782 case ASPEED_CLK_GATE_SDCLK: 783 ast2600_enable_sdclk(priv->scu); 784 break; 785 case ASPEED_CLK_GATE_SDEXTCLK: 786 ast2600_enable_extsdclk(priv->scu); 787 break; 788 case ASPEED_CLK_GATE_EMMCCLK: 789 ast2600_enable_emmcclk(priv->scu); 790 break; 791 case ASPEED_CLK_GATE_EMMCEXTCLK: 792 ast2600_enable_extemmcclk(priv->scu); 793 break; 794 default: 795 pr_debug("can't enable clk \n"); 796 return -ENOENT; 797 break; 798 } 799 800 return 0; 801 } 802 803 struct clk_ops ast2600_clk_ops = { 804 .get_rate = ast2600_clk_get_rate, 805 .set_rate = ast2600_clk_set_rate, 806 .enable = ast2600_clk_enable, 807 }; 808 809 static int ast2600_clk_probe(struct udevice *dev) 810 { 811 struct ast2600_clk_priv *priv = dev_get_priv(dev); 812 813 priv->scu = devfdt_get_addr_ptr(dev); 814 if (IS_ERR(priv->scu)) 815 return PTR_ERR(priv->scu); 816 817 return 0; 818 } 819 820 static int ast2600_clk_bind(struct udevice *dev) 821 { 822 int ret; 823 824 /* The reset driver does not have a device node, so bind it here */ 825 ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); 826 if (ret) 827 debug("Warning: No reset driver: ret=%d\n", ret); 828 829 return 0; 830 } 831 832 #if CONFIG_IS_ENABLED(CMD_CLK) 833 struct aspeed_clks { 834 ulong id; 835 const char *name; 836 }; 837 838 static struct aspeed_clks aspeed_clk_names[] = { 839 { ASPEED_CLK_HPLL, "hpll" }, 840 { ASPEED_CLK_MPLL, "mpll" }, 841 { ASPEED_CLK_APLL, "apll" }, 842 { ASPEED_CLK_EPLL, "epll" }, 843 { ASPEED_CLK_DPLL, "dpll" }, 844 { ASPEED_CLK_AHB, "hclk" }, 845 { ASPEED_CLK_APB1, "pclk1" }, 846 { ASPEED_CLK_APB2, "pclk2" }, 847 }; 848 849 int soc_clk_dump(void) 850 { 851 struct udevice *dev; 852 struct clk clk; 853 unsigned long rate; 854 int i, ret; 855 856 ret = uclass_get_device_by_driver(UCLASS_CLK, 857 DM_GET_DRIVER(aspeed_scu), &dev); 858 if (ret) 859 return ret; 860 861 printf("Clk\t\tHz\n"); 862 863 for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { 864 clk.id = aspeed_clk_names[i].id; 865 ret = clk_request(dev, &clk); 866 if (ret < 0) { 867 debug("%s clk_request() failed: %d\n", __func__, ret); 868 continue; 869 } 870 871 ret = clk_get_rate(&clk); 872 rate = ret; 873 874 clk_free(&clk); 875 876 if (ret == -ENOTSUPP) { 877 printf("clk ID %lu not supported yet\n", 878 aspeed_clk_names[i].id); 879 continue; 880 } 881 if (ret < 0) { 882 printf("%s %lu: get_rate err: %d\n", 883 __func__, aspeed_clk_names[i].id, ret); 884 continue; 885 } 886 887 printf("%s(%3lu):\t%lu\n", 888 aspeed_clk_names[i].name, aspeed_clk_names[i].id, rate); 889 } 890 891 return 0; 892 } 893 #endif 894 895 static const struct udevice_id ast2600_clk_ids[] = { 896 { .compatible = "aspeed,ast2600-scu", }, 897 { } 898 }; 899 900 U_BOOT_DRIVER(aspeed_scu) = { 901 .name = "aspeed_scu", 902 .id = UCLASS_CLK, 903 .of_match = ast2600_clk_ids, 904 .priv_auto_alloc_size = sizeof(struct ast2600_clk_priv), 905 .ops = &ast2600_clk_ops, 906 .bind = ast2600_clk_bind, 907 .probe = ast2600_clk_probe, 908 }; 909