1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2021 Rockchip Electronics Co., Ltd 4 * Author: Elaine Zhang <zhangqing@rock-chips.com> 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_rv1106.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/io.h> 17 #include <dm/lists.h> 18 #include <dt-bindings/clock/rv1106-cru.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 23 24 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 25 static struct rockchip_pll_rate_table rv1106_pll_rates[] = { 26 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 27 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), 28 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 29 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), 30 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 31 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), 32 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), 33 { /* sentinel */ }, 34 }; 35 36 static struct rockchip_pll_clock rv1106_pll_clks[] = { 37 [APLL] = PLL(pll_rk3328, PLL_APLL, RV1106_PLL_CON(0), 38 RV1106_MODE_CON, 0, 10, 0, rv1106_pll_rates), 39 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1106_PLL_CON(16), 40 RV1106_SUBDDRMODE_CON, 0, 10, 0, NULL), 41 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1106_PLL_CON(8), 42 RV1106_MODE_CON, 2, 10, 0, rv1106_pll_rates), 43 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1106_PLL_CON(24), 44 RV1106_MODE_CON, 4, 10, 0, rv1106_pll_rates), 45 }; 46 #endif 47 48 #ifndef CONFIG_SPL_BUILD 49 #define RV1106_CLK_DUMP(_id, _name, _iscru) \ 50 { \ 51 .id = _id, \ 52 .name = _name, \ 53 .is_cru = _iscru, \ 54 } 55 56 static const struct rv1106_clk_info clks_dump[] = { 57 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 58 RV1106_CLK_DUMP(PLL_APLL, "apll", true), 59 RV1106_CLK_DUMP(PLL_DPLL, "dpll", true), 60 RV1106_CLK_DUMP(PLL_GPLL, "gpll", true), 61 RV1106_CLK_DUMP(PLL_CPLL, "cpll", true), 62 RV1106_CLK_DUMP(ACLK_PERI_ROOT, "aclk_peri_root", true), 63 RV1106_CLK_DUMP(HCLK_PERI_ROOT, "hclK_peri_root", true), 64 RV1106_CLK_DUMP(PCLK_PERI_ROOT, "pclk_peri_root", true), 65 RV1106_CLK_DUMP(ACLK_BUS_ROOT, "aclk_bus_root", true), 66 RV1106_CLK_DUMP(PCLK_TOP_ROOT, "pclk_top_root", true), 67 RV1106_CLK_DUMP(PCLK_PMU_ROOT, "pclk_pmu_root", true), 68 RV1106_CLK_DUMP(HCLK_PMU_ROOT, "hclk_pmu_root", true), 69 #endif 70 }; 71 #endif 72 73 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 74 static ulong rv1106_peri_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 75 { 76 struct rv1106_cru *cru = priv->cru; 77 u32 con, sel, rate; 78 79 switch (clk_id) { 80 case ACLK_PERI_ROOT: 81 con = readl(&cru->peri_clksel_con[1]); 82 sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT; 83 if (sel == ACLK_PERI_SEL_400M) 84 rate = 400 * MHz; 85 else if (sel == ACLK_PERI_SEL_200M) 86 rate = 200 * MHz; 87 else if (sel == ACLK_PERI_SEL_100M) 88 rate = 100 * MHz; 89 else 90 rate = OSC_HZ; 91 break; 92 case HCLK_PERI_ROOT: 93 con = readl(&cru->peri_clksel_con[1]); 94 sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT; 95 if (sel == HCLK_PERI_SEL_200M) 96 rate = 200 * MHz; 97 else if (sel == HCLK_PERI_SEL_100M) 98 rate = 100 * MHz; 99 else if (sel == HCLK_PERI_SEL_50M) 100 rate = 50 * MHz; 101 else 102 rate = OSC_HZ; 103 break; 104 case PCLK_PERI_ROOT: 105 con = readl(&cru->peri_clksel_con[1]); 106 sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT; 107 if (sel == PCLK_PERI_SEL_100M) 108 rate = 100 * MHz; 109 else if (sel == PCLK_PERI_SEL_50M) 110 rate = 50 * MHz; 111 else 112 rate = OSC_HZ; 113 break; 114 case ACLK_BUS_ROOT: 115 con = readl(&cru->peri_clksel_con[9]); 116 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT; 117 if (sel == ACLK_BUS_SEL_300M) 118 rate = 300 * MHz; 119 else if (sel == ACLK_BUS_SEL_200M) 120 rate = 200 * MHz; 121 else if (sel == ACLK_BUS_SEL_100M) 122 rate = 100 * MHz; 123 else 124 rate = OSC_HZ; 125 break; 126 case PCLK_TOP_ROOT: 127 con = readl(&cru->clksel_con[24]); 128 sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; 129 if (sel == PCLK_TOP_SEL_100M) 130 rate = 100 * MHz; 131 else if (sel == PCLK_TOP_SEL_50M) 132 rate = 50 * MHz; 133 else 134 rate = OSC_HZ; 135 break; 136 case PCLK_PMU_ROOT: 137 con = readl(&cru->pmu_clksel_con[0]); 138 sel = (con & PCLK_PMU_SEL_MASK) >> PCLK_PMU_SEL_SHIFT; 139 if (sel == PCLK_PMU_SEL_100M) 140 rate = 100 * MHz; 141 else 142 rate = OSC_HZ; 143 break; 144 case HCLK_PMU_ROOT: 145 con = readl(&cru->pmu_clksel_con[0]); 146 sel = (con & HCLK_PMU_SEL_MASK) >> HCLK_PMU_SEL_SHIFT; 147 if (sel == HCLK_PMU_SEL_200M) 148 rate = 200 * MHz; 149 else if (sel == HCLK_PMU_SEL_100M) 150 rate = 100 * MHz; 151 else 152 rate = OSC_HZ; 153 break; 154 default: 155 return -ENOENT; 156 } 157 158 return rate; 159 } 160 161 static ulong rv1106_peri_set_clk(struct rv1106_clk_priv *priv, 162 ulong clk_id, ulong rate) 163 { 164 struct rv1106_cru *cru = priv->cru; 165 int src_clk; 166 167 switch (clk_id) { 168 case ACLK_PERI_ROOT: 169 if (rate >= 396 * MHz) 170 src_clk = ACLK_PERI_SEL_400M; 171 else if (rate >= 198 * MHz) 172 src_clk = ACLK_PERI_SEL_200M; 173 else if (rate >= 99 * MHz) 174 src_clk = ACLK_PERI_SEL_100M; 175 else 176 src_clk = ACLK_PERI_SEL_24M; 177 rk_clrsetreg(&cru->peri_clksel_con[1], 178 ACLK_PERI_SEL_MASK, 179 src_clk << ACLK_PERI_SEL_SHIFT); 180 break; 181 case HCLK_PERI_ROOT: 182 if (rate >= 198 * MHz) 183 src_clk = HCLK_PERI_SEL_200M; 184 else if (rate >= 99 * MHz) 185 src_clk = HCLK_PERI_SEL_100M; 186 else if (rate >= 48 * MHz) 187 src_clk = HCLK_PERI_SEL_50M; 188 else 189 src_clk = HCLK_PERI_SEL_24M; 190 rk_clrsetreg(&cru->peri_clksel_con[1], 191 HCLK_PERI_SEL_MASK, 192 src_clk << HCLK_PERI_SEL_SHIFT); 193 break; 194 case PCLK_PERI_ROOT: 195 if (rate >= 99 * MHz) 196 src_clk = PCLK_PERI_SEL_100M; 197 else if (rate >= 48 * MHz) 198 src_clk = PCLK_PERI_SEL_50M; 199 else 200 src_clk = PCLK_PERI_SEL_24M; 201 rk_clrsetreg(&cru->peri_clksel_con[1], 202 PCLK_PERI_SEL_MASK, 203 src_clk << PCLK_PERI_SEL_SHIFT); 204 break; 205 case ACLK_BUS_ROOT: 206 if (rate >= 297 * MHz) 207 src_clk = ACLK_BUS_SEL_300M; 208 else if (rate >= 198 * MHz) 209 src_clk = ACLK_BUS_SEL_200M; 210 else if (rate >= 99 * MHz) 211 src_clk = ACLK_BUS_SEL_100M; 212 else 213 src_clk = ACLK_BUS_SEL_24M; 214 rk_clrsetreg(&cru->peri_clksel_con[9], 215 ACLK_BUS_SEL_MASK, 216 src_clk << ACLK_BUS_SEL_SHIFT); 217 break; 218 case PCLK_TOP_ROOT: 219 if (rate >= 99 * MHz) 220 src_clk = PCLK_TOP_SEL_100M; 221 else if (rate >= 48 * MHz) 222 src_clk = PCLK_TOP_SEL_50M; 223 else 224 src_clk = PCLK_TOP_SEL_24M; 225 rk_clrsetreg(&cru->clksel_con[24], 226 PCLK_TOP_SEL_MASK, 227 src_clk << PCLK_TOP_SEL_SHIFT); 228 break; 229 case PCLK_PMU_ROOT: 230 if (rate >= 99 * MHz) 231 src_clk = PCLK_PMU_SEL_100M; 232 else 233 src_clk = PCLK_PMU_SEL_24M; 234 rk_clrsetreg(&cru->pmu_clksel_con[0], 235 PCLK_PMU_SEL_MASK, 236 src_clk << PCLK_PMU_SEL_SHIFT); 237 break; 238 case HCLK_PMU_ROOT: 239 if (rate >= 198 * MHz) 240 src_clk = HCLK_PMU_SEL_200M; 241 else if (rate >= 99 * MHz) 242 src_clk = HCLK_PMU_SEL_100M; 243 else 244 src_clk = HCLK_PMU_SEL_24M; 245 rk_clrsetreg(&cru->pmu_clksel_con[0], 246 HCLK_PMU_SEL_MASK, 247 src_clk << HCLK_PMU_SEL_SHIFT); 248 break; 249 default: 250 printf("do not support this permid freq\n"); 251 return -EINVAL; 252 } 253 254 return rv1106_peri_get_clk(priv, clk_id); 255 } 256 257 static ulong rv1106_i2c_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 258 { 259 struct rv1106_cru *cru = priv->cru; 260 u32 sel, con; 261 ulong rate; 262 263 switch (clk_id) { 264 case CLK_I2C1: 265 con = readl(&cru->pmu_clksel_con[0]); 266 sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT; 267 if (sel == CLK_I2C1_SEL_200M) 268 rate = 200 * MHz; 269 else if (sel == CLK_I2C1_SEL_100M) 270 rate = 100 * MHz; 271 else if (sel == CLK_I2C1_SEL_24M) 272 rate = OSC_HZ; 273 else 274 rate = 32768; 275 return rate; 276 case CLK_I2C0: 277 con = readl(&cru->peri_clksel_con[1]); 278 sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT; 279 break; 280 case CLK_I2C2: 281 con = readl(&cru->peri_clksel_con[1]); 282 sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT; 283 break; 284 case CLK_I2C3: 285 con = readl(&cru->peri_clksel_con[1]); 286 sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT; 287 break; 288 case CLK_I2C4: 289 con = readl(&cru->peri_clksel_con[2]); 290 sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT; 291 break; 292 default: 293 return -ENOENT; 294 } 295 296 if (sel == CLK_I2C0_SEL_200M) 297 rate = 200 * MHz; 298 else if (sel == CLK_I2C0_SEL_100M) 299 rate = 100 * MHz; 300 else if (sel == CLK_I2C0_SEL_50M) 301 rate = 50 * MHz; 302 else 303 rate = OSC_HZ; 304 305 return rate; 306 } 307 #endif 308 309 static ulong rv1106_crypto_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 310 { 311 struct rv1106_cru *cru = priv->cru; 312 u32 sel, con; 313 314 switch (clk_id) { 315 case CLK_CORE_CRYPTO: 316 con = readl(&cru->peri_clksel_con[6]); 317 sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >> 318 CLK_CORE_CRYPTO_SEL_SHIFT; 319 break; 320 case CLK_PKA_CRYPTO: 321 con = readl(&cru->peri_clksel_con[6]); 322 sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >> 323 CLK_PKA_CRYPTO_SEL_SHIFT; 324 break; 325 default: 326 return -ENOENT; 327 } 328 switch (sel) { 329 case CLK_CRYPTO_SEL_300M: 330 return 300 * MHz; 331 case CLK_CRYPTO_SEL_200M: 332 return 200 * MHz; 333 case CLK_CRYPTO_SEL_100M: 334 return 100 * MHz; 335 case CLK_CRYPTO_SEL_24M: 336 return OSC_HZ; 337 default: 338 return -ENOENT; 339 } 340 } 341 342 static ulong rv1106_crypto_set_clk(struct rv1106_clk_priv *priv, 343 ulong clk_id, ulong rate) 344 { 345 struct rv1106_cru *cru = priv->cru; 346 u32 sel; 347 348 if (rate >= 297 * MHz) 349 sel = CLK_CRYPTO_SEL_300M; 350 else if (rate >= 198 * MHz) 351 sel = CLK_CRYPTO_SEL_200M; 352 else if (rate >= 99 * MHz) 353 sel = CLK_CRYPTO_SEL_100M; 354 else 355 sel = CLK_CRYPTO_SEL_24M; 356 357 switch (clk_id) { 358 case CLK_CORE_CRYPTO: 359 rk_clrsetreg(&cru->peri_clksel_con[6], 360 CLK_CORE_CRYPTO_SEL_MASK, 361 sel << CLK_CORE_CRYPTO_SEL_SHIFT); 362 break; 363 case CLK_PKA_CRYPTO: 364 rk_clrsetreg(&cru->peri_clksel_con[6], 365 CLK_PKA_CRYPTO_SEL_MASK, 366 sel << CLK_PKA_CRYPTO_SEL_SHIFT); 367 break; 368 default: 369 return -ENOENT; 370 } 371 return rv1106_crypto_get_clk(priv, clk_id); 372 } 373 374 static ulong rv1106_mmc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 375 { 376 struct rv1106_cru *cru = priv->cru; 377 u32 div, sel, con, prate; 378 379 switch (clk_id) { 380 case CCLK_SRC_SDMMC: 381 case HCLK_SDMMC: 382 con = readl(&cru->vi_clksel_con[1]); 383 sel = (con & CLK_SDMMC_SEL_MASK) >> 384 CLK_SDMMC_SEL_SHIFT; 385 div = (con & CLK_SDMMC_DIV_MASK) >> 386 CLK_SDMMC_DIV_SHIFT; 387 if (sel == CLK_MMC_SEL_400M) 388 prate = 400 * MHz; 389 else 390 prate = OSC_HZ; 391 return DIV_TO_RATE(prate, div); 392 case CCLK_SRC_EMMC: 393 case HCLK_EMMC: 394 con = readl(&cru->peri_clksel_con[7]); 395 sel = (con & CLK_EMMC_SEL_MASK) >> 396 CLK_EMMC_SEL_SHIFT; 397 div = (con & CLK_EMMC_DIV_MASK) >> 398 CLK_EMMC_DIV_SHIFT; 399 if (sel) 400 prate = OSC_HZ; 401 else 402 prate = 400 * MHz; 403 return DIV_TO_RATE(prate, div); 404 case SCLK_SFC: 405 case HCLK_SFC: 406 con = readl(&cru->peri_clksel_con[7]); 407 sel = (con & CLK_SFC_SEL_MASK) >> 408 CLK_SFC_SEL_SHIFT; 409 div = (con & CLK_SFC_DIV_MASK) >> 410 CLK_SFC_DIV_SHIFT; 411 if (sel == CLK_SFC_SEL_500M) 412 prate = 500 * MHz; 413 else if (sel == CLK_SFC_SEL_300M) 414 prate = 300 * MHz; 415 else if (sel == CLK_SFC_SEL_200M) 416 prate = 200 * MHz; 417 else 418 prate = OSC_HZ; 419 return DIV_TO_RATE(prate, div); 420 default: 421 return -ENOENT; 422 } 423 } 424 425 static ulong rv1106_mmc_set_clk(struct rv1106_clk_priv *priv, 426 ulong clk_id, ulong rate) 427 { 428 struct rv1106_cru *cru = priv->cru; 429 u32 sel, src_clk_div; 430 ulong prate = 0; 431 432 if ((OSC_HZ % rate) == 0) { 433 sel = CLK_MMC_SEL_24M; 434 prate = OSC_HZ; 435 } else { 436 sel = CLK_MMC_SEL_400M; 437 prate = 400 * MHz; 438 } 439 src_clk_div = DIV_ROUND_UP(prate, rate); 440 441 switch (clk_id) { 442 case CCLK_SRC_SDMMC: 443 case HCLK_SDMMC: 444 if ((OSC_HZ % rate) == 0) { 445 sel = CLK_MMC_SEL_24M; 446 prate = OSC_HZ; 447 } else { 448 sel = CLK_MMC_SEL_400M; 449 prate = 400 * MHz; 450 } 451 src_clk_div = DIV_ROUND_UP(prate, rate); 452 rk_clrsetreg(&cru->vi_clksel_con[1], 453 CLK_SDMMC_SEL_MASK | 454 CLK_SDMMC_DIV_MASK, 455 (sel << CLK_SDMMC_SEL_SHIFT) | 456 ((src_clk_div - 1) << 457 CLK_SDMMC_DIV_SHIFT)); 458 break; 459 case CCLK_SRC_EMMC: 460 case HCLK_EMMC: 461 if ((OSC_HZ % rate) == 0) { 462 sel = CLK_MMC_SEL_24M; 463 prate = OSC_HZ; 464 } else { 465 sel = CLK_MMC_SEL_400M; 466 prate = 400 * MHz; 467 } 468 src_clk_div = DIV_ROUND_UP(prate, rate); 469 rk_clrsetreg(&cru->peri_clksel_con[7], 470 CLK_EMMC_SEL_MASK | 471 CLK_EMMC_DIV_MASK, 472 (sel << CLK_EMMC_SEL_SHIFT) | 473 ((src_clk_div - 1) << 474 CLK_EMMC_DIV_SHIFT)); 475 break; 476 case SCLK_SFC: 477 case HCLK_SFC: 478 if ((OSC_HZ % rate) == 0) { 479 sel = CLK_SFC_SEL_24M; 480 prate = OSC_HZ; 481 } else if ((500 * MHz % rate) == 0) { 482 sel = CLK_SFC_SEL_500M; 483 prate = 500 * MHz; 484 } else if ((300 * MHz % rate) == 0) { 485 sel = CLK_SFC_SEL_300M; 486 prate = 300 * MHz; 487 } else { 488 sel = CLK_SFC_SEL_200M; 489 prate = 200 * MHz; 490 } 491 src_clk_div = DIV_ROUND_UP(prate, rate); 492 rk_clrsetreg(&cru->peri_clksel_con[7], 493 CLK_SFC_SEL_MASK | 494 CLK_SFC_DIV_MASK, 495 (sel << CLK_SFC_SEL_SHIFT) | 496 ((src_clk_div - 1) << 497 CLK_SFC_DIV_SHIFT)); 498 break; 499 default: 500 return -ENOENT; 501 } 502 return rv1106_mmc_get_clk(priv, clk_id); 503 } 504 505 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 506 static ulong rv1106_i2c_set_clk(struct rv1106_clk_priv *priv, ulong clk_id, 507 ulong rate) 508 { 509 struct rv1106_cru *cru = priv->cru; 510 int src_clk; 511 512 if (rate >= 198 * MHz) 513 src_clk = CLK_I2C0_SEL_200M; 514 else if (rate >= 99 * MHz) 515 src_clk = CLK_I2C0_SEL_100M; 516 else if (rate >= 48 * MHz) 517 src_clk = CLK_I2C0_SEL_50M; 518 else 519 src_clk = CLK_I2C0_SEL_24M; 520 521 switch (clk_id) { 522 case CLK_I2C1: 523 if (rate >= 198 * MHz) 524 src_clk = CLK_I2C1_SEL_200M; 525 else if (rate >= 99 * MHz) 526 src_clk = CLK_I2C1_SEL_100M; 527 else if (rate >= 24 * MHz) 528 src_clk = CLK_I2C1_SEL_24M; 529 else 530 src_clk = CLK_I2C1_SEL_32K; 531 rk_clrsetreg(&cru->clksel_con[71], CLK_I2C1_SEL_MASK, 532 src_clk << CLK_I2C1_SEL_SHIFT); 533 return rv1106_i2c_get_clk(priv, clk_id); 534 case CLK_I2C0: 535 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C0_SEL_MASK, 536 src_clk << CLK_I2C0_SEL_SHIFT); 537 break; 538 case CLK_I2C2: 539 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C2_SEL_MASK, 540 src_clk << CLK_I2C2_SEL_SHIFT); 541 break; 542 case CLK_I2C3: 543 rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C3_SEL_MASK, 544 src_clk << CLK_I2C3_SEL_SHIFT); 545 break; 546 case CLK_I2C4: 547 rk_clrsetreg(&cru->peri_clksel_con[2], CLK_I2C4_SEL_MASK, 548 src_clk << CLK_I2C4_SEL_SHIFT); 549 break; 550 default: 551 return -ENOENT; 552 } 553 554 return rv1106_i2c_get_clk(priv, clk_id); 555 } 556 #endif 557 558 static ulong rv1106_spi_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 559 { 560 struct rv1106_cru *cru = priv->cru; 561 u32 sel, con, rate; 562 563 switch (clk_id) { 564 case CLK_SPI0: 565 con = readl(&cru->vepu_clksel_con[0]); 566 sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; 567 break; 568 case CLK_SPI1: 569 con = readl(&cru->peri_clksel_con[6]); 570 sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; 571 break; 572 default: 573 return -ENOENT; 574 } 575 if (sel == CLK_SPI0_SEL_200M) 576 rate = 200 * MHz; 577 else if (sel == CLK_SPI0_SEL_100M) 578 rate = 100 * MHz; 579 else if (sel == CLK_SPI0_SEL_50M) 580 rate = 50 * MHz; 581 else 582 rate = OSC_HZ; 583 584 return rate; 585 } 586 587 static ulong rv1106_spi_set_clk(struct rv1106_clk_priv *priv, 588 ulong clk_id, ulong rate) 589 { 590 struct rv1106_cru *cru = priv->cru; 591 int src_clk; 592 593 if (rate >= 198 * MHz) 594 src_clk = CLK_SPI0_SEL_200M; 595 else if (rate >= 99 * MHz) 596 src_clk = CLK_SPI0_SEL_100M; 597 else if (rate >= 48 * MHz) 598 src_clk = CLK_SPI0_SEL_50M; 599 else 600 src_clk = CLK_SPI0_SEL_24M; 601 602 switch (clk_id) { 603 case CLK_SPI0: 604 rk_clrsetreg(&cru->vepu_clksel_con[0], CLK_SPI0_SEL_MASK, 605 src_clk << CLK_SPI0_SEL_SHIFT); 606 break; 607 case CLK_SPI1: 608 rk_clrsetreg(&cru->peri_clksel_con[6], CLK_SPI1_SEL_MASK, 609 src_clk << CLK_SPI1_SEL_SHIFT); 610 break; 611 default: 612 return -ENOENT; 613 } 614 615 return rv1106_spi_get_clk(priv, clk_id); 616 } 617 618 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 619 static ulong rv1106_pwm_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 620 { 621 struct rv1106_cru *cru = priv->cru; 622 u32 sel, con; 623 624 switch (clk_id) { 625 case CLK_PWM0_PERI: 626 con = readl(&cru->peri_clksel_con[11]); 627 sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; 628 break; 629 case CLK_PWM1_PERI: 630 con = readl(&cru->peri_clksel_con[6]); 631 sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT; 632 break; 633 case CLK_PWM2_PERI: 634 con = readl(&cru->peri_clksel_con[6]); 635 sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; 636 break; 637 default: 638 return -ENOENT; 639 } 640 641 switch (sel) { 642 case CLK_PWM_SEL_100M: 643 return 100 * MHz; 644 case CLK_PWM_SEL_50M: 645 return 100 * MHz; 646 case CLK_PWM_SEL_24M: 647 return OSC_HZ; 648 default: 649 return -ENOENT; 650 } 651 } 652 653 static ulong rv1106_pwm_set_clk(struct rv1106_clk_priv *priv, 654 ulong clk_id, ulong rate) 655 { 656 struct rv1106_cru *cru = priv->cru; 657 int src_clk; 658 659 if (rate >= 99 * MHz) 660 src_clk = CLK_PWM_SEL_100M; 661 else if (rate >= 48 * MHz) 662 src_clk = CLK_PWM_SEL_50M; 663 else 664 src_clk = CLK_PWM_SEL_24M; 665 666 switch (clk_id) { 667 case CLK_PWM0_PERI: 668 rk_clrsetreg(&cru->peri_clksel_con[11], 669 CLK_PWM0_SEL_MASK, 670 src_clk << CLK_PWM0_SEL_SHIFT); 671 break; 672 case CLK_PWM1_PERI: 673 rk_clrsetreg(&cru->peri_clksel_con[6], 674 CLK_PWM1_SEL_MASK, 675 src_clk << CLK_PWM1_SEL_SHIFT); 676 break; 677 case CLK_PWM2_PERI: 678 rk_clrsetreg(&cru->peri_clksel_con[6], 679 CLK_PWM2_SEL_MASK, 680 src_clk << CLK_PWM2_SEL_SHIFT); 681 break; 682 default: 683 return -ENOENT; 684 } 685 686 return rv1106_pwm_get_clk(priv, clk_id); 687 } 688 #endif 689 690 static ulong rv1106_adc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 691 { 692 struct rv1106_cru *cru = priv->cru; 693 u32 div, con; 694 695 switch (clk_id) { 696 case CLK_SARADC: 697 con = readl(&cru->peri_clksel_con[6]); 698 div = (con & CLK_SARADC_DIV_MASK) >> 699 CLK_SARADC_DIV_SHIFT; 700 return DIV_TO_RATE(OSC_HZ, div); 701 case CLK_TSADC_TSEN: 702 con = readl(&cru->vo_clksel_con[3]); 703 div = (con & CLK_TSADC_TSEN_DIV_MASK) >> 704 CLK_TSADC_TSEN_DIV_SHIFT; 705 return DIV_TO_RATE(OSC_HZ, div); 706 case CLK_TSADC: 707 con = readl(&cru->vo_clksel_con[3]); 708 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT; 709 return DIV_TO_RATE(OSC_HZ, div); 710 default: 711 return -ENOENT; 712 } 713 } 714 715 static ulong rv1106_adc_set_clk(struct rv1106_clk_priv *priv, 716 ulong clk_id, ulong rate) 717 { 718 struct rv1106_cru *cru = priv->cru; 719 int src_clk_div; 720 721 src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); 722 723 switch (clk_id) { 724 case CLK_SARADC: 725 assert(src_clk_div - 1 <= 7); 726 rk_clrsetreg(&cru->peri_clksel_con[6], 727 CLK_SARADC_DIV_MASK, 728 (src_clk_div - 1) << 729 CLK_SARADC_DIV_SHIFT); 730 break; 731 case CLK_TSADC_TSEN: 732 assert(src_clk_div - 1 <= 128); 733 rk_clrsetreg(&cru->vo_clksel_con[3], 734 CLK_TSADC_TSEN_DIV_MASK, 735 (src_clk_div - 1) << 736 CLK_TSADC_TSEN_DIV_SHIFT); 737 break; 738 case CLK_TSADC: 739 assert(src_clk_div - 1 <= 128); 740 rk_clrsetreg(&cru->vo_clksel_con[3], 741 CLK_TSADC_DIV_MASK, 742 (src_clk_div - 1) << 743 CLK_TSADC_DIV_SHIFT); 744 break; 745 default: 746 return -ENOENT; 747 } 748 return rv1106_adc_get_clk(priv, clk_id); 749 } 750 751 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 752 /* 753 * 754 * rational_best_approximation(31415, 10000, 755 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 756 * 757 * you may look at given_numerator as a fixed point number, 758 * with the fractional part size described in given_denominator. 759 * 760 * for theoretical background, see: 761 * http://en.wikipedia.org/wiki/Continued_fraction 762 */ 763 static void rational_best_approximation(unsigned long given_numerator, 764 unsigned long given_denominator, 765 unsigned long max_numerator, 766 unsigned long max_denominator, 767 unsigned long *best_numerator, 768 unsigned long *best_denominator) 769 { 770 unsigned long n, d, n0, d0, n1, d1; 771 772 n = given_numerator; 773 d = given_denominator; 774 n0 = 0; 775 d1 = 0; 776 n1 = 1; 777 d0 = 1; 778 for (;;) { 779 unsigned long t, a; 780 781 if (n1 > max_numerator || d1 > max_denominator) { 782 n1 = n0; 783 d1 = d0; 784 break; 785 } 786 if (d == 0) 787 break; 788 t = d; 789 a = n / d; 790 d = n % d; 791 n = t; 792 t = n0 + a * n1; 793 n0 = n1; 794 n1 = t; 795 t = d0 + a * d1; 796 d0 = d1; 797 d1 = t; 798 } 799 *best_numerator = n1; 800 *best_denominator = d1; 801 } 802 803 static ulong rv1106_uart_get_rate(struct rv1106_clk_priv *priv, ulong clk_id) 804 { 805 struct rv1106_cru *cru = priv->cru; 806 u32 reg, con, fracdiv, div, src, p_src, p_rate; 807 unsigned long m, n; 808 809 switch (clk_id) { 810 case SCLK_UART0: 811 reg = 5; 812 break; 813 case SCLK_UART1: 814 reg = 7; 815 break; 816 case SCLK_UART2: 817 reg = 9; 818 break; 819 case SCLK_UART3: 820 reg = 11; 821 break; 822 case SCLK_UART4: 823 reg = 13; 824 break; 825 case SCLK_UART5: 826 reg = 15; 827 break; 828 default: 829 return -ENOENT; 830 } 831 con = readl(&cru->clksel_con[reg + 2]); 832 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 833 con = readl(&cru->clksel_con[reg]); 834 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; 835 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 836 if (p_src == CLK_UART_SRC_SEL_GPLL) 837 p_rate = priv->gpll_hz; 838 else if (p_src == CLK_UART_SRC_SEL_CPLL) 839 p_rate = priv->cpll_hz; 840 else 841 p_rate = 480000000; 842 if (src == CLK_UART_SEL_SRC) { 843 return DIV_TO_RATE(p_rate, div); 844 } else if (src == CLK_UART_SEL_FRAC) { 845 fracdiv = readl(&cru->clksel_con[reg + 1]); 846 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 847 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 848 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 849 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 850 return DIV_TO_RATE(p_rate, div) * n / m; 851 } else { 852 return OSC_HZ; 853 } 854 } 855 856 static ulong rv1106_uart_set_rate(struct rv1106_clk_priv *priv, 857 ulong clk_id, ulong rate) 858 { 859 struct rv1106_cru *cru = priv->cru; 860 u32 reg, clk_src, uart_src, div; 861 unsigned long m = 0, n = 0, val; 862 863 if (priv->gpll_hz % rate == 0) { 864 clk_src = CLK_UART_SRC_SEL_GPLL; 865 uart_src = CLK_UART_SEL_SRC; 866 div = DIV_ROUND_UP(priv->gpll_hz, rate); 867 } else if (priv->cpll_hz % rate == 0) { 868 clk_src = CLK_UART_SRC_SEL_CPLL; 869 uart_src = CLK_UART_SEL_SRC; 870 div = DIV_ROUND_UP(priv->gpll_hz, rate); 871 } else if (rate == OSC_HZ) { 872 clk_src = CLK_UART_SRC_SEL_GPLL; 873 uart_src = CLK_UART_SEL_XIN24M; 874 div = 2; 875 } else { 876 clk_src = CLK_UART_SRC_SEL_GPLL; 877 uart_src = CLK_UART_SEL_FRAC; 878 div = 2; 879 rational_best_approximation(rate, priv->gpll_hz / div, 880 GENMASK(16 - 1, 0), 881 GENMASK(16 - 1, 0), 882 &m, &n); 883 } 884 885 switch (clk_id) { 886 case SCLK_UART0: 887 reg = 5; 888 break; 889 case SCLK_UART1: 890 reg = 7; 891 break; 892 case SCLK_UART2: 893 reg = 9; 894 break; 895 case SCLK_UART3: 896 reg = 11; 897 break; 898 case SCLK_UART4: 899 reg = 13; 900 break; 901 case SCLK_UART5: 902 reg = 15; 903 break; 904 default: 905 return -ENOENT; 906 } 907 rk_clrsetreg(&cru->clksel_con[reg], 908 CLK_UART_SRC_SEL_MASK | 909 CLK_UART_SRC_DIV_MASK, 910 (clk_src << CLK_UART_SRC_SEL_SHIFT) | 911 ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); 912 rk_clrsetreg(&cru->clksel_con[reg + 2], 913 CLK_UART_SEL_MASK, 914 uart_src << CLK_UART_SEL_SHIFT); 915 if (m && n) { 916 val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; 917 writel(val, &cru->clksel_con[reg + 1]); 918 } 919 920 return rv1106_uart_get_rate(priv, clk_id); 921 } 922 923 static ulong rv1106_vop_get_clk(struct rv1106_clk_priv *priv, ulong clk_id) 924 { 925 struct rv1106_cru *cru = priv->cru; 926 u32 div, sel, con; 927 928 switch (clk_id) { 929 case ACLK_VOP_ROOT: 930 case ACLK_VOP: 931 con = readl(&cru->vo_clksel_con[1]); 932 sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT; 933 if (sel == ACLK_VOP_SEL_300M) 934 return 300 * MHz; 935 else if (sel == ACLK_VOP_SEL_200M) 936 return 200 * MHz; 937 else if (sel == ACLK_VOP_SEL_100M) 938 return 100 * MHz; 939 else 940 return OSC_HZ; 941 case DCLK_VOP_SRC: 942 case DCLK_VOP: 943 con = readl(&cru->clksel_con[23]); 944 sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT; 945 div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT; 946 if (sel == DCLK_VOP_SEL_GPLL) 947 return DIV_TO_RATE(priv->gpll_hz, div); 948 else 949 return DIV_TO_RATE(priv->cpll_hz, div); 950 default: 951 return -ENOENT; 952 } 953 } 954 955 static ulong rv1106_vop_set_clk(struct rv1106_clk_priv *priv, 956 ulong clk_id, ulong rate) 957 { 958 struct rv1106_cru *cru = priv->cru; 959 int div, sel; 960 961 switch (clk_id) { 962 case ACLK_VOP_ROOT: 963 case ACLK_VOP: 964 if (rate >= 297 * MHz) 965 sel = ACLK_VOP_SEL_300M; 966 else if (rate >= 198 * MHz) 967 sel = ACLK_VOP_SEL_200M; 968 else if (rate >= 99 * MHz) 969 sel = ACLK_VOP_SEL_100M; 970 else 971 sel = ACLK_VOP_SEL_24M; 972 rk_clrsetreg(&cru->vo_clksel_con[1], 973 ACLK_VOP_SEL_MASK, 974 sel << ACLK_VOP_SEL_SHIFT); 975 break; 976 case DCLK_VOP_SRC: 977 case DCLK_VOP: 978 if ((priv->cpll_hz % rate) == 0) { 979 sel = DCLK_VOP_SEL_CPLL; 980 div = DIV_ROUND_UP(priv->cpll_hz, rate); 981 } else { 982 sel = DCLK_VOP_SEL_GPLL; 983 div = DIV_ROUND_UP(priv->gpll_hz, rate); 984 } 985 rk_clrsetreg(&cru->clksel_con[23], 986 DCLK_VOP_SEL_MASK | 987 DCLK_VOP_DIV_MASK, 988 sel << DCLK_VOP_SEL_SHIFT | 989 (div - 1) << DCLK_VOP_DIV_SHIFT); 990 break; 991 default: 992 return -ENOENT; 993 } 994 995 return rv1106_vop_get_clk(priv, clk_id); 996 } 997 #endif 998 999 static ulong rv1106_clk_get_rate(struct clk *clk) 1000 { 1001 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev); 1002 ulong rate = 0; 1003 1004 if (!priv->gpll_hz) { 1005 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1006 return -ENOENT; 1007 } 1008 1009 switch (clk->id) { 1010 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1011 case PLL_APLL: 1012 rate = rockchip_pll_get_rate(&rv1106_pll_clks[APLL], priv->cru, 1013 APLL); 1014 break; 1015 case PLL_DPLL: 1016 rate = rockchip_pll_get_rate(&rv1106_pll_clks[DPLL], priv->cru, 1017 DPLL); 1018 break; 1019 case PLL_CPLL: 1020 rate = rockchip_pll_get_rate(&rv1106_pll_clks[CPLL], priv->cru, 1021 CPLL); 1022 break; 1023 case PLL_GPLL: 1024 rate = rockchip_pll_get_rate(&rv1106_pll_clks[GPLL], priv->cru, 1025 GPLL); 1026 break; 1027 case ACLK_PERI_ROOT: 1028 case HCLK_PERI_ROOT: 1029 case PCLK_PERI_ROOT: 1030 case ACLK_BUS_ROOT: 1031 case PCLK_TOP_ROOT: 1032 case PCLK_PMU_ROOT: 1033 case HCLK_PMU_ROOT: 1034 rate = rv1106_peri_get_clk(priv, clk->id); 1035 break; 1036 #endif 1037 case CLK_CORE_CRYPTO: 1038 case CLK_PKA_CRYPTO: 1039 case ACLK_CRYPTO: 1040 rate = rv1106_crypto_get_clk(priv, clk->id); 1041 break; 1042 case CCLK_SRC_SDMMC: 1043 case CCLK_SRC_EMMC: 1044 case SCLK_SFC: 1045 case HCLK_SDMMC: 1046 case HCLK_EMMC: 1047 case HCLK_SFC: 1048 rate = rv1106_mmc_get_clk(priv, clk->id); 1049 break; 1050 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1051 case CLK_I2C0: 1052 case CLK_I2C1: 1053 case CLK_I2C2: 1054 case CLK_I2C3: 1055 case CLK_I2C4: 1056 rate = rv1106_i2c_get_clk(priv, clk->id); 1057 break; 1058 #endif 1059 case CLK_SPI0: 1060 case CLK_SPI1: 1061 rate = rv1106_spi_get_clk(priv, clk->id); 1062 break; 1063 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1064 case CLK_PWM0_PERI: 1065 case CLK_PWM1_PERI: 1066 case CLK_PWM2_PERI: 1067 rate = rv1106_pwm_get_clk(priv, clk->id); 1068 break; 1069 #endif 1070 case CLK_SARADC: 1071 case CLK_TSADC_TSEN: 1072 case CLK_TSADC: 1073 rate = rv1106_adc_get_clk(priv, clk->id); 1074 break; 1075 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1076 case SCLK_UART0: 1077 case SCLK_UART1: 1078 case SCLK_UART2: 1079 case SCLK_UART3: 1080 case SCLK_UART4: 1081 case SCLK_UART5: 1082 rate = rv1106_uart_get_rate(priv, clk->id); 1083 break; 1084 case DCLK_VOP_SRC: 1085 case DCLK_VOP: 1086 case ACLK_VOP_ROOT: 1087 case ACLK_VOP: 1088 rate = rv1106_vop_get_clk(priv, clk->id); 1089 break; 1090 #endif 1091 default: 1092 return -ENOENT; 1093 } 1094 1095 return rate; 1096 }; 1097 1098 static ulong rv1106_clk_set_rate(struct clk *clk, ulong rate) 1099 { 1100 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev); 1101 ulong ret = 0; 1102 1103 if (!priv->gpll_hz) { 1104 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1105 return -ENOENT; 1106 } 1107 1108 switch (clk->id) { 1109 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1110 case PLL_APLL: 1111 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru, 1112 APLL, rate); 1113 break; 1114 case PLL_CPLL: 1115 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru, 1116 CPLL, rate); 1117 break; 1118 case PLL_GPLL: 1119 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru, 1120 GPLL, rate); 1121 break; 1122 case ACLK_PERI_ROOT: 1123 case HCLK_PERI_ROOT: 1124 case PCLK_PERI_ROOT: 1125 case ACLK_BUS_ROOT: 1126 case PCLK_TOP_ROOT: 1127 case PCLK_PMU_ROOT: 1128 case HCLK_PMU_ROOT: 1129 ret = rv1106_peri_set_clk(priv, clk->id, rate); 1130 break; 1131 #endif 1132 case CLK_CORE_CRYPTO: 1133 case CLK_PKA_CRYPTO: 1134 case ACLK_CRYPTO: 1135 ret = rv1106_crypto_set_clk(priv, clk->id, rate); 1136 break; 1137 case CCLK_SRC_SDMMC: 1138 case CCLK_SRC_EMMC: 1139 case SCLK_SFC: 1140 case HCLK_SDMMC: 1141 case HCLK_EMMC: 1142 case HCLK_SFC: 1143 ret = rv1106_mmc_set_clk(priv, clk->id, rate); 1144 break; 1145 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1146 case CLK_I2C0: 1147 case CLK_I2C1: 1148 case CLK_I2C2: 1149 case CLK_I2C3: 1150 case CLK_I2C4: 1151 ret = rv1106_i2c_set_clk(priv, clk->id, rate); 1152 break; 1153 #endif 1154 case CLK_SPI0: 1155 case CLK_SPI1: 1156 ret = rv1106_spi_set_clk(priv, clk->id, rate); 1157 break; 1158 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1159 case CLK_PWM0_PERI: 1160 case CLK_PWM1_PERI: 1161 case CLK_PWM2_PERI: 1162 ret = rv1106_pwm_set_clk(priv, clk->id, rate); 1163 break; 1164 #endif 1165 case CLK_SARADC: 1166 case CLK_TSADC_TSEN: 1167 case CLK_TSADC: 1168 ret = rv1106_adc_set_clk(priv, clk->id, rate); 1169 break; 1170 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1171 case SCLK_UART0: 1172 case SCLK_UART1: 1173 case SCLK_UART2: 1174 case SCLK_UART3: 1175 case SCLK_UART4: 1176 case SCLK_UART5: 1177 ret = rv1106_uart_set_rate(priv, clk->id, rate); 1178 break; 1179 case DCLK_VOP_SRC: 1180 case DCLK_VOP: 1181 case ACLK_VOP_ROOT: 1182 case ACLK_VOP: 1183 rate = rv1106_vop_set_clk(priv, clk->id, rate); 1184 break; 1185 #endif 1186 default: 1187 return -ENOENT; 1188 } 1189 1190 return ret; 1191 }; 1192 1193 #define ROCKCHIP_MMC_DELAY_SEL BIT(10) 1194 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1195 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 1196 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1197 1198 #define PSECS_PER_SEC 1000000000000LL 1199 /* 1200 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1201 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1202 */ 1203 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1204 1205 int rv1106_mmc_get_phase(struct clk *clk) 1206 { 1207 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev); 1208 struct rv1106_cru *cru = priv->cru; 1209 u32 raw_value = 0, delay_num; 1210 u16 degrees = 0; 1211 ulong rate; 1212 1213 rate = rv1106_clk_get_rate(clk); 1214 if (rate < 0) 1215 return rate; 1216 1217 if (clk->id == SCLK_EMMC_SAMPLE) 1218 raw_value = readl(&cru->emmc_con[1]); 1219 else if (clk->id == SCLK_SDMMC_SAMPLE) 1220 raw_value = readl(&cru->sdmmc_con[1]); 1221 1222 raw_value >>= 1; 1223 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1224 1225 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1226 /* degrees/delaynum * 10000 */ 1227 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1228 36 * (rate / 1000000); 1229 1230 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1231 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1232 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1233 } 1234 1235 return degrees % 360; 1236 } 1237 1238 int rv1106_mmc_set_phase(struct clk *clk, u32 degrees) 1239 { 1240 struct rv1106_clk_priv *priv = dev_get_priv(clk->dev); 1241 struct rv1106_cru *cru = priv->cru; 1242 u8 nineties, remainder, delay_num; 1243 u32 raw_value, delay; 1244 ulong rate; 1245 1246 rate = rv1106_clk_get_rate(clk); 1247 if (rate < 0) 1248 return rate; 1249 1250 nineties = degrees / 90; 1251 remainder = (degrees % 90); 1252 1253 /* 1254 * Convert to delay; do a little extra work to make sure we 1255 * don't overflow 32-bit / 64-bit numbers. 1256 */ 1257 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1258 delay *= remainder; 1259 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1260 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1261 1262 delay_num = (u8)min_t(u32, delay, 255); 1263 1264 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1265 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1266 raw_value |= nineties; 1267 1268 raw_value <<= 1; 1269 if (clk->id == SCLK_EMMC_SAMPLE) 1270 writel(raw_value | 0xffff0000, &cru->emmc_con[1]); 1271 else if (clk->id == SCLK_SDMMC_SAMPLE) 1272 writel(raw_value | 0xffff0000, &cru->sdmmc_con[1]); 1273 1274 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1275 degrees, delay_num, raw_value, rv1106_mmc_get_phase(clk)); 1276 1277 return 0; 1278 } 1279 1280 static int rv1106_clk_get_phase(struct clk *clk) 1281 { 1282 int ret; 1283 1284 debug("%s %ld\n", __func__, clk->id); 1285 switch (clk->id) { 1286 case SCLK_EMMC_SAMPLE: 1287 case SCLK_SDMMC_SAMPLE: 1288 ret = rv1106_mmc_get_phase(clk); 1289 break; 1290 default: 1291 return -ENOENT; 1292 } 1293 return ret; 1294 } 1295 1296 static int rv1106_clk_set_phase(struct clk *clk, int degrees) 1297 { 1298 int ret; 1299 1300 debug("%s %ld\n", __func__, clk->id); 1301 switch (clk->id) { 1302 case SCLK_EMMC_SAMPLE: 1303 case SCLK_SDMMC_SAMPLE: 1304 ret = rv1106_mmc_set_phase(clk, degrees); 1305 break; 1306 default: 1307 return -ENOENT; 1308 } 1309 1310 return ret; 1311 } 1312 1313 static int rv1106_clk_set_parent(struct clk *clk, struct clk *parent) 1314 { 1315 switch (clk->id) { 1316 default: 1317 return -ENOENT; 1318 } 1319 1320 return 0; 1321 } 1322 1323 static struct clk_ops rv1106_clk_ops = { 1324 .get_rate = rv1106_clk_get_rate, 1325 .set_rate = rv1106_clk_set_rate, 1326 .get_phase = rv1106_clk_get_phase, 1327 .set_phase = rv1106_clk_set_phase, 1328 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1329 .set_parent = rv1106_clk_set_parent, 1330 #endif 1331 }; 1332 1333 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1334 static void rv1106_clk_init(struct rv1106_clk_priv *priv) 1335 { 1336 int ret; 1337 1338 priv->sync_kernel = false; 1339 if (!priv->armclk_enter_hz) { 1340 priv->armclk_enter_hz = 1341 rockchip_pll_get_rate(&rv1106_pll_clks[APLL], 1342 priv->cru, APLL); 1343 priv->armclk_init_hz = priv->armclk_enter_hz; 1344 } 1345 1346 if (priv->armclk_init_hz != APLL_HZ) { 1347 ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru, 1348 APLL, APLL_HZ); 1349 if (!ret) 1350 priv->armclk_init_hz = APLL_HZ; 1351 } 1352 1353 if (priv->cpll_hz != CPLL_HZ) { 1354 ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru, 1355 CPLL, CPLL_HZ); 1356 if (!ret) 1357 priv->cpll_hz = CPLL_HZ; 1358 } 1359 1360 if (priv->gpll_hz != GPLL_HZ) { 1361 ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru, 1362 GPLL, GPLL_HZ); 1363 if (!ret) 1364 priv->gpll_hz = GPLL_HZ; 1365 } 1366 } 1367 #endif 1368 1369 static int rv1106_clk_probe(struct udevice *dev) 1370 { 1371 struct rv1106_clk_priv *priv = dev_get_priv(dev); 1372 #ifndef CONFIG_ROCKCHIP_IMAGE_TINY 1373 int ret; 1374 1375 rv1106_clk_init(priv); 1376 1377 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1378 ret = clk_set_defaults(dev); 1379 if (ret) 1380 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1381 else 1382 priv->sync_kernel = true; 1383 #else 1384 priv->gpll_hz = GPLL_HZ; 1385 priv->cpll_hz = CPLL_HZ; 1386 #endif 1387 rk_clrsetreg(&priv->cru->core_clksel_con[0], 1388 CLK_CORE_DIV_MASK, 1389 0 << CLK_CORE_DIV_SHIFT); 1390 return 0; 1391 } 1392 1393 static int rv1106_clk_ofdata_to_platdata(struct udevice *dev) 1394 { 1395 struct rv1106_clk_priv *priv = dev_get_priv(dev); 1396 1397 priv->cru = dev_read_addr_ptr(dev); 1398 1399 return 0; 1400 } 1401 1402 static int rv1106_clk_bind(struct udevice *dev) 1403 { 1404 int ret; 1405 struct udevice *sys_child, *sf_child; 1406 struct sysreset_reg *priv; 1407 struct softreset_reg *sf_priv; 1408 1409 /* The reset driver does not have a device node, so bind it here */ 1410 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1411 &sys_child); 1412 if (ret) { 1413 debug("Warning: No sysreset driver: ret=%d\n", ret); 1414 } else { 1415 priv = malloc(sizeof(struct sysreset_reg)); 1416 priv->glb_srst_fst_value = offsetof(struct rv1106_cru, 1417 glb_srst_fst); 1418 priv->glb_srst_snd_value = offsetof(struct rv1106_cru, 1419 glb_srst_snd); 1420 sys_child->priv = priv; 1421 } 1422 1423 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1424 dev_ofnode(dev), &sf_child); 1425 if (ret) { 1426 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1427 } else { 1428 sf_priv = malloc(sizeof(struct softreset_reg)); 1429 sf_priv->sf_reset_offset = offsetof(struct rv1106_cru, 1430 pmu_softrst_con[0]); 1431 sf_priv->sf_reset_num = 31745; 1432 sf_child->priv = sf_priv; 1433 } 1434 1435 return 0; 1436 } 1437 1438 static const struct udevice_id rv1106_clk_ids[] = { 1439 { .compatible = "rockchip,rv1106-cru" }, 1440 { } 1441 }; 1442 1443 U_BOOT_DRIVER(rockchip_rv1106_cru) = { 1444 .name = "rockchip_rv1106_cru", 1445 .id = UCLASS_CLK, 1446 .of_match = rv1106_clk_ids, 1447 .priv_auto_alloc_size = sizeof(struct rv1106_clk_priv), 1448 .ofdata_to_platdata = rv1106_clk_ofdata_to_platdata, 1449 .ops = &rv1106_clk_ops, 1450 .bind = rv1106_clk_bind, 1451 .probe = rv1106_clk_probe, 1452 }; 1453 1454 #ifndef CONFIG_SPL_BUILD 1455 /** 1456 * soc_clk_dump() - Print clock frequencies 1457 * Returns zero on success 1458 * 1459 * Implementation for the clk dump command. 1460 */ 1461 int soc_clk_dump(void) 1462 { 1463 struct udevice *cru_dev; 1464 struct rv1106_clk_priv *priv; 1465 const struct rv1106_clk_info *clk_dump; 1466 struct clk clk; 1467 unsigned long clk_count = ARRAY_SIZE(clks_dump); 1468 unsigned long rate; 1469 int i, ret; 1470 1471 ret = uclass_get_device_by_driver(UCLASS_CLK, 1472 DM_GET_DRIVER(rockchip_rv1106_cru), 1473 &cru_dev); 1474 if (ret) { 1475 printf("%s failed to get cru device\n", __func__); 1476 return ret; 1477 } 1478 1479 priv = dev_get_priv(cru_dev); 1480 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1481 priv->sync_kernel ? "sync kernel" : "uboot", 1482 priv->armclk_enter_hz / 1000, 1483 priv->armclk_init_hz / 1000, 1484 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1485 priv->set_armclk_rate ? " KHz" : "N/A"); 1486 for (i = 0; i < clk_count; i++) { 1487 clk_dump = &clks_dump[i]; 1488 if (clk_dump->name) { 1489 clk.id = clk_dump->id; 1490 if (clk_dump->is_cru) 1491 ret = clk_request(cru_dev, &clk); 1492 if (ret < 0) 1493 return ret; 1494 1495 rate = clk_get_rate(&clk); 1496 clk_free(&clk); 1497 if (i == 0) { 1498 if (rate < 0) 1499 printf(" %s %s\n", clk_dump->name, 1500 "unknown"); 1501 else 1502 printf(" %s %lu KHz\n", clk_dump->name, 1503 rate / 1000); 1504 } else { 1505 if (rate < 0) 1506 printf(" %s %s\n", clk_dump->name, 1507 "unknown"); 1508 else 1509 printf(" %s %lu KHz\n", clk_dump->name, 1510 rate / 1000); 1511 } 1512 } 1513 } 1514 1515 return 0; 1516 } 1517 #endif 1518