1 /* 2 * (C) Copyright 2015 Google, Inc 3 * (C) 2017 Theobroma Systems Design und Consulting GmbH 4 * 5 * SPDX-License-Identifier: GPL-2.0 6 */ 7 8 #include <common.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <dt-structs.h> 12 #include <errno.h> 13 #include <mapmem.h> 14 #include <syscon.h> 15 #include <bitfield.h> 16 #include <asm/io.h> 17 #include <asm/arch/clock.h> 18 #include <asm/arch/cru_rk3399.h> 19 #include <asm/arch/hardware.h> 20 #include <dm/lists.h> 21 #include <dt-bindings/clock/rk3399-cru.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #if CONFIG_IS_ENABLED(OF_PLATDATA) 26 struct rk3399_clk_plat { 27 struct dtd_rockchip_rk3399_cru dtd; 28 }; 29 30 struct rk3399_pmuclk_plat { 31 struct dtd_rockchip_rk3399_pmucru dtd; 32 }; 33 #endif 34 35 struct pll_div { 36 u32 refdiv; 37 u32 fbdiv; 38 u32 postdiv1; 39 u32 postdiv2; 40 u32 frac; 41 u32 freq; 42 }; 43 44 #define RATE_TO_DIV(input_rate, output_rate) \ 45 ((input_rate) / (output_rate) - 1); 46 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 47 48 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 49 .refdiv = _refdiv,\ 50 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 51 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2, .freq = hz}; 52 53 #if !defined(CONFIG_SPL_BUILD) 54 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1); 55 #endif 56 static const struct pll_div apll_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1); 57 static const struct pll_div apll_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1); 58 59 static const struct pll_div *apll_cfgs[] = { 60 [APLL_1600_MHZ] = &apll_1600_cfg, 61 [APLL_600_MHZ] = &apll_600_cfg, 62 }; 63 64 enum { 65 /* PLL_CON0 */ 66 PLL_FBDIV_MASK = 0xfff, 67 PLL_FBDIV_SHIFT = 0, 68 69 /* PLL_CON1 */ 70 PLL_POSTDIV2_SHIFT = 12, 71 PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, 72 PLL_POSTDIV1_SHIFT = 8, 73 PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, 74 PLL_REFDIV_MASK = 0x3f, 75 PLL_REFDIV_SHIFT = 0, 76 77 /* PLL_CON2 */ 78 PLL_LOCK_STATUS_SHIFT = 31, 79 PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, 80 PLL_FRACDIV_MASK = 0xffffff, 81 PLL_FRACDIV_SHIFT = 0, 82 83 /* PLL_CON3 */ 84 PLL_MODE_SHIFT = 8, 85 PLL_MODE_MASK = 3 << PLL_MODE_SHIFT, 86 PLL_MODE_SLOW = 0, 87 PLL_MODE_NORM, 88 PLL_MODE_DEEP, 89 PLL_DSMPD_SHIFT = 3, 90 PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, 91 PLL_INTEGER_MODE = 1, 92 93 /* PMUCRU_CLKSEL_CON0 */ 94 PMU_PCLK_DIV_CON_MASK = 0x1f, 95 PMU_PCLK_DIV_CON_SHIFT = 0, 96 97 /* PMUCRU_CLKSEL_CON1 */ 98 SPI3_PLL_SEL_SHIFT = 7, 99 SPI3_PLL_SEL_MASK = 1 << SPI3_PLL_SEL_SHIFT, 100 SPI3_PLL_SEL_24M = 0, 101 SPI3_PLL_SEL_PPLL = 1, 102 SPI3_DIV_CON_SHIFT = 0x0, 103 SPI3_DIV_CON_MASK = 0x7f, 104 105 /* PMUCRU_CLKSEL_CON2 */ 106 I2C_DIV_CON_MASK = 0x7f, 107 CLK_I2C8_DIV_CON_SHIFT = 8, 108 CLK_I2C0_DIV_CON_SHIFT = 0, 109 110 /* PMUCRU_CLKSEL_CON3 */ 111 CLK_I2C4_DIV_CON_SHIFT = 0, 112 113 /* CLKSEL_CON0 / CLKSEL_CON2 */ 114 ACLKM_CORE_DIV_CON_MASK = 0x1f, 115 ACLKM_CORE_DIV_CON_SHIFT = 8, 116 CLK_CORE_PLL_SEL_MASK = 3, 117 CLK_CORE_PLL_SEL_SHIFT = 6, 118 CLK_CORE_PLL_SEL_ALPLL = 0x0, 119 CLK_CORE_PLL_SEL_ABPLL = 0x1, 120 CLK_CORE_PLL_SEL_DPLL = 0x10, 121 CLK_CORE_PLL_SEL_GPLL = 0x11, 122 CLK_CORE_DIV_MASK = 0x1f, 123 CLK_CORE_DIV_SHIFT = 0, 124 125 /* CLKSEL_CON1 / CLKSEL_CON3 */ 126 PCLK_DBG_DIV_MASK = 0x1f, 127 PCLK_DBG_DIV_SHIFT = 0x8, 128 ATCLK_CORE_DIV_MASK = 0x1f, 129 ATCLK_CORE_DIV_SHIFT = 0, 130 131 /* CLKSEL_CON14 */ 132 PCLK_PERIHP_DIV_CON_SHIFT = 12, 133 PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, 134 HCLK_PERIHP_DIV_CON_SHIFT = 8, 135 HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, 136 ACLK_PERIHP_PLL_SEL_SHIFT = 7, 137 ACLK_PERIHP_PLL_SEL_MASK = 1 << ACLK_PERIHP_PLL_SEL_SHIFT, 138 ACLK_PERIHP_PLL_SEL_CPLL = 0, 139 ACLK_PERIHP_PLL_SEL_GPLL = 1, 140 ACLK_PERIHP_DIV_CON_SHIFT = 0, 141 ACLK_PERIHP_DIV_CON_MASK = 0x1f, 142 143 /* CLKSEL_CON21 */ 144 ACLK_EMMC_PLL_SEL_SHIFT = 7, 145 ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT, 146 ACLK_EMMC_PLL_SEL_GPLL = 0x1, 147 ACLK_EMMC_DIV_CON_SHIFT = 0, 148 ACLK_EMMC_DIV_CON_MASK = 0x1f, 149 150 /* CLKSEL_CON22 */ 151 CLK_EMMC_PLL_SHIFT = 8, 152 CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT, 153 CLK_EMMC_PLL_SEL_GPLL = 0x1, 154 CLK_EMMC_PLL_SEL_24M = 0x5, 155 CLK_EMMC_DIV_CON_SHIFT = 0, 156 CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT, 157 158 /* CLKSEL_CON23 */ 159 PCLK_PERILP0_DIV_CON_SHIFT = 12, 160 PCLK_PERILP0_DIV_CON_MASK = 0x7 << PCLK_PERILP0_DIV_CON_SHIFT, 161 HCLK_PERILP0_DIV_CON_SHIFT = 8, 162 HCLK_PERILP0_DIV_CON_MASK = 3 << HCLK_PERILP0_DIV_CON_SHIFT, 163 ACLK_PERILP0_PLL_SEL_SHIFT = 7, 164 ACLK_PERILP0_PLL_SEL_MASK = 1 << ACLK_PERILP0_PLL_SEL_SHIFT, 165 ACLK_PERILP0_PLL_SEL_CPLL = 0, 166 ACLK_PERILP0_PLL_SEL_GPLL = 1, 167 ACLK_PERILP0_DIV_CON_SHIFT = 0, 168 ACLK_PERILP0_DIV_CON_MASK = 0x1f, 169 170 /* CLKSEL_CON25 */ 171 PCLK_PERILP1_DIV_CON_SHIFT = 8, 172 PCLK_PERILP1_DIV_CON_MASK = 0x7 << PCLK_PERILP1_DIV_CON_SHIFT, 173 HCLK_PERILP1_PLL_SEL_SHIFT = 7, 174 HCLK_PERILP1_PLL_SEL_MASK = 1 << HCLK_PERILP1_PLL_SEL_SHIFT, 175 HCLK_PERILP1_PLL_SEL_CPLL = 0, 176 HCLK_PERILP1_PLL_SEL_GPLL = 1, 177 HCLK_PERILP1_DIV_CON_SHIFT = 0, 178 HCLK_PERILP1_DIV_CON_MASK = 0x1f, 179 180 /* CLKSEL_CON26 */ 181 CLK_SARADC_DIV_CON_SHIFT = 8, 182 CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8), 183 CLK_SARADC_DIV_CON_WIDTH = 8, 184 185 /* CLKSEL_CON27 */ 186 CLK_TSADC_SEL_X24M = 0x0, 187 CLK_TSADC_SEL_SHIFT = 15, 188 CLK_TSADC_SEL_MASK = 1 << CLK_TSADC_SEL_SHIFT, 189 CLK_TSADC_DIV_CON_SHIFT = 0, 190 CLK_TSADC_DIV_CON_MASK = 0x3ff, 191 192 /* CLKSEL_CON47 & CLKSEL_CON48 */ 193 ACLK_VOP_PLL_SEL_SHIFT = 6, 194 ACLK_VOP_PLL_SEL_MASK = 0x3 << ACLK_VOP_PLL_SEL_SHIFT, 195 ACLK_VOP_PLL_SEL_CPLL = 0x1, 196 ACLK_VOP_PLL_SEL_GPLL = 0x2, 197 ACLK_VOP_DIV_CON_SHIFT = 0, 198 ACLK_VOP_DIV_CON_MASK = 0x1f << ACLK_VOP_DIV_CON_SHIFT, 199 200 /* CLKSEL_CON49 & CLKSEL_CON50 */ 201 DCLK_VOP_DCLK_SEL_SHIFT = 11, 202 DCLK_VOP_DCLK_SEL_MASK = 1 << DCLK_VOP_DCLK_SEL_SHIFT, 203 DCLK_VOP_DCLK_SEL_DIVOUT = 0, 204 DCLK_VOP_PLL_SEL_SHIFT = 8, 205 DCLK_VOP_PLL_SEL_MASK = 3 << DCLK_VOP_PLL_SEL_SHIFT, 206 DCLK_VOP_PLL_SEL_VPLL = 0, 207 DCLK_VOP_PLL_SEL_CPLL = 1, 208 DCLK_VOP_DIV_CON_MASK = 0xff, 209 DCLK_VOP_DIV_CON_SHIFT = 0, 210 211 /* CLKSEL_CON58 */ 212 CLK_SPI_PLL_SEL_WIDTH = 1, 213 CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1), 214 CLK_SPI_PLL_SEL_CPLL = 0, 215 CLK_SPI_PLL_SEL_GPLL = 1, 216 CLK_SPI_PLL_DIV_CON_WIDTH = 7, 217 CLK_SPI_PLL_DIV_CON_MASK = ((1 << CLK_SPI_PLL_DIV_CON_WIDTH) - 1), 218 219 CLK_SPI5_PLL_DIV_CON_SHIFT = 8, 220 CLK_SPI5_PLL_SEL_SHIFT = 15, 221 222 /* CLKSEL_CON59 */ 223 CLK_SPI1_PLL_SEL_SHIFT = 15, 224 CLK_SPI1_PLL_DIV_CON_SHIFT = 8, 225 CLK_SPI0_PLL_SEL_SHIFT = 7, 226 CLK_SPI0_PLL_DIV_CON_SHIFT = 0, 227 228 /* CLKSEL_CON60 */ 229 CLK_SPI4_PLL_SEL_SHIFT = 15, 230 CLK_SPI4_PLL_DIV_CON_SHIFT = 8, 231 CLK_SPI2_PLL_SEL_SHIFT = 7, 232 CLK_SPI2_PLL_DIV_CON_SHIFT = 0, 233 234 /* CLKSEL_CON61 */ 235 CLK_I2C_PLL_SEL_MASK = 1, 236 CLK_I2C_PLL_SEL_CPLL = 0, 237 CLK_I2C_PLL_SEL_GPLL = 1, 238 CLK_I2C5_PLL_SEL_SHIFT = 15, 239 CLK_I2C5_DIV_CON_SHIFT = 8, 240 CLK_I2C1_PLL_SEL_SHIFT = 7, 241 CLK_I2C1_DIV_CON_SHIFT = 0, 242 243 /* CLKSEL_CON62 */ 244 CLK_I2C6_PLL_SEL_SHIFT = 15, 245 CLK_I2C6_DIV_CON_SHIFT = 8, 246 CLK_I2C2_PLL_SEL_SHIFT = 7, 247 CLK_I2C2_DIV_CON_SHIFT = 0, 248 249 /* CLKSEL_CON63 */ 250 CLK_I2C7_PLL_SEL_SHIFT = 15, 251 CLK_I2C7_DIV_CON_SHIFT = 8, 252 CLK_I2C3_PLL_SEL_SHIFT = 7, 253 CLK_I2C3_DIV_CON_SHIFT = 0, 254 255 /* CRU_SOFTRST_CON4 */ 256 RESETN_DDR0_REQ_SHIFT = 8, 257 RESETN_DDR0_REQ_MASK = 1 << RESETN_DDR0_REQ_SHIFT, 258 RESETN_DDRPHY0_REQ_SHIFT = 9, 259 RESETN_DDRPHY0_REQ_MASK = 1 << RESETN_DDRPHY0_REQ_SHIFT, 260 RESETN_DDR1_REQ_SHIFT = 12, 261 RESETN_DDR1_REQ_MASK = 1 << RESETN_DDR1_REQ_SHIFT, 262 RESETN_DDRPHY1_REQ_SHIFT = 13, 263 RESETN_DDRPHY1_REQ_MASK = 1 << RESETN_DDRPHY1_REQ_SHIFT, 264 }; 265 266 #define VCO_MAX_KHZ (3200 * (MHz / KHz)) 267 #define VCO_MIN_KHZ (800 * (MHz / KHz)) 268 #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) 269 #define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) 270 271 /* 272 * the div restructions of pll in integer mode, these are defined in 273 * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 274 */ 275 #define PLL_DIV_MIN 16 276 #define PLL_DIV_MAX 3200 277 278 /* 279 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 280 * Formulas also embedded within the Fractional PLL Verilog model: 281 * If DSMPD = 1 (DSM is disabled, "integer mode") 282 * FOUTVCO = FREF / REFDIV * FBDIV 283 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 284 * Where: 285 * FOUTVCO = Fractional PLL non-divided output frequency 286 * FOUTPOSTDIV = Fractional PLL divided output frequency 287 * (output of second post divider) 288 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 289 * REFDIV = Fractional PLL input reference clock divider 290 * FBDIV = Integer value programmed into feedback divide 291 * 292 */ 293 294 static uint32_t rkclk_pll_get_rate(u32 *pll_con) 295 { 296 u32 refdiv, fbdiv, postdiv1, postdiv2; 297 u32 con; 298 299 con = readl(&pll_con[3]); 300 switch ((con & PLL_MODE_MASK) >> PLL_MODE_SHIFT) { 301 case PLL_MODE_SLOW: 302 return OSC_HZ; 303 case PLL_MODE_NORM: 304 /* normal mode */ 305 con = readl(&pll_con[0]); 306 fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; 307 con = readl(&pll_con[1]); 308 postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT; 309 postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT; 310 refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT; 311 return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; 312 case PLL_MODE_DEEP: 313 default: 314 return 32768; 315 } 316 } 317 318 static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div) 319 { 320 /* All 8 PLLs have same VCO and output frequency range restrictions. */ 321 u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; 322 u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; 323 324 debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, " 325 "postdiv2=%d, vco=%u khz, output=%u khz\n", 326 pll_con, div->fbdiv, div->refdiv, div->postdiv1, 327 div->postdiv2, vco_khz, output_khz); 328 assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && 329 output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && 330 div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); 331 332 /* 333 * When power on or changing PLL setting, 334 * we must force PLL into slow mode to ensure output stable clock. 335 */ 336 rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, 337 PLL_MODE_SLOW << PLL_MODE_SHIFT); 338 339 /* use integer mode */ 340 rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK, 341 PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); 342 343 rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK, 344 div->fbdiv << PLL_FBDIV_SHIFT); 345 rk_clrsetreg(&pll_con[1], 346 PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK | 347 PLL_REFDIV_MASK | PLL_REFDIV_SHIFT, 348 (div->postdiv2 << PLL_POSTDIV2_SHIFT) | 349 (div->postdiv1 << PLL_POSTDIV1_SHIFT) | 350 (div->refdiv << PLL_REFDIV_SHIFT)); 351 352 /* waiting for pll lock */ 353 while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT))) 354 udelay(1); 355 356 /* pll enter normal mode */ 357 rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, 358 PLL_MODE_NORM << PLL_MODE_SHIFT); 359 } 360 361 static ulong rk3399_pll_get_rate(struct rk3399_clk_priv *priv, 362 enum rk3399_pll_id pll_id) 363 { 364 struct rk3399_cru *cru = priv->cru; 365 u32 *pll_con; 366 367 switch (pll_id) { 368 case PLL_APLLL: 369 pll_con = &cru->apll_l_con[0]; 370 break; 371 case PLL_APLLB: 372 pll_con = &cru->apll_b_con[0]; 373 break; 374 case PLL_DPLL: 375 pll_con = &cru->dpll_con[0]; 376 break; 377 case PLL_CPLL: 378 pll_con = &cru->cpll_con[0]; 379 break; 380 case PLL_GPLL: 381 pll_con = &cru->gpll_con[0]; 382 break; 383 case PLL_NPLL: 384 pll_con = &cru->npll_con[0]; 385 break; 386 case PLL_VPLL: 387 pll_con = &cru->vpll_con[0]; 388 break; 389 default: 390 pll_con = &cru->vpll_con[0]; 391 break; 392 } 393 394 return rkclk_pll_get_rate(pll_con); 395 } 396 397 static int pll_para_config(u32 freq_hz, struct pll_div *div) 398 { 399 u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0; 400 u32 postdiv1, postdiv2 = 1; 401 u32 fref_khz; 402 u32 diff_khz, best_diff_khz; 403 const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16; 404 const u32 max_postdiv1 = 7, max_postdiv2 = 7; 405 u32 vco_khz; 406 u32 freq_khz = freq_hz / KHz; 407 408 if (!freq_hz) { 409 printf("%s: the frequency can't be 0 Hz\n", __func__); 410 return -1; 411 } 412 413 postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz); 414 if (postdiv1 > max_postdiv1) { 415 postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1); 416 postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2); 417 } 418 419 vco_khz = freq_khz * postdiv1 * postdiv2; 420 421 if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || 422 postdiv2 > max_postdiv2) { 423 printf("%s: Cannot find out a supported VCO" 424 " for Frequency (%uHz).\n", __func__, freq_hz); 425 return -1; 426 } 427 428 div->postdiv1 = postdiv1; 429 div->postdiv2 = postdiv2; 430 431 best_diff_khz = vco_khz; 432 for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) { 433 fref_khz = ref_khz / refdiv; 434 435 fbdiv = vco_khz / fref_khz; 436 if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv)) 437 continue; 438 diff_khz = vco_khz - fbdiv * fref_khz; 439 if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) { 440 fbdiv++; 441 diff_khz = fref_khz - diff_khz; 442 } 443 444 if (diff_khz >= best_diff_khz) 445 continue; 446 447 best_diff_khz = diff_khz; 448 div->refdiv = refdiv; 449 div->fbdiv = fbdiv; 450 } 451 452 if (best_diff_khz > 4 * (MHz/KHz)) { 453 printf("%s: Failed to match output frequency %u, " 454 "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz, 455 best_diff_khz * KHz); 456 return -1; 457 } 458 return 0; 459 } 460 461 void rk3399_configure_cpu(struct rk3399_cru *cru, 462 enum apll_frequencies freq, 463 enum cpu_cluster cluster) 464 { 465 u32 aclkm_div; 466 u32 pclk_dbg_div; 467 u32 atclk_div, apll_hz; 468 int con_base, parent; 469 u32 *pll_con; 470 471 switch (cluster) { 472 case CPU_CLUSTER_LITTLE: 473 con_base = 0; 474 parent = CLK_CORE_PLL_SEL_ALPLL; 475 pll_con = &cru->apll_l_con[0]; 476 break; 477 case CPU_CLUSTER_BIG: 478 default: 479 con_base = 2; 480 parent = CLK_CORE_PLL_SEL_ABPLL; 481 pll_con = &cru->apll_b_con[0]; 482 break; 483 } 484 485 apll_hz = apll_cfgs[freq]->freq; 486 rkclk_set_pll(pll_con, apll_cfgs[freq]); 487 488 aclkm_div = apll_hz / ACLKM_CORE_HZ - 1; 489 assert((aclkm_div + 1) * ACLKM_CORE_HZ == apll_hz && 490 aclkm_div < 0x1f); 491 492 pclk_dbg_div = apll_hz / PCLK_DBG_HZ - 1; 493 assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == apll_hz && 494 pclk_dbg_div < 0x1f); 495 496 atclk_div = apll_hz / ATCLK_CORE_HZ - 1; 497 assert((atclk_div + 1) * ATCLK_CORE_HZ == apll_hz && 498 atclk_div < 0x1f); 499 500 rk_clrsetreg(&cru->clksel_con[con_base], 501 ACLKM_CORE_DIV_CON_MASK | CLK_CORE_PLL_SEL_MASK | 502 CLK_CORE_DIV_MASK, 503 aclkm_div << ACLKM_CORE_DIV_CON_SHIFT | 504 parent << CLK_CORE_PLL_SEL_SHIFT | 505 0 << CLK_CORE_DIV_SHIFT); 506 507 rk_clrsetreg(&cru->clksel_con[con_base + 1], 508 PCLK_DBG_DIV_MASK | ATCLK_CORE_DIV_MASK, 509 pclk_dbg_div << PCLK_DBG_DIV_SHIFT | 510 atclk_div << ATCLK_CORE_DIV_SHIFT); 511 } 512 #define I2C_CLK_REG_MASK(bus) \ 513 (I2C_DIV_CON_MASK << \ 514 CLK_I2C ##bus## _DIV_CON_SHIFT | \ 515 CLK_I2C_PLL_SEL_MASK << \ 516 CLK_I2C ##bus## _PLL_SEL_SHIFT) 517 518 #define I2C_CLK_REG_VALUE(bus, clk_div) \ 519 ((clk_div - 1) << \ 520 CLK_I2C ##bus## _DIV_CON_SHIFT | \ 521 CLK_I2C_PLL_SEL_GPLL << \ 522 CLK_I2C ##bus## _PLL_SEL_SHIFT) 523 524 #define I2C_CLK_DIV_VALUE(con, bus) \ 525 (con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \ 526 I2C_DIV_CON_MASK; 527 528 #define I2C_PMUCLK_REG_MASK(bus) \ 529 (I2C_DIV_CON_MASK << \ 530 CLK_I2C ##bus## _DIV_CON_SHIFT) 531 532 #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \ 533 ((clk_div - 1) << \ 534 CLK_I2C ##bus## _DIV_CON_SHIFT) 535 536 static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id) 537 { 538 u32 div, con; 539 540 switch (clk_id) { 541 case SCLK_I2C1: 542 con = readl(&cru->clksel_con[61]); 543 div = I2C_CLK_DIV_VALUE(con, 1); 544 break; 545 case SCLK_I2C2: 546 con = readl(&cru->clksel_con[62]); 547 div = I2C_CLK_DIV_VALUE(con, 2); 548 break; 549 case SCLK_I2C3: 550 con = readl(&cru->clksel_con[63]); 551 div = I2C_CLK_DIV_VALUE(con, 3); 552 break; 553 case SCLK_I2C5: 554 con = readl(&cru->clksel_con[61]); 555 div = I2C_CLK_DIV_VALUE(con, 5); 556 break; 557 case SCLK_I2C6: 558 con = readl(&cru->clksel_con[62]); 559 div = I2C_CLK_DIV_VALUE(con, 6); 560 break; 561 case SCLK_I2C7: 562 con = readl(&cru->clksel_con[63]); 563 div = I2C_CLK_DIV_VALUE(con, 7); 564 break; 565 default: 566 printf("do not support this i2c bus\n"); 567 return -EINVAL; 568 } 569 570 return DIV_TO_RATE(GPLL_HZ, div); 571 } 572 573 static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) 574 { 575 int src_clk_div; 576 577 /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/ 578 src_clk_div = GPLL_HZ / hz; 579 assert(src_clk_div - 1 <= 127); 580 581 switch (clk_id) { 582 case SCLK_I2C1: 583 rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(1), 584 I2C_CLK_REG_VALUE(1, src_clk_div)); 585 break; 586 case SCLK_I2C2: 587 rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(2), 588 I2C_CLK_REG_VALUE(2, src_clk_div)); 589 break; 590 case SCLK_I2C3: 591 rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(3), 592 I2C_CLK_REG_VALUE(3, src_clk_div)); 593 break; 594 case SCLK_I2C5: 595 rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(5), 596 I2C_CLK_REG_VALUE(5, src_clk_div)); 597 break; 598 case SCLK_I2C6: 599 rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(6), 600 I2C_CLK_REG_VALUE(6, src_clk_div)); 601 break; 602 case SCLK_I2C7: 603 rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(7), 604 I2C_CLK_REG_VALUE(7, src_clk_div)); 605 break; 606 default: 607 printf("do not support this i2c bus\n"); 608 return -EINVAL; 609 } 610 611 return rk3399_i2c_get_clk(cru, clk_id); 612 } 613 614 /* 615 * RK3399 SPI clocks have a common divider-width (7 bits) and a single bit 616 * to select either CPLL or GPLL as the clock-parent. The location within 617 * the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable. 618 */ 619 620 struct spi_clkreg { 621 uint8_t reg; /* CLKSEL_CON[reg] register in CRU */ 622 uint8_t div_shift; 623 uint8_t sel_shift; 624 }; 625 626 /* 627 * The entries are numbered relative to their offset from SCLK_SPI0. 628 * 629 * Note that SCLK_SPI3 (which is configured via PMUCRU and requires different 630 * logic is not supported). 631 */ 632 static const struct spi_clkreg spi_clkregs[] = { 633 [0] = { .reg = 59, 634 .div_shift = CLK_SPI0_PLL_DIV_CON_SHIFT, 635 .sel_shift = CLK_SPI0_PLL_SEL_SHIFT, }, 636 [1] = { .reg = 59, 637 .div_shift = CLK_SPI1_PLL_DIV_CON_SHIFT, 638 .sel_shift = CLK_SPI1_PLL_SEL_SHIFT, }, 639 [2] = { .reg = 60, 640 .div_shift = CLK_SPI2_PLL_DIV_CON_SHIFT, 641 .sel_shift = CLK_SPI2_PLL_SEL_SHIFT, }, 642 [3] = { .reg = 60, 643 .div_shift = CLK_SPI4_PLL_DIV_CON_SHIFT, 644 .sel_shift = CLK_SPI4_PLL_SEL_SHIFT, }, 645 [4] = { .reg = 58, 646 .div_shift = CLK_SPI5_PLL_DIV_CON_SHIFT, 647 .sel_shift = CLK_SPI5_PLL_SEL_SHIFT, }, 648 }; 649 650 static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id) 651 { 652 const struct spi_clkreg *spiclk = NULL; 653 u32 div, val; 654 655 switch (clk_id) { 656 case SCLK_SPI0 ... SCLK_SPI5: 657 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 658 break; 659 660 default: 661 pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 662 return -EINVAL; 663 } 664 665 val = readl(&cru->clksel_con[spiclk->reg]); 666 div = bitfield_extract(val, spiclk->div_shift, 667 CLK_SPI_PLL_DIV_CON_WIDTH); 668 669 return DIV_TO_RATE(GPLL_HZ, div); 670 } 671 672 static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) 673 { 674 const struct spi_clkreg *spiclk = NULL; 675 int src_clk_div; 676 677 src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1; 678 assert(src_clk_div < 128); 679 680 switch (clk_id) { 681 case SCLK_SPI1 ... SCLK_SPI5: 682 spiclk = &spi_clkregs[clk_id - SCLK_SPI0]; 683 break; 684 685 default: 686 pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id); 687 return -EINVAL; 688 } 689 690 rk_clrsetreg(&cru->clksel_con[spiclk->reg], 691 ((CLK_SPI_PLL_DIV_CON_MASK << spiclk->div_shift) | 692 (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)), 693 ((src_clk_div << spiclk->div_shift) | 694 (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift))); 695 696 return rk3399_spi_get_clk(cru, clk_id); 697 } 698 699 #define RK3399_LIMIT_PLL_DCLK_VOP (600 * 1000000) 700 #define RK3399_LIMIT_PLL_ACLK_VOP (400 * 1000000) 701 702 static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz) 703 { 704 struct pll_div vpll_config = {0}, cpll_config = {0}; 705 int aclk_vop = RK3399_LIMIT_PLL_ACLK_VOP; 706 void *aclkreg_addr, *dclkreg_addr; 707 u32 div = 1; 708 709 switch (clk_id) { 710 case DCLK_VOP0: 711 aclkreg_addr = &cru->clksel_con[47]; 712 dclkreg_addr = &cru->clksel_con[49]; 713 break; 714 case DCLK_VOP1: 715 aclkreg_addr = &cru->clksel_con[48]; 716 dclkreg_addr = &cru->clksel_con[50]; 717 break; 718 default: 719 return -EINVAL; 720 } 721 /* vop aclk source clk: cpll */ 722 div = GPLL_HZ / aclk_vop; 723 assert(div - 1 <= 31); 724 725 rk_clrsetreg(aclkreg_addr, 726 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, 727 ACLK_VOP_PLL_SEL_GPLL << ACLK_VOP_PLL_SEL_SHIFT | 728 (div - 1) << ACLK_VOP_DIV_CON_SHIFT); 729 730 div = DIV_ROUND_UP(RK3399_LIMIT_PLL_DCLK_VOP, hz); 731 732 if (readl(dclkreg_addr) & DCLK_VOP_PLL_SEL_MASK) { 733 if (pll_para_config(div * hz, &cpll_config)) 734 return -1; 735 rkclk_set_pll(&cru->cpll_con[0], &cpll_config); 736 } else { 737 if (pll_para_config(div * hz, &vpll_config)) 738 return -1; 739 rkclk_set_pll(&cru->vpll_con[0], &vpll_config); 740 } 741 742 rk_clrsetreg(dclkreg_addr, 743 DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_DIV_CON_MASK, 744 DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT | 745 (div - 1) << DCLK_VOP_DIV_CON_SHIFT); 746 747 return hz; 748 } 749 750 static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id) 751 { 752 u32 div, con; 753 754 switch (clk_id) { 755 case HCLK_SDMMC: 756 case SCLK_SDMMC: 757 con = readl(&cru->clksel_con[16]); 758 /* dwmmc controller have internal div 2 */ 759 div = 2; 760 break; 761 case SCLK_EMMC: 762 con = readl(&cru->clksel_con[21]); 763 div = 1; 764 break; 765 default: 766 return -EINVAL; 767 } 768 769 div *= (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 770 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 771 == CLK_EMMC_PLL_SEL_24M) 772 return DIV_TO_RATE(OSC_HZ, div); 773 else 774 return DIV_TO_RATE(GPLL_HZ, div); 775 } 776 777 static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, 778 ulong clk_id, ulong set_rate) 779 { 780 int src_clk_div; 781 int aclk_emmc = 198*MHz; 782 783 switch (clk_id) { 784 case HCLK_SDMMC: 785 case SCLK_SDMMC: 786 /* Select clk_sdmmc source from GPLL by default */ 787 /* mmc clock defaulg div 2 internal, provide double in cru */ 788 src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); 789 790 if (src_clk_div > 128) { 791 /* use 24MHz source for 400KHz clock */ 792 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 793 assert(src_clk_div - 1 < 128); 794 rk_clrsetreg(&cru->clksel_con[16], 795 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 796 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 797 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 798 } else { 799 rk_clrsetreg(&cru->clksel_con[16], 800 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 801 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 802 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 803 } 804 break; 805 case SCLK_EMMC: 806 /* Select aclk_emmc source from GPLL */ 807 src_clk_div = DIV_ROUND_UP(GPLL_HZ , aclk_emmc); 808 assert(src_clk_div - 1 < 32); 809 810 rk_clrsetreg(&cru->clksel_con[21], 811 ACLK_EMMC_PLL_SEL_MASK | ACLK_EMMC_DIV_CON_MASK, 812 ACLK_EMMC_PLL_SEL_GPLL << ACLK_EMMC_PLL_SEL_SHIFT | 813 (src_clk_div - 1) << ACLK_EMMC_DIV_CON_SHIFT); 814 815 /* Select clk_emmc source from GPLL too */ 816 src_clk_div = DIV_ROUND_UP(GPLL_HZ, set_rate); 817 assert(src_clk_div - 1 < 128); 818 819 rk_clrsetreg(&cru->clksel_con[22], 820 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 821 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 822 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 823 break; 824 default: 825 return -EINVAL; 826 } 827 return rk3399_mmc_get_clk(cru, clk_id); 828 } 829 830 static ulong rk3399_gmac_set_clk(struct rk3399_cru *cru, ulong rate) 831 { 832 ulong ret; 833 834 /* 835 * The RGMII CLK can be derived either from an external "clkin" 836 * or can be generated from internally by a divider from SCLK_MAC. 837 */ 838 if (readl(&cru->clksel_con[19]) & BIT(4)) { 839 /* An external clock will always generate the right rate... */ 840 ret = rate; 841 } else { 842 /* 843 * No platform uses an internal clock to date. 844 * Implement this once it becomes necessary and print an error 845 * if someone tries to use it (while it remains unimplemented). 846 */ 847 pr_err("%s: internal clock is UNIMPLEMENTED\n", __func__); 848 ret = 0; 849 } 850 851 return ret; 852 } 853 854 #define PMUSGRF_DDR_RGN_CON16 0xff330040 855 static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru, 856 ulong set_rate) 857 { 858 struct pll_div dpll_cfg; 859 860 /* IC ECO bug, need to set this register */ 861 writel(0xc000c000, PMUSGRF_DDR_RGN_CON16); 862 863 /* clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */ 864 switch (set_rate) { 865 case 200*MHz: 866 dpll_cfg = (struct pll_div) 867 {.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1}; 868 break; 869 case 300*MHz: 870 dpll_cfg = (struct pll_div) 871 {.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1}; 872 break; 873 case 666*MHz: 874 dpll_cfg = (struct pll_div) 875 {.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1}; 876 break; 877 case 800*MHz: 878 dpll_cfg = (struct pll_div) 879 {.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1}; 880 break; 881 case 933*MHz: 882 dpll_cfg = (struct pll_div) 883 {.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1}; 884 break; 885 default: 886 pr_err("Unsupported SDRAM frequency!,%ld\n", set_rate); 887 } 888 rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg); 889 890 return set_rate; 891 } 892 893 static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru) 894 { 895 u32 div, val; 896 897 val = readl(&cru->clksel_con[26]); 898 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 899 CLK_SARADC_DIV_CON_WIDTH); 900 901 return DIV_TO_RATE(OSC_HZ, div); 902 } 903 904 static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz) 905 { 906 int src_clk_div; 907 908 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 909 assert(src_clk_div <= 255); 910 911 rk_clrsetreg(&cru->clksel_con[26], 912 CLK_SARADC_DIV_CON_MASK, 913 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 914 915 return rk3399_saradc_get_clk(cru); 916 } 917 918 static ulong rk3399_clk_get_rate(struct clk *clk) 919 { 920 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 921 ulong rate = 0; 922 923 switch (clk->id) { 924 case PLL_APLLL: 925 case PLL_APLLB: 926 case PLL_DPLL: 927 case PLL_CPLL: 928 case PLL_GPLL: 929 case PLL_NPLL: 930 case PLL_VPLL: 931 rate = rk3399_pll_get_rate(priv, clk->id - 1); 932 break; 933 case HCLK_SDMMC: 934 case SCLK_SDMMC: 935 case SCLK_EMMC: 936 rate = rk3399_mmc_get_clk(priv->cru, clk->id); 937 break; 938 case SCLK_I2C1: 939 case SCLK_I2C2: 940 case SCLK_I2C3: 941 case SCLK_I2C5: 942 case SCLK_I2C6: 943 case SCLK_I2C7: 944 rate = rk3399_i2c_get_clk(priv->cru, clk->id); 945 break; 946 case SCLK_SPI0...SCLK_SPI5: 947 rate = rk3399_spi_get_clk(priv->cru, clk->id); 948 break; 949 case SCLK_UART0: 950 case SCLK_UART1: 951 case SCLK_UART2: 952 case SCLK_UART3: 953 return 24000000; 954 break; 955 case PCLK_HDMI_CTRL: 956 break; 957 case DCLK_VOP0: 958 case DCLK_VOP1: 959 break; 960 case PCLK_EFUSE1024NS: 961 break; 962 case SCLK_SARADC: 963 rate = rk3399_saradc_get_clk(priv->cru); 964 break; 965 default: 966 return -ENOENT; 967 } 968 969 return rate; 970 } 971 972 static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) 973 { 974 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 975 ulong ret = 0; 976 977 switch (clk->id) { 978 case 0 ... 63: 979 return 0; 980 981 case ACLK_PERIHP: 982 case HCLK_PERIHP: 983 case PCLK_PERIHP: 984 return 0; 985 986 case ACLK_PERILP0: 987 case HCLK_PERILP0: 988 case PCLK_PERILP0: 989 return 0; 990 991 case ACLK_CCI: 992 return 0; 993 994 case HCLK_PERILP1: 995 case PCLK_PERILP1: 996 return 0; 997 998 case HCLK_SDMMC: 999 case SCLK_SDMMC: 1000 case SCLK_EMMC: 1001 ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); 1002 break; 1003 case SCLK_MAC: 1004 ret = rk3399_gmac_set_clk(priv->cru, rate); 1005 break; 1006 case SCLK_I2C1: 1007 case SCLK_I2C2: 1008 case SCLK_I2C3: 1009 case SCLK_I2C5: 1010 case SCLK_I2C6: 1011 case SCLK_I2C7: 1012 ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate); 1013 break; 1014 case SCLK_SPI0...SCLK_SPI5: 1015 ret = rk3399_spi_set_clk(priv->cru, clk->id, rate); 1016 break; 1017 case PCLK_HDMI_CTRL: 1018 case PCLK_VIO_GRF: 1019 /* the PCLK gates for video are enabled by default */ 1020 break; 1021 case DCLK_VOP0: 1022 case DCLK_VOP1: 1023 ret = rk3399_vop_set_clk(priv->cru, clk->id, rate); 1024 break; 1025 case SCLK_DDRCLK: 1026 ret = rk3399_ddr_set_clk(priv->cru, rate); 1027 break; 1028 case PCLK_EFUSE1024NS: 1029 break; 1030 case SCLK_SARADC: 1031 ret = rk3399_saradc_set_clk(priv->cru, rate); 1032 break; 1033 default: 1034 return -ENOENT; 1035 } 1036 1037 return ret; 1038 } 1039 1040 static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *parent) 1041 { 1042 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 1043 const char *clock_output_name; 1044 int ret; 1045 1046 /* 1047 * If the requested parent is in the same clock-controller and 1048 * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock. 1049 */ 1050 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) { 1051 debug("%s: switching RGMII to SCLK_MAC\n", __func__); 1052 rk_clrreg(&priv->cru->clksel_con[19], BIT(4)); 1053 return 0; 1054 } 1055 1056 /* 1057 * Otherwise, we need to check the clock-output-names of the 1058 * requested parent to see if the requested id is "clkin_gmac". 1059 */ 1060 ret = dev_read_string_index(parent->dev, "clock-output-names", 1061 parent->id, &clock_output_name); 1062 if (ret < 0) 1063 return -ENODATA; 1064 1065 /* If this is "clkin_gmac", switch to the external clock input */ 1066 if (!strcmp(clock_output_name, "clkin_gmac")) { 1067 debug("%s: switching RGMII to CLKIN\n", __func__); 1068 rk_setreg(&priv->cru->clksel_con[19], BIT(4)); 1069 return 0; 1070 } 1071 1072 return -EINVAL; 1073 } 1074 1075 static int __maybe_unused rk3399_dclk_vop_set_parent(struct clk *clk, 1076 struct clk *parent) 1077 { 1078 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 1079 void *dclkreg_addr; 1080 1081 switch (clk->id) { 1082 case DCLK_VOP0_DIV: 1083 dclkreg_addr = &priv->cru->clksel_con[49]; 1084 break; 1085 case DCLK_VOP1_DIV: 1086 dclkreg_addr = &priv->cru->clksel_con[50]; 1087 break; 1088 default: 1089 return -EINVAL; 1090 } 1091 if (parent->id == PLL_CPLL) { 1092 rk_clrsetreg(dclkreg_addr, DCLK_VOP_PLL_SEL_MASK, 1093 DCLK_VOP_PLL_SEL_CPLL << DCLK_VOP_PLL_SEL_SHIFT); 1094 } else { 1095 rk_clrsetreg(dclkreg_addr, DCLK_VOP_PLL_SEL_MASK, 1096 DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT); 1097 } 1098 1099 return 0; 1100 } 1101 1102 static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent) 1103 { 1104 switch (clk->id) { 1105 case SCLK_RMII_SRC: 1106 return rk3399_gmac_set_parent(clk, parent); 1107 case DCLK_VOP0_DIV: 1108 case DCLK_VOP1_DIV: 1109 return rk3399_dclk_vop_set_parent(clk, parent); 1110 } 1111 1112 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1113 return -ENOENT; 1114 } 1115 1116 static int rk3399_clk_enable(struct clk *clk) 1117 { 1118 switch (clk->id) { 1119 case HCLK_HOST0: 1120 case HCLK_HOST0_ARB: 1121 case SCLK_USBPHY0_480M_SRC: 1122 case HCLK_HOST1: 1123 case HCLK_HOST1_ARB: 1124 case SCLK_USBPHY1_480M_SRC: 1125 return 0; 1126 } 1127 1128 debug("%s: unsupported clk %ld\n", __func__, clk->id); 1129 return -ENOENT; 1130 } 1131 1132 static struct clk_ops rk3399_clk_ops = { 1133 .get_rate = rk3399_clk_get_rate, 1134 .set_rate = rk3399_clk_set_rate, 1135 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1136 .set_parent = rk3399_clk_set_parent, 1137 #endif 1138 .enable = rk3399_clk_enable, 1139 }; 1140 1141 static void rkclk_init(struct rk3399_cru *cru) 1142 { 1143 u32 aclk_div; 1144 u32 hclk_div; 1145 u32 pclk_div; 1146 1147 rk3399_configure_cpu(cru, APLL_600_MHZ, CPU_CLUSTER_LITTLE); 1148 1149 /* 1150 * some cru registers changed by bootrom, we'd better reset them to 1151 * reset/default values described in TRM to avoid confusion in kernel. 1152 * Please consider these three lines as a fix of bootrom bug. 1153 */ 1154 rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101); 1155 rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f); 1156 rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003); 1157 1158 /* configure perihp aclk, hclk, pclk */ 1159 aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; 1160 assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f); 1161 1162 hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; 1163 assert((hclk_div + 1) * PERIHP_HCLK_HZ == 1164 PERIHP_ACLK_HZ && (hclk_div <= 0x3)); 1165 1166 pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; 1167 assert((pclk_div + 1) * PERIHP_PCLK_HZ == 1168 PERIHP_ACLK_HZ && (pclk_div <= 0x7)); 1169 1170 rk_clrsetreg(&cru->clksel_con[14], 1171 PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK | 1172 ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, 1173 pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | 1174 hclk_div << HCLK_PERIHP_DIV_CON_SHIFT | 1175 ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | 1176 aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); 1177 1178 /* configure perilp0 aclk, hclk, pclk */ 1179 aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1; 1180 assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f); 1181 1182 hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1; 1183 assert((hclk_div + 1) * PERILP0_HCLK_HZ == 1184 PERILP0_ACLK_HZ && (hclk_div <= 0x3)); 1185 1186 pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1; 1187 assert((pclk_div + 1) * PERILP0_PCLK_HZ == 1188 PERILP0_ACLK_HZ && (pclk_div <= 0x7)); 1189 1190 rk_clrsetreg(&cru->clksel_con[23], 1191 PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK | 1192 ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK, 1193 pclk_div << PCLK_PERILP0_DIV_CON_SHIFT | 1194 hclk_div << HCLK_PERILP0_DIV_CON_SHIFT | 1195 ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT | 1196 aclk_div << ACLK_PERILP0_DIV_CON_SHIFT); 1197 1198 /* perilp1 hclk select gpll as source */ 1199 hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1; 1200 assert((hclk_div + 1) * PERILP1_HCLK_HZ == 1201 GPLL_HZ && (hclk_div <= 0x1f)); 1202 1203 pclk_div = PERILP1_HCLK_HZ / PERILP1_PCLK_HZ - 1; 1204 assert((pclk_div + 1) * PERILP1_PCLK_HZ == 1205 PERILP1_HCLK_HZ && (pclk_div <= 0x7)); 1206 1207 rk_clrsetreg(&cru->clksel_con[25], 1208 PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK | 1209 HCLK_PERILP1_PLL_SEL_MASK, 1210 pclk_div << PCLK_PERILP1_DIV_CON_SHIFT | 1211 hclk_div << HCLK_PERILP1_DIV_CON_SHIFT | 1212 HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT); 1213 } 1214 1215 static int rk3399_clk_probe(struct udevice *dev) 1216 { 1217 struct rk3399_clk_priv *priv = dev_get_priv(dev); 1218 1219 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1220 struct rk3399_clk_plat *plat = dev_get_platdata(dev); 1221 1222 priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 1223 #endif 1224 rkclk_init(priv->cru); 1225 return 0; 1226 } 1227 1228 static int rk3399_clk_ofdata_to_platdata(struct udevice *dev) 1229 { 1230 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 1231 struct rk3399_clk_priv *priv = dev_get_priv(dev); 1232 1233 priv->cru = dev_read_addr_ptr(dev); 1234 #endif 1235 return 0; 1236 } 1237 1238 static int rk3399_clk_bind(struct udevice *dev) 1239 { 1240 int ret; 1241 struct udevice *sys_child, *sf_child; 1242 struct sysreset_reg *priv; 1243 struct softreset_reg *sf_priv; 1244 1245 /* The reset driver does not have a device node, so bind it here */ 1246 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 1247 &sys_child); 1248 if (ret) { 1249 debug("Warning: No sysreset driver: ret=%d\n", ret); 1250 } else { 1251 priv = malloc(sizeof(struct sysreset_reg)); 1252 priv->glb_srst_fst_value = offsetof(struct rk3399_cru, 1253 glb_srst_fst_value); 1254 priv->glb_srst_snd_value = offsetof(struct rk3399_cru, 1255 glb_srst_snd_value); 1256 sys_child->priv = priv; 1257 } 1258 1259 ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset", 1260 dev_ofnode(dev), &sf_child); 1261 if (ret) { 1262 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1263 } else { 1264 sf_priv = malloc(sizeof(struct softreset_reg)); 1265 sf_priv->sf_reset_offset = offsetof(struct rk3399_cru, 1266 softrst_con[0]); 1267 sf_priv->sf_reset_num = 21; 1268 sf_child->priv = sf_priv; 1269 } 1270 1271 return 0; 1272 } 1273 1274 static const struct udevice_id rk3399_clk_ids[] = { 1275 { .compatible = "rockchip,rk3399-cru" }, 1276 { } 1277 }; 1278 1279 U_BOOT_DRIVER(clk_rk3399) = { 1280 .name = "rockchip_rk3399_cru", 1281 .id = UCLASS_CLK, 1282 .of_match = rk3399_clk_ids, 1283 .priv_auto_alloc_size = sizeof(struct rk3399_clk_priv), 1284 .ofdata_to_platdata = rk3399_clk_ofdata_to_platdata, 1285 .ops = &rk3399_clk_ops, 1286 .bind = rk3399_clk_bind, 1287 .probe = rk3399_clk_probe, 1288 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1289 .platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat), 1290 #endif 1291 }; 1292 1293 static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id) 1294 { 1295 u32 div, con; 1296 1297 switch (clk_id) { 1298 case SCLK_I2C0_PMU: 1299 con = readl(&pmucru->pmucru_clksel[2]); 1300 div = I2C_CLK_DIV_VALUE(con, 0); 1301 break; 1302 case SCLK_I2C4_PMU: 1303 con = readl(&pmucru->pmucru_clksel[3]); 1304 div = I2C_CLK_DIV_VALUE(con, 4); 1305 break; 1306 case SCLK_I2C8_PMU: 1307 con = readl(&pmucru->pmucru_clksel[2]); 1308 div = I2C_CLK_DIV_VALUE(con, 8); 1309 break; 1310 default: 1311 printf("do not support this i2c bus\n"); 1312 return -EINVAL; 1313 } 1314 1315 return DIV_TO_RATE(PPLL_HZ, div); 1316 } 1317 1318 static ulong rk3399_i2c_set_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id, 1319 uint hz) 1320 { 1321 int src_clk_div; 1322 1323 src_clk_div = PPLL_HZ / hz; 1324 assert(src_clk_div - 1 < 127); 1325 1326 switch (clk_id) { 1327 case SCLK_I2C0_PMU: 1328 rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(0), 1329 I2C_PMUCLK_REG_VALUE(0, src_clk_div)); 1330 break; 1331 case SCLK_I2C4_PMU: 1332 rk_clrsetreg(&pmucru->pmucru_clksel[3], I2C_PMUCLK_REG_MASK(4), 1333 I2C_PMUCLK_REG_VALUE(4, src_clk_div)); 1334 break; 1335 case SCLK_I2C8_PMU: 1336 rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(8), 1337 I2C_PMUCLK_REG_VALUE(8, src_clk_div)); 1338 break; 1339 default: 1340 printf("do not support this i2c bus\n"); 1341 return -EINVAL; 1342 } 1343 1344 return DIV_TO_RATE(PPLL_HZ, src_clk_div); 1345 } 1346 1347 static ulong rk3399_pwm_get_clk(struct rk3399_pmucru *pmucru) 1348 { 1349 u32 div, con; 1350 1351 /* PWM closk rate is same as pclk_pmu */ 1352 con = readl(&pmucru->pmucru_clksel[0]); 1353 div = con & PMU_PCLK_DIV_CON_MASK; 1354 1355 return DIV_TO_RATE(PPLL_HZ, div); 1356 } 1357 1358 static ulong rk3399_pmuclk_get_rate(struct clk *clk) 1359 { 1360 struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev); 1361 ulong rate = 0; 1362 1363 switch (clk->id) { 1364 case PCLK_RKPWM_PMU: 1365 rate = rk3399_pwm_get_clk(priv->pmucru); 1366 break; 1367 case SCLK_I2C0_PMU: 1368 case SCLK_I2C4_PMU: 1369 case SCLK_I2C8_PMU: 1370 rate = rk3399_i2c_get_pmuclk(priv->pmucru, clk->id); 1371 break; 1372 case SCLK_UART4_PMU: 1373 rate = 24000000; 1374 break; 1375 default: 1376 return -ENOENT; 1377 } 1378 1379 return rate; 1380 } 1381 1382 static ulong rk3399_pmuclk_set_rate(struct clk *clk, ulong rate) 1383 { 1384 struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev); 1385 ulong ret = 0; 1386 1387 switch (clk->id) { 1388 case SCLK_I2C0_PMU: 1389 case SCLK_I2C4_PMU: 1390 case SCLK_I2C8_PMU: 1391 ret = rk3399_i2c_set_pmuclk(priv->pmucru, clk->id, rate); 1392 break; 1393 default: 1394 return -ENOENT; 1395 } 1396 1397 return ret; 1398 } 1399 1400 static struct clk_ops rk3399_pmuclk_ops = { 1401 .get_rate = rk3399_pmuclk_get_rate, 1402 .set_rate = rk3399_pmuclk_set_rate, 1403 }; 1404 1405 #ifndef CONFIG_SPL_BUILD 1406 static void pmuclk_init(struct rk3399_pmucru *pmucru) 1407 { 1408 u32 pclk_div; 1409 1410 /* configure pmu pll(ppll) */ 1411 rkclk_set_pll(&pmucru->ppll_con[0], &ppll_init_cfg); 1412 1413 /* configure pmu pclk */ 1414 pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1; 1415 assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div <= 0x1f); 1416 rk_clrsetreg(&pmucru->pmucru_clksel[0], 1417 PMU_PCLK_DIV_CON_MASK, 1418 pclk_div << PMU_PCLK_DIV_CON_SHIFT); 1419 } 1420 #endif 1421 1422 static int rk3399_pmuclk_probe(struct udevice *dev) 1423 { 1424 #if CONFIG_IS_ENABLED(OF_PLATDATA) || !defined(CONFIG_SPL_BUILD) 1425 struct rk3399_pmuclk_priv *priv = dev_get_priv(dev); 1426 #endif 1427 1428 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1429 struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev); 1430 1431 priv->pmucru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); 1432 #endif 1433 1434 #ifndef CONFIG_SPL_BUILD 1435 pmuclk_init(priv->pmucru); 1436 #endif 1437 return 0; 1438 } 1439 1440 static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev) 1441 { 1442 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 1443 struct rk3399_pmuclk_priv *priv = dev_get_priv(dev); 1444 1445 priv->pmucru = dev_read_addr_ptr(dev); 1446 #endif 1447 return 0; 1448 } 1449 1450 static int rk3399_pmuclk_bind(struct udevice *dev) 1451 { 1452 int ret = 0; 1453 struct udevice *sf_child; 1454 struct softreset_reg *sf_priv; 1455 1456 ret = device_bind_driver_to_node(dev, "rockchip_reset", 1457 "reset", dev_ofnode(dev), 1458 &sf_child); 1459 if (ret) { 1460 debug("Warning: No rockchip reset driver: ret=%d\n", ret); 1461 } else { 1462 sf_priv = malloc(sizeof(struct softreset_reg)); 1463 sf_priv->sf_reset_offset = offsetof(struct rk3399_pmucru, 1464 pmucru_softrst_con[0]); 1465 sf_priv->sf_reset_num = 2; 1466 sf_child->priv = sf_priv; 1467 } 1468 1469 return 0; 1470 } 1471 1472 static const struct udevice_id rk3399_pmuclk_ids[] = { 1473 { .compatible = "rockchip,rk3399-pmucru" }, 1474 { } 1475 }; 1476 1477 U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = { 1478 .name = "rockchip_rk3399_pmucru", 1479 .id = UCLASS_CLK, 1480 .of_match = rk3399_pmuclk_ids, 1481 .priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv), 1482 .ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata, 1483 .ops = &rk3399_pmuclk_ops, 1484 .probe = rk3399_pmuclk_probe, 1485 .bind = rk3399_pmuclk_bind, 1486 #if CONFIG_IS_ENABLED(OF_PLATDATA) 1487 .platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat), 1488 #endif 1489 }; 1490