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 extern u32 ast2600_get_apll_rate(struct ast2600_scu *scu) 120 { 121 u32 clk_in = AST2600_CLK_IN; 122 u32 apll_reg = readl(&scu->a_pll_param); 123 unsigned int mult, div = 1; 124 125 if (apll_reg & BIT(20)) { 126 /* Pass through mode */ 127 mult = div = 1; 128 } else { 129 /* F = 25Mhz * (2-OD) * [(M + 2) / (n + 1)] */ 130 u32 m = (apll_reg >> 5) & 0x3f; 131 u32 od = (apll_reg >> 4) & 0x1; 132 u32 n = apll_reg & 0xf; 133 134 mult = (2 - od) * ((m + 2) / (n + 1)); 135 } 136 return (clk_in * mult)/div; 137 } 138 139 extern u32 ast2600_get_epll_rate(struct ast2600_scu *scu) 140 { 141 u32 clk_in = AST2600_CLK_IN; 142 u32 epll_reg = readl(&scu->e_pll_param); 143 unsigned int mult, div = 1; 144 145 if (epll_reg & BIT(24)) { 146 /* Pass through mode */ 147 mult = div = 1; 148 } else { 149 /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)*/ 150 u32 m = epll_reg & 0x1fff; 151 u32 n = (epll_reg >> 13) & 0x3f; 152 u32 p = (epll_reg >> 19) & 0x7; 153 154 mult = ((m + 1) / (n + 1)); 155 div = (p + 1); 156 } 157 return (clk_in * mult)/div; 158 } 159 160 static u32 ast2600_a0_axi_ahb_div_table[] = { 161 2, 2, 3, 5, 162 }; 163 164 static u32 ast2600_a1_axi_ahb_div_table[] = { 165 4, 6, 2, 4, 166 }; 167 168 static u32 ast2600_get_hclk(struct ast2600_scu *scu) 169 { 170 u32 hw_rev = readl(&scu->chip_id0); 171 u32 hwstrap1 = readl(&scu->hwstrap1); 172 u32 axi_div = 1; 173 u32 ahb_div = 0; 174 u32 rate = 0; 175 176 if((hwstrap1 >> 16) & 0x1) 177 axi_div = 1; 178 else 179 axi_div = 2; 180 181 if (hw_rev & BIT(16)) 182 ahb_div = ast2600_a1_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 183 else 184 ahb_div = ast2600_a0_axi_ahb_div_table[(hwstrap1 >> 11) & 0x3]; 185 186 rate = ast2600_get_hpll_rate(scu); 187 188 return (rate / axi_div / ahb_div); 189 } 190 191 static u32 ast2600_hpll_pclk_div_table[] = { 192 4, 8, 12, 16, 20, 24, 28, 32, 193 }; 194 195 static u32 ast2600_get_pclk(struct ast2600_scu *scu) 196 { 197 u32 clk_sel1 = readl(&scu->clk_sel1); 198 u32 apb_div = ast2600_hpll_pclk_div_table[((clk_sel1 >> 23) & 0x7)]; 199 u32 rate = ast2600_get_hpll_rate(scu); 200 201 return (rate / apb_div); 202 } 203 204 205 static u32 ast2600_get_uxclk_rate(struct ast2600_scu *scu) 206 { 207 u32 clk_in = 0; 208 u32 uxclk_sel = readl(&scu->clk_sel4); 209 210 uxclk_sel &= 0x3; 211 switch(uxclk_sel) { 212 case 0: 213 clk_in = ast2600_get_apll_rate(scu) / 4; 214 break; 215 case 1: 216 clk_in = ast2600_get_apll_rate(scu) / 2; 217 break; 218 case 2: 219 clk_in = ast2600_get_apll_rate(scu); 220 break; 221 case 3: 222 clk_in = ast2600_get_hclk(scu); 223 break; 224 } 225 226 return clk_in; 227 } 228 229 static u32 ast2600_get_huxclk_rate(struct ast2600_scu *scu) 230 { 231 u32 clk_in = 0; 232 u32 huclk_sel = readl(&scu->clk_sel4); 233 234 huclk_sel = ((huclk_sel >> 3) & 0x3); 235 switch(huclk_sel) { 236 case 0: 237 clk_in = ast2600_get_apll_rate(scu) / 4; 238 break; 239 case 1: 240 clk_in = ast2600_get_apll_rate(scu) / 2; 241 break; 242 case 2: 243 clk_in = ast2600_get_apll_rate(scu); 244 break; 245 case 3: 246 clk_in = ast2600_get_hclk(scu); 247 break; 248 } 249 250 return clk_in; 251 } 252 253 static u32 ast2600_get_uart_from_uxclk_rate(struct ast2600_scu *scu) 254 { 255 u32 clk_in = ast2600_get_uxclk_rate(scu); 256 u32 div_reg = readl(&scu->uart_24m_ref_uxclk); 257 unsigned int mult, div; 258 259 u32 n = (div_reg >> 8) & 0x3ff; 260 u32 r = div_reg & 0xff; 261 262 mult = r; 263 div = (n * 4); 264 return (clk_in * mult)/div; 265 } 266 267 static u32 ast2600_get_uart_from_huxclk_rate(struct ast2600_scu *scu) 268 { 269 u32 clk_in = ast2600_get_huxclk_rate(scu); 270 u32 div_reg = readl(&scu->uart_24m_ref_huxclk); 271 272 unsigned int mult, div; 273 274 u32 n = (div_reg >> 8) & 0x3ff; 275 u32 r = div_reg & 0xff; 276 277 mult = r; 278 div = (n * 4); 279 return (clk_in * mult)/div; 280 } 281 282 static u32 ast2600_get_sdio_clk_rate(struct ast2600_scu *scu) 283 { 284 u32 clkin = 0; 285 u32 clk_sel = readl(&scu->clk_sel4); 286 u32 div = (clk_sel >> 28) & 0x7; 287 288 if(clk_sel & BIT(8)) { 289 clkin = ast2600_get_apll_rate(scu); 290 } else { 291 clkin = 200 * 1000 * 1000; 292 } 293 div = (div + 1) << 1; 294 295 return (clkin / div); 296 } 297 298 static u32 ast2600_get_emmc_clk_rate(struct ast2600_scu *scu) 299 { 300 u32 clkin = ast2600_get_hpll_rate(scu); 301 u32 clk_sel = readl(&scu->clk_sel1); 302 u32 div = (clk_sel >> 12) & 0x7; 303 304 div = (div + 1) << 2; 305 306 return (clkin / div); 307 } 308 309 static u32 ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx) 310 { 311 u32 uart_sel = readl(&scu->clk_sel4); 312 u32 uart_sel5 = readl(&scu->clk_sel5); 313 ulong uart_clk = 0; 314 315 switch(uart_idx) { 316 case 1: 317 case 2: 318 case 3: 319 case 4: 320 case 6: 321 if(uart_sel & 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 case 5: //24mhz is come form usb phy 48Mhz 327 { 328 u8 uart5_clk_sel = 0; 329 //high bit 330 if (readl(&scu->misc_ctrl1) & BIT(12)) 331 uart5_clk_sel = 0x2; 332 else 333 uart5_clk_sel = 0x0; 334 335 if (readl(&scu->clk_sel2) & BIT(14)) 336 uart5_clk_sel |= 0x1; 337 338 switch(uart5_clk_sel) { 339 case 0: 340 uart_clk = 24000000; 341 break; 342 case 1: 343 uart_clk = 0; 344 break; 345 case 2: 346 uart_clk = 24000000/13; 347 break; 348 case 3: 349 uart_clk = 192000000/13; 350 break; 351 } 352 } 353 break; 354 case 7: 355 case 8: 356 case 9: 357 case 10: 358 case 11: 359 case 12: 360 case 13: 361 if(uart_sel5 & BIT(uart_idx - 1)) 362 uart_clk = ast2600_get_uart_from_uxclk_rate(scu)/13 ; 363 else 364 uart_clk = ast2600_get_uart_from_huxclk_rate(scu)/13 ; 365 break; 366 } 367 368 return uart_clk; 369 } 370 371 static ulong ast2600_clk_get_rate(struct clk *clk) 372 { 373 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 374 ulong rate = 0; 375 376 switch (clk->id) { 377 case ASPEED_CLK_HPLL: 378 rate = ast2600_get_hpll_rate(priv->scu); 379 break; 380 case ASPEED_CLK_MPLL: 381 rate = ast2600_get_mpll_rate(priv->scu); 382 break; 383 case ASPEED_CLK_AHB: 384 rate = ast2600_get_hclk(priv->scu); 385 break; 386 case ASPEED_CLK_APB: 387 rate = ast2600_get_pclk(priv->scu); 388 break; 389 case ASPEED_CLK_GATE_UART1CLK: 390 rate = ast2600_get_uart_clk_rate(priv->scu, 1); 391 break; 392 case ASPEED_CLK_GATE_UART2CLK: 393 rate = ast2600_get_uart_clk_rate(priv->scu, 2); 394 break; 395 case ASPEED_CLK_GATE_UART3CLK: 396 rate = ast2600_get_uart_clk_rate(priv->scu, 3); 397 break; 398 case ASPEED_CLK_GATE_UART4CLK: 399 rate = ast2600_get_uart_clk_rate(priv->scu, 4); 400 break; 401 case ASPEED_CLK_GATE_UART5CLK: 402 rate = ast2600_get_uart_clk_rate(priv->scu, 5); 403 break; 404 case ASPEED_CLK_SDIO: 405 rate = ast2600_get_sdio_clk_rate(priv->scu); 406 break; 407 case ASPEED_CLK_EMMC: 408 rate = ast2600_get_emmc_clk_rate(priv->scu); 409 break; 410 default: 411 pr_debug("can't get clk rate \n"); 412 return -ENOENT; 413 break; 414 } 415 416 return rate; 417 } 418 419 struct aspeed_clock_config { 420 ulong input_rate; 421 ulong rate; 422 struct ast2600_div_config cfg; 423 }; 424 425 static const struct aspeed_clock_config aspeed_clock_config_defaults[] = { 426 { 25000000, 400000000, { .num = 95, .denum = 2, .post_div = 1 } }, 427 }; 428 429 static bool aspeed_get_clock_config_default(ulong input_rate, 430 ulong requested_rate, 431 struct ast2600_div_config *cfg) 432 { 433 int i; 434 435 for (i = 0; i < ARRAY_SIZE(aspeed_clock_config_defaults); i++) { 436 const struct aspeed_clock_config *default_cfg = 437 &aspeed_clock_config_defaults[i]; 438 if (default_cfg->input_rate == input_rate && 439 default_cfg->rate == requested_rate) { 440 *cfg = default_cfg->cfg; 441 return true; 442 } 443 } 444 445 return false; 446 } 447 448 /* 449 * @input_rate - the rate of input clock in Hz 450 * @requested_rate - desired output rate in Hz 451 * @div - this is an IN/OUT parameter, at input all fields of the config 452 * need to be set to their maximum allowed values. 453 * The result (the best config we could find), would also be returned 454 * in this structure. 455 * 456 * @return The clock rate, when the resulting div_config is used. 457 */ 458 static ulong aspeed_calc_clock_config(ulong input_rate, ulong requested_rate, 459 struct ast2600_div_config *cfg) 460 { 461 /* 462 * The assumption is that kHz precision is good enough and 463 * also enough to avoid overflow when multiplying. 464 */ 465 const ulong input_rate_khz = input_rate / 1000; 466 const ulong rate_khz = requested_rate / 1000; 467 const struct ast2600_div_config max_vals = *cfg; 468 struct ast2600_div_config it = { 0, 0, 0 }; 469 ulong delta = rate_khz; 470 ulong new_rate_khz = 0; 471 472 /* 473 * Look for a well known frequency first. 474 */ 475 if (aspeed_get_clock_config_default(input_rate, requested_rate, cfg)) 476 return requested_rate; 477 478 for (; it.denum <= max_vals.denum; ++it.denum) { 479 for (it.post_div = 0; it.post_div <= max_vals.post_div; 480 ++it.post_div) { 481 it.num = (rate_khz * (it.post_div + 1) / input_rate_khz) 482 * (it.denum + 1); 483 if (it.num > max_vals.num) 484 continue; 485 486 new_rate_khz = (input_rate_khz 487 * ((it.num + 1) / (it.denum + 1))) 488 / (it.post_div + 1); 489 490 /* Keep the rate below requested one. */ 491 if (new_rate_khz > rate_khz) 492 continue; 493 494 if (new_rate_khz - rate_khz < delta) { 495 delta = new_rate_khz - rate_khz; 496 *cfg = it; 497 if (delta == 0) 498 return new_rate_khz * 1000; 499 } 500 } 501 } 502 503 return new_rate_khz * 1000; 504 } 505 506 static u32 ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate) 507 { 508 u32 clkin = AST2600_CLK_IN; 509 u32 mpll_reg; 510 struct ast2600_div_config div_cfg = { 511 .num = 0x1fff, /* SCU220 bit[12:0] */ 512 .denum = 0x3f, /* SCU220 bit[18:13] */ 513 .post_div = 0xf, /* SCU220 bit[22:19] */ 514 }; 515 516 aspeed_calc_clock_config(clkin, rate, &div_cfg); 517 518 mpll_reg = readl(&scu->m_pll_param); 519 mpll_reg &= ~0x7fffff; 520 mpll_reg |= (div_cfg.post_div << 19) 521 | (div_cfg.denum << 13) 522 | (div_cfg.num << 0); 523 524 writel(mpll_reg, &scu->m_pll_param); 525 526 return ast2600_get_mpll_rate(scu); 527 } 528 529 static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate) 530 { 531 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 532 533 ulong new_rate; 534 switch (clk->id) { 535 case ASPEED_CLK_MPLL: 536 new_rate = ast2600_configure_ddr(priv->scu, rate); 537 break; 538 default: 539 return -ENOENT; 540 } 541 542 return new_rate; 543 } 544 545 #define SCU_CLKSTOP_MAC1 (20) 546 #define SCU_CLKSTOP_MAC2 (21) 547 #define SCU_CLKSTOP_MAC3 (20) 548 #define SCU_CLKSTOP_MAC4 (21) 549 550 static u32 ast2600_configure_mac(struct ast2600_scu *scu, int index) 551 { 552 u32 reset_bit; 553 u32 clkstop_bit; 554 555 556 switch (index) { 557 case 1: 558 reset_bit = BIT(ASPEED_RESET_MAC1); 559 clkstop_bit = BIT(SCU_CLKSTOP_MAC1); 560 writel(reset_bit, &scu->sysreset_ctrl1); 561 udelay(100); 562 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 563 mdelay(10); 564 writel(reset_bit, &scu->sysreset_clr_ctrl1); 565 566 break; 567 case 2: 568 reset_bit = BIT(ASPEED_RESET_MAC2); 569 clkstop_bit = BIT(SCU_CLKSTOP_MAC2); 570 writel(reset_bit, &scu->sysreset_ctrl1); 571 udelay(100); 572 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 573 mdelay(10); 574 writel(reset_bit, &scu->sysreset_clr_ctrl1); 575 break; 576 case 3: 577 reset_bit = BIT(ASPEED_RESET_MAC3 - 32); 578 clkstop_bit = BIT(SCU_CLKSTOP_MAC3); 579 writel(reset_bit, &scu->sysreset_ctrl2); 580 udelay(100); 581 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 582 mdelay(10); 583 writel(reset_bit, &scu->sysreset_clr_ctrl2); 584 break; 585 case 4: 586 reset_bit = BIT(ASPEED_RESET_MAC4 - 32); 587 clkstop_bit = BIT(SCU_CLKSTOP_MAC4); 588 writel(reset_bit, &scu->sysreset_ctrl2); 589 udelay(100); 590 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 591 mdelay(10); 592 writel(reset_bit, &scu->sysreset_clr_ctrl2); 593 break; 594 default: 595 return -EINVAL; 596 } 597 598 return 0; 599 } 600 601 #define SCU_CLKSTOP_SDIO 4 602 static ulong ast2600_enable_sdclk(struct ast2600_scu *scu) 603 { 604 u32 reset_bit; 605 u32 clkstop_bit; 606 607 reset_bit = BIT(ASPEED_RESET_SD - 32); 608 clkstop_bit = BIT(SCU_CLKSTOP_SDIO); 609 610 writel(reset_bit, &scu->sysreset_clr_ctrl2); 611 udelay(100); 612 //enable clk 613 writel(clkstop_bit, &scu->clk_stop_clr_ctrl2); 614 mdelay(10); 615 writel(reset_bit, &scu->sysreset_ctrl2); 616 617 return 0; 618 } 619 620 #define SCU_CLKSTOP_EXTSD 31 621 #define SCU_CLK_SD_MASK (0x7 << 28) 622 #define SCU_CLK_SD_DIV(x) (x << 28) 623 624 static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu) 625 { 626 u32 clk_sel = readl(&scu->clk_sel4); 627 u32 enableclk_bit; 628 629 enableclk_bit = BIT(SCU_CLKSTOP_EXTSD); 630 631 clk_sel &= ~SCU_CLK_SD_MASK; 632 clk_sel |= SCU_CLK_SD_DIV(0); 633 writel(clk_sel, &scu->clk_sel4); 634 635 //enable clk 636 setbits_le32(&scu->clk_sel4, enableclk_bit); 637 638 return 0; 639 } 640 641 #define SCU_CLKSTOP_EMMC 27 642 static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu) 643 { 644 u32 reset_bit; 645 u32 clkstop_bit; 646 647 reset_bit = BIT(ASPEED_RESET_EMMC); 648 clkstop_bit = BIT(SCU_CLKSTOP_EMMC); 649 650 writel(reset_bit, &scu->sysreset_clr_ctrl1); 651 udelay(100); 652 //enable clk 653 writel(clkstop_bit, &scu->clk_stop_clr_ctrl1); 654 mdelay(10); 655 writel(reset_bit, &scu->sysreset_ctrl2); 656 657 return 0; 658 } 659 660 #define SCU_CLKSTOP_EXTEMMC 15 661 #define SCU_CLK_EMMC_MASK (0x7 << 12) 662 #define SCU_CLK_EMMC_DIV(x) (x << 12) 663 664 static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu) 665 { 666 u32 clk_sel = readl(&scu->clk_sel1); 667 u32 enableclk_bit; 668 669 enableclk_bit = BIT(SCU_CLKSTOP_EXTSD); 670 671 clk_sel &= ~SCU_CLK_SD_MASK; 672 clk_sel |= SCU_CLK_SD_DIV(1); 673 writel(clk_sel, &scu->clk_sel1); 674 675 //enable clk 676 setbits_le32(&scu->clk_sel1, enableclk_bit); 677 678 return 0; 679 } 680 681 static int ast2600_clk_enable(struct clk *clk) 682 { 683 struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); 684 685 switch (clk->id) { 686 case ASPEED_CLK_GATE_MAC1CLK: 687 ast2600_configure_mac(priv->scu, 1); 688 break; 689 case ASPEED_CLK_GATE_MAC2CLK: 690 ast2600_configure_mac(priv->scu, 2); 691 break; 692 case ASPEED_CLK_GATE_MAC3CLK: 693 ast2600_configure_mac(priv->scu, 3); 694 break; 695 case ASPEED_CLK_GATE_MAC4CLK: 696 ast2600_configure_mac(priv->scu, 4); 697 break; 698 case ASPEED_CLK_GATE_SDCLK: 699 ast2600_enable_sdclk(priv->scu); 700 break; 701 case ASPEED_CLK_GATE_SDEXTCLK: 702 ast2600_enable_extsdclk(priv->scu); 703 break; 704 case ASPEED_CLK_GATE_EMMCCLK: 705 ast2600_enable_emmcclk(priv->scu); 706 break; 707 case ASPEED_CLK_GATE_EMMCEXTCLK: 708 ast2600_enable_extemmcclk(priv->scu); 709 break; 710 default: 711 pr_debug("can't enable clk \n"); 712 return -ENOENT; 713 break; 714 } 715 716 return 0; 717 } 718 719 struct clk_ops ast2600_clk_ops = { 720 .get_rate = ast2600_clk_get_rate, 721 .set_rate = ast2600_clk_set_rate, 722 .enable = ast2600_clk_enable, 723 }; 724 725 static int ast2600_clk_probe(struct udevice *dev) 726 { 727 struct ast2600_clk_priv *priv = dev_get_priv(dev); 728 729 priv->scu = devfdt_get_addr_ptr(dev); 730 if (IS_ERR(priv->scu)) 731 return PTR_ERR(priv->scu); 732 733 return 0; 734 } 735 736 static int ast2600_clk_bind(struct udevice *dev) 737 { 738 int ret; 739 740 /* The reset driver does not have a device node, so bind it here */ 741 ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); 742 if (ret) 743 debug("Warning: No reset driver: ret=%d\n", ret); 744 745 return 0; 746 } 747 748 #if CONFIG_IS_ENABLED(CMD_CLK) 749 struct aspeed_clks { 750 ulong id; 751 const char *name; 752 }; 753 754 static struct aspeed_clks aspeed_clk_names[] = { 755 { ASPEED_CLK_HPLL, "hpll" }, 756 { ASPEED_CLK_MPLL, "mpll" }, 757 { ASPEED_CLK_APLL, "apll" }, 758 { ASPEED_CLK_EPLL, "epll" }, 759 { ASPEED_CLK_DPLL, "dpll" }, 760 { ASPEED_CLK_AHB, "hclk" }, 761 { ASPEED_CLK_APB, "pclk" }, 762 }; 763 764 int soc_clk_dump(void) 765 { 766 struct udevice *dev; 767 struct clk clk; 768 unsigned long rate; 769 int i, ret; 770 771 ret = uclass_get_device_by_driver(UCLASS_CLK, 772 DM_GET_DRIVER(aspeed_scu), &dev); 773 if (ret) 774 return ret; 775 776 printf("Clk\t\tHz\n"); 777 778 for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { 779 clk.id = aspeed_clk_names[i].id; 780 ret = clk_request(dev, &clk); 781 if (ret < 0) { 782 debug("%s clk_request() failed: %d\n", __func__, ret); 783 continue; 784 } 785 786 ret = clk_get_rate(&clk); 787 rate = ret; 788 789 clk_free(&clk); 790 791 if (ret == -ENOTSUPP) { 792 printf("clk ID %lu not supported yet\n", 793 aspeed_clk_names[i].id); 794 continue; 795 } 796 if (ret < 0) { 797 printf("%s %lu: get_rate err: %d\n", 798 __func__, aspeed_clk_names[i].id, ret); 799 continue; 800 } 801 802 printf("%s(%3lu):\t%lu\n", 803 aspeed_clk_names[i].name, aspeed_clk_names[i].id, rate); 804 } 805 806 return 0; 807 } 808 #endif 809 810 static const struct udevice_id ast2600_clk_ids[] = { 811 { .compatible = "aspeed,ast2600-scu", }, 812 { } 813 }; 814 815 U_BOOT_DRIVER(aspeed_scu) = { 816 .name = "aspeed_scu", 817 .id = UCLASS_CLK, 818 .of_match = ast2600_clk_ids, 819 .priv_auto_alloc_size = sizeof(struct ast2600_clk_priv), 820 .ops = &ast2600_clk_ops, 821 .bind = ast2600_clk_bind, 822 .probe = ast2600_clk_probe, 823 }; 824