1 /* 2 * (C) Copyright 2015 Google, Inc 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 <dt-structs.h> 12 #include <errno.h> 13 #include <mapmem.h> 14 #include <syscon.h> 15 #include <asm/io.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/cru_rk3288.h> 18 #include <asm/arch/grf_rk3288.h> 19 #include <asm/arch/hardware.h> 20 #include <dt-bindings/clock/rk3288-cru.h> 21 #include <dm/device-internal.h> 22 #include <dm/lists.h> 23 #include <dm/uclass-internal.h> 24 #include <linux/log2.h> 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 struct rk3288_clk_plat { 29 #if CONFIG_IS_ENABLED(OF_PLATDATA) 30 struct dtd_rockchip_rk3288_cru dtd; 31 #endif 32 }; 33 34 struct pll_div { 35 u32 nr; 36 u32 nf; 37 u32 no; 38 }; 39 40 #ifndef CONFIG_SPL_BUILD 41 #define RK3288_CLK_DUMP(_id, _name, _iscru) \ 42 { \ 43 .id = _id, \ 44 .name = _name, \ 45 .is_cru = _iscru, \ 46 } 47 48 static const struct rk3288_clk_info clks_dump[] = { 49 RK3288_CLK_DUMP(PLL_APLL, "apll", true), 50 RK3288_CLK_DUMP(PLL_DPLL, "dpll", true), 51 RK3288_CLK_DUMP(PLL_CPLL, "cpll", true), 52 RK3288_CLK_DUMP(PLL_GPLL, "gpll", true), 53 RK3288_CLK_DUMP(PLL_NPLL, "npll", true), 54 RK3288_CLK_DUMP(ACLK_CPU, "aclk_bus", true), 55 }; 56 #endif 57 58 enum { 59 VCO_MAX_HZ = 2200U * 1000000, 60 VCO_MIN_HZ = 440 * 1000000, 61 OUTPUT_MAX_HZ = 2200U * 1000000, 62 OUTPUT_MIN_HZ = 27500000, 63 FREF_MAX_HZ = 2200U * 1000000, 64 FREF_MIN_HZ = 269 * 1000, 65 }; 66 67 enum { 68 /* PLL CON0 */ 69 PLL_OD_MASK = 0x0f, 70 71 /* PLL CON1 */ 72 PLL_NF_MASK = 0x1fff, 73 74 /* PLL CON2 */ 75 PLL_BWADJ_MASK = 0x0fff, 76 77 /* PLL CON3 */ 78 PLL_RESET_SHIFT = 5, 79 80 /* CLKSEL0 */ 81 CORE_SEL_PLL_SHIFT = 15, 82 CORE_SEL_PLL_MASK = 1 << CORE_SEL_PLL_SHIFT, 83 A17_DIV_SHIFT = 8, 84 A17_DIV_MASK = 0x1f << A17_DIV_SHIFT, 85 MP_DIV_SHIFT = 4, 86 MP_DIV_MASK = 0xf << MP_DIV_SHIFT, 87 M0_DIV_SHIFT = 0, 88 M0_DIV_MASK = 0xf << M0_DIV_SHIFT, 89 90 /* CLKSEL1: pd bus clk pll sel: codec or general */ 91 PD_BUS_SEL_PLL_MASK = 15, 92 PD_BUS_SEL_CPLL = 0, 93 PD_BUS_SEL_GPLL, 94 95 /* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */ 96 PD_BUS_PCLK_DIV_SHIFT = 12, 97 PD_BUS_PCLK_DIV_MASK = 7 << PD_BUS_PCLK_DIV_SHIFT, 98 99 /* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */ 100 PD_BUS_HCLK_DIV_SHIFT = 8, 101 PD_BUS_HCLK_DIV_MASK = 3 << PD_BUS_HCLK_DIV_SHIFT, 102 103 /* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */ 104 PD_BUS_ACLK_DIV0_SHIFT = 3, 105 PD_BUS_ACLK_DIV0_MASK = 0x1f << PD_BUS_ACLK_DIV0_SHIFT, 106 PD_BUS_ACLK_DIV1_SHIFT = 0, 107 PD_BUS_ACLK_DIV1_MASK = 0x7 << PD_BUS_ACLK_DIV1_SHIFT, 108 109 /* CLKSEL2: tsadc */ 110 CLK_TSADC_DIV_CON_SHIFT = 0, 111 CLK_TSADC_DIV_CON_MASK = GENMASK(5, 0), 112 CLK_TSADC_DIV_CON_WIDTH = 6, 113 114 /* 115 * CLKSEL10 116 * peripheral bus pclk div: 117 * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1 118 */ 119 PERI_SEL_PLL_SHIFT = 15, 120 PERI_SEL_PLL_MASK = 1 << PERI_SEL_PLL_SHIFT, 121 PERI_SEL_CPLL = 0, 122 PERI_SEL_GPLL, 123 124 PERI_PCLK_DIV_SHIFT = 12, 125 PERI_PCLK_DIV_MASK = 3 << PERI_PCLK_DIV_SHIFT, 126 127 /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */ 128 PERI_HCLK_DIV_SHIFT = 8, 129 PERI_HCLK_DIV_MASK = 3 << PERI_HCLK_DIV_SHIFT, 130 131 /* 132 * peripheral bus aclk div: 133 * aclk_periph = periph_clk_src / (peri_aclk_div_con + 1) 134 */ 135 PERI_ACLK_DIV_SHIFT = 0, 136 PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT, 137 138 /* 139 * CLKSEL24 140 * saradc_div_con: 141 * clk_saradc=24MHz/(saradc_div_con+1) 142 */ 143 CLK_SARADC_DIV_CON_SHIFT = 8, 144 CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8), 145 CLK_SARADC_DIV_CON_WIDTH = 8, 146 147 /* CLKSEL26 */ 148 CLK_CRYPTO_DIV_CON_SHIFT = 6, 149 CLK_CRYPTO_DIV_CON_MASK = GENMASK(7, 6), 150 151 /* CLKSEL33 */ 152 PCLK_ALIVE_DIV_CON_SHIFT = 8, 153 PCLK_ALIVE_DIV_CON_MASK = 0x1f << PCLK_ALIVE_DIV_CON_SHIFT, 154 155 SOCSTS_DPLL_LOCK = 1 << 5, 156 SOCSTS_APLL_LOCK = 1 << 6, 157 SOCSTS_CPLL_LOCK = 1 << 7, 158 SOCSTS_GPLL_LOCK = 1 << 8, 159 SOCSTS_NPLL_LOCK = 1 << 9, 160 }; 161 162 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 163 164 #define PLL_DIVISORS(hz, _nr, _no) {\ 165 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\ 166 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\ 167 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\ 168 "divisors on line " __stringify(__LINE__)); 169 170 /* Keep divisors as low as possible to reduce jitter and power usage */ 171 static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1); 172 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 4); 173 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2); 174 175 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, 176 const struct pll_div *div) 177 { 178 int pll_id = rk_pll_id(clk_id); 179 struct rk3288_pll *pll = &cru->pll[pll_id]; 180 /* All PLLs have same VCO and output frequency range restrictions. */ 181 uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000; 182 uint output_hz = vco_hz / div->no; 183 184 debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", 185 (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz); 186 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && 187 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ && 188 (div->no == 1 || !(div->no % 2))); 189 190 /* enter reset */ 191 rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT); 192 193 rk_clrsetreg(&pll->con0, CLKR_MASK | PLL_OD_MASK, 194 ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1)); 195 rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1); 196 197 /* adjust gpll bw for better clock jitter */ 198 if (pll_id == 3) 199 rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, 0); 200 else 201 rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1); 202 203 udelay(10); 204 205 /* return from reset */ 206 rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT); 207 208 return 0; 209 } 210 211 /* Get pll rate by id */ 212 static u32 rkclk_pll_get_rate(struct rk3288_cru *cru, 213 enum rk_clk_id clk_id) 214 { 215 u32 nr, no, nf; 216 u32 con; 217 int pll_id = rk_pll_id(clk_id); 218 struct rk3288_pll *pll = &cru->pll[pll_id]; 219 static u8 clk_shift[CLK_COUNT] = { 220 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT, 221 GPLL_MODE_SHIFT, NPLL_MODE_SHIFT 222 }; 223 uint shift; 224 225 con = readl(&cru->cru_mode_con); 226 shift = clk_shift[clk_id]; 227 switch ((con >> shift) & CRU_MODE_MASK) { 228 case APLL_MODE_SLOW: 229 return OSC_HZ; 230 case APLL_MODE_NORMAL: 231 /* normal mode */ 232 con = readl(&pll->con0); 233 no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1; 234 nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1; 235 con = readl(&pll->con1); 236 nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1; 237 238 return (24 * nf / (nr * no)) * 1000000; 239 case APLL_MODE_DEEP: 240 default: 241 return 32768; 242 } 243 } 244 245 static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, 246 unsigned int hz) 247 { 248 static const struct pll_div dpll_cfg[] = { 249 {.nf = 25, .nr = 2, .no = 1}, 250 {.nf = 400, .nr = 9, .no = 2}, 251 {.nf = 500, .nr = 9, .no = 2}, 252 {.nf = 100, .nr = 3, .no = 1}, 253 }; 254 int cfg; 255 256 switch (hz) { 257 case 300000000: 258 cfg = 0; 259 break; 260 case 533000000: /* actually 533.3P MHz */ 261 cfg = 1; 262 break; 263 case 666000000: /* actually 666.6P MHz */ 264 cfg = 2; 265 break; 266 case 800000000: 267 cfg = 3; 268 break; 269 default: 270 debug("Unsupported SDRAM frequency"); 271 return -EINVAL; 272 } 273 274 /* pll enter slow-mode */ 275 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, 276 DPLL_MODE_SLOW << DPLL_MODE_SHIFT); 277 278 rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]); 279 280 /* wait for pll lock */ 281 while (!(readl(&grf->soc_status[1]) & SOCSTS_DPLL_LOCK)) 282 udelay(1); 283 284 /* PLL enter normal-mode */ 285 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, 286 DPLL_MODE_NORMAL << DPLL_MODE_SHIFT); 287 288 return 0; 289 } 290 291 #ifndef CONFIG_SPL_BUILD 292 #define VCO_MAX_KHZ 2200000 293 #define VCO_MIN_KHZ 440000 294 #define FREF_MAX_KHZ 2200000 295 #define FREF_MIN_KHZ 269 296 #define PLL_LIMIT_FREQ 600000000 297 298 static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div) 299 { 300 uint ref_khz = OSC_HZ / 1000, nr, nf = 0; 301 uint fref_khz; 302 uint diff_khz, best_diff_khz; 303 const uint max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4; 304 uint vco_khz; 305 uint no = 1; 306 uint freq_khz = freq_hz / 1000; 307 308 if (!freq_hz) { 309 printf("%s: the frequency can not be 0 Hz\n", __func__); 310 return -EINVAL; 311 } 312 313 no = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz); 314 if (ext_div) { 315 *ext_div = DIV_ROUND_UP(PLL_LIMIT_FREQ, freq_hz); 316 no = DIV_ROUND_UP(no, *ext_div); 317 } 318 319 /* only even divisors (and 1) are supported */ 320 if (no > 1) 321 no = DIV_ROUND_UP(no, 2) * 2; 322 323 vco_khz = freq_khz * no; 324 if (ext_div) 325 vco_khz *= *ext_div; 326 327 if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) { 328 printf("%s: Cannot find out a supported VCO for Frequency (%luHz).\n", 329 __func__, freq_hz); 330 return -1; 331 } 332 333 div->no = no; 334 335 best_diff_khz = vco_khz; 336 for (nr = 1; nr < max_nr && best_diff_khz; nr++) { 337 fref_khz = ref_khz / nr; 338 if (fref_khz < FREF_MIN_KHZ) 339 break; 340 if (fref_khz > FREF_MAX_KHZ) 341 continue; 342 343 nf = vco_khz / fref_khz; 344 if (nf >= max_nf) 345 continue; 346 diff_khz = vco_khz - nf * fref_khz; 347 if (nf + 1 < max_nf && diff_khz > fref_khz / 2) { 348 nf++; 349 diff_khz = fref_khz - diff_khz; 350 } 351 352 if (diff_khz >= best_diff_khz) 353 continue; 354 355 best_diff_khz = diff_khz; 356 div->nr = nr; 357 div->nf = nf; 358 } 359 360 if (best_diff_khz > 4 * 1000) { 361 printf("%s: Failed to match output frequency %lu, difference is %u Hz, exceed 4MHZ\n", 362 __func__, freq_hz, best_diff_khz * 1000); 363 return -EINVAL; 364 } 365 366 return 0; 367 } 368 369 static int rockchip_mac_set_clk(struct rk3288_cru *cru, uint freq) 370 { 371 ulong ret; 372 373 /* 374 * The gmac clock can be derived either from an external clock 375 * or can be generated from internally by a divider from SCLK_MAC. 376 */ 377 if (readl(&cru->cru_clksel_con[21]) & RMII_EXTCLK_MASK) { 378 /* An external clock will always generate the right rate... */ 379 ret = freq; 380 } else { 381 u32 con = readl(&cru->cru_clksel_con[21]); 382 ulong pll_rate; 383 u8 div; 384 385 if (((con >> EMAC_PLL_SHIFT) & EMAC_PLL_MASK) == 386 EMAC_PLL_SELECT_GENERAL) 387 pll_rate = GPLL_HZ; 388 else if (((con >> EMAC_PLL_SHIFT) & EMAC_PLL_MASK) == 389 EMAC_PLL_SELECT_CODEC) 390 pll_rate = CPLL_HZ; 391 else 392 pll_rate = NPLL_HZ; 393 394 div = DIV_ROUND_UP(pll_rate, freq) - 1; 395 if (div <= 0x1f) 396 rk_clrsetreg(&cru->cru_clksel_con[21], MAC_DIV_CON_MASK, 397 div << MAC_DIV_CON_SHIFT); 398 else 399 debug("Unsupported div for gmac:%d\n", div); 400 401 return DIV_TO_RATE(pll_rate, div); 402 } 403 404 return ret; 405 } 406 407 static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf, 408 int periph, unsigned int rate_hz) 409 { 410 struct pll_div cpll_config = {0}; 411 u32 lcdc_div, parent; 412 int ret; 413 unsigned int gpll_rate, npll_rate; 414 415 gpll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); 416 npll_rate = rkclk_pll_get_rate(cru, CLK_NEW); 417 418 /* vop dclk source clk: cpll,dclk_div: 1 */ 419 switch (periph) { 420 case DCLK_VOP0: 421 ret = (readl(&cru->cru_clksel_con[27]) & DCLK_VOP0_PLL_MASK) >> 422 DCLK_VOP0_PLL_SHIFT; 423 if (ret == DCLK_VOP0_SELECT_CPLL) { 424 ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div); 425 if (ret) 426 return ret; 427 428 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK, 429 CPLL_MODE_SLOW << CPLL_MODE_SHIFT); 430 rkclk_set_pll(cru, CLK_CODEC, &cpll_config); 431 432 /* waiting for pll lock */ 433 while (1) { 434 if (readl(&grf->soc_status[1]) & 435 SOCSTS_CPLL_LOCK) 436 break; 437 udelay(1); 438 } 439 440 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK, 441 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT); 442 parent = DCLK_VOP0_SELECT_CPLL; 443 } else if (ret == DCLK_VOP0_SELECT_GPLL) { 444 parent = DCLK_VOP0_SELECT_GPLL; 445 lcdc_div = DIV_ROUND_UP(gpll_rate, 446 rate_hz); 447 } else { 448 parent = DCLK_VOP0_SELECT_NPLL; 449 lcdc_div = DIV_ROUND_UP(npll_rate, 450 rate_hz); 451 } 452 rk_clrsetreg(&cru->cru_clksel_con[27], 453 DCLK_VOP0_DIV_MASK | DCLK_VOP0_PLL_MASK, 454 ((lcdc_div - 1) << DCLK_VOP0_DIV_SHIFT) | 455 (parent << DCLK_VOP0_PLL_SHIFT)); 456 break; 457 case DCLK_VOP1: 458 ret = (readl(&cru->cru_clksel_con[29]) & DCLK_VOP1_PLL_MASK) >> 459 DCLK_VOP1_PLL_SHIFT; 460 if (ret == DCLK_VOP1_SELECT_CPLL) { 461 ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div); 462 if (ret) 463 return ret; 464 465 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK, 466 CPLL_MODE_SLOW << CPLL_MODE_SHIFT); 467 rkclk_set_pll(cru, CLK_CODEC, &cpll_config); 468 469 /* waiting for pll lock */ 470 while (1) { 471 if (readl(&grf->soc_status[1]) & 472 SOCSTS_CPLL_LOCK) 473 break; 474 udelay(1); 475 } 476 477 rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK, 478 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT); 479 480 parent = DCLK_VOP1_SELECT_CPLL; 481 } else if (ret == DCLK_VOP1_SELECT_GPLL) { 482 parent = DCLK_VOP1_SELECT_GPLL; 483 lcdc_div = DIV_ROUND_UP(gpll_rate, 484 rate_hz); 485 } else { 486 parent = DCLK_VOP1_SELECT_NPLL; 487 lcdc_div = DIV_ROUND_UP(npll_rate, 488 rate_hz); 489 } 490 rk_clrsetreg(&cru->cru_clksel_con[29], 491 DCLK_VOP1_DIV_MASK | DCLK_VOP1_PLL_MASK, 492 ((lcdc_div - 1) << DCLK_VOP1_DIV_SHIFT) | 493 (parent << DCLK_VOP1_PLL_SHIFT)); 494 break; 495 case ACLK_VIO0: 496 lcdc_div = DIV_ROUND_UP(gpll_rate, rate_hz); 497 rk_clrsetreg(&cru->cru_clksel_con[31], 498 ACLK_VIO0_PLL_MASK | ACLK_VIO0_DIV_MASK, 499 ACLK_VIO_SELECT_GPLL << ACLK_VIO0_PLL_SHIFT | 500 (lcdc_div - 1) << ACLK_VIO0_DIV_SHIFT); 501 break; 502 case ACLK_VIO1: 503 lcdc_div = DIV_ROUND_UP(gpll_rate, rate_hz); 504 rk_clrsetreg(&cru->cru_clksel_con[31], 505 ACLK_VIO1_PLL_MASK | ACLK_VIO1_DIV_MASK, 506 ACLK_VIO_SELECT_GPLL << ACLK_VIO1_PLL_SHIFT | 507 (lcdc_div - 1) << ACLK_VIO1_DIV_SHIFT); 508 509 lcdc_div = DIV_ROUND_UP(rate_hz, HCLK_VIO_HZ); 510 rk_clrsetreg(&cru->cru_clksel_con[28], 511 HCLK_VIO_DIV_MASK, 512 (lcdc_div - 1) << HCLK_VIO_DIV_SHIFT); 513 break; 514 } 515 516 return 0; 517 } 518 #endif /* CONFIG_SPL_BUILD */ 519 520 static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) 521 { 522 u32 aclk_div; 523 u32 hclk_div; 524 u32 pclk_div; 525 526 /* pll enter slow-mode */ 527 rk_clrsetreg(&cru->cru_mode_con, 528 GPLL_MODE_MASK | CPLL_MODE_MASK, 529 GPLL_MODE_SLOW << GPLL_MODE_SHIFT | 530 CPLL_MODE_SLOW << CPLL_MODE_SHIFT); 531 532 /* init pll */ 533 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); 534 rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); 535 536 /* waiting for pll lock */ 537 while ((readl(&grf->soc_status[1]) & 538 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) != 539 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) 540 udelay(1); 541 542 /* 543 * pd_bus clock pll source selection and 544 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 545 */ 546 aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1; 547 assert((aclk_div + 1) * PD_BUS_ACLK_HZ <= GPLL_HZ && aclk_div <= 0x1f); 548 hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1; 549 assert((hclk_div + 1) * PD_BUS_HCLK_HZ <= 550 PD_BUS_ACLK_HZ && (hclk_div <= 0x3) && (hclk_div != 0x2)); 551 552 pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1; 553 assert((pclk_div + 1) * PD_BUS_PCLK_HZ <= 554 PD_BUS_ACLK_HZ && pclk_div <= 0x7); 555 556 rk_clrsetreg(&cru->cru_clksel_con[1], 557 PD_BUS_PCLK_DIV_MASK | PD_BUS_HCLK_DIV_MASK | 558 PD_BUS_ACLK_DIV0_MASK | PD_BUS_ACLK_DIV1_MASK, 559 pclk_div << PD_BUS_PCLK_DIV_SHIFT | 560 hclk_div << PD_BUS_HCLK_DIV_SHIFT | 561 aclk_div << PD_BUS_ACLK_DIV0_SHIFT | 562 0 << 0); 563 564 /* 565 * peri clock pll source selection and 566 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 567 */ 568 aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1; 569 assert((aclk_div + 1) * PERI_ACLK_HZ <= GPLL_HZ && aclk_div <= 0x1f); 570 571 hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ); 572 assert((1 << hclk_div) * PERI_HCLK_HZ <= 573 PERI_ACLK_HZ && (hclk_div <= 0x2)); 574 575 pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ); 576 assert((1 << pclk_div) * PERI_PCLK_HZ <= 577 PERI_ACLK_HZ && (pclk_div <= 0x3)); 578 579 rk_clrsetreg(&cru->cru_clksel_con[10], 580 PERI_PCLK_DIV_MASK | PERI_HCLK_DIV_MASK | 581 PERI_ACLK_DIV_MASK, 582 PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT | 583 pclk_div << PERI_PCLK_DIV_SHIFT | 584 hclk_div << PERI_HCLK_DIV_SHIFT | 585 aclk_div << PERI_ACLK_DIV_SHIFT); 586 587 /* PLL enter normal-mode */ 588 rk_clrsetreg(&cru->cru_mode_con, 589 GPLL_MODE_MASK | CPLL_MODE_MASK, 590 GPLL_MODE_NORMAL << GPLL_MODE_SHIFT | 591 CPLL_MODE_NORMAL << CPLL_MODE_SHIFT); 592 } 593 594 void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf) 595 { 596 /* pll enter slow-mode */ 597 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, 598 APLL_MODE_SLOW << APLL_MODE_SHIFT); 599 600 rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); 601 602 /* waiting for pll lock */ 603 while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK)) 604 udelay(1); 605 606 /* 607 * core clock pll source selection and 608 * set up dependent divisors for MPAXI/M0AXI and ARM clocks. 609 * core clock select apll, apll clk = 1800MHz 610 * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz 611 */ 612 rk_clrsetreg(&cru->cru_clksel_con[0], 613 CORE_SEL_PLL_MASK | A17_DIV_MASK | MP_DIV_MASK | 614 M0_DIV_MASK, 615 0 << A17_DIV_SHIFT | 616 3 << MP_DIV_SHIFT | 617 1 << M0_DIV_SHIFT); 618 619 /* 620 * set up dependent divisors for L2RAM/ATCLK and PCLK clocks. 621 * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz 622 */ 623 rk_clrsetreg(&cru->cru_clksel_con[37], 624 CLK_L2RAM_DIV_MASK | ATCLK_CORE_DIV_CON_MASK | 625 PCLK_CORE_DBG_DIV_MASK, 626 1 << CLK_L2RAM_DIV_SHIFT | 627 3 << ATCLK_CORE_DIV_CON_SHIFT | 628 3 << PCLK_CORE_DBG_DIV_SHIFT); 629 630 /* PLL enter normal-mode */ 631 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, 632 APLL_MODE_NORMAL << APLL_MODE_SHIFT); 633 } 634 635 static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate, 636 int periph) 637 { 638 uint src_rate; 639 uint div, mux; 640 u32 con; 641 642 switch (periph) { 643 case HCLK_EMMC: 644 case SCLK_EMMC: 645 case SCLK_EMMC_SAMPLE: 646 con = readl(&cru->cru_clksel_con[12]); 647 mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT; 648 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 649 break; 650 case HCLK_SDMMC: 651 case SCLK_SDMMC: 652 con = readl(&cru->cru_clksel_con[11]); 653 mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT; 654 div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT; 655 break; 656 case HCLK_SDIO0: 657 case SCLK_SDIO0: 658 con = readl(&cru->cru_clksel_con[12]); 659 mux = (con & SDIO0_PLL_MASK) >> SDIO0_PLL_SHIFT; 660 div = (con & SDIO0_DIV_MASK) >> SDIO0_DIV_SHIFT; 661 break; 662 default: 663 return -EINVAL; 664 } 665 666 src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : gclk_rate; 667 return DIV_TO_RATE(src_rate, div) / 2; 668 } 669 670 static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate, 671 int periph, uint freq) 672 { 673 int src_clk_div; 674 int mux; 675 676 debug("%s: gclk_rate=%u\n", __func__, gclk_rate); 677 /* mmc clock default div 2 internal, need provide double in cru */ 678 src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq); 679 680 if (src_clk_div > 0x3f) { 681 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq); 682 assert(src_clk_div < 0x40); 683 mux = EMMC_PLL_SELECT_24MHZ; 684 assert((int)EMMC_PLL_SELECT_24MHZ == 685 (int)MMC0_PLL_SELECT_24MHZ); 686 } else { 687 mux = EMMC_PLL_SELECT_GENERAL; 688 assert((int)EMMC_PLL_SELECT_GENERAL == 689 (int)MMC0_PLL_SELECT_GENERAL); 690 } 691 switch (periph) { 692 case HCLK_EMMC: 693 case SCLK_EMMC: 694 rk_clrsetreg(&cru->cru_clksel_con[12], 695 EMMC_PLL_MASK | EMMC_DIV_MASK, 696 mux << EMMC_PLL_SHIFT | 697 (src_clk_div - 1) << EMMC_DIV_SHIFT); 698 break; 699 case HCLK_SDMMC: 700 case SCLK_SDMMC: 701 rk_clrsetreg(&cru->cru_clksel_con[11], 702 MMC0_PLL_MASK | MMC0_DIV_MASK, 703 mux << MMC0_PLL_SHIFT | 704 (src_clk_div - 1) << MMC0_DIV_SHIFT); 705 break; 706 case HCLK_SDIO0: 707 case SCLK_SDIO0: 708 rk_clrsetreg(&cru->cru_clksel_con[12], 709 SDIO0_PLL_MASK | SDIO0_DIV_MASK, 710 mux << SDIO0_PLL_SHIFT | 711 (src_clk_div - 1) << SDIO0_DIV_SHIFT); 712 break; 713 default: 714 return -EINVAL; 715 } 716 717 return rockchip_mmc_get_clk(cru, gclk_rate, periph); 718 } 719 720 static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate, 721 int periph) 722 { 723 uint div, mux; 724 u32 con; 725 726 switch (periph) { 727 case SCLK_SPI0: 728 con = readl(&cru->cru_clksel_con[25]); 729 mux = (con & SPI0_PLL_MASK) >> SPI0_PLL_SHIFT; 730 div = (con & SPI0_DIV_MASK) >> SPI0_DIV_SHIFT; 731 break; 732 case SCLK_SPI1: 733 con = readl(&cru->cru_clksel_con[25]); 734 mux = (con & SPI1_PLL_MASK) >> SPI1_PLL_SHIFT; 735 div = (con & SPI1_DIV_MASK) >> SPI1_DIV_SHIFT; 736 break; 737 case SCLK_SPI2: 738 con = readl(&cru->cru_clksel_con[39]); 739 mux = (con & SPI2_PLL_MASK) >> SPI2_PLL_SHIFT; 740 div = (con & SPI2_DIV_MASK) >> SPI2_DIV_SHIFT; 741 break; 742 default: 743 return -EINVAL; 744 } 745 assert(mux == SPI0_PLL_SELECT_GENERAL); 746 747 return DIV_TO_RATE(gclk_rate, div); 748 } 749 750 static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate, 751 int periph, uint freq) 752 { 753 int src_clk_div; 754 755 debug("%s: clk_general_rate=%u\n", __func__, gclk_rate); 756 src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1; 757 assert(src_clk_div < 128); 758 switch (periph) { 759 case SCLK_SPI0: 760 rk_clrsetreg(&cru->cru_clksel_con[25], 761 SPI0_PLL_MASK | SPI0_DIV_MASK, 762 SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT | 763 src_clk_div << SPI0_DIV_SHIFT); 764 break; 765 case SCLK_SPI1: 766 rk_clrsetreg(&cru->cru_clksel_con[25], 767 SPI1_PLL_MASK | SPI1_DIV_MASK, 768 SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT | 769 src_clk_div << SPI1_DIV_SHIFT); 770 break; 771 case SCLK_SPI2: 772 rk_clrsetreg(&cru->cru_clksel_con[39], 773 SPI2_PLL_MASK | SPI2_DIV_MASK, 774 SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT | 775 src_clk_div << SPI2_DIV_SHIFT); 776 break; 777 default: 778 return -EINVAL; 779 } 780 781 return rockchip_spi_get_clk(cru, gclk_rate, periph); 782 } 783 784 static ulong rockchip_saradc_get_clk(struct rk3288_cru *cru) 785 { 786 u32 div, val; 787 788 val = readl(&cru->cru_clksel_con[24]); 789 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 790 CLK_SARADC_DIV_CON_WIDTH); 791 792 return DIV_TO_RATE(OSC_HZ, div); 793 } 794 795 static ulong rockchip_saradc_set_clk(struct rk3288_cru *cru, uint hz) 796 { 797 int src_clk_div; 798 799 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 800 assert(src_clk_div < 128); 801 802 rk_clrsetreg(&cru->cru_clksel_con[24], 803 CLK_SARADC_DIV_CON_MASK, 804 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 805 806 return rockchip_saradc_get_clk(cru); 807 } 808 809 static ulong rockchip_tsadc_get_clk(struct rk3288_cru *cru) 810 { 811 u32 div, val; 812 813 val = readl(&cru->cru_clksel_con[2]); 814 div = bitfield_extract(val, CLK_TSADC_DIV_CON_SHIFT, 815 CLK_TSADC_DIV_CON_WIDTH); 816 817 return DIV_TO_RATE(32768, div); 818 } 819 820 static ulong rockchip_tsadc_set_clk(struct rk3288_cru *cru, uint hz) 821 { 822 int src_clk_div; 823 824 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 825 assert(src_clk_div < 128); 826 827 rk_clrsetreg(&cru->cru_clksel_con[2], 828 CLK_TSADC_DIV_CON_MASK, 829 src_clk_div << CLK_TSADC_DIV_CON_SHIFT); 830 831 return rockchip_tsadc_get_clk(cru); 832 } 833 834 static ulong rockchip_aclk_cpu_get_clk(struct rk3288_cru *cru, uint gclk_rate) 835 { 836 u32 div, val; 837 838 val = readl(&cru->cru_clksel_con[1]); 839 div = (val & PD_BUS_ACLK_DIV0_MASK) >> PD_BUS_ACLK_DIV0_SHIFT; 840 841 return DIV_TO_RATE(gclk_rate, div); 842 } 843 844 #ifndef CONFIG_SPL_BUILD 845 846 static ulong rockchip_crypto_get_clk(struct rk3288_cru *cru, uint gclk_rate) 847 { 848 u32 div, val; 849 850 val = readl(&cru->cru_clksel_con[26]); 851 div = (val & CLK_CRYPTO_DIV_CON_MASK) >> CLK_CRYPTO_DIV_CON_SHIFT; 852 853 return DIV_TO_RATE(rockchip_aclk_cpu_get_clk(cru, gclk_rate), div); 854 } 855 856 static ulong rockchip_crypto_set_clk(struct rk3288_cru *cru, 857 uint gclk_rate, uint hz) 858 { 859 int src_clk_div; 860 uint p_rate; 861 862 p_rate = rockchip_aclk_cpu_get_clk(cru, gclk_rate); 863 src_clk_div = DIV_ROUND_UP(p_rate, hz) - 1; 864 assert(src_clk_div < 3); 865 866 rk_clrsetreg(&cru->cru_clksel_con[26], 867 CLK_CRYPTO_DIV_CON_MASK, 868 src_clk_div << CLK_CRYPTO_DIV_CON_SHIFT); 869 870 return rockchip_crypto_get_clk(cru, gclk_rate); 871 } 872 873 static ulong rk3288_alive_get_clk(struct rk3288_cru *cru, uint gclk_rate) 874 { 875 u32 div, con, parent; 876 877 con = readl(&cru->cru_clksel_con[33]); 878 div = (con & PCLK_ALIVE_DIV_CON_MASK) >> 879 PCLK_ALIVE_DIV_CON_SHIFT; 880 parent = gclk_rate; 881 return DIV_TO_RATE(parent, div); 882 } 883 #endif 884 885 static ulong rk3288_clk_get_rate(struct clk *clk) 886 { 887 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 888 ulong new_rate, gclk_rate; 889 890 gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL); 891 switch (clk->id) { 892 case 0 ... 63: 893 new_rate = rkclk_pll_get_rate(priv->cru, clk->id); 894 break; 895 case HCLK_EMMC: 896 case HCLK_SDMMC: 897 case HCLK_SDIO0: 898 case SCLK_EMMC: 899 case SCLK_EMMC_SAMPLE: 900 case SCLK_SDMMC: 901 case SCLK_SDMMC_SAMPLE: 902 case SCLK_SDIO0: 903 new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id); 904 break; 905 case SCLK_SPI0: 906 case SCLK_SPI1: 907 case SCLK_SPI2: 908 new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, clk->id); 909 break; 910 case PCLK_I2C0: 911 case PCLK_I2C1: 912 case PCLK_I2C2: 913 case PCLK_I2C3: 914 case PCLK_I2C4: 915 case PCLK_I2C5: 916 return gclk_rate; 917 case PCLK_PWM: 918 return PD_BUS_PCLK_HZ; 919 case SCLK_SARADC: 920 new_rate = rockchip_saradc_get_clk(priv->cru); 921 break; 922 case SCLK_TSADC: 923 new_rate = rockchip_tsadc_get_clk(priv->cru); 924 break; 925 case ACLK_CPU: 926 new_rate = rockchip_aclk_cpu_get_clk(priv->cru, gclk_rate); 927 break; 928 #ifndef CONFIG_SPL_BUILD 929 case SCLK_CRYPTO: 930 new_rate = rockchip_crypto_get_clk(priv->cru, gclk_rate); 931 break; 932 case PCLK_WDT: 933 new_rate = rk3288_alive_get_clk(priv->cru, gclk_rate); 934 break; 935 #endif 936 default: 937 return -ENOENT; 938 } 939 940 return new_rate; 941 } 942 943 static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate) 944 { 945 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 946 struct rk3288_cru *cru = priv->cru; 947 ulong new_rate, gclk_rate; 948 949 gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL); 950 switch (clk->id) { 951 case PLL_APLL: 952 /* We only support a fixed rate here */ 953 if (rate != 1800000000) 954 return -EINVAL; 955 rk3288_clk_configure_cpu(priv->cru, priv->grf); 956 new_rate = rate; 957 break; 958 case CLK_DDR: 959 new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate); 960 break; 961 case HCLK_EMMC: 962 case HCLK_SDMMC: 963 case HCLK_SDIO0: 964 case SCLK_EMMC: 965 case SCLK_SDMMC: 966 case SCLK_SDIO0: 967 new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate); 968 break; 969 case SCLK_SPI0: 970 case SCLK_SPI1: 971 case SCLK_SPI2: 972 new_rate = rockchip_spi_set_clk(cru, gclk_rate, clk->id, rate); 973 break; 974 #ifndef CONFIG_SPL_BUILD 975 case SCLK_MAC: 976 new_rate = rockchip_mac_set_clk(priv->cru, rate); 977 break; 978 case DCLK_VOP0: 979 case DCLK_VOP1: 980 case ACLK_VIO0: 981 case ACLK_VIO1: 982 new_rate = rockchip_vop_set_clk(cru, priv->grf, clk->id, rate); 983 break; 984 case SCLK_EDP_24M: 985 /* clk_edp_24M source: 24M */ 986 rk_setreg(&cru->cru_clksel_con[28], 1 << 15); 987 988 /* rst edp */ 989 rk_setreg(&cru->cru_clksel_con[6], 1 << 15); 990 udelay(1); 991 rk_clrreg(&cru->cru_clksel_con[6], 1 << 15); 992 new_rate = rate; 993 break; 994 case PCLK_HDMI_CTRL: 995 /* enable pclk hdmi ctrl */ 996 rk_clrreg(&cru->cru_clkgate_con[16], 1 << 9); 997 998 /* software reset hdmi */ 999 rk_setreg(&cru->cru_clkgate_con[7], 1 << 9); 1000 udelay(1); 1001 rk_clrreg(&cru->cru_clkgate_con[7], 1 << 9); 1002 new_rate = rate; 1003 break; 1004 case SCLK_CRYPTO: 1005 new_rate = rockchip_crypto_set_clk(priv->cru, gclk_rate, rate); 1006 break; 1007 #endif 1008 case SCLK_SARADC: 1009 new_rate = rockchip_saradc_set_clk(priv->cru, rate); 1010 break; 1011 case SCLK_TSADC: 1012 new_rate = rockchip_tsadc_set_clk(priv->cru, rate); 1013 break; 1014 case PLL_GPLL: 1015 case PLL_CPLL: 1016 case PLL_NPLL: 1017 case ACLK_CPU: 1018 case HCLK_CPU: 1019 case PCLK_CPU: 1020 case ACLK_PERI: 1021 case HCLK_PERI: 1022 case PCLK_PERI: 1023 case SCLK_UART0: 1024 return 0; 1025 default: 1026 return -ENOENT; 1027 } 1028 1029 return new_rate; 1030 } 1031 1032 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1033 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1034 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1035 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1036 1037 #define PSECS_PER_SEC 1000000000000LL 1038 /* 1039 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1040 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1041 */ 1042 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1043 1044 int rockchip_mmc_get_phase(struct clk *clk) 1045 { 1046 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 1047 struct rk3288_cru *cru = priv->cru; 1048 u32 raw_value, delay_num; 1049 u16 degrees = 0; 1050 ulong rate; 1051 1052 rate = rk3288_clk_get_rate(clk); 1053 1054 if (rate < 0) 1055 return rate; 1056 1057 if (clk->id == SCLK_EMMC_SAMPLE) 1058 raw_value = readl(&cru->cru_emmc_con[1]); 1059 else 1060 raw_value = readl(&cru->cru_sdmmc_con[1]); 1061 1062 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1063 1064 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1065 /* degrees/delaynum * 10000 */ 1066 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1067 36 * (rate / 1000000); 1068 1069 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1070 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1071 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1072 } 1073 1074 return degrees % 360; 1075 } 1076 1077 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees) 1078 { 1079 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 1080 struct rk3288_cru *cru = priv->cru; 1081 u8 nineties, remainder, delay_num; 1082 u32 raw_value, delay; 1083 ulong rate; 1084 1085 rate = rk3288_clk_get_rate(clk); 1086 1087 if (rate < 0) 1088 return rate; 1089 1090 nineties = degrees / 90; 1091 remainder = (degrees % 90); 1092 1093 /* 1094 * Convert to delay; do a little extra work to make sure we 1095 * don't overflow 32-bit / 64-bit numbers. 1096 */ 1097 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1098 delay *= remainder; 1099 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1100 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1101 1102 delay_num = (u8)min_t(u32, delay, 255); 1103 1104 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1105 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1106 raw_value |= nineties; 1107 1108 if (clk->id == SCLK_EMMC_SAMPLE) 1109 writel(raw_value | 0xffff0000, &cru->cru_emmc_con[1]); 1110 else 1111 writel(raw_value | 0xffff0000, &cru->cru_sdmmc_con[1]); 1112 1113 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1114 degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk)); 1115 1116 return 0; 1117 } 1118 1119 static int rk3288_clk_get_phase(struct clk *clk) 1120 { 1121 int ret; 1122 1123 switch (clk->id) { 1124 case SCLK_EMMC_SAMPLE: 1125 case SCLK_SDMMC_SAMPLE: 1126 ret = rockchip_mmc_get_phase(clk); 1127 break; 1128 default: 1129 return -ENOENT; 1130 } 1131 1132 return ret; 1133 } 1134 1135 static int rk3288_clk_set_phase(struct clk *clk, int degrees) 1136 { 1137 int ret; 1138 1139 switch (clk->id) { 1140 case SCLK_EMMC_SAMPLE: 1141 case SCLK_SDMMC_SAMPLE: 1142 ret = rockchip_mmc_set_phase(clk, degrees); 1143 break; 1144 default: 1145 return -ENOENT; 1146 } 1147 1148 return ret; 1149 } 1150 1151 static int __maybe_unused rk3288_gmac_set_parent(struct clk *clk, struct clk *parent) 1152 { 1153 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 1154 struct rk3288_cru *cru = priv->cru; 1155 const char *clock_output_name; 1156 int ret; 1157 1158 /* 1159 * If the requested parent is in the same clock-controller and 1160 * the id is SCLK_MAC_PLL ("mac_pll_src"), switch to the internal 1161 * clock. 1162 */ 1163 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC_PLL)) { 1164 debug("%s: switching GAMC to SCLK_MAC_PLL\n", __func__); 1165 rk_clrsetreg(&cru->cru_clksel_con[21], RMII_EXTCLK_MASK, 0); 1166 return 0; 1167 } 1168 1169 /* 1170 * Otherwise, we need to check the clock-output-names of the 1171 * requested parent to see if the requested id is "ext_gmac". 1172 */ 1173 ret = dev_read_string_index(parent->dev, "clock-output-names", 1174 parent->id, &clock_output_name); 1175 if (ret < 0) 1176 return -ENODATA; 1177 1178 /* If this is "ext_gmac", switch to the external clock input */ 1179 if (!strcmp(clock_output_name, "ext_gmac")) { 1180 debug("%s: switching GMAC to external clock\n", __func__); 1181 rk_clrsetreg(&cru->cru_clksel_con[21], RMII_EXTCLK_MASK, 1182 RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT); 1183 return 0; 1184 } 1185 1186 return -EINVAL; 1187 } 1188 1189 static int __maybe_unused rk3288_vop_set_parent(struct clk *clk, 1190 struct clk *parent) 1191 { 1192 struct rk3288_clk_priv *priv = dev_get_priv(clk->dev); 1193 struct rk3288_cru *cru = priv->cru; 1194 int parent_sel; 1195 1196 switch (parent->id) { 1197 case PLL_CPLL: 1198 parent_sel = 0; 1199 break; 1200 case PLL_GPLL: 1201 parent_sel = 1; 1202 break; 1203 case PLL_NPLL: 1204 parent_sel = 2; 1205 break; 1206 default: 1207 parent_sel = 0; 1208 break; 1209 } 1210 1211 switch (clk->id) { 1212 case DCLK_VOP0: 1213 rk_clrsetreg(&cru->cru_clksel_con[27], 1214 DCLK_VOP0_PLL_MASK, parent_sel << 0); 1215 break; 1216 case DCLK_VOP1: 1217 rk_clrsetreg(&cru->cru_clksel_con[29], 1218 DCLK_VOP1_PLL_MASK, parent_sel << 6); 1219 break; 1220 default: 1221 return -EINVAL; 1222 } 1223 1224 return 0; 1225 } 1226 1227 static int __maybe_unused rk3288_clk_set_parent(struct clk *clk, struct clk *parent) 1228 { 1229 switch (clk->id) { 1230 case SCLK_MAC: 1231 return rk3288_gmac_set_parent(clk, parent); 1232 case DCLK_VOP0: 1233 case DCLK_VOP1: 1234 return rk3288_vop_set_parent(clk, parent); 1235 case SCLK_USBPHY480M_SRC: 1236 return 0; 1237 } 1238 1239 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1240 return -ENOENT; 1241 } 1242 1243 static struct clk_ops rk3288_clk_ops = { 1244 .get_rate = rk3288_clk_get_rate, 1245 .set_rate = rk3288_clk_set_rate, 1246 .get_phase = rk3288_clk_get_phase, 1247 .set_phase = rk3288_clk_set_phase, 1248 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1249 .set_parent = rk3288_clk_set_parent, 1250 #endif 1251 }; 1252 1253 static int rk3288_clk_ofdata_to_platdata(struct udevice *dev) 1254 { 1255 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 1256 struct rk3288_clk_priv *priv = dev_get_priv(dev); 1257 1258 priv->cru = dev_read_addr_ptr(dev); 1259 #endif 1260 1261 return 0; 1262 } 1263 1264 static int rk3288_clk_probe(struct udevice *dev) 1265 { 1266 struct rk3288_clk_priv *priv = dev_get_priv(dev); 1267 bool init_clocks = false; 1268 int ret; 1269 1270 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1271 if (IS_ERR(priv->grf)) 1272 return PTR_ERR(priv->grf); 1273 #ifdef CONFIG_SPL_BUILD 1274 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1275 struct rk3288_clk_plat *plat = dev_get_platdata(dev); 1276 1277 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 1278 #endif 1279 init_clocks = true; 1280 #endif 1281 if (!(gd->flags & GD_FLG_RELOC)) { 1282 u32 reg; 1283 1284 /* 1285 * Init clocks in U-Boot proper if the NPLL is runnning. This 1286 * indicates that a previous boot loader set up the clocks, so 1287 * we need to redo it. U-Boot's SPL does not set this clock. 1288 * Or if the CPLL is not init, we need to redo the clk_init. 1289 */ 1290 reg = readl(&priv->cru->cru_mode_con); 1291 if ((((reg & NPLL_MODE_MASK) >> NPLL_MODE_SHIFT) == 1292 NPLL_MODE_NORMAL) || 1293 !(reg & CPLL_MODE_MASK)) 1294 init_clocks = true; 1295 } 1296 1297 priv->sync_kernel = false; 1298 if (!priv->armclk_enter_hz) 1299 priv->armclk_enter_hz = rkclk_pll_get_rate(priv->cru, 1300 CLK_ARM); 1301 1302 if (init_clocks) { 1303 rkclk_init(priv->cru, priv->grf); 1304 if (!priv->armclk_init_hz) 1305 priv->armclk_init_hz = rkclk_pll_get_rate(priv->cru, 1306 CLK_ARM); 1307 } else { 1308 if (!priv->armclk_init_hz) 1309 priv->armclk_init_hz = priv->armclk_enter_hz; 1310 } 1311 1312 ret = clk_set_defaults(dev); 1313 if (ret) 1314 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1315 else 1316 priv->sync_kernel = true; 1317 1318 return 0; 1319 } 1320 1321 static int rk3288_clk_bind(struct udevice *dev) 1322 { 1323 int ret; 1324 struct udevice *sys_child, *sf_child; 1325 struct sysreset_reg *priv; 1326 struct softreset_reg *sf_priv; 1327 1328 /* The reset driver does not have a device node, so bind it here */ 1329 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1330 &sys_child); 1331 if (ret) { 1332 debug("Warning: No sysreset driver: ret=%d\n", ret); 1333 } else { 1334 priv = malloc(sizeof(struct sysreset_reg)); 1335 priv->glb_srst_fst_value = offsetof(struct rk3288_cru, 1336 cru_glb_srst_fst_value); 1337 priv->glb_srst_snd_value = offsetof(struct rk3288_cru, 1338 cru_glb_srst_snd_value); 1339 sys_child->priv = priv; 1340 } 1341 1342 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1343 dev_ofnode(dev), &sf_child); 1344 if (ret) { 1345 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1346 } else { 1347 sf_priv = malloc(sizeof(struct softreset_reg)); 1348 sf_priv->sf_reset_offset = offsetof(struct rk3288_cru, 1349 cru_softrst_con[0]); 1350 sf_priv->sf_reset_num = 12; 1351 sf_child->priv = sf_priv; 1352 } 1353 1354 return 0; 1355 } 1356 1357 static const struct udevice_id rk3288_clk_ids[] = { 1358 { .compatible = "rockchip,rk3288-cru" }, 1359 { } 1360 }; 1361 1362 U_BOOT_DRIVER(rockchip_rk3288_cru) = { 1363 .name = "rockchip_rk3288_cru", 1364 .id = UCLASS_CLK, 1365 .of_match = rk3288_clk_ids, 1366 .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv), 1367 .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat), 1368 .ops = &rk3288_clk_ops, 1369 .bind = rk3288_clk_bind, 1370 .ofdata_to_platdata = rk3288_clk_ofdata_to_platdata, 1371 .probe = rk3288_clk_probe, 1372 }; 1373 1374 #ifndef CONFIG_SPL_BUILD 1375 /** 1376 * soc_clk_dump() - Print clock frequencies 1377 * Returns zero on success 1378 * 1379 * Implementation for the clk dump command. 1380 */ 1381 int soc_clk_dump(void) 1382 { 1383 struct udevice *cru_dev; 1384 struct rk3288_clk_priv *priv; 1385 const struct rk3288_clk_info *clk_dump; 1386 struct clk clk; 1387 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1388 unsigned long rate; 1389 int i, ret; 1390 1391 ret = uclass_get_device_by_driver(UCLASS_CLK, 1392 DM_GET_DRIVER(rockchip_rk3288_cru), 1393 &cru_dev); 1394 if (ret) { 1395 printf("%s failed to get cru device\n", __func__); 1396 return ret; 1397 } 1398 1399 priv = dev_get_priv(cru_dev); 1400 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1401 priv->sync_kernel ? "sync kernel" : "uboot", 1402 priv->armclk_enter_hz / 1000, 1403 priv->armclk_init_hz / 1000, 1404 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1405 priv->set_armclk_rate ? " KHz" : "N/A"); 1406 for (i = 0; i < clk_count; i++) { 1407 clk_dump = &clks_dump[i]; 1408 if (clk_dump->name) { 1409 clk.id = clk_dump->id; 1410 if (clk_dump->is_cru) 1411 ret = clk_request(cru_dev, &clk); 1412 if (ret < 0) 1413 return ret; 1414 1415 rate = clk_get_rate(&clk); 1416 clk_free(&clk); 1417 if (i == 0) { 1418 if (rate < 0) 1419 printf(" %s %s\n", clk_dump->name, 1420 "unknown"); 1421 else 1422 printf(" %s %lu KHz\n", clk_dump->name, 1423 rate / 1000); 1424 } else { 1425 if (rate < 0) 1426 printf(" %s %s\n", clk_dump->name, 1427 "unknown"); 1428 else 1429 printf(" %s %lu KHz\n", clk_dump->name, 1430 rate / 1000); 1431 } 1432 } 1433 } 1434 1435 return 0; 1436 } 1437 #endif 1438 1439