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