1 /* 2 * (C) Copyright 2015 Google, Inc 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <syscon.h> 12 #include <asm/io.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rk3399.h> 15 #include <asm/arch/hardware.h> 16 #include <dm/lists.h> 17 #include <dt-bindings/clock/rk3399-cru.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 struct rk3399_pmuclk_priv { 22 struct rk3399_pmucru *pmucru; 23 }; 24 25 struct pll_div { 26 u32 refdiv; 27 u32 fbdiv; 28 u32 postdiv1; 29 u32 postdiv2; 30 u32 frac; 31 }; 32 33 #define RATE_TO_DIV(input_rate, output_rate) \ 34 ((input_rate) / (output_rate) - 1); 35 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 36 37 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 38 .refdiv = _refdiv,\ 39 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 40 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; 41 42 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); 43 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2); 44 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1); 45 46 static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1); 47 static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1); 48 49 static const struct pll_div *apll_l_cfgs[] = { 50 [APLL_L_1600_MHZ] = &apll_l_1600_cfg, 51 [APLL_L_600_MHZ] = &apll_l_600_cfg, 52 }; 53 54 enum { 55 /* PLL_CON0 */ 56 PLL_FBDIV_MASK = 0xfff, 57 PLL_FBDIV_SHIFT = 0, 58 59 /* PLL_CON1 */ 60 PLL_POSTDIV2_SHIFT = 12, 61 PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, 62 PLL_POSTDIV1_SHIFT = 8, 63 PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, 64 PLL_REFDIV_MASK = 0x3f, 65 PLL_REFDIV_SHIFT = 0, 66 67 /* PLL_CON2 */ 68 PLL_LOCK_STATUS_SHIFT = 31, 69 PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, 70 PLL_FRACDIV_MASK = 0xffffff, 71 PLL_FRACDIV_SHIFT = 0, 72 73 /* PLL_CON3 */ 74 PLL_MODE_SHIFT = 8, 75 PLL_MODE_MASK = 3 << PLL_MODE_SHIFT, 76 PLL_MODE_SLOW = 0, 77 PLL_MODE_NORM, 78 PLL_MODE_DEEP, 79 PLL_DSMPD_SHIFT = 3, 80 PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, 81 PLL_INTEGER_MODE = 1, 82 83 /* PMUCRU_CLKSEL_CON0 */ 84 PMU_PCLK_DIV_CON_MASK = 0x1f, 85 PMU_PCLK_DIV_CON_SHIFT = 0, 86 87 /* PMUCRU_CLKSEL_CON1 */ 88 SPI3_PLL_SEL_SHIFT = 7, 89 SPI3_PLL_SEL_MASK = 1 << SPI3_PLL_SEL_SHIFT, 90 SPI3_PLL_SEL_24M = 0, 91 SPI3_PLL_SEL_PPLL = 1, 92 SPI3_DIV_CON_SHIFT = 0x0, 93 SPI3_DIV_CON_MASK = 0x7f, 94 95 /* PMUCRU_CLKSEL_CON2 */ 96 I2C_DIV_CON_MASK = 0x7f, 97 CLK_I2C8_DIV_CON_SHIFT = 8, 98 CLK_I2C0_DIV_CON_SHIFT = 0, 99 100 /* PMUCRU_CLKSEL_CON3 */ 101 CLK_I2C4_DIV_CON_SHIFT = 0, 102 103 /* CLKSEL_CON0 */ 104 ACLKM_CORE_L_DIV_CON_SHIFT = 8, 105 ACLKM_CORE_L_DIV_CON_MASK = 0x1f << ACLKM_CORE_L_DIV_CON_SHIFT, 106 CLK_CORE_L_PLL_SEL_SHIFT = 6, 107 CLK_CORE_L_PLL_SEL_MASK = 3 << CLK_CORE_L_PLL_SEL_SHIFT, 108 CLK_CORE_L_PLL_SEL_ALPLL = 0x0, 109 CLK_CORE_L_PLL_SEL_ABPLL = 0x1, 110 CLK_CORE_L_PLL_SEL_DPLL = 0x10, 111 CLK_CORE_L_PLL_SEL_GPLL = 0x11, 112 CLK_CORE_L_DIV_MASK = 0x1f, 113 CLK_CORE_L_DIV_SHIFT = 0, 114 115 /* CLKSEL_CON1 */ 116 PCLK_DBG_L_DIV_SHIFT = 0x8, 117 PCLK_DBG_L_DIV_MASK = 0x1f << PCLK_DBG_L_DIV_SHIFT, 118 ATCLK_CORE_L_DIV_SHIFT = 0, 119 ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT, 120 121 /* CLKSEL_CON14 */ 122 PCLK_PERIHP_DIV_CON_SHIFT = 12, 123 PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, 124 HCLK_PERIHP_DIV_CON_SHIFT = 8, 125 HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, 126 ACLK_PERIHP_PLL_SEL_SHIFT = 7, 127 ACLK_PERIHP_PLL_SEL_MASK = 1 << ACLK_PERIHP_PLL_SEL_SHIFT, 128 ACLK_PERIHP_PLL_SEL_CPLL = 0, 129 ACLK_PERIHP_PLL_SEL_GPLL = 1, 130 ACLK_PERIHP_DIV_CON_SHIFT = 0, 131 ACLK_PERIHP_DIV_CON_MASK = 0x1f, 132 133 /* CLKSEL_CON21 */ 134 ACLK_EMMC_PLL_SEL_SHIFT = 7, 135 ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT, 136 ACLK_EMMC_PLL_SEL_GPLL = 0x1, 137 ACLK_EMMC_DIV_CON_SHIFT = 0, 138 ACLK_EMMC_DIV_CON_MASK = 0x1f, 139 140 /* CLKSEL_CON22 */ 141 CLK_EMMC_PLL_SHIFT = 8, 142 CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT, 143 CLK_EMMC_PLL_SEL_GPLL = 0x1, 144 CLK_EMMC_PLL_SEL_24M = 0x5, 145 CLK_EMMC_DIV_CON_SHIFT = 0, 146 CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT, 147 148 /* CLKSEL_CON23 */ 149 PCLK_PERILP0_DIV_CON_SHIFT = 12, 150 PCLK_PERILP0_DIV_CON_MASK = 0x7 << PCLK_PERILP0_DIV_CON_SHIFT, 151 HCLK_PERILP0_DIV_CON_SHIFT = 8, 152 HCLK_PERILP0_DIV_CON_MASK = 3 << HCLK_PERILP0_DIV_CON_SHIFT, 153 ACLK_PERILP0_PLL_SEL_SHIFT = 7, 154 ACLK_PERILP0_PLL_SEL_MASK = 1 << ACLK_PERILP0_PLL_SEL_SHIFT, 155 ACLK_PERILP0_PLL_SEL_CPLL = 0, 156 ACLK_PERILP0_PLL_SEL_GPLL = 1, 157 ACLK_PERILP0_DIV_CON_SHIFT = 0, 158 ACLK_PERILP0_DIV_CON_MASK = 0x1f, 159 160 /* CLKSEL_CON25 */ 161 PCLK_PERILP1_DIV_CON_SHIFT = 8, 162 PCLK_PERILP1_DIV_CON_MASK = 0x7 << PCLK_PERILP1_DIV_CON_SHIFT, 163 HCLK_PERILP1_PLL_SEL_SHIFT = 7, 164 HCLK_PERILP1_PLL_SEL_MASK = 1 << HCLK_PERILP1_PLL_SEL_SHIFT, 165 HCLK_PERILP1_PLL_SEL_CPLL = 0, 166 HCLK_PERILP1_PLL_SEL_GPLL = 1, 167 HCLK_PERILP1_DIV_CON_SHIFT = 0, 168 HCLK_PERILP1_DIV_CON_MASK = 0x1f, 169 170 /* CLKSEL_CON26 */ 171 CLK_SARADC_DIV_CON_SHIFT = 8, 172 CLK_SARADC_DIV_CON_MASK = 0xff << CLK_SARADC_DIV_CON_SHIFT, 173 174 /* CLKSEL_CON27 */ 175 CLK_TSADC_SEL_X24M = 0x0, 176 CLK_TSADC_SEL_SHIFT = 15, 177 CLK_TSADC_SEL_MASK = 1 << CLK_TSADC_SEL_SHIFT, 178 CLK_TSADC_DIV_CON_SHIFT = 0, 179 CLK_TSADC_DIV_CON_MASK = 0x3ff, 180 181 /* CLKSEL_CON47 & CLKSEL_CON48 */ 182 ACLK_VOP_PLL_SEL_SHIFT = 6, 183 ACLK_VOP_PLL_SEL_MASK = 0x3 << ACLK_VOP_PLL_SEL_SHIFT, 184 ACLK_VOP_PLL_SEL_CPLL = 0x1, 185 ACLK_VOP_DIV_CON_SHIFT = 0, 186 ACLK_VOP_DIV_CON_MASK = 0x1f << ACLK_VOP_DIV_CON_SHIFT, 187 188 /* CLKSEL_CON49 & CLKSEL_CON50 */ 189 DCLK_VOP_DCLK_SEL_SHIFT = 11, 190 DCLK_VOP_DCLK_SEL_MASK = 1 << DCLK_VOP_DCLK_SEL_SHIFT, 191 DCLK_VOP_DCLK_SEL_DIVOUT = 0, 192 DCLK_VOP_PLL_SEL_SHIFT = 8, 193 DCLK_VOP_PLL_SEL_MASK = 3 << DCLK_VOP_PLL_SEL_SHIFT, 194 DCLK_VOP_PLL_SEL_VPLL = 0, 195 DCLK_VOP_DIV_CON_MASK = 0xff, 196 DCLK_VOP_DIV_CON_SHIFT = 0, 197 198 /* CLKSEL_CON58 */ 199 CLK_SPI_PLL_SEL_MASK = 1, 200 CLK_SPI_PLL_SEL_CPLL = 0, 201 CLK_SPI_PLL_SEL_GPLL = 1, 202 CLK_SPI_PLL_DIV_CON_MASK = 0x7f, 203 CLK_SPI5_PLL_DIV_CON_SHIFT = 8, 204 CLK_SPI5_PLL_SEL_SHIFT = 15, 205 206 /* CLKSEL_CON59 */ 207 CLK_SPI1_PLL_SEL_SHIFT = 15, 208 CLK_SPI1_PLL_DIV_CON_SHIFT = 8, 209 CLK_SPI0_PLL_SEL_SHIFT = 7, 210 CLK_SPI0_PLL_DIV_CON_SHIFT = 0, 211 212 /* CLKSEL_CON60 */ 213 CLK_SPI4_PLL_SEL_SHIFT = 15, 214 CLK_SPI4_PLL_DIV_CON_SHIFT = 8, 215 CLK_SPI2_PLL_SEL_SHIFT = 7, 216 CLK_SPI2_PLL_DIV_CON_SHIFT = 0, 217 218 /* CLKSEL_CON61 */ 219 CLK_I2C_PLL_SEL_MASK = 1, 220 CLK_I2C_PLL_SEL_CPLL = 0, 221 CLK_I2C_PLL_SEL_GPLL = 1, 222 CLK_I2C5_PLL_SEL_SHIFT = 15, 223 CLK_I2C5_DIV_CON_SHIFT = 8, 224 CLK_I2C1_PLL_SEL_SHIFT = 7, 225 CLK_I2C1_DIV_CON_SHIFT = 0, 226 227 /* CLKSEL_CON62 */ 228 CLK_I2C6_PLL_SEL_SHIFT = 15, 229 CLK_I2C6_DIV_CON_SHIFT = 8, 230 CLK_I2C2_PLL_SEL_SHIFT = 7, 231 CLK_I2C2_DIV_CON_SHIFT = 0, 232 233 /* CLKSEL_CON63 */ 234 CLK_I2C7_PLL_SEL_SHIFT = 15, 235 CLK_I2C7_DIV_CON_SHIFT = 8, 236 CLK_I2C3_PLL_SEL_SHIFT = 7, 237 CLK_I2C3_DIV_CON_SHIFT = 0, 238 239 /* CRU_SOFTRST_CON4 */ 240 RESETN_DDR0_REQ_SHIFT = 8, 241 RESETN_DDR0_REQ_MASK = 1 << RESETN_DDR0_REQ_SHIFT, 242 RESETN_DDRPHY0_REQ_SHIFT = 9, 243 RESETN_DDRPHY0_REQ_MASK = 1 << RESETN_DDRPHY0_REQ_SHIFT, 244 RESETN_DDR1_REQ_SHIFT = 12, 245 RESETN_DDR1_REQ_MASK = 1 << RESETN_DDR1_REQ_SHIFT, 246 RESETN_DDRPHY1_REQ_SHIFT = 13, 247 RESETN_DDRPHY1_REQ_MASK = 1 << RESETN_DDRPHY1_REQ_SHIFT, 248 }; 249 250 #define VCO_MAX_KHZ (3200 * (MHz / KHz)) 251 #define VCO_MIN_KHZ (800 * (MHz / KHz)) 252 #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) 253 #define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) 254 255 /* 256 * the div restructions of pll in integer mode, these are defined in 257 * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 258 */ 259 #define PLL_DIV_MIN 16 260 #define PLL_DIV_MAX 3200 261 262 /* 263 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 264 * Formulas also embedded within the Fractional PLL Verilog model: 265 * If DSMPD = 1 (DSM is disabled, "integer mode") 266 * FOUTVCO = FREF / REFDIV * FBDIV 267 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 268 * Where: 269 * FOUTVCO = Fractional PLL non-divided output frequency 270 * FOUTPOSTDIV = Fractional PLL divided output frequency 271 * (output of second post divider) 272 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 273 * REFDIV = Fractional PLL input reference clock divider 274 * FBDIV = Integer value programmed into feedback divide 275 * 276 */ 277 static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div) 278 { 279 /* All 8 PLLs have same VCO and output frequency range restrictions. */ 280 u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; 281 u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; 282 283 debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, " 284 "postdiv2=%d, vco=%u khz, output=%u khz\n", 285 pll_con, div->fbdiv, div->refdiv, div->postdiv1, 286 div->postdiv2, vco_khz, output_khz); 287 assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && 288 output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && 289 div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); 290 291 /* 292 * When power on or changing PLL setting, 293 * we must force PLL into slow mode to ensure output stable clock. 294 */ 295 rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, 296 PLL_MODE_SLOW << PLL_MODE_SHIFT); 297 298 /* use integer mode */ 299 rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK, 300 PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); 301 302 rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK, 303 div->fbdiv << PLL_FBDIV_SHIFT); 304 rk_clrsetreg(&pll_con[1], 305 PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK | 306 PLL_REFDIV_MASK | PLL_REFDIV_SHIFT, 307 (div->postdiv2 << PLL_POSTDIV2_SHIFT) | 308 (div->postdiv1 << PLL_POSTDIV1_SHIFT) | 309 (div->refdiv << PLL_REFDIV_SHIFT)); 310 311 /* waiting for pll lock */ 312 while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT))) 313 udelay(1); 314 315 /* pll enter normal mode */ 316 rk_clrsetreg(&pll_con[3], PLL_MODE_MASK, 317 PLL_MODE_NORM << PLL_MODE_SHIFT); 318 } 319 320 static int pll_para_config(u32 freq_hz, struct pll_div *div) 321 { 322 u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0; 323 u32 postdiv1, postdiv2 = 1; 324 u32 fref_khz; 325 u32 diff_khz, best_diff_khz; 326 const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16; 327 const u32 max_postdiv1 = 7, max_postdiv2 = 7; 328 u32 vco_khz; 329 u32 freq_khz = freq_hz / KHz; 330 331 if (!freq_hz) { 332 printf("%s: the frequency can't be 0 Hz\n", __func__); 333 return -1; 334 } 335 336 postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz); 337 if (postdiv1 > max_postdiv1) { 338 postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1); 339 postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2); 340 } 341 342 vco_khz = freq_khz * postdiv1 * postdiv2; 343 344 if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || 345 postdiv2 > max_postdiv2) { 346 printf("%s: Cannot find out a supported VCO" 347 " for Frequency (%uHz).\n", __func__, freq_hz); 348 return -1; 349 } 350 351 div->postdiv1 = postdiv1; 352 div->postdiv2 = postdiv2; 353 354 best_diff_khz = vco_khz; 355 for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) { 356 fref_khz = ref_khz / refdiv; 357 358 fbdiv = vco_khz / fref_khz; 359 if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv)) 360 continue; 361 diff_khz = vco_khz - fbdiv * fref_khz; 362 if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) { 363 fbdiv++; 364 diff_khz = fref_khz - diff_khz; 365 } 366 367 if (diff_khz >= best_diff_khz) 368 continue; 369 370 best_diff_khz = diff_khz; 371 div->refdiv = refdiv; 372 div->fbdiv = fbdiv; 373 } 374 375 if (best_diff_khz > 4 * (MHz/KHz)) { 376 printf("%s: Failed to match output frequency %u, " 377 "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz, 378 best_diff_khz * KHz); 379 return -1; 380 } 381 return 0; 382 } 383 384 static void rkclk_init(struct rk3399_cru *cru) 385 { 386 u32 aclk_div; 387 u32 hclk_div; 388 u32 pclk_div; 389 390 /* 391 * some cru registers changed by bootrom, we'd better reset them to 392 * reset/default values described in TRM to avoid confusion in kernel. 393 * Please consider these three lines as a fix of bootrom bug. 394 */ 395 rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101); 396 rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f); 397 rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003); 398 399 /* configure gpll cpll */ 400 rkclk_set_pll(&cru->gpll_con[0], &gpll_init_cfg); 401 rkclk_set_pll(&cru->cpll_con[0], &cpll_init_cfg); 402 403 /* configure perihp aclk, hclk, pclk */ 404 aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; 405 assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); 406 407 hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; 408 assert((hclk_div + 1) * PERIHP_HCLK_HZ == 409 PERIHP_ACLK_HZ && (hclk_div < 0x4)); 410 411 pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; 412 assert((pclk_div + 1) * PERIHP_PCLK_HZ == 413 PERIHP_ACLK_HZ && (pclk_div < 0x7)); 414 415 rk_clrsetreg(&cru->clksel_con[14], 416 PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK | 417 ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, 418 pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | 419 hclk_div << HCLK_PERIHP_DIV_CON_SHIFT | 420 ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | 421 aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); 422 423 /* configure perilp0 aclk, hclk, pclk */ 424 aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1; 425 assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); 426 427 hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1; 428 assert((hclk_div + 1) * PERILP0_HCLK_HZ == 429 PERILP0_ACLK_HZ && (hclk_div < 0x4)); 430 431 pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1; 432 assert((pclk_div + 1) * PERILP0_PCLK_HZ == 433 PERILP0_ACLK_HZ && (pclk_div < 0x7)); 434 435 rk_clrsetreg(&cru->clksel_con[23], 436 PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK | 437 ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK, 438 pclk_div << PCLK_PERILP0_DIV_CON_SHIFT | 439 hclk_div << HCLK_PERILP0_DIV_CON_SHIFT | 440 ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT | 441 aclk_div << ACLK_PERILP0_DIV_CON_SHIFT); 442 443 /* perilp1 hclk select gpll as source */ 444 hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1; 445 assert((hclk_div + 1) * PERILP1_HCLK_HZ == 446 GPLL_HZ && (hclk_div < 0x1f)); 447 448 pclk_div = PERILP1_HCLK_HZ / PERILP1_HCLK_HZ - 1; 449 assert((pclk_div + 1) * PERILP1_HCLK_HZ == 450 PERILP1_HCLK_HZ && (hclk_div < 0x7)); 451 452 rk_clrsetreg(&cru->clksel_con[25], 453 PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK | 454 HCLK_PERILP1_PLL_SEL_MASK, 455 pclk_div << PCLK_PERILP1_DIV_CON_SHIFT | 456 hclk_div << HCLK_PERILP1_DIV_CON_SHIFT | 457 HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT); 458 } 459 460 void rk3399_configure_cpu(struct rk3399_cru *cru, 461 enum apll_l_frequencies apll_l_freq) 462 { 463 u32 aclkm_div; 464 u32 pclk_dbg_div; 465 u32 atclk_div; 466 467 rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]); 468 469 aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1; 470 assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ && 471 aclkm_div < 0x1f); 472 473 pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1; 474 assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ && 475 pclk_dbg_div < 0x1f); 476 477 atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1; 478 assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ && 479 atclk_div < 0x1f); 480 481 rk_clrsetreg(&cru->clksel_con[0], 482 ACLKM_CORE_L_DIV_CON_MASK | CLK_CORE_L_PLL_SEL_MASK | 483 CLK_CORE_L_DIV_MASK, 484 aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT | 485 CLK_CORE_L_PLL_SEL_ALPLL << CLK_CORE_L_PLL_SEL_SHIFT | 486 0 << CLK_CORE_L_DIV_SHIFT); 487 488 rk_clrsetreg(&cru->clksel_con[1], 489 PCLK_DBG_L_DIV_MASK | ATCLK_CORE_L_DIV_MASK, 490 pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT | 491 atclk_div << ATCLK_CORE_L_DIV_SHIFT); 492 } 493 #define I2C_CLK_REG_MASK(bus) \ 494 (I2C_DIV_CON_MASK << \ 495 CLK_I2C ##bus## _DIV_CON_SHIFT | \ 496 CLK_I2C_PLL_SEL_MASK << \ 497 CLK_I2C ##bus## _PLL_SEL_SHIFT) 498 499 #define I2C_CLK_REG_VALUE(bus, clk_div) \ 500 ((clk_div - 1) << \ 501 CLK_I2C ##bus## _DIV_CON_SHIFT | \ 502 CLK_I2C_PLL_SEL_GPLL << \ 503 CLK_I2C ##bus## _PLL_SEL_SHIFT) 504 505 #define I2C_CLK_DIV_VALUE(con, bus) \ 506 (con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \ 507 I2C_DIV_CON_MASK; 508 509 #define I2C_PMUCLK_REG_MASK(bus) \ 510 (I2C_DIV_CON_MASK << \ 511 CLK_I2C ##bus## _DIV_CON_SHIFT) 512 513 #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \ 514 ((clk_div - 1) << \ 515 CLK_I2C ##bus## _DIV_CON_SHIFT) 516 517 static ulong rk3399_i2c_get_clk(struct rk3399_cru *cru, ulong clk_id) 518 { 519 u32 div, con; 520 521 switch (clk_id) { 522 case SCLK_I2C1: 523 con = readl(&cru->clksel_con[61]); 524 div = I2C_CLK_DIV_VALUE(con, 1); 525 break; 526 case SCLK_I2C2: 527 con = readl(&cru->clksel_con[62]); 528 div = I2C_CLK_DIV_VALUE(con, 2); 529 break; 530 case SCLK_I2C3: 531 con = readl(&cru->clksel_con[63]); 532 div = I2C_CLK_DIV_VALUE(con, 3); 533 break; 534 case SCLK_I2C5: 535 con = readl(&cru->clksel_con[61]); 536 div = I2C_CLK_DIV_VALUE(con, 5); 537 break; 538 case SCLK_I2C6: 539 con = readl(&cru->clksel_con[62]); 540 div = I2C_CLK_DIV_VALUE(con, 6); 541 break; 542 case SCLK_I2C7: 543 con = readl(&cru->clksel_con[63]); 544 div = I2C_CLK_DIV_VALUE(con, 7); 545 break; 546 default: 547 printf("do not support this i2c bus\n"); 548 return -EINVAL; 549 } 550 551 return DIV_TO_RATE(GPLL_HZ, div); 552 } 553 554 static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) 555 { 556 int src_clk_div; 557 558 /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/ 559 src_clk_div = GPLL_HZ / hz; 560 assert(src_clk_div - 1 < 127); 561 562 switch (clk_id) { 563 case SCLK_I2C1: 564 rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(1), 565 I2C_CLK_REG_VALUE(1, src_clk_div)); 566 break; 567 case SCLK_I2C2: 568 rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(2), 569 I2C_CLK_REG_VALUE(2, src_clk_div)); 570 break; 571 case SCLK_I2C3: 572 rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(3), 573 I2C_CLK_REG_VALUE(3, src_clk_div)); 574 break; 575 case SCLK_I2C5: 576 rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(5), 577 I2C_CLK_REG_VALUE(5, src_clk_div)); 578 break; 579 case SCLK_I2C6: 580 rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(6), 581 I2C_CLK_REG_VALUE(6, src_clk_div)); 582 break; 583 case SCLK_I2C7: 584 rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(7), 585 I2C_CLK_REG_VALUE(7, src_clk_div)); 586 break; 587 default: 588 printf("do not support this i2c bus\n"); 589 return -EINVAL; 590 } 591 592 return DIV_TO_RATE(GPLL_HZ, src_clk_div); 593 } 594 595 static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz) 596 { 597 struct pll_div vpll_config = {0}; 598 int aclk_vop = 198*MHz; 599 void *aclkreg_addr, *dclkreg_addr; 600 u32 div; 601 602 switch (clk_id) { 603 case DCLK_VOP0: 604 aclkreg_addr = &cru->clksel_con[47]; 605 dclkreg_addr = &cru->clksel_con[49]; 606 break; 607 case DCLK_VOP1: 608 aclkreg_addr = &cru->clksel_con[48]; 609 dclkreg_addr = &cru->clksel_con[50]; 610 break; 611 default: 612 return -EINVAL; 613 } 614 /* vop aclk source clk: cpll */ 615 div = CPLL_HZ / aclk_vop; 616 assert(div - 1 < 32); 617 618 rk_clrsetreg(aclkreg_addr, 619 ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, 620 ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | 621 (div - 1) << ACLK_VOP_DIV_CON_SHIFT); 622 623 /* vop dclk source from vpll, and equals to vpll(means div == 1) */ 624 if (pll_para_config(hz, &vpll_config)) 625 return -1; 626 627 rkclk_set_pll(&cru->vpll_con[0], &vpll_config); 628 629 rk_clrsetreg(dclkreg_addr, 630 DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK| 631 DCLK_VOP_DIV_CON_MASK, 632 DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT | 633 DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT | 634 (1 - 1) << DCLK_VOP_DIV_CON_SHIFT); 635 636 return hz; 637 } 638 639 static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id) 640 { 641 u32 div, con; 642 643 switch (clk_id) { 644 case SCLK_SDMMC: 645 con = readl(&cru->clksel_con[16]); 646 break; 647 case SCLK_EMMC: 648 con = readl(&cru->clksel_con[21]); 649 break; 650 default: 651 return -EINVAL; 652 } 653 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 654 655 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 656 == CLK_EMMC_PLL_SEL_24M) 657 return DIV_TO_RATE(24*1024*1024, div); 658 else 659 return DIV_TO_RATE(GPLL_HZ, div); 660 } 661 662 static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, 663 ulong clk_id, ulong set_rate) 664 { 665 int src_clk_div; 666 int aclk_emmc = 198*MHz; 667 668 switch (clk_id) { 669 case SCLK_SDMMC: 670 /* Select clk_sdmmc source from GPLL by default */ 671 src_clk_div = GPLL_HZ / set_rate; 672 673 if (src_clk_div > 127) { 674 /* use 24MHz source for 400KHz clock */ 675 src_clk_div = 24*1024*1024 / set_rate; 676 rk_clrsetreg(&cru->clksel_con[16], 677 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 678 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 679 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 680 } else { 681 rk_clrsetreg(&cru->clksel_con[16], 682 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 683 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 684 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 685 } 686 break; 687 case SCLK_EMMC: 688 /* Select aclk_emmc source from GPLL */ 689 src_clk_div = GPLL_HZ / aclk_emmc; 690 assert(src_clk_div - 1 < 31); 691 692 rk_clrsetreg(&cru->clksel_con[21], 693 ACLK_EMMC_PLL_SEL_MASK | ACLK_EMMC_DIV_CON_MASK, 694 ACLK_EMMC_PLL_SEL_GPLL << ACLK_EMMC_PLL_SEL_SHIFT | 695 (src_clk_div - 1) << ACLK_EMMC_DIV_CON_SHIFT); 696 697 /* Select clk_emmc source from GPLL too */ 698 src_clk_div = GPLL_HZ / set_rate; 699 assert(src_clk_div - 1 < 127); 700 701 rk_clrsetreg(&cru->clksel_con[22], 702 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 703 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 704 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 705 break; 706 default: 707 return -EINVAL; 708 } 709 return rk3399_mmc_get_clk(cru, clk_id); 710 } 711 712 static ulong rk3399_clk_get_rate(struct clk *clk) 713 { 714 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 715 ulong rate = 0; 716 717 switch (clk->id) { 718 case 0 ... 63: 719 return 0; 720 case SCLK_SDMMC: 721 case SCLK_EMMC: 722 rate = rk3399_mmc_get_clk(priv->cru, clk->id); 723 break; 724 case SCLK_I2C1: 725 case SCLK_I2C2: 726 case SCLK_I2C3: 727 case SCLK_I2C5: 728 case SCLK_I2C6: 729 case SCLK_I2C7: 730 rate = rk3399_i2c_get_clk(priv->cru, clk->id); 731 break; 732 case DCLK_VOP0: 733 case DCLK_VOP1: 734 break; 735 default: 736 return -ENOENT; 737 } 738 739 return rate; 740 } 741 742 static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) 743 { 744 struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); 745 ulong ret = 0; 746 747 switch (clk->id) { 748 case 0 ... 63: 749 return 0; 750 case SCLK_SDMMC: 751 case SCLK_EMMC: 752 ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); 753 break; 754 case SCLK_I2C1: 755 case SCLK_I2C2: 756 case SCLK_I2C3: 757 case SCLK_I2C5: 758 case SCLK_I2C6: 759 case SCLK_I2C7: 760 ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate); 761 break; 762 case DCLK_VOP0: 763 case DCLK_VOP1: 764 ret = rk3399_vop_set_clk(priv->cru, clk->id, rate); 765 break; 766 default: 767 return -ENOENT; 768 } 769 770 return ret; 771 } 772 773 static struct clk_ops rk3399_clk_ops = { 774 .get_rate = rk3399_clk_get_rate, 775 .set_rate = rk3399_clk_set_rate, 776 }; 777 778 static int rk3399_clk_probe(struct udevice *dev) 779 { 780 struct rk3399_clk_priv *priv = dev_get_priv(dev); 781 782 rkclk_init(priv->cru); 783 784 return 0; 785 } 786 787 static int rk3399_clk_ofdata_to_platdata(struct udevice *dev) 788 { 789 struct rk3399_clk_priv *priv = dev_get_priv(dev); 790 791 priv->cru = (struct rk3399_cru *)dev_get_addr(dev); 792 793 return 0; 794 } 795 796 static int rk3399_clk_bind(struct udevice *dev) 797 { 798 int ret; 799 800 /* The reset driver does not have a device node, so bind it here */ 801 ret = device_bind_driver(gd->dm_root, "rk3399_sysreset", "reset", &dev); 802 if (ret) 803 printf("Warning: No RK3399 reset driver: ret=%d\n", ret); 804 805 return 0; 806 } 807 808 static const struct udevice_id rk3399_clk_ids[] = { 809 { .compatible = "rockchip,rk3399-cru" }, 810 { } 811 }; 812 813 U_BOOT_DRIVER(clk_rk3399) = { 814 .name = "clk_rk3399", 815 .id = UCLASS_CLK, 816 .of_match = rk3399_clk_ids, 817 .priv_auto_alloc_size = sizeof(struct rk3399_clk_priv), 818 .ofdata_to_platdata = rk3399_clk_ofdata_to_platdata, 819 .ops = &rk3399_clk_ops, 820 .bind = rk3399_clk_bind, 821 .probe = rk3399_clk_probe, 822 }; 823 824 static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id) 825 { 826 u32 div, con; 827 828 switch (clk_id) { 829 case SCLK_I2C0_PMU: 830 con = readl(&pmucru->pmucru_clksel[2]); 831 div = I2C_CLK_DIV_VALUE(con, 0); 832 break; 833 case SCLK_I2C4_PMU: 834 con = readl(&pmucru->pmucru_clksel[3]); 835 div = I2C_CLK_DIV_VALUE(con, 4); 836 break; 837 case SCLK_I2C8_PMU: 838 con = readl(&pmucru->pmucru_clksel[2]); 839 div = I2C_CLK_DIV_VALUE(con, 8); 840 break; 841 default: 842 printf("do not support this i2c bus\n"); 843 return -EINVAL; 844 } 845 846 return DIV_TO_RATE(PPLL_HZ, div); 847 } 848 849 static ulong rk3399_i2c_set_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id, 850 uint hz) 851 { 852 int src_clk_div; 853 854 src_clk_div = PPLL_HZ / hz; 855 assert(src_clk_div - 1 < 127); 856 857 switch (clk_id) { 858 case SCLK_I2C0_PMU: 859 rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(0), 860 I2C_PMUCLK_REG_VALUE(0, src_clk_div)); 861 break; 862 case SCLK_I2C4_PMU: 863 rk_clrsetreg(&pmucru->pmucru_clksel[3], I2C_PMUCLK_REG_MASK(4), 864 I2C_PMUCLK_REG_VALUE(4, src_clk_div)); 865 break; 866 case SCLK_I2C8_PMU: 867 rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(8), 868 I2C_PMUCLK_REG_VALUE(8, src_clk_div)); 869 break; 870 default: 871 printf("do not support this i2c bus\n"); 872 return -EINVAL; 873 } 874 875 return DIV_TO_RATE(PPLL_HZ, src_clk_div); 876 } 877 878 static ulong rk3399_pwm_get_clk(struct rk3399_pmucru *pmucru) 879 { 880 u32 div, con; 881 882 /* PWM closk rate is same as pclk_pmu */ 883 con = readl(&pmucru->pmucru_clksel[0]); 884 div = con & PMU_PCLK_DIV_CON_MASK; 885 886 return DIV_TO_RATE(PPLL_HZ, div); 887 } 888 889 static ulong rk3399_pmuclk_get_rate(struct clk *clk) 890 { 891 struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev); 892 ulong rate = 0; 893 894 switch (clk->id) { 895 case PCLK_RKPWM_PMU: 896 rate = rk3399_pwm_get_clk(priv->pmucru); 897 break; 898 case SCLK_I2C0_PMU: 899 case SCLK_I2C4_PMU: 900 case SCLK_I2C8_PMU: 901 rate = rk3399_i2c_get_pmuclk(priv->pmucru, clk->id); 902 break; 903 default: 904 return -ENOENT; 905 } 906 907 return rate; 908 } 909 910 static ulong rk3399_pmuclk_set_rate(struct clk *clk, ulong rate) 911 { 912 struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev); 913 ulong ret = 0; 914 915 switch (clk->id) { 916 case SCLK_I2C0_PMU: 917 case SCLK_I2C4_PMU: 918 case SCLK_I2C8_PMU: 919 ret = rk3399_i2c_set_pmuclk(priv->pmucru, clk->id, rate); 920 break; 921 default: 922 return -ENOENT; 923 } 924 925 return ret; 926 } 927 928 static struct clk_ops rk3399_pmuclk_ops = { 929 .get_rate = rk3399_pmuclk_get_rate, 930 .set_rate = rk3399_pmuclk_set_rate, 931 }; 932 933 static void pmuclk_init(struct rk3399_pmucru *pmucru) 934 { 935 u32 pclk_div; 936 937 /* configure pmu pll(ppll) */ 938 rkclk_set_pll(&pmucru->ppll_con[0], &ppll_init_cfg); 939 940 /* configure pmu pclk */ 941 pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1; 942 assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f); 943 rk_clrsetreg(&pmucru->pmucru_clksel[0], 944 PMU_PCLK_DIV_CON_MASK, 945 pclk_div << PMU_PCLK_DIV_CON_SHIFT); 946 } 947 948 static int rk3399_pmuclk_probe(struct udevice *dev) 949 { 950 struct rk3399_pmuclk_priv *priv = dev_get_priv(dev); 951 952 pmuclk_init(priv->pmucru); 953 954 return 0; 955 } 956 957 static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev) 958 { 959 struct rk3399_pmuclk_priv *priv = dev_get_priv(dev); 960 961 priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev); 962 963 return 0; 964 } 965 966 static const struct udevice_id rk3399_pmuclk_ids[] = { 967 { .compatible = "rockchip,rk3399-pmucru" }, 968 { } 969 }; 970 971 U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = { 972 .name = "pmuclk_rk3399", 973 .id = UCLASS_CLK, 974 .of_match = rk3399_pmuclk_ids, 975 .priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv), 976 .ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata, 977 .ops = &rk3399_pmuclk_ops, 978 .probe = rk3399_pmuclk_probe, 979 }; 980