1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2022 Fuzhou Rockchip Electronics Co., Ltd 4 * Author: Joseph Chen <chenjh@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_rk3528.h> 13 #include <asm/arch/grf_rk3528.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/io.h> 16 #include <dm/lists.h> 17 #include <dt-bindings/clock/rk3528-cru.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 22 23 /* 24 * PLL attention. 25 * 26 * [FRAC PLL]: GPLL, PPLL, DPLL 27 * - frac mode: refdiv can be 1 or 2 only 28 * - int mode: refdiv has no special limit 29 * - VCO range: [950, 3800] MHZ 30 * 31 * [INT PLL]: CPLL, APLL 32 * - int mode: refdiv can be 1 or 2 only 33 * - VCO range: [475, 1900] MHZ 34 * 35 * [PPLL]: normal mode only. 36 * 37 */ 38 static struct rockchip_pll_rate_table rk3528_pll_rates[] = { 39 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 40 RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), 41 RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), 42 RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), 43 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 44 RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), 45 RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), 46 RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), 47 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 48 RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), /* GPLL */ 49 RK3036_PLL_RATE(1092000000, 2, 91, 1, 1, 1, 0), 50 RK3036_PLL_RATE(1008000000, 1, 42, 1, 1, 1, 0), 51 RK3036_PLL_RATE(1000000000, 1, 125, 3, 1, 1, 0), /* PPLL */ 52 RK3036_PLL_RATE(996000000, 2, 83, 1, 1, 1, 0), /* CPLL */ 53 RK3036_PLL_RATE(960000000, 1, 40, 1, 1, 1, 0), 54 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), 55 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 56 RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0), 57 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), 58 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), 59 RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), 60 RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), 61 RK3036_PLL_RATE(96000000, 1, 24, 3, 2, 1, 0), 62 { /* sentinel */ }, 63 }; 64 65 static struct rockchip_pll_clock rk3528_pll_clks[] = { 66 [APLL] = PLL(pll_rk3328, PLL_APLL, RK3528_PLL_CON(0), 67 RK3528_MODE_CON, 0, 10, 0, rk3528_pll_rates), 68 69 [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3528_PLL_CON(8), 70 RK3528_MODE_CON, 2, 10, 0, rk3528_pll_rates), 71 72 [GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3528_PLL_CON(24), 73 RK3528_MODE_CON, 4, 10, 0, rk3528_pll_rates), 74 75 [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3528_PCIE_PLL_CON(32), 76 RK3528_MODE_CON, 6, 10, ROCKCHIP_PLL_FIXED_MODE, rk3528_pll_rates), 77 78 [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3528_DDRPHY_PLL_CON(16), 79 RK3528_DDRPHY_MODE_CON, 0, 10, 0, rk3528_pll_rates), 80 }; 81 82 #define RK3528_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg) \ 83 { \ 84 .rate = _rate##U, \ 85 .aclk_div = (_aclk_m_core), \ 86 .pclk_div = (_pclk_dbg), \ 87 } 88 89 /* sign-off: _aclk_m_core: 550M, _pclk_dbg: 137.5M, */ 90 static struct rockchip_cpu_rate_table rk3528_cpu_rates[] = { 91 RK3528_CPUCLK_RATE(1896000000, 1, 13), 92 RK3528_CPUCLK_RATE(1800000000, 1, 12), 93 RK3528_CPUCLK_RATE(1704000000, 1, 11), 94 RK3528_CPUCLK_RATE(1608000000, 1, 11), 95 RK3528_CPUCLK_RATE(1512000000, 1, 11), 96 RK3528_CPUCLK_RATE(1416000000, 1, 9), 97 RK3528_CPUCLK_RATE(1296000000, 1, 8), 98 RK3528_CPUCLK_RATE(1200000000, 1, 8), 99 RK3528_CPUCLK_RATE(1188000000, 1, 8), 100 RK3528_CPUCLK_RATE(1092000000, 1, 7), 101 RK3528_CPUCLK_RATE(1008000000, 1, 6), 102 RK3528_CPUCLK_RATE(1000000000, 1, 6), 103 RK3528_CPUCLK_RATE(996000000, 1, 6), 104 RK3528_CPUCLK_RATE(960000000, 1, 6), 105 RK3528_CPUCLK_RATE(912000000, 1, 6), 106 RK3528_CPUCLK_RATE(816000000, 1, 5), 107 RK3528_CPUCLK_RATE(600000000, 1, 3), 108 RK3528_CPUCLK_RATE(594000000, 1, 3), 109 RK3528_CPUCLK_RATE(408000000, 1, 2), 110 RK3528_CPUCLK_RATE(312000000, 1, 2), 111 RK3528_CPUCLK_RATE(216000000, 1, 1), 112 RK3528_CPUCLK_RATE(96000000, 1, 0), 113 }; 114 115 #ifndef CONFIG_SPL_BUILD 116 #define RK3528_CLK_DUMP(_id, _name) \ 117 { \ 118 .id = _id, \ 119 .name = _name, \ 120 } 121 122 static const struct rk3528_clk_info clks_dump[] = { 123 RK3528_CLK_DUMP(PLL_APLL, "apll"), 124 RK3528_CLK_DUMP(PLL_GPLL, "gpll"), 125 RK3528_CLK_DUMP(PLL_CPLL, "cpll"), 126 RK3528_CLK_DUMP(PLL_DPLL, "dpll"), 127 RK3528_CLK_DUMP(PLL_PPLL, "ppll"), 128 RK3528_CLK_DUMP(CLK_MATRIX_50M_SRC, "clk_50m"), 129 RK3528_CLK_DUMP(CLK_MATRIX_100M_SRC, "clk_100m"), 130 RK3528_CLK_DUMP(CLK_MATRIX_150M_SRC, "clk_150m"), 131 RK3528_CLK_DUMP(CLK_MATRIX_200M_SRC, "clk_200m"), 132 RK3528_CLK_DUMP(CLK_MATRIX_250M_SRC, "clk_250m"), 133 RK3528_CLK_DUMP(CLK_MATRIX_300M_SRC, "clk_300m"), 134 RK3528_CLK_DUMP(CLK_MATRIX_339M_SRC, "clk_339m"), 135 RK3528_CLK_DUMP(CLK_MATRIX_400M_SRC, "clk_400m"), 136 RK3528_CLK_DUMP(CLK_MATRIX_500M_SRC, "clk_600m"), 137 RK3528_CLK_DUMP(CLK_MATRIX_600M_SRC, "clk_600m"), 138 RK3528_CLK_DUMP(CLK_PPLL_50M_MATRIX, "clk_ppll_50m"), 139 RK3528_CLK_DUMP(CLK_PPLL_100M_MATRIX, "clk_ppll_100m"), 140 RK3528_CLK_DUMP(CLK_PPLL_125M_MATRIX, "clk_ppll_125m"), 141 }; 142 #endif 143 144 /* 145 * 146 * rational_best_approximation(31415, 10000, 147 * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 148 * 149 * you may look at given_numerator as a fixed point number, 150 * with the fractional part size described in given_denominator. 151 * 152 * for theoretical background, see: 153 * http://en.wikipedia.org/wiki/Continued_fraction 154 */ 155 static void rational_best_approximation(unsigned long given_numerator, 156 unsigned long given_denominator, 157 unsigned long max_numerator, 158 unsigned long max_denominator, 159 unsigned long *best_numerator, 160 unsigned long *best_denominator) 161 { 162 unsigned long n, d, n0, d0, n1, d1; 163 164 n = given_numerator; 165 d = given_denominator; 166 n0 = 0; 167 d1 = 0; 168 n1 = 1; 169 d0 = 1; 170 for (;;) { 171 unsigned long t, a; 172 173 if (n1 > max_numerator || d1 > max_denominator) { 174 n1 = n0; 175 d1 = d0; 176 break; 177 } 178 if (d == 0) 179 break; 180 t = d; 181 a = n / d; 182 d = n % d; 183 n = t; 184 t = n0 + a * n1; 185 n0 = n1; 186 n1 = t; 187 t = d0 + a * d1; 188 d0 = d1; 189 d1 = t; 190 } 191 *best_numerator = n1; 192 *best_denominator = d1; 193 } 194 195 static int rk3528_armclk_set_clk(struct rk3528_clk_priv *priv, ulong new_rate) 196 { 197 const struct rockchip_cpu_rate_table *rate; 198 struct rk3528_cru *cru = priv->cru; 199 ulong old_rate; 200 201 rate = rockchip_get_cpu_settings(rk3528_cpu_rates, new_rate); 202 if (!rate) { 203 printf("%s unsupported rate\n", __func__); 204 return -EINVAL; 205 } 206 207 /* 208 * set up dependent divisors for DBG and ACLK clocks. 209 */ 210 old_rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, APLL); 211 if (old_rate > new_rate) { 212 if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL], 213 priv->cru, APLL, new_rate)) 214 return -EINVAL; 215 216 rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, 217 rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT); 218 219 rk_clrsetreg(&cru->clksel_con[5], RK3528_DIV_ACLK_M_CORE_MASK, 220 rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT); 221 } else if (old_rate < new_rate) { 222 rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, 223 rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT); 224 225 rk_clrsetreg(&cru->clksel_con[5], RK3528_DIV_ACLK_M_CORE_MASK, 226 rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT); 227 228 if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL], 229 priv->cru, APLL, new_rate)) 230 return -EINVAL; 231 } 232 233 return 0; 234 } 235 236 static ulong rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv *priv, 237 ulong clk_id) 238 { 239 struct rk3528_cru *cru = priv->cru; 240 u32 div, mask, shift; 241 void *reg; 242 243 switch (clk_id) { 244 case CLK_PPLL_50M_MATRIX: 245 case CLK_GMAC1_RMII_VPU: 246 mask = PCEICRU_CLKSEL_CON01_CLK_MATRIX_50M_SRC_DIV_MASK; 247 shift = PCEICRU_CLKSEL_CON01_CLK_MATRIX_50M_SRC_DIV_SHIFT; 248 reg = &cru->pcieclksel_con[1]; 249 break; 250 251 case CLK_PPLL_100M_MATRIX: 252 mask = PCEICRU_CLKSEL_CON01_CLK_MATRIX_100M_SRC_DIV_MASK; 253 shift = PCEICRU_CLKSEL_CON01_CLK_MATRIX_100M_SRC_DIV_SHIFT; 254 reg = &cru->pcieclksel_con[1]; 255 break; 256 257 case CLK_PPLL_125M_MATRIX: 258 case CLK_GMAC1_SRC_VPU: 259 mask = CRU_CLKSEL_CON60_CLK_MATRIX_125M_SRC_DIV_MASK; 260 shift = CRU_CLKSEL_CON60_CLK_MATRIX_125M_SRC_DIV_SHIFT; 261 reg = &cru->clksel_con[60]; 262 break; 263 264 case CLK_GMAC1_VPU_25M: 265 mask = CRU_CLKSEL_CON60_CLK_MATRIX_25M_SRC_DIV_MASK; 266 shift = CRU_CLKSEL_CON60_CLK_MATRIX_25M_SRC_DIV_SHIFT; 267 reg = &cru->clksel_con[60]; 268 break; 269 default: 270 return -ENOENT; 271 } 272 273 div = (readl(reg) & mask) >> shift; 274 275 return DIV_TO_RATE(priv->ppll_hz, div); 276 } 277 278 static ulong rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv *priv, 279 ulong clk_id, ulong rate) 280 { 281 struct rk3528_cru *cru = priv->cru; 282 u32 id, div, mask, shift; 283 u8 is_pciecru = 0; 284 285 switch (clk_id) { 286 case CLK_PPLL_50M_MATRIX: 287 id = 1; 288 mask = PCEICRU_CLKSEL_CON01_CLK_MATRIX_50M_SRC_DIV_MASK; 289 shift = PCEICRU_CLKSEL_CON01_CLK_MATRIX_50M_SRC_DIV_SHIFT; 290 is_pciecru = 1; 291 break; 292 293 case CLK_PPLL_100M_MATRIX: 294 id = 1; 295 mask = PCEICRU_CLKSEL_CON01_CLK_MATRIX_100M_SRC_DIV_MASK; 296 shift = PCEICRU_CLKSEL_CON01_CLK_MATRIX_100M_SRC_DIV_SHIFT; 297 is_pciecru = 1; 298 break; 299 300 case CLK_PPLL_125M_MATRIX: 301 id = 60; 302 mask = CRU_CLKSEL_CON60_CLK_MATRIX_125M_SRC_DIV_MASK; 303 shift = CRU_CLKSEL_CON60_CLK_MATRIX_125M_SRC_DIV_SHIFT; 304 break; 305 case CLK_GMAC1_VPU_25M: 306 id = 60; 307 mask = CRU_CLKSEL_CON60_CLK_MATRIX_25M_SRC_DIV_MASK; 308 shift = CRU_CLKSEL_CON60_CLK_MATRIX_25M_SRC_DIV_SHIFT; 309 break; 310 default: 311 return -ENOENT; 312 } 313 314 div = DIV_ROUND_UP(priv->ppll_hz, rate); 315 if (is_pciecru) 316 rk_clrsetreg(&cru->pcieclksel_con[id], mask, (div - 1) << shift); 317 else 318 rk_clrsetreg(&cru->clksel_con[id], mask, (div - 1) << shift); 319 320 return rk3528_ppll_matrix_get_rate(priv, clk_id); 321 } 322 323 static ulong rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv *priv, 324 ulong clk_id) 325 { 326 struct rk3528_cru *cru = priv->cru; 327 u32 sel, div, mask, shift, con; 328 u32 sel_mask = 0, sel_shift; 329 u8 is_gpll_parent = 1; 330 u8 is_halfdiv = 0; 331 ulong prate; 332 333 switch (clk_id) { 334 case CLK_MATRIX_50M_SRC: 335 con = 0; 336 mask = CRU_CLKSEL_CON00_CLK_MATRIX_50M_SRC_DIV_MASK; 337 shift = CRU_CLKSEL_CON00_CLK_MATRIX_50M_SRC_DIV_SHIFT; 338 is_gpll_parent = 0; 339 break; 340 341 case CLK_MATRIX_100M_SRC: 342 con = 0; 343 mask = CRU_CLKSEL_CON00_CLK_MATRIX_100M_SRC_DIV_MASK; 344 shift = CRU_CLKSEL_CON00_CLK_MATRIX_100M_SRC_DIV_SHIFT; 345 is_gpll_parent = 0; 346 break; 347 348 case CLK_MATRIX_150M_SRC: 349 con = 1; 350 mask = CRU_CLKSEL_CON01_CLK_MATRIX_150M_SRC_DIV_MASK; 351 shift = CRU_CLKSEL_CON01_CLK_MATRIX_150M_SRC_DIV_SHIFT; 352 break; 353 354 case CLK_MATRIX_200M_SRC: 355 con = 1; 356 mask = CRU_CLKSEL_CON01_CLK_MATRIX_200M_SRC_DIV_MASK; 357 shift = CRU_CLKSEL_CON01_CLK_MATRIX_200M_SRC_DIV_SHIFT; 358 break; 359 360 case CLK_MATRIX_250M_SRC: 361 con = 1; 362 mask = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_DIV_MASK; 363 shift = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_DIV_SHIFT; 364 sel_mask = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_SEL_MASK; 365 sel_shift = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_SEL_SHIFT; 366 break; 367 368 case CLK_MATRIX_300M_SRC: 369 con = 2; 370 mask = CRU_CLKSEL_CON02_CLK_MATRIX_300M_SRC_DIV_MASK; 371 shift = CRU_CLKSEL_CON02_CLK_MATRIX_300M_SRC_DIV_SHIFT; 372 break; 373 374 case CLK_MATRIX_339M_SRC: 375 con = 2; 376 mask = CRU_CLKSEL_CON02_CLK_MATRIX_339M_SRC_DIV_MASK; 377 shift = CRU_CLKSEL_CON02_CLK_MATRIX_339M_SRC_DIV_SHIFT; 378 is_halfdiv = 1; 379 break; 380 381 case CLK_MATRIX_400M_SRC: 382 con = 2; 383 mask = CRU_CLKSEL_CON02_CLK_MATRIX_400M_SRC_DIV_MASK; 384 shift = CRU_CLKSEL_CON02_CLK_MATRIX_400M_SRC_DIV_SHIFT; 385 break; 386 387 case CLK_MATRIX_500M_SRC: 388 con = 3; 389 mask = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_DIV_MASK; 390 shift = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_DIV_SHIFT; 391 sel_mask = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_SEL_MASK; 392 sel_shift = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_SEL_SHIFT; 393 break; 394 395 case CLK_MATRIX_600M_SRC: 396 con = 4; 397 mask = CRU_CLKSEL_CON04_CLK_MATRIX_600M_SRC_DIV_MASK; 398 shift = CRU_CLKSEL_CON04_CLK_MATRIX_600M_SRC_DIV_SHIFT; 399 break; 400 401 case ACLK_BUS_VOPGL_ROOT: 402 case ACLK_BUS_VOPGL_BIU: 403 con = 43; 404 mask = CRU_CLKSEL_CON43_ACLK_BUS_VOPGL_ROOT_DIV_MASK; 405 shift = CRU_CLKSEL_CON43_ACLK_BUS_VOPGL_ROOT_DIV_SHIFT; 406 break; 407 408 default: 409 return -ENOENT; 410 } 411 412 if (sel_mask) { 413 sel = (readl(&cru->clksel_con[con]) & sel_mask) >> sel_shift; 414 if (sel == CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX) // TODO 415 prate = priv->gpll_hz; 416 else 417 prate = priv->cpll_hz; 418 } else { 419 if (is_gpll_parent) 420 prate = priv->gpll_hz; 421 else 422 prate = priv->cpll_hz; 423 } 424 425 div = (readl(&cru->clksel_con[con]) & mask) >> shift; 426 427 return is_halfdiv ? DIV_TO_RATE(prate * 2, (3 + 2 * div) + 1) : DIV_TO_RATE(prate, div); 428 } 429 430 static ulong rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv *priv, 431 ulong clk_id, ulong rate) 432 { 433 struct rk3528_cru *cru = priv->cru; 434 u32 sel, div, mask, shift, con; 435 u32 sel_mask = 0, sel_shift; 436 u8 is_gpll_parent = 1; 437 u8 is_halfdiv = 0; 438 ulong prate = 0; 439 440 switch (clk_id) { 441 case CLK_MATRIX_50M_SRC: 442 con = 0; 443 mask = CRU_CLKSEL_CON00_CLK_MATRIX_50M_SRC_DIV_MASK; 444 shift = CRU_CLKSEL_CON00_CLK_MATRIX_50M_SRC_DIV_SHIFT; 445 is_gpll_parent = 0; 446 break; 447 448 case CLK_MATRIX_100M_SRC: 449 con = 0; 450 mask = CRU_CLKSEL_CON00_CLK_MATRIX_100M_SRC_DIV_MASK; 451 shift = CRU_CLKSEL_CON00_CLK_MATRIX_100M_SRC_DIV_SHIFT; 452 is_gpll_parent = 0; 453 break; 454 455 case CLK_MATRIX_150M_SRC: 456 con = 1; 457 mask = CRU_CLKSEL_CON01_CLK_MATRIX_150M_SRC_DIV_MASK; 458 shift = CRU_CLKSEL_CON01_CLK_MATRIX_150M_SRC_DIV_SHIFT; 459 break; 460 461 case CLK_MATRIX_200M_SRC: 462 con = 1; 463 mask = CRU_CLKSEL_CON01_CLK_MATRIX_200M_SRC_DIV_MASK; 464 shift = CRU_CLKSEL_CON01_CLK_MATRIX_200M_SRC_DIV_SHIFT; 465 break; 466 467 case CLK_MATRIX_250M_SRC: 468 con = 1; 469 mask = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_DIV_MASK; 470 shift = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_DIV_SHIFT; 471 sel_mask = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_SEL_MASK; 472 sel_shift = CRU_CLKSEL_CON01_CLK_MATRIX_250M_SRC_SEL_SHIFT; 473 break; 474 475 case CLK_MATRIX_300M_SRC: 476 con = 2; 477 mask = CRU_CLKSEL_CON02_CLK_MATRIX_300M_SRC_DIV_MASK; 478 shift = CRU_CLKSEL_CON02_CLK_MATRIX_300M_SRC_DIV_SHIFT; 479 break; 480 481 case CLK_MATRIX_339M_SRC: 482 con = 2; 483 mask = CRU_CLKSEL_CON02_CLK_MATRIX_339M_SRC_DIV_MASK; 484 shift = CRU_CLKSEL_CON02_CLK_MATRIX_339M_SRC_DIV_SHIFT; 485 is_halfdiv = 1; 486 break; 487 488 case CLK_MATRIX_400M_SRC: 489 con = 2; 490 mask = CRU_CLKSEL_CON02_CLK_MATRIX_400M_SRC_DIV_MASK; 491 shift = CRU_CLKSEL_CON02_CLK_MATRIX_400M_SRC_DIV_SHIFT; 492 break; 493 494 case CLK_MATRIX_500M_SRC: 495 con = 3; 496 mask = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_DIV_MASK; 497 shift = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_DIV_SHIFT; 498 sel_mask = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_SEL_MASK; 499 sel_shift = CRU_CLKSEL_CON03_CLK_MATRIX_500M_SRC_SEL_SHIFT; 500 break; 501 502 case CLK_MATRIX_600M_SRC: 503 con = 4; 504 mask = CRU_CLKSEL_CON04_CLK_MATRIX_600M_SRC_DIV_MASK; 505 shift = CRU_CLKSEL_CON04_CLK_MATRIX_600M_SRC_DIV_SHIFT; 506 break; 507 508 case ACLK_BUS_VOPGL_ROOT: 509 case ACLK_BUS_VOPGL_BIU: 510 con = 43; 511 mask = CRU_CLKSEL_CON43_ACLK_BUS_VOPGL_ROOT_DIV_MASK; 512 shift = CRU_CLKSEL_CON43_ACLK_BUS_VOPGL_ROOT_DIV_SHIFT; 513 break; 514 515 default: 516 return -ENOENT; 517 } 518 519 if (sel_mask) { 520 if (priv->gpll_hz % rate == 0) { 521 sel = CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX; // TODO 522 prate = priv->gpll_hz; 523 } else { 524 sel = CLK_MATRIX_250M_SRC_SEL_CLK_CPLL_MUX; 525 prate = priv->cpll_hz; 526 } 527 } else { 528 if (is_gpll_parent) 529 prate = priv->gpll_hz; 530 else 531 prate = priv->cpll_hz; 532 } 533 534 if (is_halfdiv) 535 div = DIV_ROUND_UP((prate * 2) - (3 * rate), 2 * rate); 536 else 537 div = DIV_ROUND_UP(prate, rate); 538 539 rk_clrsetreg(&cru->clksel_con[con], mask, (div - 1) << shift); 540 if (sel_mask) 541 rk_clrsetreg(&cru->clksel_con[con], sel_mask, sel << sel_shift); 542 543 return rk3528_cgpll_matrix_get_rate(priv, clk_id); 544 } 545 546 static ulong rk3528_i2c_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 547 { 548 struct rk3528_cru *cru = priv->cru; 549 u32 id, sel, con, mask, shift; 550 u8 is_pmucru = 0; 551 ulong rate; 552 553 switch (clk_id) { 554 case CLK_I2C0: 555 id = 79; 556 mask = CRU_CLKSEL_CON79_CLK_I2C0_SEL_MASK; 557 shift = CRU_CLKSEL_CON79_CLK_I2C0_SEL_SHIFT; 558 break; 559 560 case CLK_I2C1: 561 id = 79; 562 mask = CRU_CLKSEL_CON79_CLK_I2C1_SEL_MASK; 563 shift = CRU_CLKSEL_CON79_CLK_I2C1_SEL_SHIFT; 564 break; 565 566 case CLK_I2C2: 567 id = 0; 568 mask = PMUCRU_CLKSEL_CON0_CLK_I2C2_SEL_MASK; 569 shift = PMUCRU_CLKSEL_CON0_CLK_I2C2_SEL_SHIFT; 570 is_pmucru = 1; 571 break; 572 573 case CLK_I2C3: 574 id = 63; 575 mask = CRU_CLKSEL_CON63_CLK_I2C3_SEL_MASK; 576 shift = CRU_CLKSEL_CON63_CLK_I2C3_SEL_SHIFT; 577 break; 578 579 case CLK_I2C4: 580 id = 85; 581 mask = CRU_CLKSEL_CON85_CLK_I2C4_SEL_MASK; 582 shift = CRU_CLKSEL_CON85_CLK_I2C4_SEL_SHIFT; 583 break; 584 585 case CLK_I2C5: 586 id = 63; 587 mask = CRU_CLKSEL_CON63_CLK_I2C5_SEL_MASK; 588 shift = CRU_CLKSEL_CON63_CLK_I2C5_SEL_SHIFT; 589 break; 590 591 case CLK_I2C6: 592 id = 64; 593 mask = CRU_CLKSEL_CON64_CLK_I2C6_SEL_MASK; 594 shift = CRU_CLKSEL_CON64_CLK_I2C6_SEL_SHIFT; 595 break; 596 597 case CLK_I2C7: 598 id = 86; 599 mask = CRU_CLKSEL_CON86_CLK_I2C7_SEL_MASK; 600 shift = CRU_CLKSEL_CON86_CLK_I2C7_SEL_SHIFT; 601 break; 602 603 default: 604 return -ENOENT; 605 } 606 607 if (is_pmucru) 608 con = readl(&cru->pmuclksel_con[id]); 609 else 610 con = readl(&cru->clksel_con[id]); 611 sel = (con & mask) >> shift; 612 if (sel == CLK_I2C3_SEL_CLK_MATRIX_200M_SRC) 613 rate = 200 * MHz; 614 else if (sel == CLK_I2C3_SEL_CLK_MATRIX_100M_SRC) 615 rate = 100 * MHz; 616 else if (sel == CLK_I2C3_SEL_CLK_MATRIX_50M_SRC) 617 rate = 50 * MHz; 618 else 619 rate = OSC_HZ; 620 621 return rate; 622 } 623 624 static ulong rk3528_i2c_set_clk(struct rk3528_clk_priv *priv, ulong clk_id, 625 ulong rate) 626 { 627 struct rk3528_cru *cru = priv->cru; 628 u32 id, sel, mask, shift; 629 u8 is_pmucru = 0; 630 631 if (rate == 200 * MHz) 632 sel = CLK_I2C3_SEL_CLK_MATRIX_200M_SRC; 633 else if (rate == 100 * MHz) 634 sel = CLK_I2C3_SEL_CLK_MATRIX_100M_SRC; 635 else if (rate == 50 * MHz) 636 sel = CLK_I2C3_SEL_CLK_MATRIX_50M_SRC; 637 else 638 sel = CLK_I2C3_SEL_XIN_OSC0_FUNC; 639 640 switch (clk_id) { 641 case CLK_I2C0: 642 id = 79; 643 mask = CRU_CLKSEL_CON79_CLK_I2C0_SEL_MASK; 644 shift = CRU_CLKSEL_CON79_CLK_I2C0_SEL_SHIFT; 645 break; 646 647 case CLK_I2C1: 648 id = 79; 649 mask = CRU_CLKSEL_CON79_CLK_I2C1_SEL_MASK; 650 shift = CRU_CLKSEL_CON79_CLK_I2C1_SEL_SHIFT; 651 break; 652 653 case CLK_I2C2: 654 id = 0; 655 mask = PMUCRU_CLKSEL_CON0_CLK_I2C2_SEL_MASK; 656 shift = PMUCRU_CLKSEL_CON0_CLK_I2C2_SEL_SHIFT; 657 is_pmucru = 1; 658 break; 659 660 case CLK_I2C3: 661 id = 63; 662 mask = CRU_CLKSEL_CON63_CLK_I2C3_SEL_MASK; 663 shift = CRU_CLKSEL_CON63_CLK_I2C3_SEL_SHIFT; 664 break; 665 666 case CLK_I2C4: 667 id = 85; 668 mask = CRU_CLKSEL_CON85_CLK_I2C4_SEL_MASK; 669 shift = CRU_CLKSEL_CON85_CLK_I2C4_SEL_SHIFT; 670 break; 671 672 case CLK_I2C5: 673 id = 63; 674 mask = CRU_CLKSEL_CON63_CLK_I2C5_SEL_MASK; 675 shift = CRU_CLKSEL_CON63_CLK_I2C5_SEL_SHIFT; 676 677 case CLK_I2C6: 678 id = 64; 679 mask = CRU_CLKSEL_CON64_CLK_I2C6_SEL_MASK; 680 shift = CRU_CLKSEL_CON64_CLK_I2C6_SEL_SHIFT; 681 break; 682 683 case CLK_I2C7: 684 id = 86; 685 mask = CRU_CLKSEL_CON86_CLK_I2C7_SEL_MASK; 686 shift = CRU_CLKSEL_CON86_CLK_I2C7_SEL_SHIFT; 687 break; 688 689 default: 690 return -ENOENT; 691 } 692 693 if (is_pmucru) 694 rk_clrsetreg(&cru->pmuclksel_con[id], mask, sel << shift); 695 else 696 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); 697 698 return rk3528_i2c_get_clk(priv, clk_id); 699 } 700 701 static ulong rk3528_spi_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 702 { 703 struct rk3528_cru *cru = priv->cru; 704 u32 id, sel, con, mask, shift; 705 ulong rate; 706 707 switch (clk_id) { 708 case CLK_SPI0: 709 id = 79; 710 mask = CRU_CLKSEL_CON79_CLK_SPI0_SEL_MASK; 711 shift = CRU_CLKSEL_CON79_CLK_SPI0_SEL_SHIFT; 712 break; 713 714 case CLK_SPI1: 715 id = 63; 716 mask = CRU_CLKSEL_CON63_CLK_SPI1_SEL_MASK; 717 shift = CRU_CLKSEL_CON63_CLK_SPI1_SEL_SHIFT; 718 break; 719 default: 720 return -ENOENT; 721 } 722 723 con = readl(&cru->clksel_con[id]); 724 sel = (con & mask) >> shift; 725 if (sel == CLK_SPI1_SEL_CLK_MATRIX_200M_SRC) 726 rate = 200 * MHz; 727 if (sel == CLK_SPI1_SEL_CLK_MATRIX_100M_SRC) 728 rate = 100 * MHz; 729 if (sel == CLK_SPI1_SEL_CLK_MATRIX_50M_SRC) 730 rate = 50 * MHz; 731 else 732 rate = OSC_HZ; 733 734 return rate; 735 } 736 737 static ulong rk3528_spi_set_clk(struct rk3528_clk_priv *priv, 738 ulong clk_id, ulong rate) 739 { 740 struct rk3528_cru *cru = priv->cru; 741 u32 id, sel, mask, shift; 742 743 if (rate == 200 * MHz) 744 sel = CLK_SPI1_SEL_CLK_MATRIX_200M_SRC; 745 else if (rate == 100 * MHz) 746 sel = CLK_SPI1_SEL_CLK_MATRIX_100M_SRC; 747 else if (rate == 50 * MHz) 748 sel = CLK_SPI1_SEL_CLK_MATRIX_50M_SRC; 749 else 750 sel = CLK_SPI1_SEL_XIN_OSC0_FUNC; 751 752 switch (clk_id) { 753 case CLK_SPI0: 754 id = 79; 755 mask = CRU_CLKSEL_CON79_CLK_SPI0_SEL_MASK; 756 shift = CRU_CLKSEL_CON79_CLK_SPI0_SEL_SHIFT; 757 break; 758 759 case CLK_SPI1: 760 id = 63; 761 mask = CRU_CLKSEL_CON63_CLK_SPI1_SEL_MASK; 762 shift = CRU_CLKSEL_CON63_CLK_SPI1_SEL_SHIFT; 763 break; 764 default: 765 return -ENOENT; 766 } 767 768 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); 769 770 return rk3528_spi_get_clk(priv, clk_id); 771 } 772 773 static ulong rk3528_pwm_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 774 { 775 struct rk3528_cru *cru = priv->cru; 776 u32 id, sel, con, mask, shift; 777 ulong rate; 778 779 switch (clk_id) { 780 case CLK_PWM0: 781 id = 44; 782 mask = CRU_CLKSEL_CON44_CLK_PWM0_SEL_MASK; 783 shift = CRU_CLKSEL_CON44_CLK_PWM0_SEL_SHIFT; 784 break; 785 786 case CLK_PWM1: 787 id = 44; 788 mask = CRU_CLKSEL_CON44_CLK_PWM1_SEL_MASK; 789 shift = CRU_CLKSEL_CON44_CLK_PWM1_SEL_SHIFT; 790 break; 791 792 default: 793 return -ENOENT; 794 } 795 796 con = readl(&cru->clksel_con[id]); 797 sel = (con & mask) >> shift; 798 if (sel == CLK_PWM0_SEL_CLK_MATRIX_100M_SRC) 799 rate = 100 * MHz; 800 if (sel == CLK_PWM0_SEL_CLK_MATRIX_50M_SRC) 801 rate = 50 * MHz; 802 else 803 rate = OSC_HZ; 804 805 return rate; 806 } 807 808 static ulong rk3528_pwm_set_clk(struct rk3528_clk_priv *priv, 809 ulong clk_id, ulong rate) 810 { 811 struct rk3528_cru *cru = priv->cru; 812 u32 id, sel, mask, shift; 813 814 if (rate == 100 * MHz) 815 sel = CLK_PWM0_SEL_CLK_MATRIX_100M_SRC; 816 else if (rate == 50 * MHz) 817 sel = CLK_PWM0_SEL_CLK_MATRIX_50M_SRC; 818 else 819 sel = CLK_PWM0_SEL_XIN_OSC0_FUNC; 820 821 switch (clk_id) { 822 case CLK_PWM0: 823 id = 44; 824 mask = CRU_CLKSEL_CON44_CLK_PWM0_SEL_MASK; 825 shift = CRU_CLKSEL_CON44_CLK_PWM0_SEL_SHIFT; 826 break; 827 828 case CLK_PWM1: 829 id = 44; 830 mask = CRU_CLKSEL_CON44_CLK_PWM1_SEL_MASK; 831 shift = CRU_CLKSEL_CON44_CLK_PWM1_SEL_SHIFT; 832 break; 833 834 default: 835 return -ENOENT; 836 } 837 838 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); 839 840 return rk3528_pwm_get_clk(priv, clk_id); 841 } 842 843 static ulong rk3528_adc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 844 { 845 struct rk3528_cru *cru = priv->cru; 846 u32 div, con; 847 848 con = readl(&cru->clksel_con[74]); 849 switch (clk_id) { 850 case CLK_SARADC: 851 div = (con & CRU_CLKSEL_CON74_CLK_SARADC_DIV_MASK) >> 852 CRU_CLKSEL_CON74_CLK_SARADC_DIV_SHIFT; 853 break; 854 855 case CLK_TSADC_TSEN: 856 div = (con & CRU_CLKSEL_CON74_CLK_TSADC_TSEN_DIV_MASK) >> 857 CRU_CLKSEL_CON74_CLK_TSADC_TSEN_DIV_SHIFT; 858 break; 859 860 case CLK_TSADC: 861 div = (con & CRU_CLKSEL_CON74_CLK_TSADC_DIV_MASK) >> 862 CRU_CLKSEL_CON74_CLK_TSADC_DIV_SHIFT; 863 break; 864 865 default: 866 return -ENOENT; 867 } 868 869 return DIV_TO_RATE(OSC_HZ, div); 870 } 871 872 static ulong rk3528_adc_set_clk(struct rk3528_clk_priv *priv, 873 ulong clk_id, ulong rate) 874 { 875 struct rk3528_cru *cru = priv->cru; 876 u32 div, mask, shift; 877 878 switch (clk_id) { 879 case CLK_SARADC: 880 mask = CRU_CLKSEL_CON74_CLK_SARADC_DIV_MASK; 881 shift = CRU_CLKSEL_CON74_CLK_SARADC_DIV_SHIFT; 882 break; 883 884 case CLK_TSADC_TSEN: 885 mask = CRU_CLKSEL_CON74_CLK_TSADC_TSEN_DIV_MASK; 886 shift = CRU_CLKSEL_CON74_CLK_TSADC_TSEN_DIV_SHIFT; 887 break; 888 889 case CLK_TSADC: 890 mask = CRU_CLKSEL_CON74_CLK_TSADC_DIV_MASK; 891 shift = CRU_CLKSEL_CON74_CLK_TSADC_DIV_SHIFT; 892 break; 893 894 default: 895 return -ENOENT; 896 } 897 898 div = DIV_ROUND_UP(OSC_HZ, rate); 899 rk_clrsetreg(&cru->clksel_con[74], mask, (div - 1) << shift); 900 901 return rk3528_adc_get_clk(priv, clk_id); 902 } 903 904 905 static ulong rk3528_crypto_get_rate(struct rk3528_clk_priv *priv, ulong clk_id) 906 { 907 struct rk3528_cru *cru = priv->cru; 908 u32 id, sel, con, mask, shift; 909 ulong rate; 910 911 switch (clk_id) { 912 case CLK_CORE_CRYPTO: 913 id = 43; 914 mask = CRU_CLKSEL_CON43_CLK_CORE_CRYPTO_SEL_MASK; 915 shift = CRU_CLKSEL_CON43_CLK_CORE_CRYPTO_SEL_SHIFT; 916 break; 917 918 case CLK_PKA_CRYPTO: 919 id = 44; 920 mask = CRU_CLKSEL_CON44_CLK_PKA_CRYPTO_SEL_MASK; 921 shift = CRU_CLKSEL_CON44_CLK_PKA_CRYPTO_SEL_SHIFT; 922 break; 923 924 default: 925 return -ENOENT; 926 } 927 928 con = readl(&cru->clksel_con[id]); 929 sel = (con & mask) >> shift; 930 if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC) 931 rate = 300 * MHz; 932 else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC) 933 rate = 200 * MHz; 934 else if (sel == CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC) 935 rate = 100 * MHz; 936 else 937 rate = OSC_HZ; 938 939 return rate; 940 } 941 942 static ulong rk3528_crypto_set_rate(struct rk3528_clk_priv *priv, 943 ulong clk_id, ulong rate) 944 { 945 struct rk3528_cru *cru = priv->cru; 946 u32 id, sel, mask, shift; 947 948 if (rate == 300 * MHz) 949 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC; 950 else if (rate == 200 * MHz) 951 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC; 952 else if (rate == 100 * MHz) 953 sel = CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC; 954 else 955 sel = CLK_CORE_CRYPTO_SEL_XIN_OSC0_FUNC; 956 957 switch (clk_id) { 958 case CLK_CORE_CRYPTO: 959 id = 43; 960 mask = CRU_CLKSEL_CON43_CLK_CORE_CRYPTO_SEL_MASK; 961 shift = CRU_CLKSEL_CON43_CLK_CORE_CRYPTO_SEL_SHIFT; 962 break; 963 964 case CLK_PKA_CRYPTO: 965 id = 44; 966 mask = CRU_CLKSEL_CON44_CLK_PKA_CRYPTO_SEL_MASK; 967 shift = CRU_CLKSEL_CON44_CLK_PKA_CRYPTO_SEL_SHIFT; 968 break; 969 970 default: 971 return -ENOENT; 972 } 973 974 rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); 975 976 return rk3528_crypto_get_rate(priv, clk_id); 977 } 978 979 static ulong rk3528_sdmmc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 980 { 981 struct rk3528_cru *cru = priv->cru; 982 u32 div, sel, con; 983 ulong prate; 984 985 con = readl(&cru->clksel_con[85]); 986 div = (con & CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_DIV_MASK) >> 987 CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_DIV_SHIFT; 988 sel = (con & CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_SEL_MASK) >> 989 CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_SEL_SHIFT; 990 991 if (sel == CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX) 992 prate = priv->gpll_hz; 993 else if (sel == CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX) 994 prate = priv->cpll_hz; 995 else 996 prate = OSC_HZ; 997 998 return DIV_TO_RATE(prate, div); 999 } 1000 1001 static ulong rk3528_sdmmc_set_clk(struct rk3528_clk_priv *priv, 1002 ulong clk_id, ulong rate) 1003 { 1004 struct rk3528_cru *cru = priv->cru; 1005 u32 div, sel; 1006 1007 if (OSC_HZ % rate == 0) { 1008 div = DIV_ROUND_UP(OSC_HZ, rate); 1009 sel = CCLK_SRC_SDMMC0_SEL_XIN_OSC0_FUNC; 1010 } else if ((priv->cpll_hz % rate) == 0) { 1011 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1012 sel = CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX; 1013 } else { 1014 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1015 sel = CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX; 1016 } 1017 1018 assert(div - 1 <= 31); 1019 rk_clrsetreg(&cru->clksel_con[85], 1020 CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_SEL_MASK | 1021 CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_DIV_MASK, 1022 sel << CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_SEL_SHIFT | 1023 (div - 1) << CRU_CLKSEL_CON85_CCLK_SRC_SDMMC0_DIV_SHIFT); 1024 1025 return rk3528_sdmmc_get_clk(priv, clk_id); 1026 } 1027 1028 static ulong rk3528_sfc_get_clk(struct rk3528_clk_priv *priv) 1029 { 1030 struct rk3528_cru *cru = priv->cru; 1031 u32 div, sel, con, parent; 1032 1033 con = readl(&cru->clksel_con[61]); 1034 div = (con & CRU_CLKSEL_CON61_SCLK_SFC_DIV_MASK) >> 1035 CRU_CLKSEL_CON61_SCLK_SFC_DIV_SHIFT; 1036 sel = (con & CRU_CLKSEL_CON61_SCLK_SFC_SEL_MASK) >> 1037 CRU_CLKSEL_CON61_SCLK_SFC_SEL_SHIFT; 1038 if (sel == SCLK_SFC_SEL_CLK_GPLL_MUX) 1039 parent = priv->gpll_hz; 1040 else if (sel == SCLK_SFC_SEL_CLK_CPLL_MUX) 1041 parent = priv->cpll_hz; 1042 else 1043 parent = OSC_HZ; 1044 1045 return DIV_TO_RATE(parent, div); 1046 } 1047 1048 static ulong rk3528_sfc_set_clk(struct rk3528_clk_priv *priv, ulong rate) 1049 { 1050 struct rk3528_cru *cru = priv->cru; 1051 int div, sel; 1052 1053 if (OSC_HZ % rate == 0) { 1054 div = DIV_ROUND_UP(OSC_HZ, rate); 1055 sel = SCLK_SFC_SEL_XIN_OSC0_FUNC; 1056 } else if ((priv->cpll_hz % rate) == 0) { 1057 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1058 sel = SCLK_SFC_SEL_CLK_CPLL_MUX; 1059 } else { 1060 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1061 sel = SCLK_SFC_SEL_CLK_GPLL_MUX; 1062 } 1063 1064 assert(div - 1 <= 63); 1065 rk_clrsetreg(&cru->clksel_con[61], 1066 CRU_CLKSEL_CON61_SCLK_SFC_SEL_MASK | 1067 CRU_CLKSEL_CON61_SCLK_SFC_DIV_MASK, 1068 sel << CRU_CLKSEL_CON61_SCLK_SFC_SEL_SHIFT | 1069 (div - 1) << CRU_CLKSEL_CON61_SCLK_SFC_DIV_SHIFT); 1070 1071 return rk3528_sfc_get_clk(priv); 1072 } 1073 1074 static ulong rk3528_emmc_get_clk(struct rk3528_clk_priv *priv) 1075 { 1076 struct rk3528_cru *cru = priv->cru; 1077 u32 div, sel, con, parent; 1078 1079 con = readl(&cru->clksel_con[62]); 1080 div = (con & CRU_CLKSEL_CON62_CCLK_SRC_EMMC_DIV_MASK) >> 1081 CRU_CLKSEL_CON62_CCLK_SRC_EMMC_DIV_SHIFT; 1082 sel = (con & CRU_CLKSEL_CON62_CCLK_SRC_EMMC_SEL_MASK) >> 1083 CRU_CLKSEL_CON62_CCLK_SRC_EMMC_SEL_SHIFT; 1084 1085 if (sel == CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX) 1086 parent = priv->gpll_hz; 1087 else if (sel == CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX) 1088 parent = priv->cpll_hz; 1089 else 1090 parent = OSC_HZ; 1091 1092 return DIV_TO_RATE(parent, div); 1093 } 1094 1095 static ulong rk3528_emmc_set_clk(struct rk3528_clk_priv *priv, ulong rate) 1096 { 1097 struct rk3528_cru *cru = priv->cru; 1098 u32 div, sel; 1099 1100 if (OSC_HZ % rate == 0) { 1101 div = DIV_ROUND_UP(OSC_HZ, rate); 1102 sel = CCLK_SRC_EMMC_SEL_XIN_OSC0_FUNC; 1103 } else if ((priv->cpll_hz % rate) == 0) { 1104 div = DIV_ROUND_UP(priv->cpll_hz, rate); 1105 sel = CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX; 1106 } else { 1107 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1108 sel = CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX; 1109 } 1110 1111 assert(div - 1 <= 31); 1112 rk_clrsetreg(&cru->clksel_con[62], 1113 CRU_CLKSEL_CON62_CCLK_SRC_EMMC_SEL_MASK | 1114 CRU_CLKSEL_CON62_CCLK_SRC_EMMC_DIV_MASK, 1115 sel << CRU_CLKSEL_CON62_CCLK_SRC_EMMC_SEL_SHIFT | 1116 (div - 1) << CRU_CLKSEL_CON62_CCLK_SRC_EMMC_DIV_SHIFT); 1117 1118 return rk3528_emmc_get_clk(priv); 1119 } 1120 1121 static ulong rk3528_dclk_vop_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) 1122 { 1123 struct rk3528_cru *cru = priv->cru; 1124 u32 div_mask, div_shift; 1125 u32 sel_mask, sel_shift; 1126 u32 id, con, sel, div; 1127 ulong prate; 1128 1129 switch (clk_id) { 1130 case DCLK_VOP0: 1131 id = 32; 1132 sel_mask = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_SEL_MASK; 1133 sel_shift = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_SEL_SHIFT; 1134 /* FIXME if need src: clk_hdmiphy_pixel_io */ 1135 div_mask = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_DIV_MASK; 1136 div_shift = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_DIV_SHIFT; 1137 break; 1138 1139 case DCLK_VOP1: 1140 id = 33; 1141 sel_mask = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_SEL_MASK; 1142 sel_shift = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_SEL_SHIFT; 1143 div_mask = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_DIV_MASK; 1144 div_shift = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_DIV_SHIFT; 1145 break; 1146 1147 default: 1148 return -ENOENT; 1149 } 1150 1151 con = readl(&cru->clksel_con[id]); 1152 div = (con & div_mask) >> div_shift; 1153 sel = (con & sel_mask) >> sel_shift; 1154 if (sel == DCLK_VOP_SRC_SEL_CLK_GPLL_MUX) 1155 prate = priv->gpll_hz; 1156 else 1157 prate = priv->cpll_hz; 1158 1159 return DIV_TO_RATE(prate, div); 1160 } 1161 1162 static ulong rk3528_dclk_vop_set_clk(struct rk3528_clk_priv *priv, 1163 ulong clk_id, ulong rate) 1164 { 1165 struct rk3528_cru *cru = priv->cru; 1166 u32 div_mask, div_shift; 1167 u32 sel_mask, sel_shift; 1168 u32 id, sel, div; 1169 ulong prate; 1170 1171 switch (clk_id) { 1172 case DCLK_VOP0: 1173 id = 32; 1174 sel_mask = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_SEL_MASK; 1175 sel_shift = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_SEL_SHIFT; 1176 /* FIXME if need src: clk_hdmiphy_pixel_io */ 1177 div_mask = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_DIV_MASK; 1178 div_shift = CRU_CLKSEL_CON32_DCLK_VOP_SRC0_DIV_SHIFT; 1179 break; 1180 1181 case DCLK_VOP1: 1182 id = 33; 1183 sel_mask = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_SEL_MASK; 1184 sel_shift = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_SEL_SHIFT; 1185 div_mask = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_DIV_MASK; 1186 div_shift = CRU_CLKSEL_CON33_DCLK_VOP_SRC1_DIV_SHIFT; 1187 break; 1188 1189 default: 1190 return -ENOENT; 1191 } 1192 1193 if ((priv->gpll_hz % rate) == 0) { 1194 prate = priv->gpll_hz; 1195 sel = (DCLK_VOP_SRC_SEL_CLK_GPLL_MUX << sel_shift) & sel_mask; 1196 } else { 1197 prate = priv->cpll_hz; 1198 sel = (DCLK_VOP_SRC_SEL_CLK_CPLL_MUX << sel_shift) & sel_mask; 1199 } 1200 1201 div = ((DIV_ROUND_UP(prate, rate) - 1) << div_shift) & div_mask; 1202 rk_clrsetreg(&cru->clksel_con[id], sel, div); 1203 1204 return rk3528_dclk_vop_get_clk(priv, clk_id); 1205 } 1206 1207 static ulong rk3528_uart_get_rate(struct rk3528_clk_priv *priv, ulong clk_id) 1208 { 1209 struct rk3528_cru *cru = priv->cru; 1210 u32 sel_shift, sel_mask, div_shift, div_mask; 1211 u32 sel, id, con, frac_div, div; 1212 ulong m, n, rate; 1213 1214 switch (clk_id) { 1215 case SCLK_UART0: 1216 id = 6; 1217 sel_shift = CRU_CLKSEL_CON06_SCLK_UART0_SRC_SEL_SHIFT; 1218 sel_mask = CRU_CLKSEL_CON06_SCLK_UART0_SRC_SEL_MASK; 1219 div_shift = CRU_CLKSEL_CON04_CLK_UART0_SRC_DIV_SHIFT; 1220 div_mask = CRU_CLKSEL_CON04_CLK_UART0_SRC_DIV_MASK; 1221 break; 1222 1223 case SCLK_UART1: 1224 id = 8; 1225 sel_shift = CRU_CLKSEL_CON08_SCLK_UART1_SRC_SEL_SHIFT; 1226 sel_mask = CRU_CLKSEL_CON08_SCLK_UART1_SRC_SEL_MASK; 1227 div_shift = CRU_CLKSEL_CON06_CLK_UART1_SRC_DIV_SHIFT; 1228 div_mask = CRU_CLKSEL_CON06_CLK_UART1_SRC_DIV_MASK; 1229 break; 1230 1231 case SCLK_UART2: 1232 id = 10; 1233 sel_shift = CRU_CLKSEL_CON10_SCLK_UART2_SRC_SEL_SHIFT; 1234 sel_mask = CRU_CLKSEL_CON10_SCLK_UART2_SRC_SEL_MASK; 1235 div_shift = CRU_CLKSEL_CON08_CLK_UART2_SRC_DIV_SHIFT; 1236 div_mask = CRU_CLKSEL_CON08_CLK_UART2_SRC_DIV_MASK; 1237 break; 1238 1239 case SCLK_UART3: 1240 id = 12; 1241 sel_shift = CRU_CLKSEL_CON12_SCLK_UART3_SRC_SEL_SHIFT; 1242 sel_mask = CRU_CLKSEL_CON12_SCLK_UART3_SRC_SEL_MASK; 1243 div_shift = CRU_CLKSEL_CON10_CLK_UART3_SRC_DIV_SHIFT; 1244 div_mask = CRU_CLKSEL_CON10_CLK_UART3_SRC_DIV_MASK; 1245 break; 1246 1247 case SCLK_UART4: 1248 id = 14; 1249 sel_shift = CRU_CLKSEL_CON14_SCLK_UART4_SRC_SEL_SHIFT; 1250 sel_mask = CRU_CLKSEL_CON14_SCLK_UART4_SRC_SEL_MASK; 1251 div_shift = CRU_CLKSEL_CON12_CLK_UART4_SRC_DIV_SHIFT; 1252 div_mask = CRU_CLKSEL_CON12_CLK_UART4_SRC_DIV_MASK; 1253 break; 1254 1255 case SCLK_UART5: 1256 id = 16; 1257 sel_shift = CRU_CLKSEL_CON16_SCLK_UART5_SRC_SEL_SHIFT; 1258 sel_mask = CRU_CLKSEL_CON16_SCLK_UART5_SRC_SEL_MASK; 1259 div_shift = CRU_CLKSEL_CON14_CLK_UART5_SRC_DIV_SHIFT; 1260 div_mask = CRU_CLKSEL_CON14_CLK_UART5_SRC_DIV_MASK; 1261 break; 1262 1263 case SCLK_UART6: 1264 id = 18; 1265 sel_shift = CRU_CLKSEL_CON18_SCLK_UART6_SRC_SEL_SHIFT; 1266 sel_mask = CRU_CLKSEL_CON18_SCLK_UART6_SRC_SEL_MASK; 1267 div_shift = CRU_CLKSEL_CON16_CLK_UART6_SRC_DIV_SHIFT; 1268 div_mask = CRU_CLKSEL_CON16_CLK_UART6_SRC_DIV_MASK; 1269 break; 1270 1271 case SCLK_UART7: 1272 id = 20; 1273 sel_shift = CRU_CLKSEL_CON20_SCLK_UART7_SRC_SEL_SHIFT; 1274 sel_mask = CRU_CLKSEL_CON20_SCLK_UART7_SRC_SEL_MASK; 1275 div_shift = CRU_CLKSEL_CON18_CLK_UART7_SRC_DIV_SHIFT; 1276 div_mask = CRU_CLKSEL_CON18_CLK_UART7_SRC_DIV_MASK; 1277 break; 1278 1279 default: 1280 return -ENOENT; 1281 } 1282 1283 con = readl(&cru->clksel_con[id - 2]); 1284 div = (con & div_mask) >> div_shift; 1285 1286 con = readl(&cru->clksel_con[id]); 1287 sel = (con & sel_mask) >> sel_shift; 1288 1289 if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_SRC) { 1290 rate = DIV_TO_RATE(priv->gpll_hz, div); 1291 } else if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_FRAC) { 1292 frac_div = readl(&cru->clksel_con[id - 1]); 1293 n = (frac_div & 0xffff0000) >> 16; 1294 m = frac_div & 0x0000ffff; 1295 rate = DIV_TO_RATE(priv->gpll_hz, div) * n / m; 1296 } else { 1297 rate = OSC_HZ; 1298 } 1299 1300 return rate; 1301 } 1302 1303 static ulong rk3528_uart_set_rate(struct rk3528_clk_priv *priv, 1304 ulong clk_id, ulong rate) 1305 { 1306 struct rk3528_cru *cru = priv->cru; 1307 u32 sel_shift, sel_mask, div_shift, div_mask; 1308 u32 sel, id, div; 1309 ulong m = 0, n = 0, val; 1310 1311 if (rate == OSC_HZ) { 1312 sel = SCLK_UART0_SRC_SEL_XIN_OSC0_FUNC; 1313 div = DIV_ROUND_UP(OSC_HZ, rate); 1314 } else if (priv->gpll_hz % rate == 0) { 1315 sel = SCLK_UART0_SRC_SEL_CLK_UART0_SRC; 1316 div = DIV_ROUND_UP(priv->gpll_hz, rate); 1317 } else { 1318 sel = SCLK_UART0_SRC_SEL_CLK_UART0_FRAC; 1319 div = 2; 1320 rational_best_approximation(rate, priv->gpll_hz / div, 1321 GENMASK(16 - 1, 0), 1322 GENMASK(16 - 1, 0), 1323 &n, &m); 1324 } 1325 1326 switch (clk_id) { 1327 case SCLK_UART0: 1328 id = 6; 1329 sel_shift = CRU_CLKSEL_CON06_SCLK_UART0_SRC_SEL_SHIFT; 1330 sel_mask = CRU_CLKSEL_CON06_SCLK_UART0_SRC_SEL_MASK; 1331 div_shift = CRU_CLKSEL_CON04_CLK_UART0_SRC_DIV_SHIFT; 1332 div_mask = CRU_CLKSEL_CON04_CLK_UART0_SRC_DIV_MASK; 1333 break; 1334 1335 case SCLK_UART1: 1336 id = 8; 1337 sel_shift = CRU_CLKSEL_CON08_SCLK_UART1_SRC_SEL_SHIFT; 1338 sel_mask = CRU_CLKSEL_CON08_SCLK_UART1_SRC_SEL_MASK; 1339 div_shift = CRU_CLKSEL_CON06_CLK_UART1_SRC_DIV_SHIFT; 1340 div_mask = CRU_CLKSEL_CON06_CLK_UART1_SRC_DIV_MASK; 1341 break; 1342 1343 case SCLK_UART2: 1344 id = 10; 1345 sel_shift = CRU_CLKSEL_CON10_SCLK_UART2_SRC_SEL_SHIFT; 1346 sel_mask = CRU_CLKSEL_CON10_SCLK_UART2_SRC_SEL_MASK; 1347 div_shift = CRU_CLKSEL_CON08_CLK_UART2_SRC_DIV_SHIFT; 1348 div_mask = CRU_CLKSEL_CON08_CLK_UART2_SRC_DIV_MASK; 1349 break; 1350 1351 case SCLK_UART3: 1352 id = 12; 1353 sel_shift = CRU_CLKSEL_CON12_SCLK_UART3_SRC_SEL_SHIFT; 1354 sel_mask = CRU_CLKSEL_CON12_SCLK_UART3_SRC_SEL_MASK; 1355 div_shift = CRU_CLKSEL_CON10_CLK_UART3_SRC_DIV_SHIFT; 1356 div_mask = CRU_CLKSEL_CON10_CLK_UART3_SRC_DIV_MASK; 1357 break; 1358 1359 case SCLK_UART4: 1360 id = 14; 1361 sel_shift = CRU_CLKSEL_CON14_SCLK_UART4_SRC_SEL_SHIFT; 1362 sel_mask = CRU_CLKSEL_CON14_SCLK_UART4_SRC_SEL_MASK; 1363 div_shift = CRU_CLKSEL_CON12_CLK_UART4_SRC_DIV_SHIFT; 1364 div_mask = CRU_CLKSEL_CON12_CLK_UART4_SRC_DIV_MASK; 1365 break; 1366 1367 case SCLK_UART5: 1368 id = 16; 1369 sel_shift = CRU_CLKSEL_CON16_SCLK_UART5_SRC_SEL_SHIFT; 1370 sel_mask = CRU_CLKSEL_CON16_SCLK_UART5_SRC_SEL_MASK; 1371 div_shift = CRU_CLKSEL_CON14_CLK_UART5_SRC_DIV_SHIFT; 1372 div_mask = CRU_CLKSEL_CON14_CLK_UART5_SRC_DIV_MASK; 1373 break; 1374 1375 case SCLK_UART6: 1376 id = 18; 1377 sel_shift = CRU_CLKSEL_CON18_SCLK_UART6_SRC_SEL_SHIFT; 1378 sel_mask = CRU_CLKSEL_CON18_SCLK_UART6_SRC_SEL_MASK; 1379 div_shift = CRU_CLKSEL_CON16_CLK_UART6_SRC_DIV_SHIFT; 1380 div_mask = CRU_CLKSEL_CON16_CLK_UART6_SRC_DIV_MASK; 1381 break; 1382 1383 case SCLK_UART7: 1384 id = 20; 1385 sel_shift = CRU_CLKSEL_CON20_SCLK_UART7_SRC_SEL_SHIFT; 1386 sel_mask = CRU_CLKSEL_CON20_SCLK_UART7_SRC_SEL_MASK; 1387 div_shift = CRU_CLKSEL_CON18_CLK_UART7_SRC_DIV_SHIFT; 1388 div_mask = CRU_CLKSEL_CON18_CLK_UART7_SRC_DIV_MASK; 1389 break; 1390 1391 default: 1392 return -ENOENT; 1393 } 1394 1395 rk_clrsetreg(&cru->clksel_con[id - 2], div_mask, (div - 1) << div_shift); 1396 rk_clrsetreg(&cru->clksel_con[id], sel_mask, sel << sel_shift); 1397 if (m && n) { 1398 val = n << 16 | m; 1399 writel(val, &cru->clksel_con[id - 1]); 1400 } 1401 1402 return rk3528_uart_get_rate(priv, clk_id); 1403 } 1404 1405 static ulong rk3528_clk_get_rate(struct clk *clk) 1406 { 1407 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev); 1408 ulong rate = 0; 1409 1410 if (!priv->gpll_hz || !priv->cpll_hz) { 1411 printf("%s: gpll=%lu, cpll=%ld\n", 1412 __func__, priv->gpll_hz, priv->cpll_hz); 1413 return -ENOENT; 1414 } 1415 1416 switch (clk->id) { 1417 case PLL_APLL: 1418 case ARMCLK: 1419 rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, 1420 APLL); 1421 break; 1422 case PLL_CPLL: 1423 rate = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], priv->cru, 1424 CPLL); 1425 break; 1426 case PLL_GPLL: 1427 rate = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], priv->cru, 1428 GPLL); 1429 break; 1430 1431 case PLL_PPLL: 1432 rate = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], priv->cru, 1433 PPLL); 1434 break; 1435 case PLL_DPLL: 1436 rate = rockchip_pll_get_rate(&rk3528_pll_clks[DPLL], priv->cru, 1437 DPLL); 1438 break; 1439 1440 case TCLK_WDT_NS: 1441 rate = OSC_HZ; 1442 break; 1443 case CLK_I2C0: 1444 case CLK_I2C1: 1445 case CLK_I2C2: 1446 case CLK_I2C3: 1447 case CLK_I2C4: 1448 case CLK_I2C5: 1449 case CLK_I2C6: 1450 case CLK_I2C7: 1451 rate = rk3528_i2c_get_clk(priv, clk->id); 1452 break; 1453 case CLK_SPI0: 1454 case CLK_SPI1: 1455 rate = rk3528_spi_get_clk(priv, clk->id); 1456 break; 1457 case CLK_PWM0: 1458 case CLK_PWM1: 1459 rate = rk3528_pwm_get_clk(priv, clk->id); 1460 break; 1461 case CLK_SARADC: 1462 case CLK_TSADC: 1463 case CLK_TSADC_TSEN: 1464 rate = rk3528_adc_get_clk(priv, clk->id); 1465 break; 1466 case CCLK_SRC_EMMC: 1467 rate = rk3528_emmc_get_clk(priv); 1468 break; 1469 case HCLK_SDMMC0: 1470 case CCLK_SRC_SDMMC0: 1471 rate = rk3528_sdmmc_get_clk(priv, clk->id); 1472 break; 1473 case SCLK_SFC: 1474 rate = rk3528_sfc_get_clk(priv); 1475 break; 1476 case DCLK_VOP0: 1477 case DCLK_VOP1: 1478 rate = rk3528_dclk_vop_get_clk(priv, clk->id); 1479 break; 1480 case DCLK_CVBS: 1481 rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1) / 4; 1482 break; 1483 case DCLK_4X_CVBS: 1484 rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1); 1485 break; 1486 case SCLK_UART0: 1487 case SCLK_UART1: 1488 case SCLK_UART2: 1489 case SCLK_UART3: 1490 case SCLK_UART4: 1491 case SCLK_UART5: 1492 case SCLK_UART6: 1493 case SCLK_UART7: 1494 rate = rk3528_uart_get_rate(priv, clk->id); 1495 break; 1496 case CLK_CORE_CRYPTO: 1497 case CLK_PKA_CRYPTO: 1498 rate = rk3528_crypto_get_rate(priv, clk->id); 1499 break; 1500 case CLK_MATRIX_50M_SRC: 1501 case CLK_MATRIX_100M_SRC: 1502 case CLK_MATRIX_150M_SRC: 1503 case CLK_MATRIX_200M_SRC: 1504 case CLK_MATRIX_250M_SRC: 1505 case CLK_MATRIX_300M_SRC: 1506 case CLK_MATRIX_339M_SRC: 1507 case CLK_MATRIX_400M_SRC: 1508 case CLK_MATRIX_500M_SRC: 1509 case CLK_MATRIX_600M_SRC: 1510 case ACLK_BUS_VOPGL_BIU: 1511 rate = rk3528_cgpll_matrix_get_rate(priv, clk->id); 1512 break; 1513 case CLK_PPLL_50M_MATRIX: 1514 case CLK_PPLL_100M_MATRIX: 1515 case CLK_PPLL_125M_MATRIX: 1516 case CLK_GMAC1_VPU_25M: 1517 case CLK_GMAC1_RMII_VPU: 1518 case CLK_GMAC1_SRC_VPU: 1519 rate = rk3528_ppll_matrix_get_rate(priv, clk->id); 1520 break; 1521 default: 1522 return -ENOENT; 1523 } 1524 1525 return rate; 1526 }; 1527 1528 static ulong rk3528_clk_set_rate(struct clk *clk, ulong rate) 1529 { 1530 struct rk3528_clk_priv *priv = dev_get_priv(clk->dev); 1531 ulong ret = 0; 1532 1533 if (!priv->gpll_hz) { 1534 printf("%s gpll=%lu\n", __func__, priv->gpll_hz); 1535 return -ENOENT; 1536 } 1537 1538 switch (clk->id) { 1539 case PLL_APLL: 1540 case ARMCLK: 1541 if (priv->armclk_hz) 1542 rk3528_armclk_set_clk(priv, rate); 1543 priv->armclk_hz = rate; 1544 break; 1545 case PLL_CPLL: 1546 ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru, 1547 CPLL, rate); 1548 priv->cpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], 1549 priv->cru, CPLL); 1550 break; 1551 case PLL_GPLL: 1552 ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru, 1553 GPLL, rate); 1554 priv->gpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], 1555 priv->cru, GPLL); 1556 break; 1557 case PLL_PPLL: 1558 ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru, 1559 PPLL, rate); 1560 priv->ppll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], 1561 priv->cru, PPLL); 1562 break; 1563 case TCLK_WDT_NS: 1564 return (rate == OSC_HZ) ? 0 : -EINVAL; 1565 case CLK_I2C0: 1566 case CLK_I2C1: 1567 case CLK_I2C2: 1568 case CLK_I2C3: 1569 case CLK_I2C4: 1570 case CLK_I2C5: 1571 case CLK_I2C6: 1572 case CLK_I2C7: 1573 ret = rk3528_i2c_set_clk(priv, clk->id, rate); 1574 break; 1575 case CLK_SPI0: 1576 case CLK_SPI1: 1577 ret = rk3528_spi_set_clk(priv, clk->id, rate); 1578 break; 1579 case CLK_PWM0: 1580 case CLK_PWM1: 1581 ret = rk3528_pwm_set_clk(priv, clk->id, rate); 1582 break; 1583 case CLK_SARADC: 1584 case CLK_TSADC: 1585 case CLK_TSADC_TSEN: 1586 ret = rk3528_adc_set_clk(priv, clk->id, rate); 1587 break; 1588 case HCLK_SDMMC0: 1589 case CCLK_SRC_SDMMC0: 1590 ret = rk3528_sdmmc_set_clk(priv, clk->id, rate); 1591 break; 1592 case SCLK_SFC: 1593 ret = rk3528_sfc_set_clk(priv, rate); 1594 break; 1595 case CCLK_SRC_EMMC: 1596 ret = rk3528_emmc_set_clk(priv, rate); 1597 break; 1598 case DCLK_VOP0: 1599 case DCLK_VOP1: 1600 ret = rk3528_dclk_vop_set_clk(priv, clk->id, rate); 1601 break; 1602 case SCLK_UART0: 1603 case SCLK_UART1: 1604 case SCLK_UART2: 1605 case SCLK_UART3: 1606 case SCLK_UART4: 1607 case SCLK_UART5: 1608 case SCLK_UART6: 1609 case SCLK_UART7: 1610 ret = rk3528_uart_set_rate(priv, clk->id, rate); 1611 break; 1612 case CLK_CORE_CRYPTO: 1613 case CLK_PKA_CRYPTO: 1614 ret = rk3528_crypto_set_rate(priv, clk->id, rate); 1615 break; 1616 case CLK_MATRIX_50M_SRC: 1617 case CLK_MATRIX_100M_SRC: 1618 case CLK_MATRIX_150M_SRC: 1619 case CLK_MATRIX_200M_SRC: 1620 case CLK_MATRIX_250M_SRC: 1621 case CLK_MATRIX_300M_SRC: 1622 case CLK_MATRIX_339M_SRC: 1623 case CLK_MATRIX_400M_SRC: 1624 case CLK_MATRIX_500M_SRC: 1625 case CLK_MATRIX_600M_SRC: 1626 case ACLK_BUS_VOPGL_BIU: 1627 ret = rk3528_cgpll_matrix_set_rate(priv, clk->id, rate); 1628 break; 1629 case CLK_PPLL_50M_MATRIX: 1630 case CLK_PPLL_100M_MATRIX: 1631 case CLK_PPLL_125M_MATRIX: 1632 case CLK_GMAC1_VPU_25M: 1633 ret = rk3528_ppll_matrix_set_rate(priv, clk->id, rate); 1634 break; 1635 case CLK_GMAC1_RMII_VPU: 1636 case CLK_GMAC1_SRC_VPU: 1637 /* dummy set */ 1638 ret = rk3528_ppll_matrix_get_rate(priv, clk->id); 1639 break; 1640 default: 1641 return -ENOENT; 1642 } 1643 1644 return ret; 1645 }; 1646 1647 1648 static struct clk_ops rk3528_clk_ops = { 1649 .get_rate = rk3528_clk_get_rate, 1650 .set_rate = rk3528_clk_set_rate, 1651 }; 1652 1653 static ulong rk3528_grfclk_get_rate(struct clk *clk) 1654 { 1655 struct rk3528_clk_priv *priv; 1656 struct udevice *cru_dev; 1657 ulong rate = 0; 1658 int ret; 1659 1660 ret = uclass_get_device_by_driver(UCLASS_CLK, 1661 DM_GET_DRIVER(rockchip_rk3528_cru), 1662 &cru_dev); 1663 if (ret) { 1664 printf("%s: could not find cru device\n", __func__); 1665 return ret; 1666 } 1667 priv = dev_get_priv(cru_dev); 1668 1669 switch (clk->id) { 1670 case SCLK_SDMMC_SAMPLE: 1671 rate = rk3528_sdmmc_get_clk(priv, CCLK_SRC_SDMMC0) / 2; 1672 break; 1673 default: 1674 return -ENOENT; 1675 } 1676 1677 return rate; 1678 }; 1679 1680 #define ROCKCHIP_MMC_DELAY_SEL BIT(11) 1681 #define ROCKCHIP_MMC_DEGREE_MASK 0x3 1682 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 3 1683 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 1684 #define PSECS_PER_SEC 1000000000000LL 1685 /* 1686 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 1687 * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 1688 */ 1689 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 1690 1691 int rk3528_mmc_get_phase(struct clk *clk) 1692 { 1693 struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev); 1694 u32 raw_value = 0, delay_num; 1695 u16 degrees = 0; 1696 ulong rate; 1697 1698 rate = rk3528_grfclk_get_rate(clk); 1699 if (rate < 0) 1700 return rate; 1701 1702 if (clk->id == SCLK_SDMMC_SAMPLE) 1703 raw_value = readl(&priv->grf->sdmmc_con1); 1704 else 1705 return -ENONET; 1706 1707 raw_value >>= 1; 1708 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 1709 1710 if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 1711 /* degrees/delaynum * 10000 */ 1712 unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 1713 36 * (rate / 1000000); 1714 1715 delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 1716 delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 1717 degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000); 1718 } 1719 1720 return degrees % 360; 1721 } 1722 1723 int rk3528_mmc_set_phase(struct clk *clk, u32 degrees) 1724 { 1725 struct rk3528_grf_clk_priv *priv = dev_get_priv(clk->dev); 1726 u8 nineties, remainder, delay_num; 1727 u32 raw_value, delay; 1728 ulong rate; 1729 1730 rate = rk3528_grfclk_get_rate(clk); 1731 if (rate < 0) 1732 return rate; 1733 1734 nineties = degrees / 90; 1735 remainder = (degrees % 90); 1736 1737 /* 1738 * Convert to delay; do a little extra work to make sure we 1739 * don't overflow 32-bit / 64-bit numbers. 1740 */ 1741 delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1742 delay *= remainder; 1743 delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * 1744 (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1745 1746 delay_num = (u8)min_t(u32, delay, 255); 1747 1748 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1749 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1750 raw_value |= nineties; 1751 1752 raw_value <<= 1; 1753 if (clk->id == SCLK_SDMMC_SAMPLE) 1754 writel(raw_value | 0xffff0000, &priv->grf->sdmmc_con1); 1755 else 1756 return -ENONET; 1757 1758 debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n", 1759 degrees, delay_num, raw_value, rk3528_mmc_get_phase(clk)); 1760 1761 return 0; 1762 } 1763 1764 static int rk3528_grfclk_get_phase(struct clk *clk) 1765 { 1766 int ret; 1767 1768 debug("%s %ld\n", __func__, clk->id); 1769 switch (clk->id) { 1770 case SCLK_SDMMC_SAMPLE: 1771 ret = rk3528_mmc_get_phase(clk); 1772 break; 1773 default: 1774 return -ENOENT; 1775 } 1776 1777 return ret; 1778 } 1779 1780 static int rk3528_grfclk_set_phase(struct clk *clk, int degrees) 1781 { 1782 int ret; 1783 1784 debug("%s %ld\n", __func__, clk->id); 1785 switch (clk->id) { 1786 case SCLK_SDMMC_SAMPLE: 1787 ret = rk3528_mmc_set_phase(clk, degrees); 1788 break; 1789 default: 1790 return -ENOENT; 1791 } 1792 1793 return ret; 1794 } 1795 1796 static struct clk_ops rk3528_grfclk_ops = { 1797 .get_rate = rk3528_grfclk_get_rate, 1798 .get_phase = rk3528_grfclk_get_phase, 1799 .set_phase = rk3528_grfclk_set_phase, 1800 }; 1801 1802 #ifndef CONFIG_SPL_BUILD 1803 /** 1804 * soc_clk_dump() - Print clock frequencies 1805 * Returns zero on success 1806 * 1807 * Implementation for the clk dump command. 1808 */ 1809 int soc_clk_dump(void) 1810 { 1811 const struct rk3528_clk_info *clk_dump; 1812 struct rk3528_clk_priv *priv; 1813 struct udevice *cru_dev; 1814 struct clk clk; 1815 ulong clk_count = ARRAY_SIZE(clks_dump); 1816 ulong rate; 1817 int i, ret; 1818 1819 ret = uclass_get_device_by_driver(UCLASS_CLK, 1820 DM_GET_DRIVER(rockchip_rk3528_cru), 1821 &cru_dev); 1822 if (ret) { 1823 printf("%s failed to get cru device\n", __func__); 1824 return ret; 1825 } 1826 1827 priv = dev_get_priv(cru_dev); 1828 printf("CLK: (%s. arm: enter %lu KHz, init %lu KHz, kernel %lu%s)\n", 1829 priv->sync_kernel ? "sync kernel" : "uboot", 1830 priv->armclk_enter_hz / 1000, 1831 priv->armclk_init_hz / 1000, 1832 priv->set_armclk_rate ? priv->armclk_hz / 1000 : 0, 1833 priv->set_armclk_rate ? " KHz" : "N/A"); 1834 for (i = 0; i < clk_count; i++) { 1835 clk_dump = &clks_dump[i]; 1836 if (clk_dump->name) { 1837 clk.id = clk_dump->id; 1838 ret = clk_request(cru_dev, &clk); 1839 if (ret < 0) 1840 return ret; 1841 1842 rate = clk_get_rate(&clk); 1843 clk_free(&clk); 1844 if (i == 0) { 1845 if (rate < 0) 1846 printf(" %s %s\n", clk_dump->name, 1847 "unknown"); 1848 else 1849 printf(" %s %lu KHz\n", clk_dump->name, 1850 rate / 1000); 1851 } else { 1852 if (rate < 0) 1853 printf(" %s %s\n", clk_dump->name, 1854 "unknown"); 1855 else 1856 printf(" %s %lu KHz\n", clk_dump->name, 1857 rate / 1000); 1858 } 1859 } 1860 } 1861 1862 return 0; 1863 } 1864 #endif 1865 1866 static int rk3528_grfclk_probe(struct udevice *dev) 1867 { 1868 struct rk3528_grf_clk_priv *priv = dev_get_priv(dev); 1869 1870 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1871 if (IS_ERR(priv->grf)) 1872 return PTR_ERR(priv->grf); 1873 1874 return 0; 1875 } 1876 1877 static const struct udevice_id rk3528_grf_cru_ids[] = { 1878 { .compatible = "rockchip,rk3528-grf-cru" }, 1879 { } 1880 }; 1881 1882 U_BOOT_DRIVER(rockchip_rk3528_grf_cru) = { 1883 .name = "rockchip_rk3528_grf_cru", 1884 .id = UCLASS_CLK, 1885 .of_match = rk3528_grf_cru_ids, 1886 .priv_auto_alloc_size = sizeof(struct rk3528_grf_clk_priv), 1887 .ops = &rk3528_grfclk_ops, 1888 .probe = rk3528_grfclk_probe, 1889 }; 1890 1891 static void rk3528_clk_init(struct rk3528_clk_priv *priv) 1892 { 1893 int ret; 1894 1895 priv->sync_kernel = false; 1896 if (!priv->armclk_enter_hz) { 1897 priv->armclk_enter_hz = 1898 rockchip_pll_get_rate(&rk3528_pll_clks[APLL], 1899 priv->cru, APLL); 1900 priv->armclk_init_hz = priv->armclk_enter_hz; 1901 } 1902 1903 if (priv->armclk_init_hz != APLL_HZ) { 1904 ret = rk3528_armclk_set_clk(priv, APLL_HZ); 1905 if (!ret) 1906 priv->armclk_init_hz = APLL_HZ; 1907 } 1908 1909 if (priv->cpll_hz != CPLL_HZ) { 1910 ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru, 1911 CPLL, CPLL_HZ); 1912 if (!ret) 1913 priv->cpll_hz = CPLL_HZ; 1914 } 1915 1916 if (priv->gpll_hz != GPLL_HZ) { 1917 ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru, 1918 GPLL, GPLL_HZ); 1919 if (!ret) 1920 priv->gpll_hz = GPLL_HZ; 1921 } 1922 #if 0 1923 if (priv->ppll_hz != PPLL_HZ) { 1924 ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru, 1925 PPLL, PPLL_HZ); 1926 if (!ret) 1927 priv->ppll_hz = PPLL_HZ; 1928 } 1929 #endif 1930 /* The default rate is 100Mhz, it's not friendly for remote IR module */ 1931 rk3528_pwm_set_clk(priv, CLK_PWM0, 24000000); 1932 rk3528_pwm_set_clk(priv, CLK_PWM1, 24000000); 1933 } 1934 1935 static int rk3528_clk_probe(struct udevice *dev) 1936 { 1937 struct rk3528_clk_priv *priv = dev_get_priv(dev); 1938 int ret; 1939 1940 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1941 if (IS_ERR(priv->grf)) 1942 return PTR_ERR(priv->grf); 1943 1944 rk3528_clk_init(priv); 1945 1946 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1947 ret = clk_set_defaults(dev); 1948 if (ret) 1949 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1950 else 1951 priv->sync_kernel = true; 1952 1953 return 0; 1954 } 1955 1956 static int rk3528_clk_ofdata_to_platdata(struct udevice *dev) 1957 { 1958 struct rk3528_clk_priv *priv = dev_get_priv(dev); 1959 1960 priv->cru = dev_read_addr_ptr(dev); 1961 1962 return 0; 1963 } 1964 1965 static int rk3528_clk_bind(struct udevice *dev) 1966 { 1967 struct udevice *sys_child, *sf_child; 1968 struct softreset_reg *sf_priv; 1969 struct sysreset_reg *priv; 1970 int ret; 1971 1972 /* The reset driver does not have a device node, so bind it here */ 1973 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1974 &sys_child); 1975 if (ret) { 1976 debug("Warning: No sysreset driver: ret=%d\n", ret); 1977 } else { 1978 priv = malloc(sizeof(struct sysreset_reg)); 1979 priv->glb_srst_fst_value = offsetof(struct rk3528_cru, 1980 glb_srst_fst); 1981 priv->glb_srst_snd_value = offsetof(struct rk3528_cru, 1982 glb_srst_snd); 1983 sys_child->priv = priv; 1984 } 1985 1986 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1987 dev_ofnode(dev), &sf_child); 1988 if (ret) { 1989 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1990 } else { 1991 sf_priv = malloc(sizeof(struct softreset_reg)); 1992 sf_priv->sf_reset_offset = offsetof(struct rk3528_cru, 1993 softrst_con[0]); 1994 sf_priv->sf_reset_num = 47; 1995 sf_child->priv = sf_priv; 1996 } 1997 1998 return 0; 1999 } 2000 2001 static const struct udevice_id rk3528_clk_ids[] = { 2002 { .compatible = "rockchip,rk3528-cru" }, 2003 { } 2004 }; 2005 2006 U_BOOT_DRIVER(rockchip_rk3528_cru) = { 2007 .name = "rockchip_rk3528_cru", 2008 .id = UCLASS_CLK, 2009 .of_match = rk3528_clk_ids, 2010 .priv_auto_alloc_size = sizeof(struct rk3528_clk_priv), 2011 .ofdata_to_platdata = rk3528_clk_ofdata_to_platdata, 2012 .ops = &rk3528_clk_ops, 2013 .bind = rk3528_clk_bind, 2014 .probe = rk3528_clk_probe, 2015 }; 2016 2017