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 <clk-uclass.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <syscon.h> 12 #include <asm/io.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rk3128.h> 15 #include <asm/arch/hardware.h> 16 #include <bitfield.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rk3128-cru.h> 19 #include <linux/log2.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 24 25 #ifndef CONFIG_SPL_BUILD 26 #define RK3128_CLK_DUMP(_id, _name, _iscru) \ 27 { \ 28 .id = _id, \ 29 .name = _name, \ 30 .is_cru = _iscru, \ 31 } 32 #endif 33 34 static struct rockchip_pll_rate_table rk3128_pll_rates[] = { 35 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 36 #ifndef CONFIG_SPL_BUILD 37 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 38 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), 39 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 40 #endif 41 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 42 RK3036_PLL_RATE(800000000, 1, 200, 6, 1, 1, 0), 43 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), 44 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), 45 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), 46 RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0), 47 { /* sentinel */ }, 48 }; 49 50 #define RK3128_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ 51 { \ 52 .rate = _rate##U, \ 53 .aclk_div = _aclk_div, \ 54 .pclk_div = _pclk_div, \ 55 } 56 57 static struct rockchip_cpu_rate_table rk3128_cpu_rates[] = { 58 RK3128_CPUCLK_RATE(1200000000, 1, 5), 59 RK3128_CPUCLK_RATE(1008000000, 1, 5), 60 RK3128_CPUCLK_RATE(816000000, 1, 3), 61 RK3128_CPUCLK_RATE(600000000, 1, 3), 62 }; 63 64 #ifndef CONFIG_SPL_BUILD 65 static const struct rk3128_clk_info clks_dump[] = { 66 RK3128_CLK_DUMP(PLL_APLL, "apll", true), 67 RK3128_CLK_DUMP(PLL_DPLL, "dpll", true), 68 RK3128_CLK_DUMP(PLL_CPLL, "cpll", true), 69 RK3128_CLK_DUMP(PLL_GPLL, "gpll", true), 70 RK3128_CLK_DUMP(ARMCLK, "armclk", true), 71 RK3128_CLK_DUMP(ACLK_CPU, "aclk_cpu", true), 72 RK3128_CLK_DUMP(HCLK_CPU, "hclk_cpu", true), 73 RK3128_CLK_DUMP(PCLK_CPU, "pclk_cpu", true), 74 RK3128_CLK_DUMP(ACLK_PERI, "aclk_peri", true), 75 RK3128_CLK_DUMP(HCLK_PERI, "hclk_peri", true), 76 RK3128_CLK_DUMP(PCLK_PERI, "pclk_peri", true), 77 }; 78 #endif 79 80 static struct rockchip_pll_clock rk3128_pll_clks[] = { 81 [APLL] = PLL(pll_rk3036, PLL_APLL, RK2928_PLL_CON(0), 82 RK2928_MODE_CON, 0, 10, 0, rk3128_pll_rates), 83 [DPLL] = PLL(pll_rk3036, PLL_DPLL, RK2928_PLL_CON(4), 84 RK2928_MODE_CON, 4, 10, 0, NULL), 85 [CPLL] = PLL(pll_rk3036, PLL_CPLL, RK2928_PLL_CON(8), 86 RK2928_MODE_CON, 8, 10, 0, rk3128_pll_rates), 87 [GPLL] = PLL(pll_rk3036, PLL_GPLL, RK2928_PLL_CON(12), 88 RK2928_MODE_CON, 12, 10, 0, rk3128_pll_rates), 89 }; 90 91 static ulong rk3128_armclk_set_clk(struct rk3128_clk_priv *priv, ulong hz) 92 { 93 struct rk3128_cru *cru = priv->cru; 94 const struct rockchip_cpu_rate_table *rate; 95 ulong old_rate; 96 97 rate = rockchip_get_cpu_settings(rk3128_cpu_rates, hz); 98 if (!rate) { 99 printf("%s unsupported rate\n", __func__); 100 return -EINVAL; 101 } 102 103 /* 104 * select apll as cpu/core clock pll source and 105 * set up dependent divisors for PERI and ACLK clocks. 106 * core hz : apll = 1:1 107 */ 108 old_rate = rockchip_pll_get_rate(&rk3128_pll_clks[APLL], 109 priv->cru, APLL); 110 if (old_rate > hz) { 111 if (rockchip_pll_set_rate(&rk3128_pll_clks[APLL], 112 priv->cru, APLL, hz)) 113 return -EINVAL; 114 rk_clrsetreg(&cru->cru_clksel_con[0], 115 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 116 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 117 0 << CORE_DIV_CON_SHIFT); 118 rk_clrsetreg(&cru->cru_clksel_con[1], 119 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 120 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 121 rate->pclk_div << CORE_DBG_DIV_SHIFT); 122 } else if (old_rate < hz) { 123 rk_clrsetreg(&cru->cru_clksel_con[1], 124 CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, 125 rate->aclk_div << CORE_ACLK_DIV_SHIFT | 126 rate->pclk_div << CORE_DBG_DIV_SHIFT); 127 rk_clrsetreg(&cru->cru_clksel_con[0], 128 CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK, 129 CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | 130 0 << CORE_DIV_CON_SHIFT); 131 if (rockchip_pll_set_rate(&rk3128_pll_clks[APLL], 132 priv->cru, APLL, hz)) 133 return -EINVAL; 134 } 135 136 return rockchip_pll_get_rate(&rk3128_pll_clks[APLL], priv->cru, APLL); 137 } 138 139 static ulong rockchip_mmc_get_clk(struct rk3128_clk_priv *priv, 140 int periph) 141 { 142 struct rk3128_cru *cru = priv->cru; 143 uint src_rate; 144 uint div, mux; 145 u32 con; 146 147 switch (periph) { 148 case HCLK_EMMC: 149 case SCLK_EMMC: 150 case SCLK_EMMC_SAMPLE: 151 con = readl(&cru->cru_clksel_con[12]); 152 mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT; 153 div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; 154 break; 155 case HCLK_SDMMC: 156 case SCLK_SDMMC: 157 case SCLK_SDMMC_SAMPLE: 158 con = readl(&cru->cru_clksel_con[11]); 159 mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT; 160 div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT; 161 break; 162 case HCLK_SDIO: 163 case SCLK_SDIO: 164 case SCLK_SDIO_SAMPLE: 165 con = readl(&cru->cru_clksel_con[12]); 166 mux = (con & SDIO_PLL_MASK) >> SDIO_PLL_SHIFT; 167 div = (con & SDIO_DIV_MASK) >> SDIO_DIV_SHIFT; 168 break; 169 default: 170 return -EINVAL; 171 } 172 173 src_rate = mux == EMMC_SEL_24M ? OSC_HZ : priv->gpll_hz; 174 return DIV_TO_RATE(src_rate, div); 175 } 176 177 static ulong rockchip_mmc_set_clk(struct rk3128_clk_priv *priv, 178 int periph, uint freq) 179 { 180 struct rk3128_cru *cru = priv->cru; 181 int src_clk_div; 182 int mux; 183 184 /* mmc clock defaulg div 2 internal, need provide double in cru */ 185 src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, freq); 186 187 if (src_clk_div > 128) { 188 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq); 189 mux = EMMC_SEL_24M; 190 } else { 191 mux = EMMC_SEL_GPLL; 192 } 193 194 switch (periph) { 195 case HCLK_EMMC: 196 case SCLK_EMMC: 197 rk_clrsetreg(&cru->cru_clksel_con[12], 198 EMMC_PLL_MASK | EMMC_DIV_MASK, 199 mux << EMMC_PLL_SHIFT | 200 (src_clk_div - 1) << EMMC_DIV_SHIFT); 201 break; 202 case HCLK_SDMMC: 203 case SCLK_SDMMC: 204 rk_clrsetreg(&cru->cru_clksel_con[11], 205 MMC0_PLL_MASK | MMC0_DIV_MASK, 206 mux << MMC0_PLL_SHIFT | 207 (src_clk_div - 1) << MMC0_DIV_SHIFT); 208 break; 209 case HCLK_SDIO: 210 case SCLK_SDIO: 211 rk_clrsetreg(&cru->cru_clksel_con[12], 212 SDIO_PLL_MASK | SDIO_DIV_MASK, 213 mux << SDIO_PLL_SHIFT | 214 (src_clk_div - 1) << SDIO_DIV_SHIFT); 215 break; 216 default: 217 return -EINVAL; 218 } 219 220 return rockchip_mmc_get_clk(priv, periph); 221 } 222 223 static ulong rk3128_peri_get_clk(struct rk3128_clk_priv *priv, ulong clk_id) 224 { 225 struct rk3128_cru *cru = priv->cru; 226 u32 div, con, parent; 227 228 switch (clk_id) { 229 case ACLK_PERI: 230 con = readl(&cru->cru_clksel_con[10]); 231 div = (con & ACLK_PERI_DIV_MASK) >> ACLK_PERI_DIV_SHIFT; 232 parent = priv->gpll_hz; 233 break; 234 case PCLK_PERI: 235 case PCLK_I2C0: 236 case PCLK_I2C1: 237 case PCLK_I2C2: 238 case PCLK_I2C3: 239 case PCLK_PWM: 240 case PCLK_WDT: 241 con = readl(&cru->cru_clksel_con[10]); 242 div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT; 243 parent = rk3128_peri_get_clk(priv, ACLK_PERI); 244 break; 245 case HCLK_PERI: 246 con = readl(&cru->cru_clksel_con[10]); 247 div = (con & HCLK_PERI_DIV_MASK) >> HCLK_PERI_DIV_SHIFT; 248 parent = rk3128_peri_get_clk(priv, ACLK_PERI); 249 break; 250 default: 251 printf("do not support this peripheral bus\n"); 252 return -EINVAL; 253 } 254 255 return DIV_TO_RATE(parent, div); 256 } 257 258 static ulong rk3128_peri_set_clk(struct rk3128_clk_priv *priv, 259 ulong clk_id, uint hz) 260 { 261 struct rk3128_cru *cru = priv->cru; 262 int src_clk_div; 263 264 switch (clk_id) { 265 case ACLK_PERI: 266 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 267 assert(src_clk_div - 1 < 32); 268 rk_clrsetreg(&cru->cru_clksel_con[10], 269 PERI_PLL_SEL_MASK | ACLK_PERI_DIV_MASK, 270 PERI_PLL_SEL_GPLL << PERI_PLL_SEL_SHIFT | 271 (src_clk_div - 1) << ACLK_PERI_DIV_SHIFT); 272 break; 273 case PCLK_I2C0: 274 case PCLK_I2C1: 275 case PCLK_I2C2: 276 case PCLK_I2C3: 277 case PCLK_PWM: 278 case PCLK_PERI: 279 src_clk_div = DIV_ROUND_UP(rk3128_peri_get_clk(priv, 280 ACLK_PERI), 281 hz); 282 assert(src_clk_div - 1 < 3); 283 rk_clrsetreg(&cru->cru_clksel_con[10], 284 PCLK_PERI_DIV_MASK, 285 (src_clk_div - 1) << PCLK_PERI_DIV_SHIFT); 286 break; 287 case HCLK_PERI: 288 src_clk_div = DIV_ROUND_UP(rk3128_peri_get_clk(priv, 289 ACLK_PERI), 290 hz); 291 assert(src_clk_div - 1 < 7); 292 rk_clrsetreg(&cru->cru_clksel_con[10], 293 HCLK_PERI_DIV_MASK, 294 (src_clk_div - 1) << HCLK_PERI_DIV_SHIFT); 295 break; 296 default: 297 printf("do not support this peripheral bus\n"); 298 return -EINVAL; 299 } 300 301 return rk3128_peri_get_clk(priv, clk_id); 302 } 303 304 static ulong rk3128_bus_get_clk(struct rk3128_clk_priv *priv, ulong clk_id) 305 { 306 struct rk3128_cru *cru = priv->cru; 307 u32 div, con, parent; 308 309 switch (clk_id) { 310 case ACLK_CPU: 311 con = readl(&cru->cru_clksel_con[0]); 312 div = (con & ACLK_BUS_DIV_MASK) >> ACLK_BUS_DIV_SHIFT; 313 parent = priv->gpll_hz; 314 break; 315 case PCLK_CPU: 316 con = readl(&cru->cru_clksel_con[1]); 317 div = (con & PCLK_BUS_DIV_MASK) >> PCLK_BUS_DIV_SHIFT; 318 parent = rk3128_bus_get_clk(priv, ACLK_CPU); 319 break; 320 case HCLK_CPU: 321 con = readl(&cru->cru_clksel_con[1]); 322 div = (con & HCLK_BUS_DIV_MASK) >> HCLK_BUS_DIV_SHIFT; 323 parent = rk3128_bus_get_clk(priv, ACLK_CPU); 324 break; 325 default: 326 printf("do not support this peripheral bus\n"); 327 return -EINVAL; 328 } 329 330 return DIV_TO_RATE(parent, div); 331 } 332 333 static ulong rk3128_bus_set_clk(struct rk3128_clk_priv *priv, 334 ulong clk_id, uint hz) 335 { 336 struct rk3128_cru *cru = priv->cru; 337 int src_clk_div; 338 339 switch (clk_id) { 340 case ACLK_CPU: 341 src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); 342 assert(src_clk_div - 1 < 32); 343 rk_clrsetreg(&cru->cru_clksel_con[0], 344 BUS_PLL_SEL_MASK | ACLK_BUS_DIV_MASK, 345 BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT | 346 (src_clk_div - 1) << ACLK_BUS_DIV_SHIFT); 347 break; 348 case PCLK_CPU: 349 src_clk_div = DIV_ROUND_UP(rk3128_bus_get_clk(priv, 350 ACLK_CPU), 351 hz); 352 assert(src_clk_div - 1 < 3); 353 rk_clrsetreg(&cru->cru_clksel_con[1], 354 PCLK_BUS_DIV_MASK, 355 (src_clk_div - 1) << PCLK_BUS_DIV_SHIFT); 356 break; 357 case HCLK_CPU: 358 src_clk_div = DIV_ROUND_UP(rk3128_bus_get_clk(priv, 359 ACLK_CPU), 360 hz); 361 assert(src_clk_div - 1 < 7); 362 rk_clrsetreg(&cru->cru_clksel_con[1], 363 HCLK_BUS_DIV_MASK, 364 (src_clk_div - 1) << HCLK_BUS_DIV_SHIFT); 365 break; 366 default: 367 printf("do not support this peripheral bus\n"); 368 return -EINVAL; 369 } 370 371 return rk3128_bus_get_clk(priv, clk_id); 372 } 373 374 #ifndef CONFIG_SPL_BUILD 375 static ulong rk3128_saradc_get_clk(struct rk3128_clk_priv *priv) 376 { 377 struct rk3128_cru *cru = priv->cru; 378 u32 div, val; 379 380 val = readl(&cru->cru_clksel_con[24]); 381 div = bitfield_extract(val, SARADC_DIV_CON_SHIFT, 382 SARADC_DIV_CON_WIDTH); 383 384 return DIV_TO_RATE(OSC_HZ, div); 385 } 386 387 static ulong rk3128_saradc_set_clk(struct rk3128_clk_priv *priv, uint hz) 388 { 389 struct rk3128_cru *cru = priv->cru; 390 int src_clk_div; 391 392 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 393 assert(src_clk_div < 128); 394 395 rk_clrsetreg(&cru->cru_clksel_con[24], 396 SARADC_DIV_CON_MASK, 397 src_clk_div << SARADC_DIV_CON_SHIFT); 398 399 return rk3128_saradc_get_clk(priv); 400 } 401 402 #define RK3128_LCDC_PLL_LIMIT 600000000 403 404 static ulong rk3128_vop_set_clk(struct rk3128_clk_priv *priv, 405 ulong clk_id, uint hz) 406 { 407 struct rk3128_cru *cru = priv->cru; 408 int src_clk_div; 409 410 src_clk_div = GPLL_HZ / hz; 411 assert(src_clk_div - 1 < 31); 412 413 switch (clk_id) { 414 case ACLK_LCDC0: 415 case ACLK_VIO0: 416 rk_clrsetreg(&cru->cru_clksel_con[31], 417 VIO0_PLL_MASK | VIO0_DIV_MASK, 418 VIO0_SEL_GPLL << VIO0_PLL_SHIFT | 419 (src_clk_div - 1) << VIO0_DIV_SHIFT); 420 break; 421 case ACLK_VIO1: 422 rk_clrsetreg(&cru->cru_clksel_con[31], 423 VIO1_PLL_MASK | VIO1_DIV_MASK, 424 VIO1_SEL_GPLL << VIO1_PLL_SHIFT | 425 (src_clk_div - 1) << VIO1_DIV_SHIFT); 426 break; 427 case DCLK_VOP: 428 src_clk_div = DIV_ROUND_UP(RK3128_LCDC_PLL_LIMIT, hz); 429 rockchip_pll_set_rate(&rk3128_pll_clks[CPLL], 430 priv->cru, CPLL, src_clk_div * hz); 431 rk_clrsetreg(&cru->cru_clksel_con[27], 432 DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_CON_MASK, 433 DCLK_VOP_PLL_SEL_CPLL << DCLK_VOP_SEL_SHIFT | 434 (src_clk_div - 1) << DCLK_VOP_DIV_CON_SHIFT); 435 break; 436 default: 437 printf("do not support this vop freq\n"); 438 return -EINVAL; 439 } 440 441 return hz; 442 } 443 444 static ulong rk3128_vop_get_rate(struct rk3128_clk_priv *priv, ulong clk_id) 445 { 446 struct rk3128_cru *cru = priv->cru; 447 u32 div, con, parent; 448 449 switch (clk_id) { 450 case ACLK_LCDC0: 451 case ACLK_VIO0: 452 con = readl(&cru->cru_clksel_con[31]); 453 div = con & 0x1f; 454 parent = GPLL_HZ; 455 break; 456 case ACLK_VIO1: 457 con = readl(&cru->cru_clksel_con[31]); 458 div = (con >> 8) & 0x1f; 459 parent = GPLL_HZ; 460 break; 461 case DCLK_VOP: 462 con = readl(&cru->cru_clksel_con[27]); 463 div = (con & DCLK_VOP_DIV_CON_MASK) >> DCLK_VOP_DIV_CON_SHIFT; 464 parent = rockchip_pll_get_rate(&rk3128_pll_clks[CPLL], 465 priv->cru, CPLL); 466 break; 467 default: 468 return -ENOENT; 469 } 470 return DIV_TO_RATE(parent, div); 471 } 472 473 static ulong rk3128_crypto_get_rate(struct rk3128_clk_priv *priv) 474 { 475 struct rk3128_cru *cru = priv->cru; 476 u32 div, val; 477 478 val = readl(&cru->cru_clksel_con[24]); 479 div = (val & CLK_CRYPTO_DIV_CON_MASK) >> CLK_CRYPTO_DIV_CON_SHIFT; 480 481 return DIV_TO_RATE(rk3128_bus_get_clk(priv, ACLK_CPU), div); 482 } 483 484 static ulong rk3128_crypto_set_rate(struct rk3128_clk_priv *priv, 485 uint hz) 486 { 487 struct rk3128_cru *cru = priv->cru; 488 int src_clk_div; 489 uint p_rate; 490 491 p_rate = rk3128_bus_get_clk(priv, ACLK_CPU); 492 src_clk_div = DIV_ROUND_UP(p_rate, hz) - 1; 493 assert(src_clk_div < 3); 494 495 rk_clrsetreg(&cru->cru_clksel_con[24], 496 CLK_CRYPTO_DIV_CON_MASK, 497 src_clk_div << CLK_CRYPTO_DIV_CON_SHIFT); 498 499 return rk3128_crypto_get_rate(priv); 500 } 501 #endif 502 503 static ulong rk3128_clk_get_rate(struct clk *clk) 504 { 505 struct rk3128_clk_priv *priv = dev_get_priv(clk->dev); 506 ulong rate = 0; 507 508 switch (clk->id) { 509 case PLL_APLL: 510 case PLL_DPLL: 511 case PLL_CPLL: 512 case PLL_GPLL: 513 rate = rockchip_pll_get_rate(&rk3128_pll_clks[clk->id - 1], 514 priv->cru, clk->id - 1); 515 break; 516 case ARMCLK: 517 rate = rockchip_pll_get_rate(&rk3128_pll_clks[APLL], 518 priv->cru, APLL); 519 break; 520 case HCLK_EMMC: 521 case SCLK_EMMC: 522 case HCLK_SDMMC: 523 case SCLK_SDMMC: 524 case HCLK_SDIO: 525 case SCLK_SDIO: 526 rate = rockchip_mmc_get_clk(priv, clk->id); 527 break; 528 case ACLK_PERI: 529 case HCLK_PERI: 530 case PCLK_PERI: 531 case PCLK_I2C0: 532 case PCLK_I2C1: 533 case PCLK_I2C2: 534 case PCLK_I2C3: 535 case PCLK_PWM: 536 case PCLK_WDT: 537 rate = rk3128_peri_get_clk(priv, clk->id); 538 break; 539 case ACLK_CPU: 540 case HCLK_CPU: 541 case PCLK_CPU: 542 rate = rk3128_bus_get_clk(priv, clk->id); 543 break; 544 #ifndef CONFIG_SPL_BUILD 545 case SCLK_SARADC: 546 rate = rk3128_saradc_get_clk(priv); 547 break; 548 case DCLK_VOP: 549 case ACLK_VIO0: 550 case ACLK_VIO1: 551 case ACLK_LCDC0: 552 rate = rk3128_vop_get_rate(priv, clk->id); 553 break; 554 case SCLK_CRYPTO: 555 rate = rk3128_crypto_get_rate(priv); 556 break; 557 #endif 558 default: 559 return -ENOENT; 560 } 561 return rate; 562 } 563 564 static ulong rk3128_clk_set_rate(struct clk *clk, ulong rate) 565 { 566 struct rk3128_clk_priv *priv = dev_get_priv(clk->dev); 567 ulong ret = 0; 568 569 switch (clk->id) { 570 case PLL_APLL: 571 case PLL_DPLL: 572 case PLL_CPLL: 573 ret = rockchip_pll_set_rate(&rk3128_pll_clks[clk->id - 1], 574 priv->cru, clk->id - 1, rate); 575 case PLL_GPLL: 576 ret = rockchip_pll_set_rate(&rk3128_pll_clks[GPLL], 577 priv->cru, GPLL, rate); 578 priv->gpll_hz = rate; 579 break; 580 case ARMCLK: 581 if (priv->armclk_hz) 582 ret = rk3128_armclk_set_clk(priv, rate); 583 priv->armclk_hz = rate; 584 break; 585 case HCLK_EMMC: 586 case SCLK_EMMC: 587 case SCLK_EMMC_SAMPLE: 588 case HCLK_SDMMC: 589 case SCLK_SDMMC: 590 case SCLK_SDMMC_SAMPLE: 591 case HCLK_SDIO: 592 case SCLK_SDIO: 593 case SCLK_SDIO_SAMPLE: 594 ret = rockchip_mmc_set_clk(priv, clk->id, rate); 595 break; 596 case ACLK_PERI: 597 case PCLK_PERI: 598 case HCLK_PERI: 599 case PCLK_I2C0: 600 case PCLK_I2C1: 601 case PCLK_I2C2: 602 case PCLK_I2C3: 603 case PCLK_PWM: 604 ret = rk3128_peri_set_clk(priv, clk->id, rate); 605 break; 606 case ACLK_CPU: 607 case HCLK_CPU: 608 case PCLK_CPU: 609 ret = rk3128_bus_set_clk(priv, clk->id, rate); 610 break; 611 #ifndef CONFIG_SPL_BUILD 612 case SCLK_SARADC: 613 ret = rk3128_saradc_set_clk(priv, rate); 614 break; 615 case DCLK_VOP: 616 case ACLK_VIO0: 617 case ACLK_VIO1: 618 case ACLK_LCDC0: 619 ret = rk3128_vop_set_clk(priv, clk->id, rate); 620 break; 621 case SCLK_CRYPTO: 622 ret = rk3128_crypto_set_rate(priv, rate); 623 break; 624 #endif 625 default: 626 return -ENOENT; 627 } 628 return ret; 629 } 630 631 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 632 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 633 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 634 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 635 636 #define PSECS_PER_SEC 1000000000000LL 637 /* 638 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 639 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 640 */ 641 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 642 643 int rk3128_mmc_get_phase(struct clk *clk) 644 { 645 struct rk3128_clk_priv *priv = dev_get_priv(clk->dev); 646 struct rk3128_cru *cru = priv->cru; 647 u32 raw_value, delay_num; 648 u16 degrees = 0; 649 ulong rate; 650 651 rate = rk3128_clk_get_rate(clk); 652 653 if (rate < 0) 654 return rate; 655 656 if (clk->id == SCLK_EMMC_SAMPLE) 657 raw_value = readl(&cru->cru_emmc_con[1]); 658 else if (clk->id == SCLK_SDMMC_SAMPLE) 659 raw_value = readl(&cru->cru_sdmmc_con[1]); 660 else 661 raw_value = readl(&cru->cru_sdio_con[1]); 662 663 raw_value >>= 1; 664 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 665 666 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 667 /* degrees/delaynum * 10000 */ 668 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 669 36 * (rate / 1000000); 670 671 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 672 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 673 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 674 } 675 676 return degrees % 360; 677 } 678 679 int rk3128_mmc_set_phase(struct clk *clk, u32 degrees) 680 { 681 struct rk3128_clk_priv *priv = dev_get_priv(clk->dev); 682 struct rk3128_cru *cru = priv->cru; 683 u8 nineties, remainder, delay_num; 684 u32 raw_value, delay; 685 ulong rate; 686 687 rate = rk3128_clk_get_rate(clk); 688 689 if (rate < 0) 690 return rate; 691 692 nineties = degrees / 90; 693 remainder = (degrees % 90); 694 695 /* 696 * Convert to delay; do a little extra work to make sure we 697 * don't overflow 32-bit / 64-bit numbers. 698 */ 699 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 700 delay *= remainder; 701 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 702 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 703 704 delay_num = (u8)min_t(u32, delay, 255); 705 706 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 707 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 708 raw_value |= nineties; 709 710 raw_value <<= 1; 711 if (clk->id == SCLK_EMMC_SAMPLE) 712 writel(raw_value | 0xffff0000, &cru->cru_emmc_con[1]); 713 else if (clk->id == SCLK_SDMMC_SAMPLE) 714 writel(raw_value | 0xffff0000, &cru->cru_sdmmc_con[1]); 715 else 716 writel(raw_value | 0xffff0000, &cru->cru_sdio_con[1]); 717 718 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 719 degrees, delay_num, raw_value, rk3128_mmc_get_phase(clk)); 720 721 return 0; 722 } 723 724 static int rk3128_clk_get_phase(struct clk *clk) 725 { 726 int ret; 727 728 debug("%s %ld\n", __func__, clk->id); 729 switch (clk->id) { 730 case SCLK_EMMC_SAMPLE: 731 case SCLK_SDMMC_SAMPLE: 732 case SCLK_SDIO_SAMPLE: 733 ret = rk3128_mmc_get_phase(clk); 734 break; 735 default: 736 return -ENOENT; 737 } 738 739 return ret; 740 } 741 742 static int rk3128_clk_set_phase(struct clk *clk, int degrees) 743 { 744 int ret; 745 746 debug("%s %ld\n", __func__, clk->id); 747 switch (clk->id) { 748 case SCLK_EMMC_SAMPLE: 749 case SCLK_SDMMC_SAMPLE: 750 case SCLK_SDIO_SAMPLE: 751 ret = rk3128_mmc_set_phase(clk, degrees); 752 break; 753 default: 754 return -ENOENT; 755 } 756 757 return ret; 758 } 759 760 static struct clk_ops rk3128_clk_ops = { 761 .get_rate = rk3128_clk_get_rate, 762 .set_rate = rk3128_clk_set_rate, 763 .get_phase = rk3128_clk_get_phase, 764 .set_phase = rk3128_clk_set_phase, 765 }; 766 767 static int rk3128_clk_ofdata_to_platdata(struct udevice *dev) 768 { 769 struct rk3128_clk_priv *priv = dev_get_priv(dev); 770 771 priv->cru = dev_read_addr_ptr(dev); 772 773 return 0; 774 } 775 776 static void rkclk_init(struct rk3128_clk_priv *priv) 777 { 778 if (rockchip_pll_get_rate(&rk3128_pll_clks[APLL], 779 priv->cru, APLL) != APLL_HZ) 780 rk3128_armclk_set_clk(priv, APLL_HZ); 781 782 priv->gpll_hz = rockchip_pll_get_rate(&rk3128_pll_clks[GPLL], 783 priv->cru, GPLL); 784 rk3128_bus_set_clk(priv, ACLK_CPU, ACLK_BUS_HZ / 2); 785 rk3128_peri_set_clk(priv, ACLK_PERI, ACLK_PERI_HZ / 2); 786 rockchip_pll_set_rate(&rk3128_pll_clks[GPLL], 787 priv->cru, GPLL, GPLL_HZ); 788 priv->gpll_hz = GPLL_HZ; 789 rk_clrsetreg(&priv->cru->cru_clksel_con[2], 790 NANDC_PLL_SEL_MASK | NANDC_CLK_DIV_MASK, 791 NANDC_PLL_SEL_GPLL << NANDC_PLL_SEL_SHIFT | 792 3 << NANDC_CLK_DIV_SHIFT); 793 rk_clrsetreg(&priv->cru->cru_clksel_con[11], 794 SFC_PLL_SEL_MASK | SFC_CLK_DIV_MASK, 795 SFC_PLL_SEL_GPLL << SFC_PLL_SEL_SHIFT | 796 9 << SFC_CLK_DIV_SHIFT); 797 798 rk3128_bus_set_clk(priv, ACLK_CPU, ACLK_BUS_HZ); 799 rk3128_bus_set_clk(priv, HCLK_CPU, ACLK_BUS_HZ / 2); 800 rk3128_bus_set_clk(priv, PCLK_CPU, ACLK_BUS_HZ / 2); 801 rk3128_peri_set_clk(priv, ACLK_PERI, ACLK_PERI_HZ); 802 rk3128_peri_set_clk(priv, HCLK_PERI, ACLK_PERI_HZ / 2); 803 rk3128_peri_set_clk(priv, PCLK_PERI, ACLK_PERI_HZ / 2); 804 805 rockchip_pll_set_rate(&rk3128_pll_clks[CPLL], 806 priv->cru, CPLL, CPLL_HZ); 807 } 808 809 static int rk3128_clk_probe(struct udevice *dev) 810 { 811 struct rk3128_clk_priv *priv = dev_get_priv(dev); 812 813 priv->sync_kernel = false; 814 if (!priv->armclk_enter_hz) 815 priv->armclk_enter_hz = 816 rockchip_pll_get_rate(&rk3128_pll_clks[APLL], 817 priv->cru, APLL); 818 rkclk_init(priv); 819 if (!priv->armclk_init_hz) 820 priv->armclk_init_hz = 821 rockchip_pll_get_rate(&rk3128_pll_clks[APLL], 822 priv->cru, APLL); 823 824 return 0; 825 } 826 827 static int rk3128_clk_bind(struct udevice *dev) 828 { 829 int ret; 830 struct udevice *sys_child, *sf_child; 831 struct sysreset_reg *priv; 832 struct softreset_reg *sf_priv; 833 834 /* The reset driver does not have a device node, so bind it here */ 835 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 836 &sys_child); 837 if (ret) { 838 debug("Warning: No sysreset driver: ret=%d\n", ret); 839 } else { 840 priv = malloc(sizeof(struct sysreset_reg)); 841 priv->glb_srst_fst_value = offsetof(struct rk3128_cru, 842 cru_glb_srst_fst_value); 843 priv->glb_srst_snd_value = offsetof(struct rk3128_cru, 844 cru_glb_srst_snd_value); 845 sys_child->priv = priv; 846 } 847 848 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 849 dev_ofnode(dev), &sf_child); 850 if (ret) { 851 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 852 } else { 853 sf_priv = malloc(sizeof(struct softreset_reg)); 854 sf_priv->sf_reset_offset = offsetof(struct rk3128_cru, 855 cru_softrst_con[0]); 856 sf_priv->sf_reset_num = 9; 857 sf_child->priv = sf_priv; 858 } 859 860 return 0; 861 } 862 863 static const struct udevice_id rk3128_clk_ids[] = { 864 { .compatible = "rockchip,rk3128-cru" }, 865 { .compatible = "rockchip,rk3126-cru" }, 866 { } 867 }; 868 869 U_BOOT_DRIVER(rockchip_rk3128_cru) = { 870 .name = "clk_rk3128", 871 .id = UCLASS_CLK, 872 .of_match = rk3128_clk_ids, 873 .priv_auto_alloc_size = sizeof(struct rk3128_clk_priv), 874 .ofdata_to_platdata = rk3128_clk_ofdata_to_platdata, 875 .ops = &rk3128_clk_ops, 876 .bind = rk3128_clk_bind, 877 .probe = rk3128_clk_probe, 878 }; 879 880 #ifndef CONFIG_SPL_BUILD 881 /** 882 * soc_clk_dump() - Print clock frequencies 883 * Returns zero on success 884 * 885 * Implementation for the clk dump command. 886 */ 887 int soc_clk_dump(void) 888 { 889 struct udevice *cru_dev; 890 struct rk3128_clk_priv *priv; 891 const struct rk3128_clk_info *clk_dump; 892 struct clk clk; 893 unsigned long clk_count = ARRAY_SIZE(clks_dump); 894 unsigned long rate; 895 int i, ret; 896 897 ret = uclass_get_device_by_driver(UCLASS_CLK, 898 DM_GET_DRIVER(rockchip_rk3128_cru), 899 &cru_dev); 900 if (ret) { 901 printf("%s failed to get cru device\n", __func__); 902 return ret; 903 } 904 905 priv = dev_get_priv(cru_dev); 906 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 907 priv->sync_kernel ? "sync kernel" : "uboot", 908 priv->armclk_enter_hz / 1000, 909 priv->armclk_init_hz / 1000, 910 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 911 priv->set_armclk_rate ? " KHz" : "N/A"); 912 for (i = 0; i < clk_count; i++) { 913 clk_dump = &clks_dump[i]; 914 if (clk_dump->name) { 915 clk.id = clk_dump->id; 916 if (clk_dump->is_cru) 917 ret = clk_request(cru_dev, &clk); 918 if (ret < 0) 919 return ret; 920 921 rate = clk_get_rate(&clk); 922 clk_free(&clk); 923 if (i == 0) { 924 if (rate < 0) 925 printf(" %s %s\n", clk_dump->name, 926 "unknown"); 927 else 928 printf(" %s %lu KHz\n", clk_dump->name, 929 rate / 1000); 930 } else { 931 if (rate < 0) 932 printf(" %s %s\n", clk_dump->name, 933 "unknown"); 934 else 935 printf(" %s %lu KHz\n", clk_dump->name, 936 rate / 1000); 937 } 938 } 939 } 940 941 return 0; 942 } 943 #endif 944 945