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