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