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