1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) Copyright 2015 Google, Inc 4 * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de> 5 */ 6 7#include <bitfield.h> 8#include <common.h> 9#include <clk-uclass.h> 10#include <dm.h> 11#include <dt-structs.h> 12#include <errno.h> 13#include <log.h> 14#include <malloc.h> 15#include <mapmem.h> 16#include <syscon.h> 17#include <asm/arch-rockchip/clock.h> 18#include <asm/arch-rockchip/cru_rk3066.h> 19#include <asm/arch-rockchip/grf_rk3066.h> 20#include <asm/arch-rockchip/hardware.h> 21#include <dt-bindings/clock/rk3066a-cru.h> 22#include <dm/device_compat.h> 23#include <dm/device-internal.h> 24#include <dm/lists.h> 25#include <dm/uclass-internal.h> 26#include <linux/delay.h> 27#include <linux/err.h> 28#include <linux/log2.h> 29#include <linux/stringify.h> 30 31struct rk3066_clk_plat { 32#if CONFIG_IS_ENABLED(OF_PLATDATA) 33 struct dtd_rockchip_rk3066a_cru dtd; 34#endif 35}; 36 37struct pll_div { 38 u32 nr; 39 u32 nf; 40 u32 no; 41}; 42 43enum { 44 VCO_MAX_HZ = 1416U * 1000000, 45 VCO_MIN_HZ = 300 * 1000000, 46 OUTPUT_MAX_HZ = 1416U * 1000000, 47 OUTPUT_MIN_HZ = 30 * 1000000, 48 FREF_MAX_HZ = 1416U * 1000000, 49 FREF_MIN_HZ = 30 * 1000, 50}; 51 52enum { 53 /* PLL CON0 */ 54 PLL_OD_MASK = GENMASK(3, 0), 55 56 /* PLL CON1 */ 57 PLL_NF_MASK = GENMASK(12, 0), 58 59 /* PLL CON2 */ 60 PLL_BWADJ_MASK = GENMASK(11, 0), 61 62 /* PLL CON3 */ 63 PLL_RESET_SHIFT = 5, 64 65 /* GRF_SOC_STATUS0 */ 66 SOCSTS_DPLL_LOCK = BIT(4), 67 SOCSTS_APLL_LOCK = BIT(5), 68 SOCSTS_CPLL_LOCK = BIT(6), 69 SOCSTS_GPLL_LOCK = BIT(7), 70}; 71 72#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 73 74#define PLL_DIVISORS(hz, _nr, _no) {\ 75 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\ 76 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\ 77 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\ 78 "divisors on line " __stringify(__LINE__)) 79 80/* Keep divisors as low as possible to reduce jitter and power usage. */ 81static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2); 82static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2); 83 84static int rk3066_clk_set_pll(struct rk3066_cru *cru, enum rk_clk_id clk_id, 85 const struct pll_div *div) 86{ 87 int pll_id = rk_pll_id(clk_id); 88 struct rk3066_pll *pll = &cru->pll[pll_id]; 89 /* All PLLs have the same VCO and output frequency range restrictions. */ 90 uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000; 91 uint output_hz = vco_hz / div->no; 92 93 debug("%s: PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", __func__, 94 (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz); 95 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && 96 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ && 97 (div->no == 1 || !(div->no % 2))); 98 99 /* Enter reset. */ 100 rk_setreg(&pll->con3, BIT(PLL_RESET_SHIFT)); 101 102 rk_clrsetreg(&pll->con0, 103 CLKR_MASK | PLL_OD_MASK, 104 ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1)); 105 rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1); 106 107 rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1); 108 109 /* Exit reset. */ 110 rk_clrreg(&pll->con3, BIT(PLL_RESET_SHIFT)); 111 112 return 0; 113} 114 115static int rk3066_clk_configure_ddr(struct rk3066_cru *cru, struct rk3066_grf *grf, 116 unsigned int hz) 117{ 118 static const struct pll_div dpll_cfg[] = { 119 {.nf = 25, .nr = 2, .no = 1}, 120 {.nf = 400, .nr = 9, .no = 2}, 121 {.nf = 500, .nr = 9, .no = 2}, 122 {.nf = 100, .nr = 3, .no = 1}, 123 }; 124 int cfg; 125 126 switch (hz) { 127 case 300000000: 128 cfg = 0; 129 break; 130 case 533000000: /* actually 533.3P MHz */ 131 cfg = 1; 132 break; 133 case 666000000: /* actually 666.6P MHz */ 134 cfg = 2; 135 break; 136 case 800000000: 137 cfg = 3; 138 break; 139 default: 140 debug("%s: unsupported SDRAM frequency", __func__); 141 return -EINVAL; 142 } 143 144 /* Enter PLL slow mode. */ 145 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, 146 PLL_MODE_SLOW << DPLL_MODE_SHIFT); 147 148 rk3066_clk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]); 149 150 /* Wait for PLL lock. */ 151 while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK)) 152 udelay(1); 153 154 /* Enter PLL normal mode. */ 155 rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, 156 PLL_MODE_NORMAL << DPLL_MODE_SHIFT); 157 158 return 0; 159} 160 161static int rk3066_clk_configure_cpu(struct rk3066_cru *cru, struct rk3066_grf *grf, 162 unsigned int hz) 163{ 164 static const struct pll_div apll_cfg[] = { 165 {.nf = 50, .nr = 1, .no = 2}, 166 {.nf = 59, .nr = 1, .no = 1}, 167 }; 168 int div_core_peri, div_cpu_aclk, cfg; 169 170 /* 171 * We support two possible frequencies, the safe 600MHz 172 * which will work with default pmic settings and will 173 * be set to get away from the 24MHz default and 174 * the maximum of 1.416Ghz, which boards can set if they 175 * were able to get pmic support for it. 176 */ 177 switch (hz) { 178 case APLL_SAFE_HZ: 179 cfg = 0; 180 div_core_peri = 1; 181 div_cpu_aclk = 3; 182 break; 183 case APLL_HZ: 184 cfg = 1; 185 div_core_peri = 2; 186 div_cpu_aclk = 3; 187 break; 188 default: 189 debug("unsupported ARMCLK frequency"); 190 return -EINVAL; 191 } 192 193 /* Enter PLL slow mode. */ 194 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, 195 PLL_MODE_SLOW << APLL_MODE_SHIFT); 196 197 rk3066_clk_set_pll(cru, CLK_ARM, &apll_cfg[cfg]); 198 199 /* Wait for PLL lock. */ 200 while (!(readl(&grf->soc_status0) & SOCSTS_APLL_LOCK)) 201 udelay(1); 202 203 /* Set divider for peripherals attached to the CPU core. */ 204 rk_clrsetreg(&cru->cru_clksel_con[0], 205 CORE_PERI_DIV_MASK, 206 div_core_peri << CORE_PERI_DIV_SHIFT); 207 208 /* Set up dependent divisor for cpu_aclk. */ 209 rk_clrsetreg(&cru->cru_clksel_con[1], 210 CPU_ACLK_DIV_MASK, 211 div_cpu_aclk << CPU_ACLK_DIV_SHIFT); 212 213 /* Enter PLL normal mode. */ 214 rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, 215 PLL_MODE_NORMAL << APLL_MODE_SHIFT); 216 217 return hz; 218} 219 220static uint32_t rk3066_clk_pll_get_rate(struct rk3066_cru *cru, 221 enum rk_clk_id clk_id) 222{ 223 u32 nr, no, nf; 224 u32 con; 225 int pll_id = rk_pll_id(clk_id); 226 struct rk3066_pll *pll = &cru->pll[pll_id]; 227 static u8 clk_shift[CLK_COUNT] = { 228 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT, 229 GPLL_MODE_SHIFT 230 }; 231 uint shift; 232 233 con = readl(&cru->cru_mode_con); 234 shift = clk_shift[clk_id]; 235 switch (FIELD_GET(APLL_MODE_MASK, con >> shift)) { 236 case PLL_MODE_SLOW: 237 return OSC_HZ; 238 case PLL_MODE_NORMAL: 239 /* normal mode */ 240 con = readl(&pll->con0); 241 no = bitfield_extract_by_mask(con, CLKOD_MASK) + 1; 242 nr = bitfield_extract_by_mask(con, CLKR_MASK) + 1; 243 con = readl(&pll->con1); 244 nf = bitfield_extract_by_mask(con, CLKF_MASK) + 1; 245 246 return (OSC_HZ * nf) / (nr * no); 247 case PLL_MODE_DEEP: 248 default: 249 return 32768; 250 } 251} 252 253static ulong rk3066_clk_mmc_get_clk(struct rk3066_cru *cru, uint gclk_rate, 254 int periph) 255{ 256 uint div; 257 u32 con; 258 259 switch (periph) { 260 case HCLK_EMMC: 261 case SCLK_EMMC: 262 con = readl(&cru->cru_clksel_con[12]); 263 div = bitfield_extract_by_mask(con, EMMC_DIV_MASK); 264 break; 265 case HCLK_SDMMC: 266 case SCLK_SDMMC: 267 con = readl(&cru->cru_clksel_con[11]); 268 div = bitfield_extract_by_mask(con, MMC0_DIV_MASK); 269 break; 270 case HCLK_SDIO: 271 case SCLK_SDIO: 272 con = readl(&cru->cru_clksel_con[12]); 273 div = bitfield_extract_by_mask(con, SDIO_DIV_MASK); 274 break; 275 default: 276 return -EINVAL; 277 } 278 279 return DIV_TO_RATE(gclk_rate, div) / 2; 280} 281 282static ulong rk3066_clk_mmc_set_clk(struct rk3066_cru *cru, uint gclk_rate, 283 int periph, uint freq) 284{ 285 int src_clk_div; 286 287 debug("%s: gclk_rate=%u\n", __func__, gclk_rate); 288 /* MMC clock by default divides by 2 internally, so need to provide double in CRU. */ 289 src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq) - 1; 290 assert(src_clk_div <= 0x3f); 291 292 switch (periph) { 293 case HCLK_EMMC: 294 case SCLK_EMMC: 295 rk_clrsetreg(&cru->cru_clksel_con[12], 296 EMMC_DIV_MASK, 297 src_clk_div << EMMC_DIV_SHIFT); 298 break; 299 case HCLK_SDMMC: 300 case SCLK_SDMMC: 301 rk_clrsetreg(&cru->cru_clksel_con[11], 302 MMC0_DIV_MASK, 303 src_clk_div << MMC0_DIV_SHIFT); 304 break; 305 case HCLK_SDIO: 306 case SCLK_SDIO: 307 rk_clrsetreg(&cru->cru_clksel_con[12], 308 SDIO_DIV_MASK, 309 src_clk_div << SDIO_DIV_SHIFT); 310 break; 311 default: 312 return -EINVAL; 313 } 314 315 return rk3066_clk_mmc_get_clk(cru, gclk_rate, periph); 316} 317 318static ulong rk3066_clk_spi_get_clk(struct rk3066_cru *cru, uint gclk_rate, 319 int periph) 320{ 321 uint div; 322 u32 con; 323 324 switch (periph) { 325 case SCLK_SPI0: 326 con = readl(&cru->cru_clksel_con[25]); 327 div = bitfield_extract_by_mask(con, SPI0_DIV_MASK); 328 break; 329 case SCLK_SPI1: 330 con = readl(&cru->cru_clksel_con[25]); 331 div = bitfield_extract_by_mask(con, SPI1_DIV_MASK); 332 break; 333 default: 334 return -EINVAL; 335 } 336 337 return DIV_TO_RATE(gclk_rate, div); 338} 339 340static ulong rk3066_clk_spi_set_clk(struct rk3066_cru *cru, uint gclk_rate, 341 int periph, uint freq) 342{ 343 int src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1; 344 345 assert(src_clk_div < 128); 346 switch (periph) { 347 case SCLK_SPI0: 348 assert(src_clk_div <= SPI0_DIV_MASK >> SPI0_DIV_SHIFT); 349 rk_clrsetreg(&cru->cru_clksel_con[25], 350 SPI0_DIV_MASK, 351 src_clk_div << SPI0_DIV_SHIFT); 352 break; 353 case SCLK_SPI1: 354 assert(src_clk_div <= SPI1_DIV_MASK >> SPI1_DIV_SHIFT); 355 rk_clrsetreg(&cru->cru_clksel_con[25], 356 SPI1_DIV_MASK, 357 src_clk_div << SPI1_DIV_SHIFT); 358 break; 359 default: 360 return -EINVAL; 361 } 362 363 return rk3066_clk_spi_get_clk(cru, gclk_rate, periph); 364} 365 366static ulong rk3066_clk_saradc_get_clk(struct rk3066_cru *cru, int periph) 367{ 368 u32 div, con; 369 370 switch (periph) { 371 case SCLK_SARADC: 372 con = readl(&cru->cru_clksel_con[24]); 373 div = bitfield_extract_by_mask(con, SARADC_DIV_MASK); 374 break; 375 case SCLK_TSADC: 376 con = readl(&cru->cru_clksel_con[34]); 377 div = bitfield_extract_by_mask(con, TSADC_DIV_MASK); 378 break; 379 default: 380 return -EINVAL; 381 } 382 return DIV_TO_RATE(PERI_PCLK_HZ, div); 383} 384 385static ulong rk3066_clk_saradc_set_clk(struct rk3066_cru *cru, uint hz, 386 int periph) 387{ 388 int src_clk_div; 389 390 src_clk_div = DIV_ROUND_UP(PERI_PCLK_HZ, hz) - 1; 391 assert(src_clk_div < 128); 392 393 switch (periph) { 394 case SCLK_SARADC: 395 rk_clrsetreg(&cru->cru_clksel_con[24], 396 SARADC_DIV_MASK, 397 src_clk_div << SARADC_DIV_SHIFT); 398 break; 399 case SCLK_TSADC: 400 rk_clrsetreg(&cru->cru_clksel_con[34], 401 SARADC_DIV_MASK, 402 src_clk_div << SARADC_DIV_SHIFT); 403 break; 404 default: 405 return -EINVAL; 406 } 407 408 return rk3066_clk_saradc_get_clk(cru, periph); 409} 410 411static void rk3066_clk_init(struct rk3066_cru *cru, struct rk3066_grf *grf) 412{ 413 u32 aclk_div, hclk_div, pclk_div, h2p_div; 414 415 /* Enter PLL slow mode. */ 416 rk_clrsetreg(&cru->cru_mode_con, 417 GPLL_MODE_MASK | 418 CPLL_MODE_MASK, 419 PLL_MODE_SLOW << GPLL_MODE_SHIFT | 420 PLL_MODE_SLOW << CPLL_MODE_SHIFT); 421 422 /* Init PLL. */ 423 rk3066_clk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); 424 rk3066_clk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); 425 426 /* Wait for PLL lock. */ 427 while ((readl(&grf->soc_status0) & 428 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) != 429 (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) 430 udelay(1); 431 432 /* 433 * Select CPU clock PLL source and 434 * reparent aclk_cpu_pre from APPL to GPLL. 435 * Set up dependent divisors for PCLK/HCLK and ACLK clocks. 436 */ 437 aclk_div = DIV_ROUND_UP(GPLL_HZ, CPU_ACLK_HZ) - 1; 438 assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f); 439 440 rk_clrsetreg(&cru->cru_clksel_con[0], 441 CPU_ACLK_PLL_MASK | 442 A9_CORE_DIV_MASK, 443 CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT | 444 aclk_div << A9_CORE_DIV_SHIFT); 445 446 hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ); 447 assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3); 448 pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ); 449 assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4); 450 h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ); 451 assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3); 452 453 rk_clrsetreg(&cru->cru_clksel_con[1], 454 AHB2APB_DIV_MASK | 455 CPU_PCLK_DIV_MASK | 456 CPU_HCLK_DIV_MASK, 457 h2p_div << AHB2APB_DIV_SHIFT | 458 pclk_div << CPU_PCLK_DIV_SHIFT | 459 hclk_div << CPU_HCLK_DIV_SHIFT); 460 461 /* 462 * Select PERI clock PLL source and 463 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 464 */ 465 aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1; 466 assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); 467 468 hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ); 469 assert((1 << hclk_div) * PERI_HCLK_HZ == 470 PERI_ACLK_HZ && (hclk_div < 0x4)); 471 472 pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ); 473 assert((1 << pclk_div) * PERI_PCLK_HZ == 474 PERI_ACLK_HZ && (pclk_div < 0x4)); 475 476 rk_clrsetreg(&cru->cru_clksel_con[10], 477 PERI_PCLK_DIV_MASK | 478 PERI_HCLK_DIV_MASK | 479 PERI_ACLK_DIV_MASK, 480 PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT | 481 pclk_div << PERI_PCLK_DIV_SHIFT | 482 hclk_div << PERI_HCLK_DIV_SHIFT | 483 aclk_div << PERI_ACLK_DIV_SHIFT); 484 485 /* Enter PLL normal mode. */ 486 rk_clrsetreg(&cru->cru_mode_con, 487 GPLL_MODE_MASK | 488 CPLL_MODE_MASK, 489 PLL_MODE_NORMAL << GPLL_MODE_SHIFT | 490 PLL_MODE_NORMAL << CPLL_MODE_SHIFT); 491 492 rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000); 493} 494 495static ulong rk3066_clk_get_rate(struct clk *clk) 496{ 497 struct rk3066_clk_priv *priv = dev_get_priv(clk->dev); 498 ulong new_rate, gclk_rate; 499 500 gclk_rate = rk3066_clk_pll_get_rate(priv->cru, CLK_GENERAL); 501 switch (clk->id) { 502 case 1 ... 4: 503 new_rate = rk3066_clk_pll_get_rate(priv->cru, clk->id); 504 break; 505 case HCLK_EMMC: 506 case HCLK_SDMMC: 507 case HCLK_SDIO: 508 case SCLK_EMMC: 509 case SCLK_SDMMC: 510 case SCLK_SDIO: 511 new_rate = rk3066_clk_mmc_get_clk(priv->cru, PERI_HCLK_HZ, 512 clk->id); 513 break; 514 case SCLK_SPI0: 515 case SCLK_SPI1: 516 new_rate = rk3066_clk_spi_get_clk(priv->cru, PERI_PCLK_HZ, 517 clk->id); 518 break; 519 case PCLK_I2C0: 520 case PCLK_I2C1: 521 case PCLK_I2C2: 522 case PCLK_I2C3: 523 case PCLK_I2C4: 524 return gclk_rate; 525 case SCLK_SARADC: 526 case SCLK_TSADC: 527 new_rate = rk3066_clk_saradc_get_clk(priv->cru, clk->id); 528 break; 529 case SCLK_TIMER0: 530 case SCLK_TIMER1: 531 case SCLK_TIMER2: 532 case SCLK_UART0: 533 case SCLK_UART1: 534 case SCLK_UART2: 535 case SCLK_UART3: 536 return OSC_HZ; 537 default: 538 return -ENOENT; 539 } 540 541 return new_rate; 542} 543 544static ulong rk3066_clk_set_rate(struct clk *clk, ulong rate) 545{ 546 struct rk3066_clk_priv *priv = dev_get_priv(clk->dev); 547 struct rk3066_cru *cru = priv->cru; 548 ulong new_rate; 549 550 switch (clk->id) { 551 case PLL_APLL: 552 new_rate = rk3066_clk_configure_cpu(priv->cru, priv->grf, rate); 553 break; 554 case CLK_DDR: 555 new_rate = rk3066_clk_configure_ddr(priv->cru, priv->grf, rate); 556 break; 557 case HCLK_EMMC: 558 case HCLK_SDMMC: 559 case HCLK_SDIO: 560 case SCLK_EMMC: 561 case SCLK_SDMMC: 562 case SCLK_SDIO: 563 new_rate = rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ, 564 clk->id, rate); 565 break; 566 case SCLK_SPI0: 567 case SCLK_SPI1: 568 new_rate = rk3066_clk_spi_set_clk(cru, PERI_PCLK_HZ, 569 clk->id, rate); 570 break; 571 case SCLK_SARADC: 572 case SCLK_TSADC: 573 new_rate = rk3066_clk_saradc_set_clk(cru, rate, clk->id); 574 break; 575 case PLL_CPLL: 576 case PLL_GPLL: 577 case ACLK_CPU: 578 case HCLK_CPU: 579 case PCLK_CPU: 580 case ACLK_PERI: 581 case HCLK_PERI: 582 case PCLK_PERI: 583 return 0; 584 default: 585 return -ENOENT; 586 } 587 588 return new_rate; 589} 590 591static int rk3066_clk_enable(struct clk *clk) 592{ 593 struct rk3066_clk_priv *priv = dev_get_priv(clk->dev); 594 595 switch (clk->id) { 596 case HCLK_NANDC0: 597 rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(9)); 598 break; 599 case HCLK_SDMMC: 600 rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(10)); 601 break; 602 case HCLK_SDIO: 603 rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(11)); 604 break; 605 } 606 607 return 0; 608} 609 610static int rk3066_clk_disable(struct clk *clk) 611{ 612 struct rk3066_clk_priv *priv = dev_get_priv(clk->dev); 613 614 switch (clk->id) { 615 case HCLK_NANDC0: 616 rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(9)); 617 break; 618 case HCLK_SDMMC: 619 rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(10)); 620 break; 621 case HCLK_SDIO: 622 rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(11)); 623 break; 624 } 625 626 return 0; 627} 628 629static struct clk_ops rk3066_clk_ops = { 630 .disable = rk3066_clk_disable, 631 .enable = rk3066_clk_enable, 632 .get_rate = rk3066_clk_get_rate, 633 .set_rate = rk3066_clk_set_rate, 634}; 635 636static int rk3066_clk_of_to_plat(struct udevice *dev) 637{ 638 if (CONFIG_IS_ENABLED(OF_REAL)) { 639 struct rk3066_clk_priv *priv = dev_get_priv(dev); 640 641 priv->cru = dev_read_addr_ptr(dev); 642 } 643 644 return 0; 645} 646 647static int rk3066_clk_probe(struct udevice *dev) 648{ 649 struct rk3066_clk_priv *priv = dev_get_priv(dev); 650 651 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 652 if (IS_ERR(priv->grf)) 653 return PTR_ERR(priv->grf); 654 655#if CONFIG_IS_ENABLED(OF_PLATDATA) 656 struct rk3066_clk_plat *plat = dev_get_plat(dev); 657 658 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 659#endif 660 661 if (IS_ENABLED(CONFIG_TPL_BUILD)) { 662 rk3066_clk_init(priv->cru, priv->grf); 663 664 /* Init CPU frequency. */ 665 rk3066_clk_configure_cpu(priv->cru, priv->grf, APLL_SAFE_HZ); 666 } 667 668 return 0; 669} 670 671static int rk3066_clk_bind(struct udevice *dev) 672{ 673 struct udevice *sys_child; 674 struct sysreset_reg *priv; 675 int reg_offset, ret; 676 677 /* The reset driver does not have a device node, so bind it here. */ 678 ret = device_bind(dev, DM_DRIVER_GET(sysreset_rockchip), "sysreset", 679 NULL, ofnode_null(), &sys_child); 680 if (ret) { 681 dev_dbg(dev, "Warning: No sysreset driver: ret=%d\n", ret); 682 } else { 683 priv = malloc(sizeof(struct sysreset_reg)); 684 priv->glb_srst_fst_value = offsetof(struct rk3066_cru, 685 cru_glb_srst_fst_value); 686 priv->glb_srst_snd_value = offsetof(struct rk3066_cru, 687 cru_glb_srst_snd_value); 688 dev_set_priv(sys_child, priv); 689 } 690 691 if (CONFIG_IS_ENABLED(RESET_ROCKCHIP)) { 692 reg_offset = offsetof(struct rk3066_cru, cru_softrst_con[0]); 693 ret = rockchip_reset_bind(dev, reg_offset, 9); 694 if (ret) 695 dev_dbg(dev, "Warning: software reset driver bind failed\n"); 696 } 697 698 return 0; 699} 700 701static const struct udevice_id rk3066_clk_ids[] = { 702 { .compatible = "rockchip,rk3066a-cru" }, 703 { } 704}; 705 706U_BOOT_DRIVER(rockchip_rk3066a_cru) = { 707 .name = "rockchip_rk3066a_cru", 708 .id = UCLASS_CLK, 709 .ops = &rk3066_clk_ops, 710 .probe = rk3066_clk_probe, 711 .bind = rk3066_clk_bind, 712 .of_match = rk3066_clk_ids, 713 .of_to_plat = rk3066_clk_of_to_plat, 714 .priv_auto = sizeof(struct rk3066_clk_priv), 715 .plat_auto = sizeof(struct rk3066_clk_plat), 716}; 717