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