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