1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 #include <common.h> 7 #include <bitfield.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <syscon.h> 12 #include <asm/arch/clock.h> 13 #include <asm/arch/cru_rk3308.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/io.h> 16 #include <dm/lists.h> 17 #include <dt-bindings/clock/rk3308-cru.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 enum { 22 VCO_MAX_HZ = 3200U * 1000000, 23 VCO_MIN_HZ = 800 * 1000000, 24 OUTPUT_MAX_HZ = 3200U * 1000000, 25 OUTPUT_MIN_HZ = 24 * 1000000, 26 }; 27 28 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 29 30 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 31 .refdiv = _refdiv,\ 32 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 33 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; 34 35 static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1); 36 37 static u8 pll_mode_shift[PLL_COUNT] = { 38 APLL_MODE_SHIFT, DPLL_MODE_SHIFT, VPLL0_MODE_SHIFT, 39 VPLL1_MODE_SHIFT 40 }; 41 42 static u32 pll_mode_mask[PLL_COUNT] = { 43 APLL_MODE_MASK, DPLL_MODE_MASK, VPLL0_MODE_MASK, 44 VPLL1_MODE_MASK 45 }; 46 47 static ulong apll_hz, dpll_hz, vpll0_hz; 48 49 /* 50 * How to calculate the PLL: 51 * Formulas also embedded within the Fractional PLL Verilog model: 52 * If DSMPD = 1 (DSM is disabled, "integer mode") 53 * FOUTVCO = FREF / REFDIV * FBDIV 54 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 55 * Where: 56 * FOUTVCO = Fractional PLL non-divided output frequency 57 * FOUTPOSTDIV = Fractional PLL divided output frequency 58 * (output of second post divider) 59 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 60 * REFDIV = Fractional PLL input reference clock divider 61 * FBDIV = Integer value programmed into feedback divide 62 * 63 */ 64 65 static void rkclk_set_pll(struct rk3308_cru *cru, enum rk3308_pll_id pll_id, 66 const struct pll_div *div) 67 { 68 struct rk3308_pll *pll; 69 unsigned int *mode; 70 /* All PLLs have same VCO and output frequency range restrictions. */ 71 uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000; 72 uint output_hz = vco_hz / div->postdiv1 / div->postdiv2; 73 74 pll = &cru->pll[pll_id]; 75 mode = &cru->mode; 76 77 debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n", 78 pll, div->fbdiv, div->refdiv, div->postdiv1, 79 div->postdiv2, vco_hz, output_hz); 80 assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && 81 output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ); 82 83 /* 84 * When power on or changing PLL setting, 85 * we must force PLL into slow mode to ensure output stable clock. 86 */ 87 rk_clrsetreg(mode, pll_mode_mask[pll_id], 88 PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]); 89 90 /* use integer mode */ 91 rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT); 92 /* Power down */ 93 rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT); 94 95 rk_clrsetreg(&pll->con0, 96 PLL_POSTDIV1_MASK | PLL_FBDIV_MASK, 97 (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv); 98 rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, 99 (div->postdiv2 << PLL_POSTDIV2_SHIFT | 100 div->refdiv << PLL_REFDIV_SHIFT)); 101 102 /* Power Up */ 103 rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT); 104 105 /* waiting for pll lock */ 106 while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))) 107 udelay(1); 108 109 rk_clrsetreg(mode, pll_mode_mask[pll_id], 110 PLLMUX_FROM_PLL << pll_mode_shift[pll_id]); 111 } 112 113 static uint32_t rkclk_pll_get_rate(struct rk3308_cru *cru, 114 enum rk3308_pll_id pll_id) 115 { 116 u32 refdiv, fbdiv, postdiv1, postdiv2; 117 u32 con; 118 struct rk3308_pll *pll; 119 uint shift; 120 uint mask; 121 122 pll = &cru->pll[pll_id]; 123 con = readl(&cru->mode); 124 125 shift = pll_mode_shift[pll_id]; 126 mask = pll_mode_mask[pll_id]; 127 128 switch ((con & mask) >> shift) { 129 case PLLMUX_FROM_XIN24M: 130 return OSC_HZ; 131 case PLLMUX_FROM_PLL: 132 /* normal mode */ 133 con = readl(&pll->con0); 134 postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT; 135 fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 136 con = readl(&pll->con1); 137 postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT; 138 refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT; 139 return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; 140 case PLLMUX_FROM_RTC32K: 141 default: 142 return 32768; 143 } 144 } 145 146 static void rkclk_init(struct rk3308_cru *cru) 147 { 148 u32 aclk_div, hclk_div, pclk_div; 149 150 /* init pll */ 151 rkclk_set_pll(cru, APLL, &apll_816_cfg); 152 153 /* 154 * select apll as cpu/core clock pll source and 155 * set up dependent divisors for PCLK and ACLK clocks. 156 * core hz : apll = 1:1 157 */ 158 apll_hz = rkclk_pll_get_rate(cru, APLL); 159 aclk_div = apll_hz / CORE_ACLK_HZ - 1; 160 pclk_div = apll_hz / CORE_DBG_HZ - 1; 161 rk_clrsetreg(&cru->clksel_con[0], 162 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK | 163 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 164 aclk_div << CORE_ACLK_DIV_SHIFT | 165 pclk_div << CORE_DBG_DIV_SHIFT | 166 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 167 0 << CORE_DIV_CON_SHIFT); 168 169 /* 170 * select dpll as pd_bus bus clock source and 171 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 172 */ 173 dpll_hz = rkclk_pll_get_rate(cru, DPLL); 174 aclk_div = dpll_hz / BUS_ACLK_HZ - 1; 175 hclk_div = dpll_hz / BUS_HCLK_HZ - 1; 176 pclk_div = dpll_hz / BUS_PCLK_HZ - 1; 177 rk_clrsetreg(&cru->clksel_con[5], 178 BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK, 179 BUS_PLL_SEL_DPLL << BUS_PLL_SEL_SHIFT | 180 aclk_div << BUS_ACLK_DIV_SHIFT); 181 rk_clrsetreg(&cru->clksel_con[6], 182 BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK, 183 pclk_div << BUS_PCLK_DIV_SHIFT | 184 hclk_div << BUS_HCLK_DIV_SHIFT); 185 186 /* 187 * select vpll0 as pd_peri bus clock source and 188 * set up dependent divisors for PCLK/HCLK and ACLK clocks. 189 */ 190 vpll0_hz = rkclk_pll_get_rate(cru, VPLL0); 191 aclk_div = vpll0_hz / PERI_ACLK_HZ - 1; 192 hclk_div = vpll0_hz / PERI_HCLK_HZ - 1; 193 pclk_div = vpll0_hz / PERI_PCLK_HZ - 1; 194 rk_clrsetreg(&cru->clksel_con[36], 195 PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK, 196 PERI_PLL_VPLL0 << PERI_PLL_SEL_SHIFT | 197 aclk_div << PERI_ACLK_DIV_SHIFT); 198 rk_clrsetreg(&cru->clksel_con[37], 199 PERI_PCLK_DIV_MASK | PERI_HCLK_DIV_MASK, 200 pclk_div << PERI_PCLK_DIV_SHIFT | 201 hclk_div << PERI_HCLK_DIV_SHIFT); 202 } 203 204 static ulong rk3308_i2c_get_clk(struct rk3308_cru *cru, ulong clk_id) 205 { 206 u32 div, con, con_id; 207 208 switch (clk_id) { 209 case SCLK_I2C0: 210 con_id = 25; 211 break; 212 case SCLK_I2C1: 213 con_id = 26; 214 break; 215 case SCLK_I2C2: 216 con_id = 27; 217 break; 218 case SCLK_I2C3: 219 con_id = 28; 220 break; 221 default: 222 printf("do not support this i2c bus\n"); 223 return -EINVAL; 224 } 225 226 con = readl(&cru->clksel_con[con_id]); 227 div = con >> CLK_I2C_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 228 229 return DIV_TO_RATE(dpll_hz, div); 230 } 231 232 static ulong rk3308_i2c_set_clk(struct rk3308_cru *cru, ulong clk_id, uint hz) 233 { 234 u32 src_clk_div, con_id; 235 236 src_clk_div = dpll_hz / hz; 237 assert(src_clk_div - 1 < 127); 238 239 switch (clk_id) { 240 case SCLK_I2C0: 241 con_id = 25; 242 break; 243 case SCLK_I2C1: 244 con_id = 26; 245 break; 246 case SCLK_I2C2: 247 con_id = 27; 248 break; 249 case SCLK_I2C3: 250 con_id = 28; 251 break; 252 default: 253 printf("do not support this i2c bus\n"); 254 return -EINVAL; 255 } 256 rk_clrsetreg(&cru->clksel_con[con_id], 257 CLK_I2C_PLL_SEL_MASK | CLK_I2C_DIV_CON_MASK, 258 CLK_I2C_PLL_SEL_DPLL << CLK_I2C_PLL_SEL_SHIFT | 259 (src_clk_div - 1) << CLK_I2C_DIV_CON_SHIFT); 260 261 return rk3308_i2c_get_clk(cru, clk_id); 262 } 263 264 static ulong rk3308_mmc_get_clk(struct rk3308_cru *cru, uint clk_id) 265 { 266 u32 div, con, con_id; 267 268 switch (clk_id) { 269 case HCLK_SDMMC: 270 case SCLK_SDMMC: 271 con_id = 39; 272 break; 273 case HCLK_EMMC: 274 case SCLK_EMMC: 275 case SCLK_EMMC_SAMPLE: 276 con_id = 41; 277 break; 278 default: 279 return -EINVAL; 280 } 281 282 con = readl(&cru->clksel_con[con_id]); 283 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 284 285 if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT 286 == EMMC_SEL_24M) 287 return DIV_TO_RATE(OSC_HZ, div) / 2; 288 else 289 return DIV_TO_RATE(vpll0_hz, div) / 2; 290 } 291 292 static ulong rk3308_mmc_set_clk(struct rk3308_cru *cru, 293 ulong clk_id, ulong set_rate) 294 { 295 int src_clk_div; 296 u32 con_id; 297 298 debug("%s %ld %ld\n", __func__, clk_id, set_rate); 299 300 switch (clk_id) { 301 case HCLK_SDMMC: 302 case SCLK_SDMMC: 303 con_id = 39; 304 break; 305 case HCLK_EMMC: 306 case SCLK_EMMC: 307 con_id = 41; 308 break; 309 default: 310 return -EINVAL; 311 } 312 /* Select clk_sdmmc/emmc source from VPLL0 by default */ 313 /* mmc clock defaulg div 2 internal, need provide double in cru */ 314 src_clk_div = DIV_ROUND_UP(vpll0_hz / 2, set_rate); 315 316 if (src_clk_div > 127) { 317 /* use 24MHz source for 400KHz clock */ 318 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 319 rk_clrsetreg(&cru->clksel_con[con_id], 320 EMMC_PLL_MASK | EMMC_DIV_MASK | EMMC_CLK_SEL_MASK, 321 EMMC_CLK_SEL_EMMC << EMMC_CLK_SEL_SHIFT | 322 EMMC_SEL_24M << EMMC_PLL_SHIFT | 323 (src_clk_div - 1) << EMMC_DIV_SHIFT); 324 } else { 325 rk_clrsetreg(&cru->clksel_con[con_id], 326 EMMC_PLL_MASK | EMMC_DIV_MASK | EMMC_CLK_SEL_MASK, 327 EMMC_CLK_SEL_EMMC << EMMC_CLK_SEL_SHIFT | 328 EMMC_SEL_VPLL0 << EMMC_PLL_SHIFT | 329 (src_clk_div - 1) << EMMC_DIV_SHIFT); 330 } 331 332 return rk3308_mmc_get_clk(cru, clk_id); 333 } 334 335 static ulong rk3308_saradc_get_clk(struct rk3308_cru *cru) 336 { 337 u32 div, con; 338 339 con = readl(&cru->clksel_con[34]); 340 div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; 341 342 return DIV_TO_RATE(OSC_HZ, div); 343 } 344 345 static ulong rk3308_saradc_set_clk(struct rk3308_cru *cru, uint hz) 346 { 347 int src_clk_div; 348 349 src_clk_div = OSC_HZ / hz; 350 assert(src_clk_div - 1 < 2047); 351 352 rk_clrsetreg(&cru->clksel_con[34], 353 CLK_SARADC_DIV_CON_MASK, 354 (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); 355 356 return rk3308_saradc_get_clk(cru); 357 } 358 359 static ulong rk3308_spi_get_clk(struct rk3308_cru *cru, ulong clk_id) 360 { 361 u32 div, con, con_id; 362 363 switch (clk_id) { 364 case SCLK_SPI0: 365 con_id = 30; 366 break; 367 case SCLK_SPI1: 368 con_id = 31; 369 break; 370 case SCLK_SPI2: 371 con_id = 32; 372 break; 373 default: 374 printf("do not support this spi bus\n"); 375 return -EINVAL; 376 } 377 378 con = readl(&cru->clksel_con[con_id]); 379 div = con >> CLK_SPI_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; 380 381 return DIV_TO_RATE(dpll_hz, div); 382 } 383 384 static ulong rk3308_spi_set_clk(struct rk3308_cru *cru, ulong clk_id, uint hz) 385 { 386 u32 src_clk_div, con_id; 387 388 src_clk_div = dpll_hz / hz; 389 assert(src_clk_div - 1 < 127); 390 391 switch (clk_id) { 392 case SCLK_SPI0: 393 con_id = 30; 394 break; 395 case SCLK_SPI1: 396 con_id = 31; 397 break; 398 case SCLK_SPI2: 399 con_id = 32; 400 break; 401 default: 402 printf("do not support this spi bus\n"); 403 return -EINVAL; 404 } 405 406 rk_clrsetreg(&cru->clksel_con[con_id], 407 CLK_SPI_PLL_SEL_MASK | CLK_SPI_DIV_CON_MASK, 408 CLK_SPI_PLL_SEL_DPLL << CLK_SPI_PLL_SEL_SHIFT | 409 (src_clk_div - 1) << CLK_SPI_DIV_CON_SHIFT); 410 411 return rk3308_spi_get_clk(cru, clk_id); 412 } 413 414 static ulong rk3308_pwm_get_clk(struct rk3308_cru *cru) 415 { 416 u32 div, con; 417 418 con = readl(&cru->clksel_con[29]); 419 div = con >> CLK_PWM_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; 420 421 return DIV_TO_RATE(dpll_hz, div); 422 } 423 424 static ulong rk3308_pwm_set_clk(struct rk3308_cru *cru, uint hz) 425 { 426 int src_clk_div; 427 428 src_clk_div = dpll_hz / hz; 429 assert(src_clk_div - 1 < 127); 430 431 rk_clrsetreg(&cru->clksel_con[29], 432 CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 433 CLK_PWM_PLL_SEL_DPLL << CLK_PWM_PLL_SEL_SHIFT | 434 (src_clk_div - 1) << CLK_PWM_DIV_CON_SHIFT); 435 436 return rk3308_pwm_get_clk(cru); 437 } 438 439 static ulong rk3308_clk_get_rate(struct clk *clk) 440 { 441 struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); 442 ulong rate = 0; 443 444 debug("%s id:%ld\n", __func__, clk->id); 445 446 switch (clk->id) { 447 case 0 ... 15: 448 return 0; 449 case HCLK_SDMMC: 450 case HCLK_EMMC: 451 case SCLK_SDMMC: 452 case SCLK_EMMC: 453 case SCLK_EMMC_SAMPLE: 454 rate = rk3308_mmc_get_clk(priv->cru, clk->id); 455 break; 456 case SCLK_I2C0: 457 case SCLK_I2C1: 458 case SCLK_I2C2: 459 case SCLK_I2C3: 460 rate = rk3308_i2c_get_clk(priv->cru, clk->id); 461 break; 462 case SCLK_SARADC: 463 rate = rk3308_saradc_get_clk(priv->cru); 464 break; 465 case SCLK_SPI0: 466 case SCLK_SPI1: 467 rate = rk3308_spi_get_clk(priv->cru, clk->id); 468 break; 469 case SCLK_PWM: 470 rate = rk3308_pwm_get_clk(priv->cru); 471 break; 472 default: 473 return -ENOENT; 474 } 475 476 return rate; 477 } 478 479 static ulong rk3308_clk_set_rate(struct clk *clk, ulong rate) 480 { 481 struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); 482 ulong ret = 0; 483 484 debug("%s %ld %ld\n", __func__, clk->id, rate); 485 switch (clk->id) { 486 case 0 ... 15: 487 return 0; 488 case HCLK_SDMMC: 489 case HCLK_EMMC: 490 case SCLK_SDMMC: 491 case SCLK_EMMC: 492 ret = rk3308_mmc_set_clk(priv->cru, clk->id, rate); 493 break; 494 case SCLK_I2C0: 495 case SCLK_I2C1: 496 case SCLK_I2C2: 497 case SCLK_I2C3: 498 ret = rk3308_i2c_set_clk(priv->cru, clk->id, rate); 499 break; 500 case SCLK_SARADC: 501 ret = rk3308_saradc_set_clk(priv->cru, rate); 502 break; 503 case SCLK_SPI0: 504 case SCLK_SPI1: 505 ret = rk3308_spi_set_clk(priv->cru, clk->id, rate); 506 break; 507 case SCLK_PWM: 508 ret = rk3308_pwm_set_clk(priv->cru, rate); 509 break; 510 default: 511 return -ENOENT; 512 } 513 514 return ret; 515 } 516 517 #define ROCKCHIP_MMC_DELAY_SEL BIT(11) 518 #define ROCKCHIP_MMC_DEGREE_OFFSET 1 519 #define ROCKCHIP_MMC_DEGREE_MASK (0x3 << ROCKCHIP_MMC_DEGREE_OFFSET) 520 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 3 521 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 522 523 #define PSECS_PER_SEC 1000000000000LL 524 /* 525 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 526 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 527 */ 528 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 529 530 int rockchip_mmc_get_phase(struct clk *clk) 531 { 532 struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); 533 struct rk3308_cru *cru = priv->cru; 534 u32 raw_value, delay_num; 535 u16 degrees = 0; 536 ulong rate; 537 538 rate = rk3308_clk_get_rate(clk); 539 540 if (rate < 0) 541 return rate; 542 543 if (clk->id == SCLK_EMMC_SAMPLE) 544 raw_value = readl(&cru->emmc_con[1]); 545 else 546 raw_value = readl(&cru->sdmmc_con[1]); 547 548 raw_value &= ROCKCHIP_MMC_DEGREE_MASK; 549 degrees = (raw_value >> ROCKCHIP_MMC_DEGREE_OFFSET) * 90; 550 551 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 552 /* degrees/delaynum * 10000 */ 553 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 554 36 * (rate / 1000000); 555 556 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 557 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 558 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 559 } 560 561 return degrees % 360; 562 563 } 564 565 int rockchip_mmc_set_phase(struct clk *clk, u32 degrees) 566 { 567 struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); 568 struct rk3308_cru *cru = priv->cru; 569 u8 nineties, remainder, delay_num; 570 u32 raw_value, delay; 571 ulong rate; 572 573 rate = rk3308_clk_get_rate(clk); 574 575 if (rate < 0) 576 return rate; 577 578 nineties = degrees / 90; 579 remainder = (degrees % 90); 580 581 /* 582 * Convert to delay; do a little extra work to make sure we 583 * don't overflow 32-bit / 64-bit numbers. 584 */ 585 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 586 delay *= remainder; 587 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 588 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 589 590 delay_num = (u8)min_t(u32, delay, 255); 591 592 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 593 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 594 raw_value |= nineties << ROCKCHIP_MMC_DEGREE_OFFSET; 595 596 if (clk->id == SCLK_EMMC_SAMPLE) 597 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 598 else 599 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 600 601 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 602 degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk)); 603 604 return 0; 605 606 } 607 608 static int rk3308_clk_get_phase(struct clk *clk) 609 { 610 int ret; 611 612 switch (clk->id) { 613 case SCLK_EMMC_SAMPLE: 614 case SCLK_SDMMC_SAMPLE: 615 ret = rockchip_mmc_get_phase(clk); 616 break; 617 default: 618 return -ENOENT; 619 } 620 621 return ret; 622 } 623 624 static int rk3308_clk_set_phase(struct clk *clk, int degrees) 625 { 626 int ret; 627 628 switch (clk->id) { 629 case SCLK_EMMC_SAMPLE: 630 case SCLK_SDMMC_SAMPLE: 631 ret = rockchip_mmc_set_phase(clk, degrees); 632 break; 633 default: 634 return -ENOENT; 635 } 636 637 return ret; 638 } 639 640 static struct clk_ops rk3308_clk_ops = { 641 .get_rate = rk3308_clk_get_rate, 642 .set_rate = rk3308_clk_set_rate, 643 .get_phase = rk3308_clk_get_phase, 644 .set_phase = rk3308_clk_set_phase, 645 }; 646 647 static int rk3308_clk_probe(struct udevice *dev) 648 { 649 struct rk3308_clk_priv *priv = dev_get_priv(dev); 650 651 rkclk_init(priv->cru); 652 653 return 0; 654 } 655 656 static int rk3308_clk_ofdata_to_platdata(struct udevice *dev) 657 { 658 struct rk3308_clk_priv *priv = dev_get_priv(dev); 659 660 priv->cru = dev_read_addr_ptr(dev); 661 662 return 0; 663 } 664 665 static int rk3308_clk_bind(struct udevice *dev) 666 { 667 int ret; 668 struct udevice *sys_child, *sf_child; 669 struct sysreset_reg *priv; 670 struct softreset_reg *sf_priv; 671 672 /* The reset driver does not have a device node, so bind it here */ 673 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 674 &sys_child); 675 if (ret) { 676 debug("Warning: No sysreset driver: ret=%d\n", ret); 677 } else { 678 priv = malloc(sizeof(struct sysreset_reg)); 679 priv->glb_srst_fst_value = offsetof(struct rk3308_cru, 680 glb_srst_fst); 681 priv->glb_srst_snd_value = offsetof(struct rk3308_cru, 682 glb_srst_snd); 683 sys_child->priv = priv; 684 } 685 686 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 687 dev_ofnode(dev), &sf_child); 688 if (ret) { 689 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 690 } else { 691 sf_priv = malloc(sizeof(struct softreset_reg)); 692 sf_priv->sf_reset_offset = offsetof(struct rk3308_cru, 693 softrst_con[0]); 694 sf_priv->sf_reset_num = 12; 695 sf_child->priv = sf_priv; 696 } 697 698 return 0; 699 } 700 701 static const struct udevice_id rk3308_clk_ids[] = { 702 { .compatible = "rockchip,rk3308-cru" }, 703 { } 704 }; 705 706 U_BOOT_DRIVER(rockchip_rk3308_cru) = { 707 .name = "rockchip_rk3308_cru", 708 .id = UCLASS_CLK, 709 .of_match = rk3308_clk_ids, 710 .priv_auto_alloc_size = sizeof(struct rk3308_clk_priv), 711 .ofdata_to_platdata = rk3308_clk_ofdata_to_platdata, 712 .ops = &rk3308_clk_ops, 713 .bind = rk3308_clk_bind, 714 .probe = rk3308_clk_probe, 715 }; 716