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