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