1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) ASPEED Technology Inc. 4 * Ryan Chen <ryan_chen@aspeedtech.com> 5 */ 6 7 #include <common.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <asm/io.h> 11 #include <dm/lists.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 16 /* 17 * MAC Clock Delay settings, taken from Aspeed SDK 18 */ 19 #define RGMII_TXCLK_ODLY 8 20 #define RMII_RXCLK_IDLY 2 21 22 /* 23 * TGMII Clock Duty constants, taken from Aspeed SDK 24 */ 25 #define RGMII2_TXCK_DUTY 0x66 26 #define RGMII1_TXCK_DUTY 0x64 27 28 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000) 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 /* 33 * Clock divider/multiplier configuration struct. 34 * For H-PLL and M-PLL the formula is 35 * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1) 36 * M - Numerator 37 * N - Denumerator 38 * P - Post Divider 39 * They have the same layout in their control register. 40 * 41 * D-PLL and D2-PLL have extra divider (OD + 1), which is not 42 * yet needed and ignored by clock configurations. 43 */ 44 struct ast2600_div_config { 45 unsigned int num; 46 unsigned int denum; 47 unsigned int post_div; 48 }; 49 50 /* 51 * Get the rate of the M-PLL clock from input clock frequency and 52 * the value of the M-PLL Parameter Register. 53 */ 54 extern u32 ast2600_get_mpll_rate(struct ast2600_scu *scu) 55 { 56 u32 clkin = AST2600_CLK_IN; 57 u32 mpll_reg = readl(&scu->m_pll_param); 58 unsigned int mult, div = 1; 59 60 if (mpll_reg & BIT(24)) { 61 /* Pass through mode */ 62 mult = div = 1; 63 } else { 64 /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1) */ 65 u32 m = mpll_reg & 0x1fff; 66 u32 n = (mpll_reg >> 13) & 0x3f; 67 u32 p = (mpll_reg >> 19) & 0xf; 68 mult = (m + 1) / (n + 1); 69 div = (p + 1); 70 } 71 return ((clkin * mult)/div); 72 73 } 74 75 /* 76 * Get the rate of the H-PLL clock from input clock frequency and 77 * the value of the H-PLL Parameter Register. 78 */ 79 extern u32 ast2600_get_hpll_rate(struct ast2600_scu *scu) 80 { 81 u32 clkin = AST2600_CLK_IN; 82 u32 hpll_reg = readl(&scu->h_pll_param); 83 unsigned int mult, div = 1; 84 85 if (hpll_reg & BIT(24)) { 86 /* Pass through mode */ 87 mult = div = 1; 88 } else { 89 /* F = 25Mhz * [(M + 1) / (n + 1)] / (p + 1) */ 90 u32 m = (hpll_reg & 0x1fff); 91 u32 n = (hpll_reg >> 13) & 0x3f; 92 u32 p = (hpll_reg >> 19) & 0xf; 93 mult = (m + 1) / (n + 1); 94 div = (p + 1); 95 } 96 return ((clkin * mult)/div); 97 } 98 99 static u32 ast2600_a0_axi_ahb_div_table[] = { 100 2, 2, 3, 5, 101 }; 102 103 static u32 ast2600_a1_axi_ahb_div_table[] = { 104 4, 6, 2, 4, 105 }; 106 107 static u32 ast2600_get_hclk(struct ast2600_scu *scu) 108 { 109 u32 hw_rev = readl(&scu->chip_id0); 110 u32 hwstrap1 = readl(&scu->hwstrap1); 111 u32 axi_div = 1; 112 u32 ahb_div = 0; 113 u32 rate = 0; 114 115 if((hwstrap1 >> 16) & 0x1) 116 axi_div = 1; 117 else 118 axi_div = 2; 119 120 if (hw_rev & BIT(16)) 121 ahb_div = ast2600_a1_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 122 else 123 ahb_div = ast2600_a0_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 124 125 rate = ast2600_get_hpll_rate(scu); 126 rate = rate / axi_div / ahb_div; 127 128 return rate; 129 } 130 131 extern u32 ast2600_get_apll_rate(struct ast2600_scu *scu) 132 { 133 u32 clk_in = AST2600_CLK_IN; 134 u32 apll_reg = readl(&scu->a_pll_param); 135 unsigned int mult, div = 1; 136 137 if (apll_reg & BIT(20)) { 138 /* Pass through mode */ 139 mult = div = 1; 140 } else { 141 /* F = 25Mhz * (2-OD) * [(M + 2) / (n + 1)] */ 142 u32 m = (apll_reg >> 5) & 0x3f; 143 u32 od = (apll_reg >> 4) & 0x1; 144 u32 n = apll_reg & 0xf; 145 146 mult = (2 - od) * ((m + 2) / (n + 1)); 147 } 148 return (clk_in * mult)/div; 149 } 150 151 extern u32 ast2600_get_epll_rate(struct ast2600_scu *scu) 152 { 153 u32 clk_in = AST2600_CLK_IN; 154 u32 epll_reg = readl(&scu->e_pll_param); 155 unsigned int mult, div = 1; 156 157 if (epll_reg & BIT(24)) { 158 /* Pass through mode */ 159 mult = div = 1; 160 } else { 161 /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)*/ 162 u32 m = epll_reg & 0x1fff; 163 u32 n = (epll_reg >> 13) & 0x3f; 164 u32 p = (epll_reg >> 19) & 0x7; 165 166 mult = ((m + 1) / (n + 1)); 167 div = (p + 1); 168 } 169 return (clk_in * mult)/div; 170 } 171 172 extern u32 ast2600_get_dpll_rate(struct ast2600_scu *scu) 173 { 174 u32 clk_in = AST2600_CLK_IN; 175 u32 dpll_reg = readl(&scu->d_pll_param); 176 unsigned int mult, div = 1; 177 178 if (dpll_reg & BIT(24)) { 179 /* Pass through mode */ 180 mult = div = 1; 181 } else { 182 /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)*/ 183 u32 m = dpll_reg & 0x1fff; 184 u32 n = (dpll_reg >> 13) & 0x3f; 185 u32 p = (dpll_reg >> 19) & 0x7; 186 mult = ((m + 1) / (n + 1)); 187 div = (p + 1); 188 } 189 return (clk_in * mult)/div; 190 } 191 192 static u32 ast2600_get_uxclk_rate(struct ast2600_scu *scu) 193 { 194 u32 clk_in = 0; 195 u32 uxclk_sel = readl(&scu->clk_sel4); 196 197 uxclk_sel &= 0x3; 198 switch(uxclk_sel) { 199 case 0: 200 clk_in = ast2600_get_apll_rate(scu) / 4; 201 break; 202 case 1: 203 clk_in = ast2600_get_apll_rate(scu) / 2; 204 break; 205 case 2: 206 clk_in = ast2600_get_apll_rate(scu); 207 break; 208 case 3: 209 clk_in = ast2600_get_hclk(scu); 210 break; 211 } 212 213 return clk_in; 214 } 215 216 static u32 ast2600_get_huxclk_rate(struct ast2600_scu *scu) 217 { 218 u32 clk_in = 0; 219 u32 huclk_sel = readl(&scu->clk_sel4); 220 221 huclk_sel = ((huclk_sel >> 3) & 0x3); 222 switch(huclk_sel) { 223 case 0: 224 clk_in = ast2600_get_apll_rate(scu) / 4; 225 break; 226 case 1: 227 clk_in = ast2600_get_apll_rate(scu) / 2; 228 break; 229 case 2: 230 clk_in = ast2600_get_apll_rate(scu); 231 break; 232 case 3: 233 clk_in = ast2600_get_hclk(scu); 234 break; 235 } 236 237 return clk_in; 238 } 239 240 static u32 ast2600_get_uart_from_uxclk_rate(struct ast2600_scu *scu) 241 { 242 u32 clk_in = ast2600_get_uxclk_rate(scu); 243 u32 div_reg = readl(&scu->uart_24m_ref_uxclk); 244 unsigned int mult, div; 245 246 u32 n = (div_reg >> 8) & 0x3ff; 247 u32 r = div_reg & 0xff; 248 249 mult = r; 250 div = (n * 4); 251 return (clk_in * mult)/div; 252 } 253 254 static u32 ast2600_get_uart_from_huxclk_rate(struct ast2600_scu *scu) 255 { 256 u32 clk_in = ast2600_get_huxclk_rate(scu); 257 u32 div_reg = readl(&scu->uart_24m_ref_huxclk); 258 259 unsigned int mult, div; 260 261 u32 n = (div_reg >> 8) & 0x3ff; 262 u32 r = div_reg & 0xff; 263 264 mult = r; 265 div = (n * 4); 266 return (clk_in * mult)/div; 267 } 268 269 static ulong ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx) 270 { 271 u32 uart_sel = readl(&scu->clk_sel4); 272 u32 uart_sel5 = readl(&scu->clk_sel5); 273 ulong uart_clk = 0; 274 275 switch(uart_idx) { 276 case 1: 277 case 2: 278 case 3: 279 case 4: 280 case 6: 281 if(uart_sel & BIT(uart_idx - 1)) 282 uart_clk = ast2600_get_uart_from_uxclk_rate(scu)/13 ; 283 else 284 uart_clk = ast2600_get_uart_from_huxclk_rate(scu)/13 ; 285 break; 286 case 5: //24mhz is come form usb phy 48Mhz 287 { 288 u8 uart5_clk_sel = 0; 289 //high bit 290 if (readl(&scu->misc_ctrl1) & BIT(12)) 291 uart5_clk_sel = 0x2; 292 else 293 uart5_clk_sel = 0x0; 294 295 if (readl(&scu->clk_sel2) & BIT(14)) 296 uart5_clk_sel |= 0x1; 297 298 switch(uart5_clk_sel) { 299 case 0: 300 uart_clk = 24000000; 301 break; 302 case 1: 303 uart_clk = 0; 304 break; 305 case 2: 306 uart_clk = 24000000/13; 307 break; 308 case 3: 309 uart_clk = 192000000/13; 310 break; 311 } 312 } 313 break; 314 case 7: 315 case 8: 316 case 9: 317 case 10: 318 case 11: 319 case 12: 320 case 13: 321 if(uart_sel5 & BIT(uart_idx - 1)) 322 uart_clk = ast2600_get_uart_from_uxclk_rate(scu)/13 ; 323 else 324 uart_clk = ast2600_get_uart_from_huxclk_rate(scu)/13 ; 325 break; 326 } 327 328 return uart_clk; 329 } 330 331 struct aspeed_clock_config { 332 ulong input_rate; 333 ulong rate; 334 struct ast2600_div_config cfg; 335 }; 336 337 static const struct aspeed_clock_config aspeed_clock_config_defaults[] = { 338 { 25000000, 400000000, { .num = 95, .denum = 2, .post_div = 1 } }, 339 }; 340 341 static bool aspeed_get_clock_config_default(ulong input_rate, 342 ulong requested_rate, 343 struct ast2600_div_config *cfg) 344 { 345 int i; 346 347 for (i = 0; i < ARRAY_SIZE(aspeed_clock_config_defaults); i++) { 348 const struct aspeed_clock_config *default_cfg = 349 &aspeed_clock_config_defaults[i]; 350 if (default_cfg->input_rate == input_rate && 351 default_cfg->rate == requested_rate) { 352 *cfg = default_cfg->cfg; 353 return true; 354 } 355 } 356 357 return false; 358 } 359 360 /* 361 * @input_rate - the rate of input clock in Hz 362 * @requested_rate - desired output rate in Hz 363 * @div - this is an IN/OUT parameter, at input all fields of the config 364 * need to be set to their maximum allowed values. 365 * The result (the best config we could find), would also be returned 366 * in this structure. 367 * 368 * @return The clock rate, when the resulting div_config is used. 369 */ 370 static ulong aspeed_calc_clock_config(ulong input_rate, ulong requested_rate, 371 struct ast2600_div_config *cfg) 372 { 373 /* 374 * The assumption is that kHz precision is good enough and 375 * also enough to avoid overflow when multiplying. 376 */ 377 const ulong input_rate_khz = input_rate / 1000; 378 const ulong rate_khz = requested_rate / 1000; 379 const struct ast2600_div_config max_vals = *cfg; 380 struct ast2600_div_config it = { 0, 0, 0 }; 381 ulong delta = rate_khz; 382 ulong new_rate_khz = 0; 383 384 /* 385 * Look for a well known frequency first. 386 */ 387 if (aspeed_get_clock_config_default(input_rate, requested_rate, cfg)) 388 return requested_rate; 389 390 for (; it.denum <= max_vals.denum; ++it.denum) { 391 for (it.post_div = 0; it.post_div <= max_vals.post_div; 392 ++it.post_div) { 393 it.num = (rate_khz * (it.post_div + 1) / input_rate_khz) 394 * (it.denum + 1); 395 if (it.num > max_vals.num) 396 continue; 397 398 new_rate_khz = (input_rate_khz 399 * ((it.num + 1) / (it.denum + 1))) 400 / (it.post_div + 1); 401 402 /* Keep the rate below requested one. */ 403 if (new_rate_khz > rate_khz) 404 continue; 405 406 if (new_rate_khz - rate_khz < delta) { 407 delta = new_rate_khz - rate_khz; 408 *cfg = it; 409 if (delta == 0) 410 return new_rate_khz * 1000; 411 } 412 } 413 } 414 415 return new_rate_khz * 1000; 416 } 417 418 static u32 ast2600_configure_ddr(struct ast2600_clk_priv *priv, ulong rate) 419 { 420 u32 clkin = AST2600_CLK_IN; 421 u32 mpll_reg; 422 struct ast2600_div_config div_cfg = { 423 .num = (SCU_MPLL_NUM_MASK >> SCU_MPLL_NUM_SHIFT), 424 .denum = (SCU_MPLL_DENUM_MASK >> SCU_MPLL_DENUM_SHIFT), 425 .post_div = (SCU_MPLL_POST_MASK >> SCU_MPLL_POST_SHIFT), 426 }; 427 428 aspeed_calc_clock_config(clkin, rate, &div_cfg); 429 430 mpll_reg = readl(&priv->scu->m_pll_param); 431 mpll_reg &= ~(SCU_MPLL_POST_MASK | SCU_MPLL_NUM_MASK 432 | SCU_MPLL_DENUM_MASK); 433 mpll_reg |= (div_cfg.post_div << SCU_MPLL_POST_SHIFT) 434 | (div_cfg.num << SCU_MPLL_NUM_SHIFT) 435 | (div_cfg.denum << SCU_MPLL_DENUM_SHIFT); 436 437 writel(mpll_reg, &priv->scu->m_pll_param); 438 439 return ast2600_get_mpll_rate(priv->scu); 440 } 441 442 #define SCU_CLKSTOP_MAC1 (20) 443 #define SCU_CLKSTOP_MAC2 (21) 444 #define SCU_CLKSTOP_MAC3 (20) 445 #define SCU_CLKSTOP_MAC4 (21) 446 447 static u32 ast2600_configure_mac(struct ast2600_scu *scu, int index) 448 { 449 u32 reset_bit; 450 u32 clkstop_bit; 451 452 453 switch (index) { 454 case 1: 455 reset_bit = BIT(ASPEED_RESET_MAC1); 456 clkstop_bit = BIT(SCU_CLKSTOP_MAC1); 457 writel(reset_bit, &scu->sysreset_ctrl1); 458 udelay(100); 459 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 460 mdelay(10); 461 writel(reset_bit, &scu->sysreset_clr_ctrl1); 462 463 break; 464 case 2: 465 reset_bit = BIT(ASPEED_RESET_MAC2); 466 clkstop_bit = BIT(SCU_CLKSTOP_MAC2); 467 writel(reset_bit, &scu->sysreset_ctrl1); 468 udelay(100); 469 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 470 mdelay(10); 471 writel(reset_bit, &scu->sysreset_clr_ctrl1); 472 break; 473 case 3: 474 reset_bit = BIT(ASPEED_RESET_MAC3 - 32); 475 clkstop_bit = BIT(SCU_CLKSTOP_MAC3); 476 writel(reset_bit, &scu->sysreset_ctrl2); 477 udelay(100); 478 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 479 mdelay(10); 480 writel(reset_bit, &scu->sysreset_clr_ctrl2); 481 break; 482 case 4: 483 reset_bit = BIT(ASPEED_RESET_MAC4 - 32); 484 clkstop_bit = BIT(SCU_CLKSTOP_MAC4); 485 writel(reset_bit, &scu->sysreset_ctrl2); 486 udelay(100); 487 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 488 mdelay(10); 489 writel(reset_bit, &scu->sysreset_clr_ctrl2); 490 break; 491 default: 492 return -EINVAL; 493 } 494 495 return 0; 496 } 497 498 static u32 ast2600_hpll_pclk_div_table[] = { 499 4, 8, 12, 16, 20, 24, 28, 32, 500 }; 501 static ulong ast2600_clk_get_rate(struct clk *clk) 502 { 503 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 504 ulong rate = 0; 505 506 switch (clk->id) { 507 //HPLL 508 case ASPEED_CLK_HPLL: 509 rate = ast2600_get_hpll_rate(priv->scu); 510 printf("hpll %ld \n", rate); 511 break; 512 //HCLK 513 case ASPEED_CLK_AHB: 514 rate = ast2600_get_hclk(priv->scu); 515 printf("hclk %ld \n", rate); 516 break; 517 case ASPEED_CLK_MPLL: 518 rate = ast2600_get_mpll_rate(priv->scu); 519 break; 520 //pclk 521 case ASPEED_CLK_APB: 522 { 523 u32 clk_sel1 = readl(&priv->scu->clk_sel1); 524 u32 apb_div = ast2600_hpll_pclk_div_table[((clk_sel1 >> 23) & 0x7)]; 525 rate = ast2600_get_hpll_rate(priv->scu); 526 rate = rate / apb_div; 527 } 528 break; 529 case ASPEED_CLK_GATE_UART1CLK: 530 rate = ast2600_get_uart_clk_rate(priv->scu, 1); 531 break; 532 case ASPEED_CLK_GATE_UART2CLK: 533 rate = ast2600_get_uart_clk_rate(priv->scu, 2); 534 break; 535 case ASPEED_CLK_GATE_UART3CLK: 536 rate = ast2600_get_uart_clk_rate(priv->scu, 3); 537 break; 538 case ASPEED_CLK_GATE_UART4CLK: 539 rate = ast2600_get_uart_clk_rate(priv->scu, 4); 540 break; 541 case ASPEED_CLK_GATE_UART5CLK: 542 rate = ast2600_get_uart_clk_rate(priv->scu, 5); 543 break; 544 default: 545 return -ENOENT; 546 } 547 548 return rate; 549 } 550 551 static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate) 552 { 553 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 554 555 ulong new_rate; 556 switch (clk->id) { 557 case ASPEED_CLK_MPLL: 558 new_rate = ast2600_configure_ddr(priv, rate); 559 break; 560 default: 561 return -ENOENT; 562 } 563 564 return new_rate; 565 } 566 567 static int ast2600_clk_enable(struct clk *clk) 568 { 569 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 570 571 switch (clk->id) { 572 case ASPEED_CLK_GATE_MAC1CLK: 573 ast2600_configure_mac(priv->scu, 1); 574 break; 575 case ASPEED_CLK_GATE_MAC2CLK: 576 ast2600_configure_mac(priv->scu, 2); 577 break; 578 case ASPEED_CLK_GATE_MAC3CLK: 579 ast2600_configure_mac(priv->scu, 3); 580 break; 581 case ASPEED_CLK_GATE_MAC4CLK: 582 ast2600_configure_mac(priv->scu, 4); 583 break; 584 default: 585 return -ENOENT; 586 break; 587 } 588 589 return 0; 590 } 591 592 struct clk_ops aspeed_clk_ops = { 593 .get_rate = ast2600_clk_get_rate, 594 .set_rate = ast2600_clk_set_rate, 595 .enable = ast2600_clk_enable, 596 }; 597 598 static int ast2600_clk_probe(struct udevice *dev) 599 { 600 struct ast2600_clk_priv *priv = dev_get_priv(dev); 601 602 priv->scu = devfdt_get_addr_ptr(dev); 603 if (IS_ERR(priv->scu)) 604 return PTR_ERR(priv->scu); 605 606 return 0; 607 } 608 609 static int ast2600_clk_bind(struct udevice *dev) 610 { 611 int ret; 612 613 /* The reset driver does not have a device node, so bind it here */ 614 ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); 615 if (ret) 616 debug("Warning: No reset driver: ret=%d\n", ret); 617 618 return 0; 619 } 620 621 static const struct udevice_id ast2600_clk_ids[] = { 622 { .compatible = "aspeed,ast2600-scu", }, 623 { } 624 }; 625 626 U_BOOT_DRIVER(aspeed_scu) = { 627 .name = "aspeed_scu", 628 .id = UCLASS_CLK, 629 .of_match = ast2600_clk_ids, 630 .priv_auto_alloc_size = sizeof(struct ast2600_clk_priv), 631 .ops = &aspeed_clk_ops, 632 .bind = ast2600_clk_bind, 633 .probe = ast2600_clk_probe, 634 }; 635