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