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