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