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