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