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