1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <bitfield.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <syscon.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_px30.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/px30-cru.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 enum { 23 VCO_MAX_HZ = 3200U * 1000000, 24 VCO_MIN_HZ = 800 * 1000000, 25 OUTPUT_MAX_HZ = 3200U * 1000000, 26 OUTPUT_MIN_HZ = 24 * 1000000, 27 }; 28 29 #define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 30 _postdiv2, _dsmpd, _frac) \ 31 { \ 32 .rate = _rate##U, \ 33 .fbdiv = _fbdiv, \ 34 .postdiv1 = _postdiv1, \ 35 .refdiv = _refdiv, \ 36 .postdiv2 = _postdiv2, \ 37 .dsmpd = _dsmpd, \ 38 .frac = _frac, \ 39 } 40 41 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 42 43 #define PX30_CLK_DUMP(_id, _name, _iscru) \ 44 { \ 45 .id = _id, \ 46 .name = _name, \ 47 .is_cru = _iscru, \ 48 } 49 50 static struct pll_rate_table px30_pll_rates[] = { 51 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 52 PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 53 PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), 54 PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), 55 PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), 56 PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 57 }; 58 59 static const struct px30_clk_info clks_dump[] = { 60 PX30_CLK_DUMP(PLL_APLL, "apll", true), 61 PX30_CLK_DUMP(PLL_DPLL, "dpll", true), 62 PX30_CLK_DUMP(PLL_CPLL, "cpll", true), 63 PX30_CLK_DUMP(PLL_NPLL, "npll", true), 64 PX30_CLK_DUMP(PLL_GPLL, "gpll", false), 65 PX30_CLK_DUMP(ACLK_BUS_PRE, "aclk_bus", true), 66 PX30_CLK_DUMP(HCLK_BUS_PRE, "hclk_bus", true), 67 PX30_CLK_DUMP(PCLK_BUS_PRE, "pclk_bus", true), 68 PX30_CLK_DUMP(ACLK_PERI_PRE, "aclk_peri", true), 69 PX30_CLK_DUMP(HCLK_PERI_PRE, "hclk_peri", true), 70 PX30_CLK_DUMP(PCLK_PMU_PRE, "pclk_pmu", false), 71 }; 72 73 static u8 pll_mode_shift[PLL_COUNT] = { 74 APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT, 75 NPLL_MODE_SHIFT, GPLL_MODE_SHIFT 76 }; 77 static u32 pll_mode_mask[PLL_COUNT] = { 78 APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK, 79 NPLL_MODE_MASK, GPLL_MODE_MASK 80 }; 81 82 static struct pll_rate_table auto_table; 83 84 static struct pll_rate_table *pll_clk_set_by_auto(u32 drate) 85 { 86 struct pll_rate_table *rate = &auto_table; 87 u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0; 88 u32 postdiv1, postdiv2 = 1; 89 u32 fref_khz; 90 u32 diff_khz, best_diff_khz; 91 const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16; 92 const u32 max_postdiv1 = 7, max_postdiv2 = 7; 93 u32 vco_khz; 94 u32 rate_khz = drate / KHz; 95 96 if (!drate) { 97 printf("%s: the frequency can't be 0 Hz\n", __func__); 98 return NULL; 99 } 100 101 postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz); 102 if (postdiv1 > max_postdiv1) { 103 postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1); 104 postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2); 105 } 106 107 vco_khz = rate_khz * postdiv1 * postdiv2; 108 109 if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) || 110 postdiv2 > max_postdiv2) { 111 printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n", 112 __func__, rate_khz); 113 return NULL; 114 } 115 116 rate->postdiv1 = postdiv1; 117 rate->postdiv2 = postdiv2; 118 119 best_diff_khz = vco_khz; 120 for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) { 121 fref_khz = ref_khz / refdiv; 122 123 fbdiv = vco_khz / fref_khz; 124 if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv)) 125 continue; 126 diff_khz = vco_khz - fbdiv * fref_khz; 127 if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) { 128 fbdiv++; 129 diff_khz = fref_khz - diff_khz; 130 } 131 132 if (diff_khz >= best_diff_khz) 133 continue; 134 135 best_diff_khz = diff_khz; 136 rate->refdiv = refdiv; 137 rate->fbdiv = fbdiv; 138 } 139 140 if (best_diff_khz > 4 * (MHz / KHz)) { 141 printf("%s: Failed to match output frequency %u bestis %u Hz\n", 142 __func__, rate_khz, 143 best_diff_khz * KHz); 144 return NULL; 145 } 146 147 return rate; 148 } 149 150 static const struct pll_rate_table *get_pll_settings(unsigned long rate) 151 { 152 unsigned int rate_count = ARRAY_SIZE(px30_pll_rates); 153 int i; 154 155 for (i = 0; i < rate_count; i++) { 156 if (rate == px30_pll_rates[i].rate) 157 return &px30_pll_rates[i]; 158 } 159 160 return pll_clk_set_by_auto(rate); 161 } 162 163 /* 164 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 165 * Formulas also embedded within the Fractional PLL Verilog model: 166 * If DSMPD = 1 (DSM is disabled, "integer mode") 167 * FOUTVCO = FREF / REFDIV * FBDIV 168 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 169 * Where: 170 * FOUTVCO = Fractional PLL non-divided output frequency 171 * FOUTPOSTDIV = Fractional PLL divided output frequency 172 * (output of second post divider) 173 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 174 * REFDIV = Fractional PLL input reference clock divider 175 * FBDIV = Integer value programmed into feedback divide 176 * 177 */ 178 static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode, 179 enum px30_pll_id pll_id, 180 unsigned long drate) 181 { 182 const struct pll_rate_table *rate; 183 uint vco_hz, output_hz; 184 185 rate = get_pll_settings(drate); 186 if (!rate) { 187 printf("%s unsupport rate\n", __func__); 188 return -EINVAL; 189 } 190 191 /* All PLLs have same VCO and output frequency range restrictions. */ 192 vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000; 193 output_hz = vco_hz / rate->postdiv1 / rate->postdiv2; 194 195 debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n", 196 pll, rate->fbdiv, rate->refdiv, rate->postdiv1, 197 rate->postdiv2, vco_hz, output_hz); 198 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && 199 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ); 200 201 /* 202 * When power on or changing PLL setting, 203 * we must force PLL into slow mode to ensure output stable clock. 204 */ 205 rk_clrsetreg(mode, pll_mode_mask[pll_id], 206 PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]); 207 208 /* use integer mode */ 209 rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT); 210 /* Power down */ 211 rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT); 212 213 rk_clrsetreg(&pll->con0, 214 PLL_POSTDIV1_MASK | PLL_FBDIV_MASK, 215 (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv); 216 rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, 217 (rate->postdiv2 << PLL_POSTDIV2_SHIFT | 218 rate->refdiv << PLL_REFDIV_SHIFT)); 219 220 /* Power Up */ 221 rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT); 222 223 /* waiting for pll lock */ 224 while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))) 225 udelay(1); 226 227 rk_clrsetreg(mode, pll_mode_mask[pll_id], 228 PLLMUX_FROM_PLL << pll_mode_shift[pll_id]); 229 230 return 0; 231 } 232 233 static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode, 234 enum px30_pll_id pll_id) 235 { 236 u32 refdiv, fbdiv, postdiv1, postdiv2; 237 u32 con, shift, mask; 238 239 con = readl(mode); 240 shift = pll_mode_shift[pll_id]; 241 mask = pll_mode_mask[pll_id]; 242 243 switch ((con & mask) >> shift) { 244 case PLLMUX_FROM_XIN24M: 245 return OSC_HZ; 246 case PLLMUX_FROM_PLL: 247 /* normal mode */ 248 con = readl(&pll->con0); 249 postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT; 250 fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 251 con = readl(&pll->con1); 252 postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT; 253 refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT; 254 return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; 255 case PLLMUX_FROM_RTC32K: 256 default: 257 return 32768; 258 } 259 } 260 261 static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id) 262 { 263 struct px30_cru *cru = priv->cru; 264 u32 div, con; 265 266 switch (clk_id) { 267 case SCLK_I2C0: 268 con = readl(&cru->clksel_con[49]); 269 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 270 break; 271 case SCLK_I2C1: 272 con = readl(&cru->clksel_con[49]); 273 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 274 break; 275 case SCLK_I2C2: 276 con = readl(&cru->clksel_con[50]); 277 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 278 break; 279 case SCLK_I2C3: 280 con = readl(&cru->clksel_con[50]); 281 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 282 break; 283 default: 284 printf("do not support this i2c bus\n"); 285 return -EINVAL; 286 } 287 288 return DIV_TO_RATE(priv->gpll_hz, div); 289 } 290 291 static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) 292 { 293 struct px30_cru *cru = priv->cru; 294 int src_clk_div; 295 296 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 297 assert(src_clk_div - 1 < 127); 298 299 switch (clk_id) { 300 case SCLK_I2C0: 301 rk_clrsetreg(&cru->clksel_con[49], 302 CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | 303 CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, 304 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 305 CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); 306 break; 307 case SCLK_I2C1: 308 rk_clrsetreg(&cru->clksel_con[49], 309 CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | 310 CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, 311 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 312 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 313 break; 314 case SCLK_I2C2: 315 rk_clrsetreg(&cru->clksel_con[50], 316 CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | 317 CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, 318 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 319 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 320 break; 321 case SCLK_I2C3: 322 rk_clrsetreg(&cru->clksel_con[50], 323 CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | 324 CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, 325 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 326 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 327 break; 328 default: 329 printf("do not support this i2c bus\n"); 330 return -EINVAL; 331 } 332 333 return px30_i2c_get_clk(priv, clk_id); 334 } 335 336 static ulong px30_nandc_get_clk(struct px30_clk_priv *priv) 337 { 338 struct px30_cru *cru = priv->cru; 339 u32 div, con; 340 341 con = readl(&cru->clksel_con[15]); 342 div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT; 343 344 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 345 } 346 347 static ulong px30_nandc_set_clk(struct px30_clk_priv *priv, 348 ulong set_rate) 349 { 350 struct px30_cru *cru = priv->cru; 351 int src_clk_div; 352 353 /* Select nandc source from GPLL by default */ 354 /* nandc clock defaulg div 2 internal, need provide double in cru */ 355 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); 356 assert(src_clk_div - 1 < 31); 357 358 rk_clrsetreg(&cru->clksel_con[15], 359 NANDC_CLK_SEL_MASK | NANDC_PLL_MASK | 360 NANDC_DIV_MASK, 361 NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT | 362 NANDC_SEL_GPLL << NANDC_PLL_SHIFT | 363 (src_clk_div - 1) << NANDC_DIV_SHIFT); 364 365 return px30_nandc_get_clk(priv); 366 } 367 368 static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id) 369 { 370 struct px30_cru *cru = priv->cru; 371 u32 div, con, con_id; 372 373 switch (clk_id) { 374 case HCLK_SDMMC: 375 case SCLK_SDMMC: 376 con_id = 16; 377 break; 378 case HCLK_EMMC: 379 case SCLK_EMMC: 380 case SCLK_EMMC_SAMPLE: 381 con_id = 20; 382 break; 383 default: 384 return -EINVAL; 385 } 386 387 con = readl(&cru->clksel_con[con_id]); 388 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 389 390 if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT 391 == EMMC_SEL_24M) 392 return DIV_TO_RATE(OSC_HZ, div) / 2; 393 else 394 return DIV_TO_RATE(priv->gpll_hz, div) / 2; 395 396 } 397 398 static ulong px30_mmc_set_clk(struct px30_clk_priv *priv, 399 ulong clk_id, ulong set_rate) 400 { 401 struct px30_cru *cru = priv->cru; 402 int src_clk_div; 403 u32 con_id; 404 405 switch (clk_id) { 406 case HCLK_SDMMC: 407 case SCLK_SDMMC: 408 con_id = 16; 409 break; 410 case HCLK_EMMC: 411 case SCLK_EMMC: 412 con_id = 20; 413 break; 414 default: 415 return -EINVAL; 416 } 417 418 /* Select clk_sdmmc/emmc source from GPLL by default */ 419 /* mmc clock defaulg div 2 internal, need provide double in cru */ 420 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); 421 422 if (src_clk_div > 127) { 423 /* use 24MHz source for 400KHz clock */ 424 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 425 rk_clrsetreg(&cru->clksel_con[con_id], 426 EMMC_PLL_MASK | EMMC_DIV_MASK, 427 EMMC_SEL_24M << EMMC_PLL_SHIFT | 428 (src_clk_div - 1) << EMMC_DIV_SHIFT); 429 } else { 430 rk_clrsetreg(&cru->clksel_con[con_id], 431 EMMC_PLL_MASK | EMMC_DIV_MASK, 432 EMMC_SEL_GPLL << EMMC_PLL_SHIFT | 433 (src_clk_div - 1) << EMMC_DIV_SHIFT); 434 } 435 rk_clrsetreg(&cru->clksel_con[con_id +1], EMMC_CLK_SEL_MASK, 436 EMMC_CLK_SEL_EMMC); 437 438 return px30_mmc_get_clk(priv, clk_id); 439 } 440 441 static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id) 442 { 443 struct px30_cru *cru = priv->cru; 444 u32 div, con; 445 446 switch (clk_id) { 447 case SCLK_PWM0: 448 con = readl(&cru->clksel_con[52]); 449 div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; 450 break; 451 case SCLK_PWM1: 452 con = readl(&cru->clksel_con[52]); 453 div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; 454 break; 455 default: 456 printf("do not support this pwm bus\n"); 457 return -EINVAL; 458 } 459 460 return DIV_TO_RATE(priv->gpll_hz, div); 461 } 462 463 static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) 464 { 465 struct px30_cru *cru = priv->cru; 466 int src_clk_div; 467 468 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 469 assert(src_clk_div - 1 < 127); 470 471 switch (clk_id) { 472 case SCLK_PWM0: 473 rk_clrsetreg(&cru->clksel_con[52], 474 CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT | 475 CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT, 476 (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT | 477 CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT); 478 break; 479 case SCLK_PWM1: 480 rk_clrsetreg(&cru->clksel_con[52], 481 CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT | 482 CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT, 483 (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT | 484 CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT); 485 break; 486 default: 487 printf("do not support this pwm bus\n"); 488 return -EINVAL; 489 } 490 491 return px30_pwm_get_clk(priv, clk_id); 492 } 493 494 static ulong px30_saradc_get_clk(struct px30_clk_priv *priv) 495 { 496 struct px30_cru *cru = priv->cru; 497 u32 div, con; 498 499 con = readl(&cru->clksel_con[55]); 500 div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; 501 502 return DIV_TO_RATE(OSC_HZ, div); 503 } 504 505 static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz) 506 { 507 struct px30_cru *cru = priv->cru; 508 int src_clk_div; 509 510 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz); 511 assert(src_clk_div - 1 < 2047); 512 513 rk_clrsetreg(&cru->clksel_con[55], 514 CLK_SARADC_DIV_CON_MASK, 515 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); 516 517 return px30_saradc_get_clk(priv); 518 } 519 520 static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id) 521 { 522 struct px30_cru *cru = priv->cru; 523 u32 div, con; 524 525 switch (clk_id) { 526 case SCLK_SPI0: 527 con = readl(&cru->clksel_con[53]); 528 div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; 529 break; 530 case SCLK_SPI1: 531 con = readl(&cru->clksel_con[53]); 532 div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; 533 break; 534 default: 535 printf("do not support this pwm bus\n"); 536 return -EINVAL; 537 } 538 539 return DIV_TO_RATE(priv->gpll_hz, div); 540 } 541 542 static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) 543 { 544 struct px30_cru *cru = priv->cru; 545 int src_clk_div; 546 547 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 548 assert(src_clk_div - 1 < 127); 549 550 switch (clk_id) { 551 case SCLK_SPI0: 552 rk_clrsetreg(&cru->clksel_con[53], 553 CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT | 554 CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT, 555 (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT | 556 CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT); 557 break; 558 case SCLK_SPI1: 559 rk_clrsetreg(&cru->clksel_con[53], 560 CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT | 561 CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT, 562 (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT | 563 CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT); 564 break; 565 default: 566 printf("do not support this pwm bus\n"); 567 return -EINVAL; 568 } 569 570 return px30_spi_get_clk(priv, clk_id); 571 } 572 573 static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id) 574 { 575 struct px30_cru *cru = priv->cru; 576 u32 div, con, parent; 577 578 switch (clk_id) { 579 case ACLK_VOPB: 580 con = readl(&cru->clksel_con[3]); 581 div = con & ACLK_VO_DIV_MASK; 582 parent = priv->gpll_hz; 583 break; 584 case DCLK_VOPB: 585 con = readl(&cru->clksel_con[5]); 586 div = con & DCLK_VOPB_DIV_MASK; 587 parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL); 588 break; 589 default: 590 return -ENOENT; 591 } 592 593 return DIV_TO_RATE(parent, div); 594 } 595 596 static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) 597 { 598 struct px30_cru *cru = priv->cru; 599 int src_clk_div; 600 601 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 602 assert(src_clk_div - 1 < 31); 603 604 switch (clk_id) { 605 case ACLK_VOPB: 606 rk_clrsetreg(&cru->clksel_con[3], 607 ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK, 608 ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT | 609 (src_clk_div - 1) << ACLK_VO_DIV_SHIFT); 610 break; 611 case DCLK_VOPB: 612 /* 613 * vopb dclk source from cpll, and equals to 614 * cpll(means div == 1) 615 */ 616 rkclk_set_pll(&cru->pll[CPLL], &cru->mode, CPLL, hz); 617 618 rk_clrsetreg(&cru->clksel_con[5], 619 DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK | 620 DCLK_VOPB_DIV_MASK, 621 DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT | 622 DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT | 623 (1 - 1) << DCLK_VOPB_DIV_SHIFT); 624 break; 625 default: 626 printf("do not support this vop freq\n"); 627 return -EINVAL; 628 } 629 630 return px30_vop_get_clk(priv, clk_id); 631 } 632 633 static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id) 634 { 635 struct px30_cru *cru = priv->cru; 636 u32 div, con, parent; 637 638 switch (clk_id) { 639 case ACLK_BUS_PRE: 640 con = readl(&cru->clksel_con[23]); 641 div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT; 642 parent = priv->gpll_hz; 643 break; 644 case HCLK_BUS_PRE: 645 con = readl(&cru->clksel_con[24]); 646 div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT; 647 parent = priv->gpll_hz; 648 break; 649 case PCLK_BUS_PRE: 650 parent = px30_bus_get_clk(priv, ACLK_BUS_PRE); 651 con = readl(&cru->clksel_con[24]); 652 div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT; 653 break; 654 default: 655 return -ENOENT; 656 } 657 658 return DIV_TO_RATE(parent, div); 659 } 660 661 static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id, 662 ulong hz) 663 { 664 struct px30_cru *cru = priv->cru; 665 int src_clk_div; 666 667 /* 668 * select gpll as pd_bus bus clock source and 669 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 670 */ 671 switch (clk_id) { 672 case ACLK_BUS_PRE: 673 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 674 assert(src_clk_div - 1 < 31); 675 rk_clrsetreg(&cru->clksel_con[23], 676 BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK, 677 BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT | 678 (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT); 679 break; 680 case HCLK_BUS_PRE: 681 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 682 assert(src_clk_div - 1 < 31); 683 rk_clrsetreg(&cru->clksel_con[24], 684 BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK, 685 BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT | 686 (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT); 687 break; 688 case PCLK_BUS_PRE: 689 src_clk_div = 690 DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz); 691 assert(src_clk_div - 1 < 3); 692 rk_clrsetreg(&cru->clksel_con[24], 693 BUS_PCLK_DIV_MASK, 694 (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT); 695 break; 696 default: 697 printf("do not support this bus freq\n"); 698 return -EINVAL; 699 } 700 701 return px30_bus_get_clk(priv, clk_id); 702 } 703 704 static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id) 705 { 706 struct px30_cru *cru = priv->cru; 707 u32 div, con, parent; 708 709 switch (clk_id) { 710 case ACLK_PERI_PRE: 711 con = readl(&cru->clksel_con[14]); 712 div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT; 713 parent = priv->gpll_hz; 714 break; 715 case HCLK_PERI_PRE: 716 con = readl(&cru->clksel_con[14]); 717 div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT; 718 parent = priv->gpll_hz; 719 break; 720 default: 721 return -ENOENT; 722 } 723 724 return DIV_TO_RATE(parent, div); 725 } 726 727 static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id, 728 ulong hz) 729 { 730 struct px30_cru *cru = priv->cru; 731 int src_clk_div; 732 733 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 734 assert(src_clk_div - 1 < 31); 735 736 /* 737 * select gpll as pd_peri bus clock source and 738 * set up dependent divisors for HCLK and ACLK clocks. 739 */ 740 switch (clk_id) { 741 case ACLK_PERI_PRE: 742 rk_clrsetreg(&cru->clksel_con[14], 743 PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK, 744 PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT | 745 (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT); 746 break; 747 case HCLK_PERI_PRE: 748 rk_clrsetreg(&cru->clksel_con[14], 749 PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK, 750 PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT | 751 (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT); 752 break; 753 default: 754 printf("do not support this peri freq\n"); 755 return -EINVAL; 756 } 757 758 return px30_peri_get_clk(priv, clk_id); 759 } 760 761 static int px30_clk_get_gpll_rate(ulong *rate) 762 { 763 struct udevice *pmucru_dev; 764 struct px30_pmuclk_priv *priv; 765 struct px30_pmucru *pmucru; 766 int ret; 767 768 ret = uclass_get_device_by_driver(UCLASS_CLK, 769 DM_GET_DRIVER(rockchip_px30_pmucru), 770 &pmucru_dev); 771 if (ret) { 772 printf("%s: could not find pmucru device\n", __func__); 773 return ret; 774 } 775 priv = dev_get_priv(pmucru_dev); 776 pmucru = priv->pmucru; 777 *rate = rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL); 778 779 return 0; 780 } 781 782 static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv, 783 enum px30_pll_id pll_id) 784 { 785 struct px30_cru *cru = priv->cru; 786 787 return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id); 788 } 789 790 static ulong px30_clk_get_rate(struct clk *clk) 791 { 792 struct px30_clk_priv *priv = dev_get_priv(clk->dev); 793 ulong rate = 0; 794 int ret; 795 796 if (!priv->gpll_hz) { 797 ret = px30_clk_get_gpll_rate(&priv->gpll_hz); 798 if (ret) { 799 printf("%s failed to get gpll rate\n", __func__); 800 return ret; 801 } 802 debug("%s gpll=%lu\n", __func__, priv->gpll_hz); 803 } 804 805 debug("%s %ld\n", __func__, clk->id); 806 switch (clk->id) { 807 case PLL_APLL: 808 rate = px30_clk_get_pll_rate(priv, APLL); 809 break; 810 case PLL_DPLL: 811 rate = px30_clk_get_pll_rate(priv, DPLL); 812 break; 813 case PLL_CPLL: 814 rate = px30_clk_get_pll_rate(priv, CPLL); 815 break; 816 case PLL_NPLL: 817 rate = px30_clk_get_pll_rate(priv, NPLL); 818 break; 819 case HCLK_SDMMC: 820 case HCLK_EMMC: 821 case SCLK_SDMMC: 822 case SCLK_EMMC: 823 case SCLK_EMMC_SAMPLE: 824 rate = px30_mmc_get_clk(priv, clk->id); 825 break; 826 case SCLK_I2C0: 827 case SCLK_I2C1: 828 case SCLK_I2C2: 829 case SCLK_I2C3: 830 rate = px30_i2c_get_clk(priv, clk->id); 831 break; 832 case SCLK_PWM0: 833 case SCLK_PWM1: 834 rate = px30_pwm_get_clk(priv, clk->id); 835 break; 836 case SCLK_SARADC: 837 rate = px30_saradc_get_clk(priv); 838 break; 839 case SCLK_SPI0: 840 case SCLK_SPI1: 841 rate = px30_spi_get_clk(priv, clk->id); 842 break; 843 case ACLK_VOPB: 844 case DCLK_VOPB: 845 rate = px30_vop_get_clk(priv, clk->id); 846 break; 847 case ACLK_BUS_PRE: 848 case HCLK_BUS_PRE: 849 case PCLK_BUS_PRE: 850 rate = px30_bus_get_clk(priv, clk->id); 851 break; 852 case ACLK_PERI_PRE: 853 case HCLK_PERI_PRE: 854 rate = px30_peri_get_clk(priv, clk->id); 855 break; 856 default: 857 return -ENOENT; 858 } 859 860 return rate; 861 } 862 863 static ulong px30_clk_set_rate(struct clk *clk, ulong rate) 864 { 865 struct px30_clk_priv *priv = dev_get_priv(clk->dev); 866 ulong ret = 0; 867 868 if (!priv->gpll_hz) { 869 ret = px30_clk_get_gpll_rate(&priv->gpll_hz); 870 if (ret) { 871 printf("%s failed to get gpll rate\n", __func__); 872 return ret; 873 } 874 debug("%s gpll=%lu\n", __func__, priv->gpll_hz); 875 } 876 877 debug("%s %ld %ld\n", __func__, clk->id, rate); 878 switch (clk->id) { 879 case 0 ... 15: 880 return 0; 881 case HCLK_SDMMC: 882 case HCLK_EMMC: 883 case SCLK_SDMMC: 884 case SCLK_EMMC: 885 ret = px30_mmc_set_clk(priv, clk->id, rate); 886 break; 887 case SCLK_I2C0: 888 case SCLK_I2C1: 889 case SCLK_I2C2: 890 case SCLK_I2C3: 891 ret = px30_i2c_set_clk(priv, clk->id, rate); 892 break; 893 case SCLK_PWM0: 894 case SCLK_PWM1: 895 ret = px30_pwm_set_clk(priv, clk->id, rate); 896 break; 897 case SCLK_SARADC: 898 ret = px30_saradc_set_clk(priv, rate); 899 break; 900 case SCLK_SPI0: 901 case SCLK_SPI1: 902 ret = px30_spi_set_clk(priv, clk->id, rate); 903 break; 904 case ACLK_VOPB: 905 case DCLK_VOPB: 906 ret = px30_vop_set_clk(priv, clk->id, rate); 907 break; 908 case ACLK_BUS_PRE: 909 case HCLK_BUS_PRE: 910 case PCLK_BUS_PRE: 911 ret = px30_bus_set_clk(priv, clk->id, rate); 912 break; 913 case ACLK_PERI_PRE: 914 case HCLK_PERI_PRE: 915 ret = px30_peri_set_clk(priv, clk->id, rate); 916 break; 917 default: 918 return -ENOENT; 919 } 920 921 return ret; 922 } 923 924 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 925 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 926 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 927 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 928 929 #define PSECS_PER_SEC 1000000000000LL 930 /* 931 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 932 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 933 */ 934 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 935 936 int rockchip_mmc_get_phase(struct clk *clk) 937 { 938 struct px30_clk_priv *priv = dev_get_priv(clk->dev); 939 struct px30_cru *cru = priv->cru; 940 u32 raw_value, delay_num; 941 u16 degrees = 0; 942 ulong rate; 943 944 rate = px30_clk_get_rate(clk); 945 946 if (rate < 0) 947 return rate; 948 949 if (clk->id == SCLK_EMMC_SAMPLE) 950 raw_value = readl(&cru->emmc_con[1]); 951 else 952 raw_value = readl(&cru->sdmmc_con[1]); 953 954 raw_value >>= 1; 955 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 956 957 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 958 /* degrees/delaynum * 10000 */ 959 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 960 36 * (rate / 1000000); 961 962 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 963 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 964 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 965 } 966 967 return degrees % 360; 968 } 969 970 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees) 971 { 972 struct px30_clk_priv *priv = dev_get_priv(clk->dev); 973 struct px30_cru *cru = priv->cru; 974 u8 nineties, remainder, delay_num; 975 u32 raw_value, delay; 976 ulong rate; 977 978 rate = px30_clk_get_rate(clk); 979 980 if (rate < 0) 981 return rate; 982 983 nineties = degrees / 90; 984 remainder = (degrees % 90); 985 986 /* 987 * Convert to delay; do a little extra work to make sure we 988 * don't overflow 32-bit / 64-bit numbers. 989 */ 990 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 991 delay *= remainder; 992 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 993 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 994 995 delay_num = (u8)min_t(u32, delay, 255); 996 997 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 998 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 999 raw_value |= nineties; 1000 1001 raw_value <<= 1; 1002 if (clk->id == SCLK_EMMC_SAMPLE) 1003 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1004 else 1005 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1006 1007 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1008 degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk)); 1009 1010 return 0; 1011 } 1012 1013 static int px30_clk_get_phase(struct clk *clk) 1014 { 1015 int ret; 1016 debug("%s %ld\n", __func__, clk->id); 1017 switch (clk->id) { 1018 case SCLK_EMMC_SAMPLE: 1019 case SCLK_SDMMC_SAMPLE: 1020 ret = rockchip_mmc_get_phase(clk); 1021 break; 1022 default: 1023 return -ENOENT; 1024 } 1025 1026 return ret; 1027 } 1028 1029 static int px30_clk_set_phase(struct clk *clk, int degrees) 1030 { 1031 int ret; 1032 1033 debug("%s %ld\n", __func__, clk->id); 1034 switch (clk->id) { 1035 case SCLK_EMMC_SAMPLE: 1036 case SCLK_SDMMC_SAMPLE: 1037 ret = rockchip_mmc_set_phase(clk, degrees); 1038 break; 1039 default: 1040 return -ENOENT; 1041 } 1042 1043 return ret; 1044 } 1045 1046 static struct clk_ops px30_clk_ops = { 1047 .get_rate = px30_clk_get_rate, 1048 .set_rate = px30_clk_set_rate, 1049 .get_phase = px30_clk_get_phase, 1050 .set_phase = px30_clk_set_phase, 1051 }; 1052 1053 static int px30_clk_probe(struct udevice *dev) 1054 { 1055 struct px30_clk_priv *priv = dev_get_priv(dev); 1056 struct px30_cru *cru = priv->cru; 1057 u32 aclk_div; 1058 1059 /* init pll */ 1060 rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, APLL_HZ); 1061 /* 1062 * select apll as cpu/core clock pll source and 1063 * set up dependent divisors for PERI and ACLK clocks. 1064 * core hz : apll = 1:1 1065 */ 1066 aclk_div = APLL_HZ / CORE_ACLK_HZ - 1; 1067 rk_clrsetreg(&cru->clksel_con[0], 1068 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK | 1069 CORE_ACLK_DIV_MASK, 1070 aclk_div << CORE_ACLK_DIV_SHIFT | 1071 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 1072 0 << CORE_DIV_CON_SHIFT); 1073 1074 return 0; 1075 } 1076 1077 static int px30_clk_ofdata_to_platdata(struct udevice *dev) 1078 { 1079 struct px30_clk_priv *priv = dev_get_priv(dev); 1080 1081 priv->cru = dev_read_addr_ptr(dev); 1082 1083 return 0; 1084 } 1085 1086 static int px30_clk_bind(struct udevice *dev) 1087 { 1088 int ret; 1089 struct udevice *sys_child, *sf_child; 1090 struct sysreset_reg *priv; 1091 struct softreset_reg *sf_priv; 1092 1093 /* The reset driver does not have a device node, so bind it here */ 1094 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1095 &sys_child); 1096 if (ret) { 1097 debug("Warning: No sysreset driver: ret=%d\n", ret); 1098 } else { 1099 priv = malloc(sizeof(struct sysreset_reg)); 1100 priv->glb_srst_fst_value = offsetof(struct px30_cru, 1101 glb_srst_fst); 1102 priv->glb_srst_snd_value = offsetof(struct px30_cru, 1103 glb_srst_snd); 1104 sys_child->priv = priv; 1105 } 1106 1107 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1108 dev_ofnode(dev), &sf_child); 1109 if (ret) { 1110 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1111 } else { 1112 sf_priv = malloc(sizeof(struct softreset_reg)); 1113 sf_priv->sf_reset_offset = offsetof(struct px30_cru, 1114 softrst_con[0]); 1115 sf_priv->sf_reset_num = 12; 1116 sf_child->priv = sf_priv; 1117 } 1118 1119 return 0; 1120 } 1121 1122 static const struct udevice_id px30_clk_ids[] = { 1123 { .compatible = "rockchip,px30-cru" }, 1124 { } 1125 }; 1126 1127 U_BOOT_DRIVER(rockchip_px30_cru) = { 1128 .name = "rockchip_px30_cru", 1129 .id = UCLASS_CLK, 1130 .of_match = px30_clk_ids, 1131 .priv_auto_alloc_size = sizeof(struct px30_clk_priv), 1132 .ofdata_to_platdata = px30_clk_ofdata_to_platdata, 1133 .ops = &px30_clk_ops, 1134 .bind = px30_clk_bind, 1135 .probe = px30_clk_probe, 1136 }; 1137 1138 static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv) 1139 { 1140 struct px30_pmucru *pmucru = priv->pmucru; 1141 u32 div, con; 1142 1143 con = readl(&pmucru->pmu_clksel_con[0]); 1144 div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT; 1145 1146 return DIV_TO_RATE(priv->gpll_hz, div); 1147 } 1148 1149 static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz) 1150 { 1151 struct px30_pmucru *pmucru = priv->pmucru; 1152 int src_clk_div; 1153 1154 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 1155 assert(src_clk_div - 1 < 31); 1156 1157 rk_clrsetreg(&pmucru->pmu_clksel_con[0], 1158 CLK_PMU_PCLK_DIV_MASK, 1159 (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT); 1160 1161 return px30_pclk_pmu_get_pmuclk(priv); 1162 } 1163 1164 static ulong px30_gpll_get_pmuclk(struct px30_pmuclk_priv *priv) 1165 { 1166 struct px30_pmucru *pmucru = priv->pmucru; 1167 1168 return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL); 1169 } 1170 1171 static ulong px30_gpll_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz) 1172 { 1173 struct udevice *cru_dev; 1174 struct px30_clk_priv *cru_priv; 1175 struct px30_pmucru *pmucru = priv->pmucru; 1176 u32 div; 1177 ulong emmc_rate, sdmmc_rate, nandc_rate; 1178 int ret; 1179 1180 priv->gpll_hz = px30_gpll_get_pmuclk(priv); 1181 1182 ret = uclass_get_device_by_name(UCLASS_CLK, 1183 "clock-controller@ff2b0000", 1184 &cru_dev); 1185 if (ret) { 1186 printf("%s failed to get cru device\n", __func__); 1187 return ret; 1188 } 1189 cru_priv = dev_get_priv(cru_dev); 1190 cru_priv->gpll_hz = priv->gpll_hz; 1191 1192 div = DIV_ROUND_UP(hz, priv->gpll_hz); 1193 1194 /* 1195 * avoid bus and peri clock rate too large, reduce rate first. 1196 * they will be assigned by clk_set_defaults. 1197 */ 1198 px30_bus_set_clk(cru_priv, ACLK_BUS_PRE, 1199 px30_bus_get_clk(cru_priv, ACLK_BUS_PRE) / div); 1200 px30_bus_set_clk(cru_priv, HCLK_BUS_PRE, 1201 px30_bus_get_clk(cru_priv, HCLK_BUS_PRE) / div); 1202 px30_bus_set_clk(cru_priv, PCLK_BUS_PRE, 1203 px30_bus_get_clk(cru_priv, PCLK_BUS_PRE) / div); 1204 px30_peri_set_clk(cru_priv, ACLK_PERI_PRE, 1205 px30_bus_get_clk(cru_priv, ACLK_PERI_PRE) / div); 1206 px30_peri_set_clk(cru_priv, HCLK_PERI_PRE, 1207 px30_bus_get_clk(cru_priv, HCLK_PERI_PRE) / div); 1208 px30_pclk_pmu_set_pmuclk(priv, px30_pclk_pmu_get_pmuclk(priv) / div); 1209 1210 /* 1211 * save emmc, sdmmc and nandc clock rate, 1212 * nandc clock rate should less than or equal to 150Mhz. 1213 */ 1214 emmc_rate = px30_mmc_get_clk(cru_priv, SCLK_EMMC); 1215 sdmmc_rate = px30_mmc_get_clk(cru_priv, SCLK_SDMMC); 1216 nandc_rate = px30_nandc_get_clk(cru_priv); 1217 debug("%s emmc=%lu, sdmmc=%lu, nandc=%lu\n", __func__, emmc_rate, 1218 sdmmc_rate, nandc_rate); 1219 1220 rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz); 1221 priv->gpll_hz = px30_gpll_get_pmuclk(priv); 1222 cru_priv->gpll_hz = priv->gpll_hz; 1223 1224 /* restore emmc, sdmmc and nandc clock rate */ 1225 px30_mmc_set_clk(cru_priv, SCLK_EMMC, emmc_rate); 1226 px30_mmc_set_clk(cru_priv, SCLK_SDMMC, sdmmc_rate); 1227 px30_nandc_set_clk(cru_priv, nandc_rate); 1228 1229 return priv->gpll_hz; 1230 } 1231 1232 static ulong px30_pmuclk_get_rate(struct clk *clk) 1233 { 1234 struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev); 1235 ulong rate = 0; 1236 1237 debug("%s %ld\n", __func__, clk->id); 1238 switch (clk->id) { 1239 case PLL_GPLL: 1240 rate = px30_gpll_get_pmuclk(priv); 1241 break; 1242 case PCLK_PMU_PRE: 1243 rate = px30_pclk_pmu_get_pmuclk(priv); 1244 break; 1245 default: 1246 return -ENOENT; 1247 } 1248 1249 return rate; 1250 } 1251 1252 static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate) 1253 { 1254 struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev); 1255 ulong ret = 0; 1256 1257 debug("%s %ld %ld\n", __func__, clk->id, rate); 1258 switch (clk->id) { 1259 case PLL_GPLL: 1260 ret = px30_gpll_set_pmuclk(priv, rate); 1261 break; 1262 case PCLK_PMU_PRE: 1263 ret = px30_pclk_pmu_set_pmuclk(priv, rate); 1264 break; 1265 default: 1266 return -ENOENT; 1267 } 1268 1269 return ret; 1270 } 1271 1272 static struct clk_ops px30_pmuclk_ops = { 1273 .get_rate = px30_pmuclk_get_rate, 1274 .set_rate = px30_pmuclk_set_rate, 1275 }; 1276 1277 static int px30_pmuclk_probe(struct udevice *dev) 1278 { 1279 return 0; 1280 } 1281 1282 static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev) 1283 { 1284 struct px30_pmuclk_priv *priv = dev_get_priv(dev); 1285 1286 priv->pmucru = dev_read_addr_ptr(dev); 1287 1288 return 0; 1289 } 1290 1291 static const struct udevice_id px30_pmuclk_ids[] = { 1292 { .compatible = "rockchip,px30-pmucru" }, 1293 { } 1294 }; 1295 1296 U_BOOT_DRIVER(rockchip_px30_pmucru) = { 1297 .name = "rockchip_px30_pmucru", 1298 .id = UCLASS_CLK, 1299 .of_match = px30_pmuclk_ids, 1300 .priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv), 1301 .ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata, 1302 .ops = &px30_pmuclk_ops, 1303 .probe = px30_pmuclk_probe, 1304 }; 1305 1306 /** 1307 * soc_clk_dump() - Print clock frequencies 1308 * Returns zero on success 1309 * 1310 * Implementation for the clk dump command. 1311 */ 1312 int soc_clk_dump(void) 1313 { 1314 struct udevice *cru_dev, *pmucru_dev; 1315 const struct px30_clk_info *clk_dump; 1316 struct clk clk; 1317 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1318 unsigned long rate; 1319 int i, ret; 1320 1321 ret = uclass_get_device_by_driver(UCLASS_CLK, 1322 DM_GET_DRIVER(rockchip_px30_cru), 1323 &cru_dev); 1324 if (ret) { 1325 printf("%s failed to get cru device\n", __func__); 1326 return ret; 1327 } 1328 1329 ret = uclass_get_device_by_driver(UCLASS_CLK, 1330 DM_GET_DRIVER(rockchip_px30_pmucru), 1331 &pmucru_dev); 1332 if (ret) { 1333 printf("%s failed to get pmucru device\n", __func__); 1334 return ret; 1335 } 1336 1337 printf("CLK:"); 1338 for (i = 0; i < clk_count; i++) { 1339 clk_dump = &clks_dump[i]; 1340 if (clk_dump->name) { 1341 clk.id = clk_dump->id; 1342 if (clk_dump->is_cru) 1343 ret = clk_request(cru_dev, &clk); 1344 else 1345 ret = clk_request(pmucru_dev, &clk); 1346 if (ret < 0) 1347 return ret; 1348 1349 rate = clk_get_rate(&clk); 1350 clk_free(&clk); 1351 if (i == 0) { 1352 if (rate < 0) 1353 printf("%10s%20s\n", clk_dump->name, 1354 "unknown"); 1355 else 1356 printf("%10s%20lu Hz\n", clk_dump->name, 1357 rate); 1358 } else { 1359 if (rate < 0) 1360 printf("%14s%20s\n", clk_dump->name, 1361 "unknown"); 1362 else 1363 printf("%14s%20lu Hz\n", clk_dump->name, 1364 rate); 1365 } 1366 } 1367 } 1368 1369 return 0; 1370 } 1371