1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2022 Rockchip Electronics Co., Ltd 4 * Author: Finley Xiao <finley.xiao@rock-chips.com> 5 */ 6 7 #include <common.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <syscon.h> 11 #include <asm/arch/clock.h> 12 #include <asm/arch/cru_rk3562.h> 13 #include <asm/arch/hardware.h> 14 #include <asm/io.h> 15 #include <dm/lists.h> 16 #include <dt-bindings/clock/rk3562-cru.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 21 22 static struct rockchip_pll_rate_table rk3562_pll_rates[] = { 23 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 24 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 25 RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), 26 RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), 27 RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), 28 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), 29 RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), 30 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 31 RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), 32 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), 33 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 34 RK3036_PLL_RATE(705600000, 2, 235, 4, 1, 0, 3355443), 35 RK3036_PLL_RATE(611520000, 4, 611, 6, 1, 0, 8724152), 36 RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), 37 RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), 38 RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), 39 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), 40 RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), 41 RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), 42 RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), 43 { /* sentinel */ }, 44 }; 45 46 static struct rockchip_pll_clock rk3562_pll_clks[] = { 47 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3562_PLL_CON(0), 48 RK3562_MODE_CON, 0, 10, 0, rk3562_pll_rates), 49 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3562_PLL_CON(24), 50 RK3562_MODE_CON, 2, 10, 0, rk3562_pll_rates), 51 [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3562_PLL_CON(32), 52 RK3562_MODE_CON, 6, 10, 0, rk3562_pll_rates), 53 [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3562_PLL_CON(40), 54 RK3562_MODE_CON, 8, 10, 0, rk3562_pll_rates), 55 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3562_PMU1_PLL_CON(0), 56 RK3562_PMU1_MODE_CON, 0, 10, 0, rk3562_pll_rates), 57 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3562_SUBDDR_PLL_CON(0), 58 RK3562_SUBDDR_MODE_CON, 0, 10, 0, NULL), 59 }; 60 61 #define RK3562_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg) \ 62 { \ 63 .rate = _rate##U, \ 64 .aclk_div = _aclk_m_core, \ 65 .pclk_div = _pclk_dbg, \ 66 } 67 68 static struct rockchip_cpu_rate_table rk3562_cpu_rates[] = { 69 RK3562_CPUCLK_RATE(1416000000, 1, 8), 70 RK3562_CPUCLK_RATE(1296000000, 1, 8), 71 RK3562_CPUCLK_RATE(1200000000, 1, 8), 72 RK3562_CPUCLK_RATE(1104000000, 1, 8), 73 RK3562_CPUCLK_RATE(1008000000, 1, 8), 74 RK3562_CPUCLK_RATE(912000000, 1, 6), 75 RK3562_CPUCLK_RATE(816000000, 1, 6), 76 RK3562_CPUCLK_RATE(600000000, 1, 6), 77 RK3562_CPUCLK_RATE(408000000, 1, 4), 78 { /* sentinel */ }, 79 }; 80 81 #ifndef CONFIG_SPL_BUILD 82 #define RK3562_CLK_DUMP(_id, _name) \ 83 { \ 84 .id = _id, \ 85 .name = _name, \ 86 } 87 88 static const struct rk3562_clk_info clks_dump[] = { 89 RK3562_CLK_DUMP(PLL_APLL, "apll"), 90 RK3562_CLK_DUMP(PLL_GPLL, "gpll"), 91 RK3562_CLK_DUMP(PLL_VPLL, "vpll"), 92 RK3562_CLK_DUMP(PLL_HPLL, "hpll"), 93 RK3562_CLK_DUMP(PLL_CPLL, "cpll"), 94 RK3562_CLK_DUMP(PLL_DPLL, "dpll"), 95 RK3562_CLK_DUMP(ACLK_BUS, "aclk_bus"), 96 RK3562_CLK_DUMP(HCLK_BUS, "hclk_bus"), 97 RK3562_CLK_DUMP(PCLK_BUS, "pclk_bus"), 98 RK3562_CLK_DUMP(ACLK_PERI, "aclk_peri"), 99 RK3562_CLK_DUMP(HCLK_PERI, "hclk_peri"), 100 RK3562_CLK_DUMP(PCLK_PERI, "pclk_peri"), 101 }; 102 #endif 103 104 /* 105 * 106 * rational_best_approximation(31415, 10000, 107 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 108 * 109 * you may look at given_numerator as a fixed point number, 110 * with the fractional part size described in given_denominator. 111 * 112 * for theoretical background, see: 113 * http://en.wikipedia.org/wiki/Continued_fraction 114 */ 115 static void rational_best_approximation(unsigned long given_numerator, 116 unsigned long given_denominator, 117 unsigned long max_numerator, 118 unsigned long max_denominator, 119 unsigned long *best_numerator, 120 unsigned long *best_denominator) 121 { 122 unsigned long n, d, n0, d0, n1, d1; 123 124 n = given_numerator; 125 d = given_denominator; 126 n0 = 0; 127 d1 = 0; 128 n1 = 1; 129 d0 = 1; 130 for (;;) { 131 unsigned long t, a; 132 133 if (n1 > max_numerator || d1 > max_denominator) { 134 n1 = n0; 135 d1 = d0; 136 break; 137 } 138 if (d == 0) 139 break; 140 t = d; 141 a = n / d; 142 d = n % d; 143 n = t; 144 t = n0 + a * n1; 145 n0 = n1; 146 n1 = t; 147 t = d0 + a * d1; 148 d0 = d1; 149 d1 = t; 150 } 151 *best_numerator = n1; 152 *best_denominator = d1; 153 } 154 155 static int rk3562_armclk_set_rate(struct rk3562_clk_priv *priv, ulong new_rate) 156 { 157 const struct rockchip_cpu_rate_table *rate; 158 struct rk3562_cru *cru = priv->cru; 159 ulong old_rate; 160 161 rate = rockchip_get_cpu_settings(rk3562_cpu_rates, new_rate); 162 if (!rate) { 163 printf("%s unsupported rate\n", __func__); 164 return -EINVAL; 165 } 166 167 /* 168 * set up dependent divisors for DBG and ACLK clocks. 169 */ 170 old_rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru, 171 APLL); 172 if (old_rate == new_rate) { 173 rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK, 174 rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT); 175 rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK, 176 rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT); 177 rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0); 178 } else if (old_rate > new_rate) { 179 if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL], 180 priv->cru, APLL, new_rate)) 181 return -EINVAL; 182 rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK, 183 rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT); 184 rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK, 185 rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT); 186 rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0); 187 } else if (old_rate < new_rate) { 188 rk_clrsetreg(&cru->clksel_con[11], ACLK_CORE_PRE_DIV_MASK, 189 rate->aclk_div << ACLK_CORE_PRE_DIV_SHIFT); 190 rk_clrsetreg(&cru->clksel_con[12], PCLK_DBG_PRE_DIV_MASK, 191 rate->pclk_div << PCLK_DBG_PRE_DIV_SHIFT); 192 rk_clrsetreg(&cru->clksel_con[10], CLK_CORE_PRE_DIV_MASK, 0); 193 194 if (rockchip_pll_set_rate(&rk3562_pll_clks[APLL], 195 priv->cru, APLL, new_rate)) 196 return -EINVAL; 197 } 198 199 return 0; 200 } 201 202 static ulong rk3562_bus_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 203 { 204 struct rk3562_cru *cru = priv->cru; 205 u32 sel, con, div; 206 ulong rate; 207 208 switch (clk_id) { 209 case ACLK_BUS: 210 con = readl(&cru->clksel_con[40]); 211 sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT; 212 div = (con & ACLK_BUS_DIV_MASK) >> ACLK_BUS_DIV_SHIFT; 213 break; 214 case HCLK_BUS: 215 con = readl(&cru->clksel_con[40]); 216 sel = (con & HCLK_BUS_SEL_MASK) >> HCLK_BUS_SEL_SHIFT; 217 div = (con & HCLK_BUS_DIV_MASK) >> HCLK_BUS_DIV_SHIFT; 218 break; 219 case PCLK_BUS: 220 con = readl(&cru->clksel_con[41]); 221 sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT; 222 div = (con & PCLK_BUS_DIV_MASK) >> PCLK_BUS_DIV_SHIFT; 223 break; 224 default: 225 return -ENOENT; 226 } 227 228 if (sel == ACLK_BUS_SEL_CPLL) 229 rate = priv->cpll_hz; 230 else 231 rate = priv->gpll_hz; 232 233 return DIV_TO_RATE(rate, div); 234 } 235 236 static ulong rk3562_bus_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 237 ulong rate) 238 { 239 struct rk3562_cru *cru = priv->cru; 240 u32 sel, div; 241 242 if (priv->cpll_hz % rate == 0) { 243 sel = ACLK_BUS_SEL_CPLL; 244 div = DIV_ROUND_UP(priv->cpll_hz, rate); 245 } else { 246 sel= ACLK_BUS_SEL_GPLL; 247 div = DIV_ROUND_UP(priv->gpll_hz, rate); 248 } 249 250 switch (clk_id) { 251 case ACLK_BUS: 252 rk_clrsetreg(&cru->clksel_con[40], 253 ACLK_BUS_SEL_MASK | ACLK_BUS_DIV_MASK, 254 (sel << ACLK_BUS_SEL_SHIFT) | 255 ((div - 1) << ACLK_BUS_DIV_SHIFT)); 256 break; 257 case HCLK_BUS: 258 rk_clrsetreg(&cru->clksel_con[40], 259 HCLK_BUS_SEL_MASK | HCLK_BUS_DIV_MASK, 260 (sel << HCLK_BUS_SEL_SHIFT) | 261 ((div - 1) << HCLK_BUS_DIV_SHIFT)); 262 break; 263 case PCLK_BUS: 264 rk_clrsetreg(&cru->clksel_con[41], 265 PCLK_BUS_SEL_MASK | PCLK_BUS_DIV_MASK, 266 (sel << PCLK_BUS_SEL_SHIFT) | 267 ((div - 1) << PCLK_BUS_DIV_SHIFT)); 268 break; 269 default: 270 return -ENOENT; 271 } 272 273 return rk3562_bus_get_rate(priv, clk_id); 274 } 275 276 static ulong rk3562_peri_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 277 { 278 struct rk3562_cru *cru = priv->cru; 279 u32 sel, con, div; 280 ulong rate; 281 282 switch (clk_id) { 283 case ACLK_PERI: 284 con = readl(&cru->periclksel_con[0]); 285 sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT; 286 div = (con & ACLK_PERI_DIV_MASK) >> ACLK_PERI_DIV_SHIFT; 287 break; 288 case HCLK_PERI: 289 con = readl(&cru->periclksel_con[0]); 290 sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT; 291 div = (con & HCLK_PERI_DIV_MASK) >> HCLK_PERI_DIV_SHIFT; 292 break; 293 case PCLK_PERI: 294 con = readl(&cru->periclksel_con[1]); 295 sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT; 296 div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT; 297 break; 298 default: 299 return -ENOENT; 300 } 301 302 if (sel == ACLK_PERI_SEL_CPLL) 303 rate = priv->cpll_hz; 304 else 305 rate = priv->gpll_hz; 306 307 return DIV_TO_RATE(rate, div); 308 } 309 310 static ulong rk3562_peri_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 311 ulong rate) 312 { 313 struct rk3562_cru *cru = priv->cru; 314 u32 sel, div; 315 316 if (priv->cpll_hz % rate == 0) { 317 sel = ACLK_PERI_SEL_CPLL; 318 div = DIV_ROUND_UP(priv->cpll_hz, rate); 319 } else { 320 sel= ACLK_PERI_SEL_GPLL; 321 div = DIV_ROUND_UP(priv->gpll_hz, rate); 322 } 323 324 switch (clk_id) { 325 case ACLK_PERI: 326 rk_clrsetreg(&cru->periclksel_con[0], 327 ACLK_PERI_SEL_MASK | ACLK_PERI_DIV_MASK, 328 (sel << ACLK_PERI_SEL_SHIFT) | 329 ((div - 1) << ACLK_PERI_DIV_SHIFT)); 330 break; 331 case HCLK_PERI: 332 rk_clrsetreg(&cru->periclksel_con[0], 333 HCLK_PERI_SEL_MASK | HCLK_PERI_DIV_MASK, 334 (sel << HCLK_PERI_SEL_SHIFT) | 335 ((div - 1) << HCLK_PERI_DIV_SHIFT)); 336 break; 337 case PCLK_PERI: 338 rk_clrsetreg(&cru->periclksel_con[1], 339 PCLK_PERI_SEL_MASK | PCLK_PERI_DIV_MASK, 340 (sel << PCLK_PERI_SEL_SHIFT) | 341 ((div - 1) << PCLK_PERI_DIV_SHIFT)); 342 break; 343 default: 344 return -ENOENT; 345 } 346 347 return rk3562_peri_get_rate(priv, clk_id); 348 } 349 350 static ulong rk3562_i2c_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 351 { 352 struct rk3562_cru *cru = priv->cru; 353 u32 sel, con, div; 354 ulong rate; 355 356 switch (clk_id) { 357 case CLK_PMU0_I2C0: 358 con = readl(&cru->pmu0clksel_con[3]); 359 sel = (con & CLK_PMU0_I2C0_SEL_MASK) >> CLK_PMU0_I2C0_SEL_SHIFT; 360 if (sel == CLK_PMU0_I2C0_SEL_200M) 361 rate = 200 * MHz; 362 else if (sel == CLK_PMU0_I2C0_SEL_24M) 363 rate = OSC_HZ; 364 else 365 rate = 32768; 366 div = (con & CLK_PMU0_I2C0_DIV_MASK) >> CLK_PMU0_I2C0_DIV_SHIFT; 367 368 return DIV_TO_RATE(rate, div); 369 case CLK_I2C: 370 case CLK_I2C1: 371 case CLK_I2C2: 372 case CLK_I2C3: 373 case CLK_I2C4: 374 case CLK_I2C5: 375 con = readl(&cru->clksel_con[41]); 376 sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT; 377 if (sel == CLK_I2C_SEL_200M) 378 rate = 200 * MHz; 379 else if (sel == CLK_I2C_SEL_100M) 380 rate = 100 * MHz; 381 else if (sel == CLK_I2C_SEL_50M) 382 rate = 50 * MHz; 383 else 384 rate = OSC_HZ; 385 break; 386 default: 387 return -ENOENT; 388 } 389 390 return rate; 391 } 392 393 static ulong rk3562_i2c_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 394 ulong rate) 395 { 396 struct rk3562_cru *cru = priv->cru; 397 u32 sel, div; 398 399 switch (clk_id) { 400 case CLK_PMU0_I2C0: 401 if (rate == 200 * MHz) { 402 sel = CLK_PMU0_I2C0_SEL_200M; 403 div = 1; 404 } else if (rate == OSC_HZ) { 405 sel = CLK_PMU0_I2C0_SEL_24M; 406 div = 1; 407 } else if (rate == 32768) { 408 sel = CLK_PMU0_I2C0_SEL_32K; 409 div = 1; 410 } else { 411 sel = CLK_PMU0_I2C0_SEL_200M; 412 div = DIV_ROUND_UP(200 * MHz, rate); 413 assert(div - 1 <= 31); 414 } 415 rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_DIV_MASK, 416 (div - 1) << CLK_PMU0_I2C0_DIV_SHIFT); 417 rk_clrsetreg(&cru->pmu0clksel_con[3], CLK_PMU0_I2C0_SEL_MASK, 418 sel << CLK_PMU0_I2C0_SEL_SHIFT); 419 break; 420 case CLK_I2C: 421 case CLK_I2C2: 422 case CLK_I2C3: 423 case CLK_I2C4: 424 case CLK_I2C5: 425 if (rate == 200 * MHz) 426 sel = CLK_I2C_SEL_200M; 427 else if (rate == 100 * MHz) 428 sel = CLK_I2C_SEL_100M; 429 else if (rate == 50 * MHz) 430 sel = CLK_I2C_SEL_50M; 431 else 432 sel = CLK_I2C_SEL_24M; 433 rk_clrsetreg(&cru->clksel_con[41], CLK_I2C_SEL_MASK, 434 sel << CLK_I2C_SEL_SHIFT); 435 break; 436 default: 437 return -ENOENT; 438 } 439 440 441 return rk3562_i2c_get_rate(priv, clk_id); 442 } 443 444 static ulong rk3562_uart_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 445 { 446 struct rk3562_cru *cru = priv->cru; 447 u32 reg, con, fracdiv, div, src, p_src, p_rate; 448 unsigned long m, n; 449 450 switch (clk_id) { 451 case SCLK_PMU1_UART0: 452 con = readl(&cru->pmu1clksel_con[2]); 453 src = (con & CLK_PMU1_UART0_SEL_MASK) >> 454 CLK_PMU1_UART0_SEL_SHIFT; 455 div = (con & CLK_PMU1_UART0_SRC_DIV_MASK) >> 456 CLK_PMU1_UART0_SRC_DIV_SHIFT; 457 if (src == CLK_UART_SEL_SRC) { 458 return DIV_TO_RATE(priv->cpll_hz, div); 459 } else if (src == CLK_UART_SEL_FRAC) { 460 fracdiv = readl(&cru->pmu1clksel_con[3]); 461 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 462 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 463 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 464 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 465 return DIV_TO_RATE(priv->cpll_hz, div) * n / m; 466 } else { 467 return OSC_HZ; 468 } 469 case SCLK_UART1: 470 reg = 21; 471 break; 472 case SCLK_UART2: 473 reg = 23; 474 break; 475 case SCLK_UART3: 476 reg = 25; 477 break; 478 case SCLK_UART4: 479 reg = 27; 480 break; 481 case SCLK_UART5: 482 reg = 29; 483 break; 484 case SCLK_UART6: 485 reg = 31; 486 break; 487 case SCLK_UART7: 488 reg = 33; 489 break; 490 case SCLK_UART8: 491 reg = 35; 492 break; 493 case SCLK_UART9: 494 reg = 37; 495 break; 496 default: 497 return -ENOENT; 498 } 499 con = readl(&cru->periclksel_con[reg]); 500 src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; 501 div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; 502 p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; 503 if (p_src == CLK_UART_SRC_SEL_GPLL) 504 p_rate = priv->gpll_hz; 505 else 506 p_rate = priv->cpll_hz; 507 if (src == CLK_UART_SEL_SRC) { 508 return DIV_TO_RATE(p_rate, div); 509 } else if (src == CLK_UART_SEL_FRAC) { 510 fracdiv = readl(&cru->periclksel_con[reg + 1]); 511 n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; 512 n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; 513 m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; 514 m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; 515 return DIV_TO_RATE(p_rate, div) * n / m; 516 } else { 517 return OSC_HZ; 518 } 519 } 520 521 static ulong rk3562_uart_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 522 ulong rate) 523 { 524 struct rk3562_cru *cru = priv->cru; 525 u32 reg, clk_src, uart_src, div; 526 unsigned long m = 0, n = 0, val; 527 528 switch (clk_id) { 529 case SCLK_PMU1_UART0: 530 if (priv->cpll_hz % rate == 0) { 531 uart_src = CLK_UART_SEL_SRC; 532 div = DIV_ROUND_UP(priv->cpll_hz, rate); 533 } else if (rate == OSC_HZ) { 534 uart_src = CLK_UART_SEL_XIN24M; 535 div = 2; 536 } else { 537 uart_src = CLK_UART_SEL_FRAC; 538 div = 2; 539 rational_best_approximation(rate, priv->cpll_hz / div, 540 GENMASK(16 - 1, 0), 541 GENMASK(16 - 1, 0), 542 &n, &m); 543 } 544 545 rk_clrsetreg(&cru->pmu1clksel_con[2], 546 CLK_PMU1_UART0_SEL_MASK | 547 CLK_PMU1_UART0_SRC_DIV_MASK, 548 (uart_src << CLK_PMU1_UART0_SEL_SHIFT) | 549 ((div - 1) << CLK_PMU1_UART0_SRC_DIV_SHIFT)); 550 if (m && n) { 551 val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m; 552 writel(val, &cru->pmu1clksel_con[3]); 553 } 554 555 return rk3562_uart_get_rate(priv, clk_id); 556 case SCLK_UART1: 557 reg = 21; 558 break; 559 case SCLK_UART2: 560 reg = 23; 561 break; 562 case SCLK_UART3: 563 reg = 25; 564 break; 565 case SCLK_UART4: 566 reg = 27; 567 break; 568 case SCLK_UART5: 569 reg = 29; 570 break; 571 case SCLK_UART6: 572 reg = 31; 573 break; 574 case SCLK_UART7: 575 reg = 33; 576 break; 577 case SCLK_UART8: 578 reg = 35; 579 break; 580 case SCLK_UART9: 581 reg = 37; 582 break; 583 default: 584 return -ENOENT; 585 } 586 587 if (priv->gpll_hz % rate == 0) { 588 clk_src = CLK_UART_SRC_SEL_GPLL; 589 uart_src = CLK_UART_SEL_SRC; 590 div = DIV_ROUND_UP(priv->gpll_hz, rate); 591 } else if (priv->cpll_hz % rate == 0) { 592 clk_src = CLK_UART_SRC_SEL_CPLL; 593 uart_src = CLK_UART_SEL_SRC; 594 div = DIV_ROUND_UP(priv->cpll_hz, rate); 595 } else if (rate == OSC_HZ) { 596 clk_src = CLK_UART_SRC_SEL_GPLL; 597 uart_src = CLK_UART_SEL_XIN24M; 598 div = 2; 599 } else { 600 clk_src = CLK_UART_SRC_SEL_GPLL; 601 uart_src = CLK_UART_SEL_FRAC; 602 div = 2; 603 rational_best_approximation(rate, priv->gpll_hz / div, 604 GENMASK(16 - 1, 0), 605 GENMASK(16 - 1, 0), 606 &n, &m); 607 } 608 609 rk_clrsetreg(&cru->periclksel_con[reg], 610 CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK | 611 CLK_UART_SRC_DIV_MASK, 612 (clk_src << CLK_UART_SRC_SEL_SHIFT) | 613 (uart_src << CLK_UART_SEL_SHIFT) | 614 ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); 615 if (m && n) { 616 val = n << CLK_UART_FRAC_NUMERATOR_SHIFT | m; 617 writel(val, &cru->periclksel_con[reg + 1]); 618 } 619 620 return rk3562_uart_get_rate(priv, clk_id); 621 } 622 623 static ulong rk3562_pwm_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 624 { 625 struct rk3562_cru *cru = priv->cru; 626 u32 sel, con, div, mask, shift; 627 ulong rate; 628 629 switch (clk_id) { 630 case CLK_PMU1_PWM0: 631 con = readl(&cru->pmu1clksel_con[4]); 632 sel = (con & CLK_PMU1_PWM0_SEL_MASK) >> CLK_PMU1_PWM0_SEL_SHIFT; 633 if (sel == CLK_PMU1_PWM0_SEL_200M) 634 rate = 200 * MHz; 635 else if (sel == CLK_PMU1_PWM0_SEL_24M) 636 rate = OSC_HZ; 637 else 638 rate = 32768; 639 div = (con & CLK_PMU1_PWM0_DIV_MASK) >> CLK_PMU1_PWM0_DIV_SHIFT; 640 641 return DIV_TO_RATE(rate, div); 642 case CLK_PWM1_PERI: 643 mask = CLK_PWM1_PERI_SEL_MASK; 644 shift = CLK_PWM1_PERI_SEL_SHIFT; 645 break; 646 case CLK_PWM2_PERI: 647 mask = CLK_PWM2_PERI_SEL_MASK; 648 shift = CLK_PWM2_PERI_SEL_SHIFT; 649 break; 650 case CLK_PWM3_PERI: 651 mask = CLK_PWM3_PERI_SEL_MASK; 652 shift = CLK_PWM3_PERI_SEL_SHIFT; 653 break; 654 default: 655 return -ENOENT; 656 } 657 658 con = readl(&cru->periclksel_con[40]); 659 sel = (con & mask) >> shift; 660 if (sel == CLK_PWM_SEL_100M) 661 rate = 100 * MHz; 662 else if (sel == CLK_PWM_SEL_50M) 663 rate = 50 * MHz; 664 else 665 rate = OSC_HZ; 666 667 return rate; 668 } 669 670 static ulong rk3562_pwm_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 671 ulong rate) 672 { 673 struct rk3562_cru *cru = priv->cru; 674 u32 sel, div, mask, shift; 675 676 switch (clk_id) { 677 case CLK_PMU1_PWM0: 678 if (rate == 200 * MHz) { 679 sel = CLK_PMU1_PWM0_SEL_200M; 680 div = 1; 681 } else if (rate == OSC_HZ) { 682 sel = CLK_PMU1_PWM0_SEL_24M; 683 div = 1; 684 } else if (rate == 32768) { 685 sel = CLK_PMU1_PWM0_SEL_32K; 686 div = 1; 687 } else { 688 sel = CLK_PMU1_PWM0_SEL_200M; 689 div = DIV_ROUND_UP(200 * MHz, rate); 690 assert(div - 1 <= 3); 691 } 692 rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_DIV_MASK, 693 (div - 1) << CLK_PMU1_PWM0_DIV_SHIFT); 694 rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_PWM0_SEL_MASK, 695 sel << CLK_PMU1_PWM0_SEL_SHIFT); 696 697 return rk3562_pwm_get_rate(priv, clk_id); 698 case CLK_PWM1_PERI: 699 mask = CLK_PWM1_PERI_SEL_MASK; 700 shift = CLK_PWM1_PERI_SEL_SHIFT; 701 break; 702 case CLK_PWM2_PERI: 703 mask = CLK_PWM2_PERI_SEL_MASK; 704 shift = CLK_PWM2_PERI_SEL_SHIFT; 705 break; 706 case CLK_PWM3_PERI: 707 mask = CLK_PWM3_PERI_SEL_MASK; 708 shift = CLK_PWM3_PERI_SEL_SHIFT; 709 break; 710 default: 711 return -ENOENT; 712 } 713 714 if (rate == 100 * MHz) 715 sel = CLK_PWM_SEL_100M; 716 else if (rate == 50 * MHz) 717 sel = CLK_PWM_SEL_50M; 718 else 719 sel = CLK_PWM_SEL_24M; 720 rk_clrsetreg(&cru->periclksel_con[40], mask, sel << shift); 721 722 return rk3562_pwm_get_rate(priv, clk_id); 723 } 724 725 static ulong rk3562_spi_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 726 { 727 struct rk3562_cru *cru = priv->cru; 728 u32 sel, con, div, mask, shift; 729 ulong rate; 730 731 switch (clk_id) { 732 case CLK_PMU1_SPI0: 733 con = readl(&cru->pmu1clksel_con[4]); 734 sel = (con & CLK_PMU1_SPI0_SEL_MASK) >> CLK_PMU1_SPI0_SEL_SHIFT; 735 if (sel == CLK_PMU1_SPI0_SEL_200M) 736 rate = 200 * MHz; 737 else if (sel == CLK_PMU1_SPI0_SEL_24M) 738 rate = OSC_HZ; 739 else 740 rate = 32768; 741 div = (con & CLK_PMU1_SPI0_DIV_MASK) >> CLK_PMU1_SPI0_DIV_SHIFT; 742 743 return DIV_TO_RATE(rate, div); 744 case CLK_SPI1: 745 mask = CLK_SPI1_SEL_MASK; 746 shift = CLK_SPI1_SEL_SHIFT; 747 break; 748 case CLK_SPI2: 749 mask = CLK_SPI2_SEL_MASK; 750 shift = CLK_SPI2_SEL_SHIFT; 751 break; 752 default: 753 return -ENOENT; 754 } 755 756 con = readl(&cru->periclksel_con[20]); 757 sel = (con & mask) >> shift; 758 if (sel == CLK_SPI_SEL_200M) 759 rate = 200 * MHz; 760 else if (sel == CLK_SPI_SEL_100M) 761 rate = 100 * MHz; 762 else if (sel == CLK_SPI_SEL_50M) 763 rate = 50 * MHz; 764 else 765 rate = OSC_HZ; 766 767 return rate; 768 } 769 770 static ulong rk3562_spi_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 771 ulong rate) 772 { 773 struct rk3562_cru *cru = priv->cru; 774 u32 sel, div, mask, shift; 775 776 switch (clk_id) { 777 case CLK_PMU1_SPI0: 778 if (rate == 200 * MHz) { 779 sel = CLK_PMU1_SPI0_SEL_200M; 780 div = 1; 781 } else if (rate == OSC_HZ) { 782 sel = CLK_PMU1_SPI0_SEL_24M; 783 div = 1; 784 } else if (rate == 32768) { 785 sel = CLK_PMU1_SPI0_SEL_32K; 786 div = 1; 787 } else { 788 sel = CLK_PMU1_SPI0_SEL_200M; 789 div = DIV_ROUND_UP(200 * MHz, rate); 790 assert(div - 1 <= 3); 791 } 792 rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_DIV_MASK, 793 (div - 1) << CLK_PMU1_SPI0_DIV_SHIFT); 794 rk_clrsetreg(&cru->pmu1clksel_con[4], CLK_PMU1_SPI0_SEL_MASK, 795 sel << CLK_PMU1_SPI0_SEL_SHIFT); 796 797 return rk3562_spi_get_rate(priv, clk_id); 798 case CLK_SPI1: 799 mask = CLK_SPI1_SEL_MASK; 800 shift = CLK_SPI1_SEL_SHIFT; 801 break; 802 case CLK_SPI2: 803 mask = CLK_SPI2_SEL_MASK; 804 shift = CLK_SPI2_SEL_SHIFT; 805 break; 806 default: 807 return -ENOENT; 808 } 809 810 if (rate == 200 * MHz) 811 sel = CLK_SPI_SEL_200M; 812 else if (rate == 100 * MHz) 813 sel = CLK_SPI_SEL_100M; 814 else if (rate == 50 * MHz) 815 sel = CLK_SPI_SEL_50M; 816 else 817 sel = CLK_SPI_SEL_24M; 818 rk_clrsetreg(&cru->periclksel_con[20], mask, sel << shift); 819 820 return rk3562_spi_get_rate(priv, clk_id); 821 } 822 823 static ulong rk3562_tsadc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 824 { 825 struct rk3562_cru *cru = priv->cru; 826 u32 div, con; 827 828 con = readl(&cru->clksel_con[43]); 829 switch (clk_id) { 830 case CLK_TSADC_TSEN: 831 div = (con & CLK_TSADC_TSEN_DIV_MASK) >> 832 CLK_TSADC_TSEN_DIV_SHIFT; 833 break; 834 case CLK_TSADC: 835 div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT; 836 break; 837 default: 838 return -ENOENT; 839 } 840 841 return DIV_TO_RATE(OSC_HZ, div); 842 } 843 844 static ulong rk3562_tsadc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 845 ulong rate) 846 { 847 struct rk3562_cru *cru = priv->cru; 848 u32 div, mask, shift; 849 850 switch (clk_id) { 851 case CLK_TSADC_TSEN: 852 mask = CLK_TSADC_TSEN_DIV_MASK; 853 shift = CLK_TSADC_TSEN_DIV_SHIFT; 854 break; 855 case CLK_TSADC: 856 mask = CLK_TSADC_DIV_MASK; 857 shift = CLK_TSADC_DIV_SHIFT; 858 break; 859 default: 860 return -ENOENT; 861 } 862 863 div = DIV_ROUND_UP(OSC_HZ, rate); 864 rk_clrsetreg(&cru->clksel_con[43], mask, (div - 1) << shift); 865 866 return rk3562_tsadc_get_rate(priv, clk_id); 867 } 868 869 static ulong rk3562_saradc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 870 { 871 struct rk3562_cru *cru = priv->cru; 872 u32 div, con; 873 874 switch (clk_id) { 875 case CLK_SARADC_VCCIO156: 876 con = readl(&cru->clksel_con[44]); 877 div = (con & CLK_SARADC_VCCIO156_DIV_MASK) >> 878 CLK_SARADC_VCCIO156_DIV_SHIFT; 879 break; 880 case CLK_SARADC: 881 con = readl(&cru->periclksel_con[46]); 882 div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; 883 break; 884 default: 885 return -ENOENT; 886 } 887 888 return DIV_TO_RATE(OSC_HZ, div); 889 } 890 891 static ulong rk3562_saradc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 892 ulong rate) 893 { 894 struct rk3562_cru *cru = priv->cru; 895 u32 div; 896 897 switch (clk_id) { 898 case CLK_SARADC_VCCIO156: 899 div = DIV_ROUND_UP(OSC_HZ, rate); 900 rk_clrsetreg(&cru->clksel_con[44], CLK_SARADC_VCCIO156_DIV_MASK, 901 (div - 1) << CLK_SARADC_VCCIO156_DIV_SHIFT); 902 break; 903 case CLK_SARADC: 904 div = DIV_ROUND_UP(OSC_HZ, rate); 905 rk_clrsetreg(&cru->periclksel_con[46], CLK_SARADC_DIV_MASK, 906 (div - 1) << CLK_SARADC_DIV_SHIFT); 907 break; 908 default: 909 return -ENOENT; 910 } 911 912 return rk3562_saradc_get_rate(priv, clk_id); 913 } 914 915 static ulong rk3562_sfc_get_rate(struct rk3562_clk_priv *priv) 916 { 917 struct rk3562_cru *cru = priv->cru; 918 u32 div, sel, con, parent; 919 920 con = readl(&cru->periclksel_con[20]); 921 div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT; 922 sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; 923 if (sel == SCLK_SFC_SRC_SEL_GPLL) 924 parent = priv->gpll_hz; 925 else if (sel == SCLK_SFC_SRC_SEL_CPLL) 926 parent = priv->cpll_hz; 927 else 928 parent = OSC_HZ; 929 930 return DIV_TO_RATE(parent, div); 931 } 932 933 static ulong rk3562_sfc_set_rate(struct rk3562_clk_priv *priv, ulong rate) 934 { 935 struct rk3562_cru *cru = priv->cru; 936 int div, sel; 937 938 if (OSC_HZ % rate == 0) { 939 div = DIV_ROUND_UP(OSC_HZ, rate); 940 sel = SCLK_SFC_SRC_SEL_24M; 941 } else if ((priv->cpll_hz % rate) == 0) { 942 div = DIV_ROUND_UP(priv->cpll_hz, rate); 943 sel = SCLK_SFC_SRC_SEL_CPLL; 944 } else { 945 div = DIV_ROUND_UP(priv->gpll_hz, rate); 946 sel = SCLK_SFC_SRC_SEL_GPLL; 947 } 948 949 assert(div - 1 <= 255); 950 rk_clrsetreg(&cru->periclksel_con[20], 951 SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK, 952 sel << SCLK_SFC_SEL_SHIFT | 953 (div - 1) << SCLK_SFC_DIV_SHIFT); 954 955 return rk3562_sfc_get_rate(priv); 956 } 957 958 static ulong rk3562_emmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 959 { 960 struct rk3562_cru *cru = priv->cru; 961 u32 div, sel, con, parent; 962 963 switch (clk_id) { 964 case CCLK_EMMC: 965 con = readl(&cru->periclksel_con[18]); 966 div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT; 967 sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT; 968 if (sel == CCLK_EMMC_SEL_GPLL) 969 parent = priv->gpll_hz; 970 else if (sel == CCLK_EMMC_SEL_CPLL) 971 parent = priv->cpll_hz; 972 else if (sel == CCLK_EMMC_SEL_HPLL) 973 parent = priv->hpll_hz; 974 else 975 parent = OSC_HZ; 976 break; 977 case BCLK_EMMC: 978 con = readl(&cru->periclksel_con[19]); 979 div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT; 980 sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT; 981 if (sel == BCLK_EMMC_SEL_GPLL) 982 parent = priv->gpll_hz; 983 else 984 parent = priv->cpll_hz; 985 break; 986 default: 987 return -ENOENT; 988 } 989 990 return DIV_TO_RATE(parent, div); 991 } 992 993 static ulong rk3562_emmc_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 994 ulong rate) 995 { 996 struct rk3562_cru *cru = priv->cru; 997 int div, sel; 998 999 switch (clk_id) { 1000 case CCLK_EMMC: 1001 if (OSC_HZ % rate == 0) { 1002 div = DIV_ROUND_UP(OSC_HZ, rate); 1003 sel = CCLK_EMMC_SEL_24M; 1004 } else if ((priv->cpll_hz % rate) == 0) { 1005 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1006 sel = CCLK_EMMC_SEL_CPLL; 1007 } else if ((priv->hpll_hz % rate) == 0) { 1008 div = DIV_ROUND_UP(priv->hpll_hz, rate); 1009 sel = CCLK_EMMC_SEL_HPLL; 1010 } else { 1011 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1012 sel = CCLK_EMMC_SEL_GPLL; 1013 } 1014 rk_clrsetreg(&cru->periclksel_con[18], 1015 CCLK_EMMC_SEL_MASK | CCLK_EMMC_DIV_MASK, 1016 sel << CCLK_EMMC_SEL_SHIFT | 1017 (div - 1) << CCLK_EMMC_DIV_SHIFT); 1018 break; 1019 case BCLK_EMMC: 1020 if ((priv->cpll_hz % rate) == 0) { 1021 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1022 sel = BCLK_EMMC_SEL_CPLL; 1023 } else { 1024 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1025 sel = BCLK_EMMC_SEL_GPLL; 1026 } 1027 rk_clrsetreg(&cru->periclksel_con[19], 1028 BCLK_EMMC_SEL_MASK | BCLK_EMMC_DIV_MASK, 1029 sel << BCLK_EMMC_SEL_SHIFT | 1030 (div - 1) << BCLK_EMMC_DIV_SHIFT); 1031 break; 1032 default: 1033 return -ENOENT; 1034 } 1035 1036 return rk3562_emmc_get_rate(priv, clk_id); 1037 } 1038 1039 static ulong rk3562_sdmmc_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 1040 { 1041 struct rk3562_cru *cru = priv->cru; 1042 u32 div, sel, con; 1043 ulong prate; 1044 1045 switch (clk_id) { 1046 case HCLK_SDMMC0: 1047 case CCLK_SDMMC0: 1048 case SCLK_SDMMC0_SAMPLE: 1049 con = readl(&cru->periclksel_con[16]); 1050 div = (con & CCLK_SDMMC0_DIV_MASK) >> CCLK_SDMMC0_DIV_SHIFT; 1051 sel = (con & CCLK_SDMMC0_SEL_MASK) >> CCLK_SDMMC0_SEL_SHIFT; 1052 break; 1053 case HCLK_SDMMC1: 1054 case CCLK_SDMMC1: 1055 case SCLK_SDMMC1_SAMPLE: 1056 con = readl(&cru->periclksel_con[17]); 1057 div = (con & CCLK_SDMMC1_DIV_MASK) >> CCLK_SDMMC1_DIV_SHIFT; 1058 sel = (con & CCLK_SDMMC1_SEL_MASK) >> CCLK_SDMMC1_SEL_SHIFT; 1059 break; 1060 default: 1061 return -ENOENT; 1062 } 1063 1064 if (sel == CCLK_SDMMC_SEL_GPLL) 1065 prate = priv->gpll_hz; 1066 else if (sel == CCLK_SDMMC_SEL_CPLL) 1067 prate = priv->cpll_hz; 1068 else if (sel == CCLK_SDMMC_SEL_HPLL) 1069 prate = priv->hpll_hz; 1070 else 1071 prate = OSC_HZ; 1072 1073 return DIV_TO_RATE(prate, div); 1074 } 1075 1076 static ulong rk3562_sdmmc_set_rate(struct rk3562_clk_priv *priv, 1077 ulong clk_id, ulong rate) 1078 { 1079 struct rk3562_cru *cru = priv->cru; 1080 u32 div, sel; 1081 1082 if (OSC_HZ % rate == 0) { 1083 div = DIV_ROUND_UP(OSC_HZ, rate); 1084 sel = CCLK_SDMMC_SEL_24M; 1085 } else if ((priv->cpll_hz % rate) == 0) { 1086 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1087 sel = CCLK_SDMMC_SEL_CPLL; 1088 } else if ((priv->hpll_hz % rate) == 0) { 1089 div = DIV_ROUND_UP(priv->hpll_hz, rate); 1090 sel = CCLK_SDMMC_SEL_HPLL; 1091 } else { 1092 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1093 sel = CCLK_SDMMC_SEL_CPLL; 1094 } 1095 1096 switch (clk_id) { 1097 case HCLK_SDMMC0: 1098 case CCLK_SDMMC0: 1099 rk_clrsetreg(&cru->periclksel_con[16], 1100 CCLK_SDMMC0_SEL_MASK | CCLK_SDMMC0_DIV_MASK, 1101 sel << CCLK_SDMMC0_SEL_SHIFT | 1102 (div - 1) << CCLK_SDMMC0_DIV_SHIFT); 1103 break; 1104 case HCLK_SDMMC1: 1105 case CCLK_SDMMC1: 1106 rk_clrsetreg(&cru->periclksel_con[17], 1107 CCLK_SDMMC1_SEL_MASK | CCLK_SDMMC1_DIV_MASK, 1108 sel << CCLK_SDMMC1_SEL_SHIFT | 1109 (div - 1) << CCLK_SDMMC1_DIV_SHIFT); 1110 break; 1111 default: 1112 return -ENOENT; 1113 } 1114 1115 return rk3562_sdmmc_get_rate(priv, clk_id); 1116 } 1117 1118 static ulong rk3562_vop_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 1119 { 1120 struct rk3562_cru *cru = priv->cru; 1121 u32 con, sel, div; 1122 ulong prate; 1123 1124 switch (clk_id) { 1125 case ACLK_VOP: 1126 con = readl(&cru->clksel_con[28]); 1127 div = (con & ACLK_VOP_DIV_MASK) >> ACLK_VOP_DIV_SHIFT; 1128 sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT; 1129 if (sel == ACLK_VOP_SEL_GPLL) 1130 prate = priv->gpll_hz; 1131 else if (sel == ACLK_VOP_SEL_CPLL) 1132 prate = priv->cpll_hz; 1133 else if (sel == ACLK_VOP_SEL_HPLL) 1134 prate = priv->hpll_hz; 1135 else if (sel == ACLK_VOP_SEL_VPLL) 1136 prate = priv->vpll_hz; 1137 else 1138 return -ENOENT; 1139 1140 return DIV_TO_RATE(prate, div); 1141 case DCLK_VOP: 1142 con = readl(&cru->clksel_con[30]); 1143 div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT; 1144 sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT; 1145 if (sel == DCLK_VOP_SEL_VPLL) 1146 priv->vpll_hz = 1147 rockchip_pll_get_rate(&rk3562_pll_clks[VPLL], 1148 priv->cru, VPLL); 1149 break; 1150 case DCLK_VOP1: 1151 con = readl(&cru->clksel_con[31]); 1152 div = (con & DCLK_VOP1_DIV_MASK) >> DCLK_VOP1_DIV_SHIFT; 1153 sel = (con & DCLK_VOP1_SEL_MASK) >> DCLK_VOP1_SEL_SHIFT; 1154 break; 1155 default: 1156 return -ENOENT; 1157 } 1158 1159 if (sel == DCLK_VOP_SEL_GPLL) 1160 prate = priv->gpll_hz; 1161 else if (sel == DCLK_VOP_SEL_HPLL) 1162 prate = priv->hpll_hz; 1163 else if (sel == DCLK_VOP_SEL_VPLL) 1164 prate = priv->vpll_hz; 1165 else 1166 return -ENOENT; 1167 1168 return DIV_TO_RATE(prate, div); 1169 } 1170 1171 #define RK3562_VOP_PLL_LIMIT_FREQ 594000000 1172 1173 static ulong rk3562_vop_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 1174 ulong rate) 1175 { 1176 struct rk3562_cru *cru = priv->cru; 1177 u32 i, div, sel, best_div = 0, best_sel = 0; 1178 ulong pll_rate, now, best_rate = 0; 1179 1180 switch (clk_id) { 1181 case ACLK_VOP: 1182 if ((priv->cpll_hz % rate) == 0) { 1183 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1184 sel = ACLK_VOP_SEL_CPLL; 1185 } else if ((priv->hpll_hz % rate) == 0) { 1186 div = DIV_ROUND_UP(priv->hpll_hz, rate); 1187 sel = ACLK_VOP_SEL_HPLL; 1188 } else if ((priv->vpll_hz % rate) == 0) { 1189 div = DIV_ROUND_UP(priv->vpll_hz, rate); 1190 sel = ACLK_VOP_SEL_VPLL; 1191 } else { 1192 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1193 sel = ACLK_VOP_SEL_GPLL; 1194 } 1195 rk_clrsetreg(&cru->clksel_con[28], 1196 ACLK_VOP_SEL_MASK | ACLK_VOP_DIV_MASK, 1197 sel << ACLK_VOP_SEL_SHIFT | 1198 ((div - 1) << ACLK_VOP_DIV_SHIFT)); 1199 1200 return rk3562_vop_get_rate(priv, clk_id); 1201 case DCLK_VOP: 1202 div = DIV_ROUND_UP(RK3562_VOP_PLL_LIMIT_FREQ, rate); 1203 if (div % 2) 1204 div = div + 1; 1205 rk_clrsetreg(&cru->clksel_con[30], 1206 DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK, 1207 DCLK_VOP_SEL_VPLL << DCLK_VOP_SEL_SHIFT | 1208 ((div - 1) << DCLK_VOP_DIV_SHIFT)); 1209 rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru, 1210 VPLL, div * rate); 1211 break; 1212 case DCLK_VOP1: 1213 for (i = 0; i <= DCLK_VOP_SEL_APLL; i++) { 1214 switch (i) { 1215 case DCLK_VOP_SEL_GPLL: 1216 pll_rate = priv->gpll_hz; 1217 break; 1218 case DCLK_VOP_SEL_HPLL: 1219 pll_rate = priv->hpll_hz; 1220 break; 1221 case DCLK_VOP_SEL_VPLL: 1222 case DCLK_VOP_SEL_APLL: 1223 continue; 1224 default: 1225 printf("do not support this vop pll sel\n"); 1226 return -EINVAL; 1227 } 1228 1229 div = DIV_ROUND_UP(pll_rate, rate); 1230 if (div > 255) 1231 continue; 1232 now = pll_rate / div; 1233 if (abs(rate - now) < abs(rate - best_rate)) { 1234 best_rate = now; 1235 best_div = div; 1236 best_sel = i; 1237 } 1238 debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", 1239 pll_rate, best_rate, best_div, best_sel); 1240 } 1241 if (best_rate) { 1242 rk_clrsetreg(&cru->clksel_con[31], 1243 DCLK_VOP1_SEL_MASK | DCLK_VOP1_DIV_MASK, 1244 best_sel << DCLK_VOP1_SEL_SHIFT | 1245 (best_div - 1) << DCLK_VOP1_DIV_SHIFT); 1246 } else { 1247 printf("do not support this vop freq %lu\n", rate); 1248 return -EINVAL; 1249 } 1250 break; 1251 default: 1252 return -ENOENT; 1253 } 1254 1255 return rk3562_vop_get_rate(priv, clk_id); 1256 } 1257 1258 static ulong rk3562_gmac_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 1259 { 1260 struct rk3562_cru *cru = priv->cru; 1261 u32 con, sel, div; 1262 ulong prate; 1263 1264 switch (clk_id) { 1265 case CLK_GMAC_125M_CRU_I: 1266 con = readl(&cru->clksel_con[45]); 1267 sel = (con & CLK_GMAC_125M_SEL_MASK) >> CLK_GMAC_125M_SEL_SHIFT; 1268 if (sel == CLK_GMAC_125M) 1269 return 125000000; 1270 else 1271 return OSC_HZ; 1272 case CLK_GMAC_50M_CRU_I: 1273 con = readl(&cru->clksel_con[45]); 1274 sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT; 1275 if (sel == CLK_GMAC_50M) 1276 return 50000000; 1277 else 1278 return OSC_HZ; 1279 case CLK_MAC100_50M_MATRIX: 1280 con = readl(&cru->clksel_con[47]); 1281 sel = (con & CLK_GMAC_50M_SEL_MASK) >> CLK_GMAC_50M_SEL_SHIFT; 1282 if (sel == CLK_GMAC_50M) 1283 return 50000000; 1284 else 1285 return OSC_HZ; 1286 case CLK_GMAC_ETH_OUT2IO: 1287 con = readl(&cru->clksel_con[46]); 1288 sel = (con & CLK_GMAC_ETH_OUT2IO_SEL_MASK) >> CLK_GMAC_ETH_OUT2IO_SEL_SHIFT; 1289 div = (con & CLK_GMAC_ETH_OUT2IO_DIV_MASK) >> CLK_GMAC_ETH_OUT2IO_DIV_SHIFT; 1290 if (sel == CLK_GMAC_ETH_OUT2IO_GPLL) 1291 prate = priv->gpll_hz; 1292 else 1293 prate = priv->cpll_hz; 1294 break; 1295 default: 1296 return -ENOENT; 1297 } 1298 1299 return DIV_TO_RATE(prate, div); 1300 } 1301 1302 static ulong rk3562_gmac_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 1303 ulong rate) 1304 { 1305 struct rk3562_cru *cru = priv->cru; 1306 u32 sel, div; 1307 1308 switch (clk_id) { 1309 case CLK_GMAC_125M_CRU_I: 1310 if (rate == 125000000) 1311 sel = CLK_GMAC_125M; 1312 else 1313 sel = CLK_GMAC_24M; 1314 rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_125M_SEL_MASK, 1315 sel << CLK_GMAC_125M_SEL_SHIFT); 1316 break; 1317 case CLK_GMAC_50M_CRU_I: 1318 if (rate == 50000000) 1319 sel = CLK_GMAC_50M; 1320 else 1321 sel = CLK_GMAC_24M; 1322 rk_clrsetreg(&cru->clksel_con[45], CLK_GMAC_50M_SEL_MASK, 1323 sel << CLK_GMAC_50M_SEL_SHIFT); 1324 break; 1325 case CLK_MAC100_50M_MATRIX: 1326 if (rate == 50000000) 1327 sel = CLK_GMAC_50M; 1328 else 1329 sel = CLK_GMAC_24M; 1330 rk_clrsetreg(&cru->clksel_con[47], CLK_GMAC_50M_SEL_MASK, 1331 sel << CLK_GMAC_50M_SEL_SHIFT); 1332 break; 1333 case CLK_GMAC_ETH_OUT2IO: 1334 if ((priv->cpll_hz % rate) == 0) { 1335 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1336 sel = CLK_GMAC_ETH_OUT2IO_CPLL; 1337 } else { 1338 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1339 sel = CLK_GMAC_ETH_OUT2IO_GPLL; 1340 } 1341 rk_clrsetreg(&cru->clksel_con[46], 1342 CLK_GMAC_ETH_OUT2IO_SEL_MASK | CLK_GMAC_ETH_OUT2IO_DIV_MASK, 1343 sel << CLK_GMAC_ETH_OUT2IO_SEL_SHIFT | 1344 (div - 1) << CLK_GMAC_ETH_OUT2IO_DIV_SHIFT); 1345 break; 1346 default: 1347 return -ENOENT; 1348 } 1349 1350 return rk3562_gmac_get_rate(priv, clk_id); 1351 } 1352 1353 static ulong rk3562_clk_get_rate(struct clk *clk) 1354 { 1355 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 1356 ulong rate = 0; 1357 1358 if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) { 1359 printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n", 1360 __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz); 1361 return -ENOENT; 1362 } 1363 1364 switch (clk->id) { 1365 case PLL_APLL: 1366 case ARMCLK: 1367 rate = rockchip_pll_get_rate(&rk3562_pll_clks[APLL], priv->cru, 1368 APLL); 1369 break; 1370 case PLL_GPLL: 1371 rate = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL], priv->cru, 1372 GPLL); 1373 break; 1374 1375 case PLL_VPLL: 1376 rate = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL], priv->cru, 1377 VPLL); 1378 break; 1379 case PLL_HPLL: 1380 rate = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL], priv->cru, 1381 HPLL); 1382 break; 1383 case PLL_CPLL: 1384 rate = rockchip_pll_get_rate(&rk3562_pll_clks[CPLL], priv->cru, 1385 CPLL); 1386 break; 1387 case PLL_DPLL: 1388 rate = rockchip_pll_get_rate(&rk3562_pll_clks[DPLL], priv->cru, 1389 DPLL); 1390 break; 1391 case ACLK_BUS: 1392 case HCLK_BUS: 1393 case PCLK_BUS: 1394 rate = rk3562_bus_get_rate(priv, clk->id); 1395 break; 1396 case ACLK_PERI: 1397 case HCLK_PERI: 1398 case PCLK_PERI: 1399 rate = rk3562_peri_get_rate(priv, clk->id); 1400 break; 1401 case CLK_PMU0_I2C0: 1402 case CLK_I2C: 1403 case CLK_I2C1: 1404 case CLK_I2C2: 1405 case CLK_I2C3: 1406 case CLK_I2C4: 1407 case CLK_I2C5: 1408 rate = rk3562_i2c_get_rate(priv, clk->id); 1409 break; 1410 case SCLK_PMU1_UART0: 1411 case SCLK_UART1: 1412 case SCLK_UART2: 1413 case SCLK_UART3: 1414 case SCLK_UART4: 1415 case SCLK_UART5: 1416 case SCLK_UART6: 1417 case SCLK_UART7: 1418 case SCLK_UART8: 1419 case SCLK_UART9: 1420 rate = rk3562_uart_get_rate(priv, clk->id); 1421 break; 1422 case CLK_PMU1_PWM0: 1423 case CLK_PWM1_PERI: 1424 case CLK_PWM2_PERI: 1425 case CLK_PWM3_PERI: 1426 rate = rk3562_pwm_get_rate(priv, clk->id); 1427 break; 1428 case CLK_PMU1_SPI0: 1429 case CLK_SPI1: 1430 case CLK_SPI2: 1431 rate = rk3562_spi_get_rate(priv, clk->id); 1432 break; 1433 case CLK_TSADC: 1434 case CLK_TSADC_TSEN: 1435 rate = rk3562_tsadc_get_rate(priv, clk->id); 1436 break; 1437 case CLK_SARADC: 1438 case CLK_SARADC_VCCIO156: 1439 rate = rk3562_saradc_get_rate(priv, clk->id); 1440 break; 1441 case SCLK_SFC: 1442 rate = rk3562_sfc_get_rate(priv); 1443 break; 1444 case CCLK_EMMC: 1445 case BCLK_EMMC: 1446 rate = rk3562_emmc_get_rate(priv, clk->id); 1447 break; 1448 case HCLK_SDMMC0: 1449 case HCLK_SDMMC1: 1450 case CCLK_SDMMC0: 1451 case CCLK_SDMMC1: 1452 case SCLK_SDMMC0_SAMPLE: 1453 case SCLK_SDMMC1_SAMPLE: 1454 rate = rk3562_sdmmc_get_rate(priv, clk->id); 1455 break; 1456 case ACLK_VOP: 1457 case DCLK_VOP: 1458 case DCLK_VOP1: 1459 rate = rk3562_vop_get_rate(priv, clk->id); 1460 break; 1461 case CLK_GMAC_125M_CRU_I: 1462 case CLK_GMAC_50M_CRU_I: 1463 case CLK_GMAC_ETH_OUT2IO: 1464 case CLK_MAC100_50M_MATRIX: 1465 rate = rk3562_gmac_get_rate(priv, clk->id); 1466 break; 1467 case CLK_WDTNS: 1468 rate = OSC_HZ; 1469 break; 1470 default: 1471 return -ENOENT; 1472 } 1473 1474 return rate; 1475 }; 1476 1477 static ulong rk3562_clk_set_rate(struct clk *clk, ulong rate) 1478 { 1479 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 1480 ulong ret = 0; 1481 1482 if (!priv->gpll_hz || !priv->cpll_hz || !priv->hpll_hz) { 1483 printf("%s: gpll=%lu, cpll=%lu, hpll=%lu\n", 1484 __func__, priv->gpll_hz, priv->cpll_hz, priv->hpll_hz); 1485 return -ENOENT; 1486 } 1487 1488 debug("%s: id=%ld, rate=%ld\n", __func__, clk->id, rate); 1489 1490 switch (clk->id) { 1491 case PLL_APLL: 1492 case ARMCLK: 1493 if (priv->armclk_hz) 1494 rk3562_armclk_set_rate(priv, rate); 1495 priv->armclk_hz = rate; 1496 break; 1497 case PLL_GPLL: 1498 ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru, 1499 GPLL, rate); 1500 priv->gpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[GPLL], 1501 priv->cru, GPLL); 1502 break; 1503 case PLL_VPLL: 1504 ret = rockchip_pll_set_rate(&rk3562_pll_clks[VPLL], priv->cru, 1505 VPLL, rate); 1506 priv->vpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[VPLL], 1507 priv->cru, VPLL); 1508 break; 1509 case PLL_HPLL: 1510 ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru, 1511 HPLL, rate); 1512 priv->hpll_hz = rockchip_pll_get_rate(&rk3562_pll_clks[HPLL], 1513 priv->cru, HPLL); 1514 break; 1515 case ACLK_BUS: 1516 case HCLK_BUS: 1517 case PCLK_BUS: 1518 ret = rk3562_bus_set_rate(priv, clk->id, rate); 1519 break; 1520 case ACLK_PERI: 1521 case HCLK_PERI: 1522 case PCLK_PERI: 1523 ret = rk3562_peri_set_rate(priv, clk->id, rate); 1524 break; 1525 case CLK_PMU0_I2C0: 1526 case CLK_I2C: 1527 case CLK_I2C1: 1528 case CLK_I2C2: 1529 case CLK_I2C3: 1530 case CLK_I2C4: 1531 case CLK_I2C5: 1532 ret = rk3562_i2c_set_rate(priv, clk->id, rate); 1533 break; 1534 case SCLK_PMU1_UART0: 1535 case SCLK_UART1: 1536 case SCLK_UART2: 1537 case SCLK_UART3: 1538 case SCLK_UART4: 1539 case SCLK_UART5: 1540 case SCLK_UART6: 1541 case SCLK_UART7: 1542 case SCLK_UART8: 1543 case SCLK_UART9: 1544 ret = rk3562_uart_set_rate(priv, clk->id, rate); 1545 break; 1546 case CLK_PMU1_PWM0: 1547 case CLK_PWM1_PERI: 1548 case CLK_PWM2_PERI: 1549 case CLK_PWM3_PERI: 1550 ret = rk3562_pwm_set_rate(priv, clk->id, rate); 1551 break; 1552 case CLK_PMU1_SPI0: 1553 case CLK_SPI1: 1554 case CLK_SPI2: 1555 ret = rk3562_spi_set_rate(priv, clk->id, rate); 1556 break; 1557 case CLK_TSADC: 1558 case CLK_TSADC_TSEN: 1559 ret = rk3562_tsadc_set_rate(priv, clk->id, rate); 1560 break; 1561 case CLK_SARADC: 1562 case CLK_SARADC_VCCIO156: 1563 ret = rk3562_saradc_set_rate(priv, clk->id, rate); 1564 break; 1565 case SCLK_SFC: 1566 ret = rk3562_sfc_set_rate(priv, rate); 1567 break; 1568 case CCLK_EMMC: 1569 case BCLK_EMMC: 1570 ret = rk3562_emmc_set_rate(priv, clk->id, rate); 1571 break; 1572 case HCLK_SDMMC0: 1573 case HCLK_SDMMC1: 1574 case CCLK_SDMMC0: 1575 case CCLK_SDMMC1: 1576 ret = rk3562_sdmmc_set_rate(priv, clk->id, rate); 1577 break; 1578 case ACLK_VOP: 1579 case DCLK_VOP: 1580 case DCLK_VOP1: 1581 ret = rk3562_vop_set_rate(priv, clk->id, rate); 1582 break; 1583 case CLK_GMAC_125M_CRU_I: 1584 case CLK_GMAC_50M_CRU_I: 1585 case CLK_GMAC_ETH_OUT2IO: 1586 case CLK_MAC100_50M_MATRIX: 1587 ret = rk3562_gmac_set_rate(priv, clk->id, rate); 1588 break; 1589 default: 1590 return -ENOENT; 1591 } 1592 1593 return ret; 1594 }; 1595 1596 #define ROCKCHIP_MMC_DELAY_SEL BIT(11) 1597 #define ROCKCHIP_MMC_DEGREE_SHIFT 1 1598 #define ROCKCHIP_MMC_DEGREE_MASK (0x3 << ROCKCHIP_MMC_DEGREE_SHIFT) 1599 #define ROCKCHIP_MMC_DELAYNUM_SHIFT 3 1600 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_SHIFT) 1601 #define PSECS_PER_SEC 1000000000000LL 1602 1603 /* 1604 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1605 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1606 */ 1607 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1608 1609 int rk3562_mmc_get_phase(struct clk *clk) 1610 { 1611 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 1612 struct rk3562_cru *cru = priv->cru; 1613 u32 raw_value, delay_num; 1614 u16 degrees = 0; 1615 ulong rate; 1616 1617 rate = rk3562_clk_get_rate(clk); 1618 if (rate < 0) 1619 return rate; 1620 1621 if (clk->id == SCLK_SDMMC0_SAMPLE) 1622 raw_value = readl(&cru->sdmmc0_con[1]); 1623 else if (clk->id == SCLK_SDMMC0_SAMPLE) 1624 raw_value = readl(&cru->sdmmc1_con[1]); 1625 else 1626 return -ENONET; 1627 1628 raw_value &= ROCKCHIP_MMC_DEGREE_MASK; 1629 degrees = (raw_value >> ROCKCHIP_MMC_DEGREE_SHIFT) * 90; 1630 1631 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1632 /* degrees/delaynum * 10000 */ 1633 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1634 36 * (rate / 1000000); 1635 1636 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1637 delay_num >>= ROCKCHIP_MMC_DELAYNUM_SHIFT; 1638 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1639 } 1640 1641 return degrees % 360; 1642 } 1643 1644 int rk3562_mmc_set_phase(struct clk *clk, u32 degrees) 1645 { 1646 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 1647 struct rk3562_cru *cru = priv->cru; 1648 u8 nineties, remainder, delay_num; 1649 u32 raw_value, delay; 1650 ulong rate; 1651 1652 rate = rk3562_clk_get_rate(clk); 1653 if (rate < 0) 1654 return rate; 1655 1656 nineties = degrees / 90; 1657 remainder = (degrees % 90); 1658 1659 /* 1660 * Convert to delay; do a little extra work to make sure we 1661 * don't overflow 32-bit / 64-bit numbers. 1662 */ 1663 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1664 delay *= remainder; 1665 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1666 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1667 1668 delay_num = (u8)min_t(u32, delay, 255); 1669 1670 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1671 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_SHIFT; 1672 raw_value |= nineties << ROCKCHIP_MMC_DEGREE_SHIFT; 1673 1674 if (clk->id == SCLK_SDMMC0_SAMPLE) 1675 writel(raw_value | 0xffff0000, &cru->sdmmc0_con[1]); 1676 else 1677 writel(raw_value | 0xffff0000, &cru->sdmmc1_con[1]); 1678 1679 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1680 degrees, delay_num, raw_value, rk3562_mmc_get_phase(clk)); 1681 1682 return 0; 1683 } 1684 1685 static int rk3562_clk_get_phase(struct clk *clk) 1686 { 1687 int ret; 1688 1689 switch (clk->id) { 1690 case SCLK_SDMMC0_SAMPLE: 1691 case SCLK_SDMMC1_SAMPLE: 1692 ret = rk3562_mmc_get_phase(clk); 1693 break; 1694 default: 1695 return -ENOENT; 1696 } 1697 1698 return ret; 1699 } 1700 1701 static int rk3562_clk_set_phase(struct clk *clk, int degrees) 1702 { 1703 int ret; 1704 1705 switch (clk->id) { 1706 case SCLK_SDMMC0_SAMPLE: 1707 case SCLK_SDMMC1_SAMPLE: 1708 ret = rk3562_mmc_set_phase(clk, degrees); 1709 break; 1710 default: 1711 return -ENOENT; 1712 } 1713 1714 return ret; 1715 } 1716 1717 static struct clk_ops rk3562_clk_ops = { 1718 .get_rate = rk3562_clk_get_rate, 1719 .set_rate = rk3562_clk_set_rate, 1720 .get_phase = rk3562_clk_get_phase, 1721 .set_phase = rk3562_clk_set_phase, 1722 }; 1723 1724 #ifndef CONFIG_SPL_BUILD 1725 /** 1726 * soc_clk_dump() - Print clock frequencies 1727 * Returns zero on success 1728 * 1729 * Implementation for the clk dump command. 1730 */ 1731 int soc_clk_dump(void) 1732 { 1733 const struct rk3562_clk_info *clk_dump; 1734 struct rk3562_clk_priv *priv; 1735 struct udevice *cru_dev; 1736 struct clk clk; 1737 ulong clk_count = ARRAY_SIZE(clks_dump); 1738 ulong rate; 1739 int i, ret; 1740 1741 ret = uclass_get_device_by_driver(UCLASS_CLK, 1742 DM_GET_DRIVER(rockchip_rk3562_cru), 1743 &cru_dev); 1744 if (ret) { 1745 printf("%s failed to get cru device\n", __func__); 1746 return ret; 1747 } 1748 1749 priv = dev_get_priv(cru_dev); 1750 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1751 priv->sync_kernel ? "sync kernel" : "uboot", 1752 priv->armclk_enter_hz / 1000, 1753 priv->armclk_init_hz / 1000, 1754 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1755 priv->set_armclk_rate ? " KHz" : "N/A"); 1756 for (i = 0; i < clk_count; i++) { 1757 clk_dump = &clks_dump[i]; 1758 if (clk_dump->name) { 1759 clk.id = clk_dump->id; 1760 ret = clk_request(cru_dev, &clk); 1761 if (ret < 0) 1762 return ret; 1763 1764 rate = clk_get_rate(&clk); 1765 clk_free(&clk); 1766 if (i == 0) { 1767 if (rate < 0) 1768 printf(" %s %s\n", clk_dump->name, 1769 "unknown"); 1770 else 1771 printf(" %s %lu KHz\n", clk_dump->name, 1772 rate / 1000); 1773 } else { 1774 if (rate < 0) 1775 printf(" %s %s\n", clk_dump->name, 1776 "unknown"); 1777 else 1778 printf(" %s %lu KHz\n", clk_dump->name, 1779 rate / 1000); 1780 } 1781 } 1782 } 1783 1784 return 0; 1785 } 1786 #endif 1787 1788 static void rk3562_clk_init(struct rk3562_clk_priv *priv) 1789 { 1790 int ret; 1791 1792 priv->sync_kernel = false; 1793 if (!priv->armclk_enter_hz) 1794 priv->armclk_enter_hz = 1795 rockchip_pll_get_rate(&rk3562_pll_clks[APLL], 1796 priv->cru, APLL); 1797 1798 if (!priv->armclk_init_hz) { 1799 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUPPORT_USBPLUG) 1800 ret = rk3562_armclk_set_rate(priv, APLL_HZ); 1801 if (!ret) 1802 priv->armclk_init_hz = APLL_HZ; 1803 1804 #else 1805 struct clk clk; 1806 1807 ret = rockchip_get_scmi_clk(&clk.dev); 1808 if (ret) { 1809 printf("Failed to get scmi clk dev\n"); 1810 return; 1811 } 1812 1813 clk.id = ARMCLK; 1814 ret = clk_set_rate(&clk, CPU_PVTPLL_HZ); 1815 if (ret < 0) { 1816 printf("Failed to set scmi cpu %dhz\n", CPU_PVTPLL_HZ); 1817 return; 1818 } else { 1819 priv->armclk_init_hz = CPU_PVTPLL_HZ; 1820 } 1821 #endif 1822 } 1823 if (priv->cpll_hz != CPLL_HZ) { 1824 ret = rockchip_pll_set_rate(&rk3562_pll_clks[CPLL], priv->cru, 1825 CPLL, CPLL_HZ); 1826 if (!ret) 1827 priv->cpll_hz = CPLL_HZ; 1828 } 1829 1830 if (priv->gpll_hz != GPLL_HZ) { 1831 ret = rockchip_pll_set_rate(&rk3562_pll_clks[GPLL], priv->cru, 1832 GPLL, GPLL_HZ); 1833 if (!ret) 1834 priv->gpll_hz = GPLL_HZ; 1835 } 1836 1837 if (priv->hpll_hz != HPLL_HZ) { 1838 ret = rockchip_pll_set_rate(&rk3562_pll_clks[HPLL], priv->cru, 1839 HPLL, HPLL_HZ); 1840 if (!ret) 1841 priv->hpll_hz = HPLL_HZ; 1842 } 1843 } 1844 1845 static int rk3562_clk_probe(struct udevice *dev) 1846 { 1847 struct rk3562_clk_priv *priv = dev_get_priv(dev); 1848 int ret; 1849 1850 rk3562_clk_init(priv); 1851 1852 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1853 ret = clk_set_defaults(dev); 1854 if (ret) 1855 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1856 else 1857 priv->sync_kernel = true; 1858 1859 return 0; 1860 } 1861 1862 static int rk3562_clk_ofdata_to_platdata(struct udevice *dev) 1863 { 1864 struct rk3562_clk_priv *priv = dev_get_priv(dev); 1865 1866 priv->cru = dev_read_addr_ptr(dev); 1867 1868 return 0; 1869 } 1870 1871 static int rk3562_clk_bind(struct udevice *dev) 1872 { 1873 struct udevice *sys_child, *sf_child; 1874 struct softreset_reg *sf_priv; 1875 struct sysreset_reg *priv; 1876 int ret; 1877 1878 /* The reset driver does not have a device node, so bind it here */ 1879 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1880 &sys_child); 1881 if (ret) { 1882 debug("Warning: No sysreset driver: ret=%d\n", ret); 1883 } else { 1884 priv = malloc(sizeof(struct sysreset_reg)); 1885 priv->glb_srst_fst_value = offsetof(struct rk3562_cru, 1886 glb_srst_fst); 1887 priv->glb_srst_snd_value = offsetof(struct rk3562_cru, 1888 glb_srst_snd); 1889 sys_child->priv = priv; 1890 } 1891 1892 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1893 dev_ofnode(dev), &sf_child); 1894 if (ret) { 1895 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1896 } else { 1897 sf_priv = malloc(sizeof(struct softreset_reg)); 1898 sf_priv->sf_reset_offset = offsetof(struct rk3562_cru, 1899 softrst_con[0]); 1900 /* (0x30444 - 0x400) / 4 + 1 = 49170 */ 1901 sf_priv->sf_reset_num = 49170; 1902 sf_child->priv = sf_priv; 1903 } 1904 1905 return 0; 1906 } 1907 1908 static const struct udevice_id rk3562_clk_ids[] = { 1909 { .compatible = "rockchip,rk3562-cru" }, 1910 { } 1911 }; 1912 1913 U_BOOT_DRIVER(rockchip_rk3562_cru) = { 1914 .name = "rockchip_rk3562_cru", 1915 .id = UCLASS_CLK, 1916 .of_match = rk3562_clk_ids, 1917 .priv_auto_alloc_size = sizeof(struct rk3562_clk_priv), 1918 .ofdata_to_platdata = rk3562_clk_ofdata_to_platdata, 1919 .ops = &rk3562_clk_ops, 1920 .bind = rk3562_clk_bind, 1921 .probe = rk3562_clk_probe, 1922 }; 1923 1924 /* spl scmi clk */ 1925 #ifdef CONFIG_SPL_BUILD 1926 1927 static ulong rk3562_crypto_get_rate(struct rk3562_clk_priv *priv, ulong clk_id) 1928 { 1929 struct rk3562_cru *cru = priv->cru; 1930 u32 sel, con; 1931 ulong rate; 1932 1933 con = readl(&cru->periclksel_con[43]); 1934 switch (clk_id) { 1935 case CLK_CORE_CRYPTO: 1936 sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >> 1937 CLK_CORE_CRYPTO_SEL_SHIFT; 1938 if (sel == CLK_CORE_CRYPTO_SEL_200M) 1939 rate = 200 * MHz; 1940 else if (sel == CLK_CORE_CRYPTO_SEL_100M) 1941 rate = 100 * MHz; 1942 else 1943 rate = OSC_HZ; 1944 break; 1945 case CLK_PKA_CRYPTO: 1946 sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >> 1947 CLK_PKA_CRYPTO_SEL_SHIFT; 1948 if (sel == CLK_PKA_CRYPTO_SEL_300M) 1949 rate = 300 * MHz; 1950 else if (sel == CLK_PKA_CRYPTO_SEL_200M) 1951 rate = 200 * MHz; 1952 else if (sel == CLK_PKA_CRYPTO_SEL_100M) 1953 rate = 100 * MHz; 1954 else 1955 rate = OSC_HZ; 1956 break; 1957 default: 1958 return -ENOENT; 1959 } 1960 1961 return rate; 1962 } 1963 1964 static ulong rk3562_crypto_set_rate(struct rk3562_clk_priv *priv, ulong clk_id, 1965 ulong rate) 1966 { 1967 struct rk3562_cru *cru = priv->cru; 1968 u32 mask, shift, sel; 1969 1970 switch (clk_id) { 1971 case CLK_CORE_CRYPTO: 1972 mask = CLK_CORE_CRYPTO_SEL_MASK; 1973 shift = CLK_CORE_CRYPTO_SEL_SHIFT; 1974 if (rate == 200 * MHz) 1975 sel = CLK_CORE_CRYPTO_SEL_200M; 1976 else if (rate == 100 * MHz) 1977 sel = CLK_CORE_CRYPTO_SEL_100M; 1978 else 1979 sel = CLK_CORE_CRYPTO_SEL_24M; 1980 break; 1981 case CLK_PKA_CRYPTO: 1982 mask = CLK_PKA_CRYPTO_SEL_MASK; 1983 shift = CLK_PKA_CRYPTO_SEL_SHIFT; 1984 if (rate == 300 * MHz) 1985 sel = CLK_PKA_CRYPTO_SEL_300M; 1986 else if (rate == 200 * MHz) 1987 sel = CLK_PKA_CRYPTO_SEL_200M; 1988 else if (rate == 100 * MHz) 1989 sel = CLK_PKA_CRYPTO_SEL_100M; 1990 else 1991 sel = CLK_PKA_CRYPTO_SEL_24M; 1992 break; 1993 default: 1994 return -ENOENT; 1995 } 1996 rk_clrsetreg(&cru->periclksel_con[43], mask, sel << shift); 1997 1998 return rk3562_crypto_get_rate(priv, clk_id); 1999 } 2000 2001 static ulong rk3562_clk_scmi_get_rate(struct clk *clk) 2002 { 2003 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 2004 2005 switch (clk->id) { 2006 case CLK_CORE_CRYPTO: 2007 case CLK_PKA_CRYPTO: 2008 return rk3562_crypto_get_rate(priv, clk->id); 2009 default: 2010 return -ENOENT; 2011 } 2012 }; 2013 2014 static ulong rk3562_clk_scmi_set_rate(struct clk *clk, ulong rate) 2015 { 2016 struct rk3562_clk_priv *priv = dev_get_priv(clk->dev); 2017 2018 switch (clk->id) { 2019 case CLK_CORE_CRYPTO: 2020 case CLK_PKA_CRYPTO: 2021 return rk3562_crypto_set_rate(priv, clk->id, rate); 2022 default: 2023 return -ENOENT; 2024 } 2025 return 0; 2026 }; 2027 2028 static int rk3562_scmi_clk_ofdata_to_platdata(struct udevice *dev) 2029 { 2030 struct rk3562_clk_priv *priv = dev_get_priv(dev); 2031 2032 priv->cru = (struct rk3562_cru *)0xff100000; 2033 2034 return 0; 2035 } 2036 2037 /* A fake scmi driver for SPL/TPL where smccc agent is not available. */ 2038 static const struct clk_ops scmi_clk_ops = { 2039 .get_rate = rk3562_clk_scmi_get_rate, 2040 .set_rate = rk3562_clk_scmi_set_rate, 2041 }; 2042 2043 U_BOOT_DRIVER(scmi_clock) = { 2044 .name = "scmi_clk", 2045 .id = UCLASS_CLK, 2046 .ops = &scmi_clk_ops, 2047 .priv_auto_alloc_size = sizeof(struct rk3562_clk_priv), 2048 .ofdata_to_platdata = rk3562_scmi_clk_ofdata_to_platdata, 2049 }; 2050 #endif 2051