1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <bitfield.h> 9 #include <clk-uclass.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <syscon.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/cru_rk3328.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/arch/grf_rk3328.h> 17 #include <asm/io.h> 18 #include <dm/lists.h> 19 #include <dt-bindings/clock/rk3328-cru.h> 20 21 struct pll_div { 22 u32 refdiv; 23 u32 fbdiv; 24 u32 postdiv1; 25 u32 postdiv2; 26 u32 frac; 27 }; 28 29 #define RATE_TO_DIV(input_rate, output_rate) \ 30 ((input_rate) / (output_rate) - 1); 31 #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 32 33 #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 34 .refdiv = _refdiv,\ 35 .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 36 .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; 37 38 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1); 39 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1); 40 41 static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1); 42 static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1); 43 44 static const struct pll_div *apll_cfgs[] = { 45 [APLL_816_MHZ] = &apll_816_cfg, 46 [APLL_600_MHZ] = &apll_600_cfg, 47 }; 48 49 enum { 50 /* PLL_CON0 */ 51 PLL_POSTDIV1_SHIFT = 12, 52 PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, 53 PLL_FBDIV_SHIFT = 0, 54 PLL_FBDIV_MASK = 0xfff, 55 56 /* PLL_CON1 */ 57 PLL_DSMPD_SHIFT = 12, 58 PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, 59 PLL_INTEGER_MODE = 1, 60 PLL_LOCK_STATUS_SHIFT = 10, 61 PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, 62 PLL_POSTDIV2_SHIFT = 6, 63 PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, 64 PLL_REFDIV_SHIFT = 0, 65 PLL_REFDIV_MASK = 0x3f, 66 67 /* PLL_CON2 */ 68 PLL_FRACDIV_SHIFT = 0, 69 PLL_FRACDIV_MASK = 0xffffff, 70 71 /* MODE_CON */ 72 APLL_MODE_SHIFT = 0, 73 NPLL_MODE_SHIFT = 1, 74 DPLL_MODE_SHIFT = 4, 75 CPLL_MODE_SHIFT = 8, 76 GPLL_MODE_SHIFT = 12, 77 PLL_MODE_SLOW = 0, 78 PLL_MODE_NORM, 79 80 /* CLKSEL_CON0 */ 81 CLK_CORE_PLL_SEL_APLL = 0, 82 CLK_CORE_PLL_SEL_GPLL, 83 CLK_CORE_PLL_SEL_DPLL, 84 CLK_CORE_PLL_SEL_NPLL, 85 CLK_CORE_PLL_SEL_SHIFT = 6, 86 CLK_CORE_PLL_SEL_MASK = 3 << CLK_CORE_PLL_SEL_SHIFT, 87 CLK_CORE_DIV_SHIFT = 0, 88 CLK_CORE_DIV_MASK = 0x1f, 89 90 /* CLKSEL_CON1 */ 91 ACLKM_CORE_DIV_SHIFT = 4, 92 ACLKM_CORE_DIV_MASK = 0x7 << ACLKM_CORE_DIV_SHIFT, 93 PCLK_DBG_DIV_SHIFT = 0, 94 PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, 95 96 /* CLKSEL_CON27 */ 97 GMAC2IO_PLL_SEL_SHIFT = 7, 98 GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, 99 GMAC2IO_PLL_SEL_CPLL = 0, 100 GMAC2IO_PLL_SEL_GPLL = 1, 101 GMAC2IO_CLK_DIV_MASK = 0x1f, 102 GMAC2IO_CLK_DIV_SHIFT = 0, 103 104 /* CLKSEL_CON28 */ 105 ACLK_PERIHP_PLL_SEL_CPLL = 0, 106 ACLK_PERIHP_PLL_SEL_GPLL, 107 ACLK_PERIHP_PLL_SEL_HDMIPHY, 108 ACLK_PERIHP_PLL_SEL_SHIFT = 6, 109 ACLK_PERIHP_PLL_SEL_MASK = 3 << ACLK_PERIHP_PLL_SEL_SHIFT, 110 ACLK_PERIHP_DIV_CON_SHIFT = 0, 111 ACLK_PERIHP_DIV_CON_MASK = 0x1f, 112 113 /* CLKSEL_CON29 */ 114 PCLK_PERIHP_DIV_CON_SHIFT = 4, 115 PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, 116 HCLK_PERIHP_DIV_CON_SHIFT = 0, 117 HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, 118 119 /* CLKSEL_CON22 */ 120 CLK_TSADC_DIV_CON_SHIFT = 0, 121 CLK_TSADC_DIV_CON_MASK = 0x3ff, 122 123 /* CLKSEL_CON23 */ 124 CLK_SARADC_DIV_CON_SHIFT = 0, 125 CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), 126 CLK_SARADC_DIV_CON_WIDTH = 10, 127 128 /* CLKSEL_CON24 */ 129 CLK_PWM_PLL_SEL_CPLL = 0, 130 CLK_PWM_PLL_SEL_GPLL, 131 CLK_PWM_PLL_SEL_SHIFT = 15, 132 CLK_PWM_PLL_SEL_MASK = 1 << CLK_PWM_PLL_SEL_SHIFT, 133 CLK_PWM_DIV_CON_SHIFT = 8, 134 CLK_PWM_DIV_CON_MASK = 0x7f << CLK_PWM_DIV_CON_SHIFT, 135 136 CLK_SPI_PLL_SEL_CPLL = 0, 137 CLK_SPI_PLL_SEL_GPLL, 138 CLK_SPI_PLL_SEL_SHIFT = 7, 139 CLK_SPI_PLL_SEL_MASK = 1 << CLK_SPI_PLL_SEL_SHIFT, 140 CLK_SPI_DIV_CON_SHIFT = 0, 141 CLK_SPI_DIV_CON_MASK = 0x7f << CLK_SPI_DIV_CON_SHIFT, 142 143 /* CLKSEL_CON30 */ 144 CLK_SDMMC_PLL_SEL_CPLL = 0, 145 CLK_SDMMC_PLL_SEL_GPLL, 146 CLK_SDMMC_PLL_SEL_24M, 147 CLK_SDMMC_PLL_SEL_USBPHY, 148 CLK_SDMMC_PLL_SHIFT = 8, 149 CLK_SDMMC_PLL_MASK = 0x3 << CLK_SDMMC_PLL_SHIFT, 150 CLK_SDMMC_DIV_CON_SHIFT = 0, 151 CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT, 152 153 /* CLKSEL_CON32 */ 154 CLK_EMMC_PLL_SEL_CPLL = 0, 155 CLK_EMMC_PLL_SEL_GPLL, 156 CLK_EMMC_PLL_SEL_24M, 157 CLK_EMMC_PLL_SEL_USBPHY, 158 CLK_EMMC_PLL_SHIFT = 8, 159 CLK_EMMC_PLL_MASK = 0x3 << CLK_EMMC_PLL_SHIFT, 160 CLK_EMMC_DIV_CON_SHIFT = 0, 161 CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT, 162 163 /* CLKSEL_CON34 */ 164 CLK_I2C_PLL_SEL_CPLL = 0, 165 CLK_I2C_PLL_SEL_GPLL, 166 CLK_I2C_DIV_CON_MASK = 0x7f, 167 CLK_I2C_PLL_SEL_MASK = 1, 168 CLK_I2C1_PLL_SEL_SHIFT = 15, 169 CLK_I2C1_DIV_CON_SHIFT = 8, 170 CLK_I2C0_PLL_SEL_SHIFT = 7, 171 CLK_I2C0_DIV_CON_SHIFT = 0, 172 173 /* CLKSEL_CON35 */ 174 CLK_I2C3_PLL_SEL_SHIFT = 15, 175 CLK_I2C3_DIV_CON_SHIFT = 8, 176 CLK_I2C2_PLL_SEL_SHIFT = 7, 177 CLK_I2C2_DIV_CON_SHIFT = 0, 178 }; 179 180 #define VCO_MAX_KHZ (3200 * (MHz / KHz)) 181 #define VCO_MIN_KHZ (800 * (MHz / KHz)) 182 #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) 183 #define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) 184 185 /* 186 * the div restructions of pll in integer mode, these are defined in 187 * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 188 */ 189 #define PLL_DIV_MIN 16 190 #define PLL_DIV_MAX 3200 191 192 /* 193 * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 194 * Formulas also embedded within the Fractional PLL Verilog model: 195 * If DSMPD = 1 (DSM is disabled, "integer mode") 196 * FOUTVCO = FREF / REFDIV * FBDIV 197 * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 198 * Where: 199 * FOUTVCO = Fractional PLL non-divided output frequency 200 * FOUTPOSTDIV = Fractional PLL divided output frequency 201 * (output of second post divider) 202 * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 203 * REFDIV = Fractional PLL input reference clock divider 204 * FBDIV = Integer value programmed into feedback divide 205 * 206 */ 207 static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id, 208 const struct pll_div *div) 209 { 210 u32 *pll_con; 211 u32 mode_shift, mode_mask; 212 213 pll_con = NULL; 214 mode_shift = 0; 215 switch (clk_id) { 216 case CLK_ARM: 217 pll_con = cru->apll_con; 218 mode_shift = APLL_MODE_SHIFT; 219 break; 220 case CLK_DDR: 221 pll_con = cru->dpll_con; 222 mode_shift = DPLL_MODE_SHIFT; 223 break; 224 case CLK_CODEC: 225 pll_con = cru->cpll_con; 226 mode_shift = CPLL_MODE_SHIFT; 227 break; 228 case CLK_GENERAL: 229 pll_con = cru->gpll_con; 230 mode_shift = GPLL_MODE_SHIFT; 231 break; 232 case CLK_NEW: 233 pll_con = cru->npll_con; 234 mode_shift = NPLL_MODE_SHIFT; 235 break; 236 default: 237 break; 238 } 239 mode_mask = 1 << mode_shift; 240 241 /* All 8 PLLs have same VCO and output frequency range restrictions. */ 242 u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; 243 u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; 244 245 debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \ 246 postdiv2=%d, vco=%u khz, output=%u khz\n", 247 pll_con, div->fbdiv, div->refdiv, div->postdiv1, 248 div->postdiv2, vco_khz, output_khz); 249 assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && 250 output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && 251 div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); 252 253 /* 254 * When power on or changing PLL setting, 255 * we must force PLL into slow mode to ensure output stable clock. 256 */ 257 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift); 258 259 /* use integer mode */ 260 rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK, 261 PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); 262 263 rk_clrsetreg(&pll_con[0], 264 PLL_FBDIV_MASK | PLL_POSTDIV1_MASK, 265 (div->fbdiv << PLL_FBDIV_SHIFT) | 266 (div->postdiv1 << PLL_POSTDIV1_SHIFT)); 267 rk_clrsetreg(&pll_con[1], 268 PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, 269 (div->postdiv2 << PLL_POSTDIV2_SHIFT) | 270 (div->refdiv << PLL_REFDIV_SHIFT)); 271 272 /* waiting for pll lock */ 273 while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT))) 274 udelay(1); 275 276 /* pll enter normal mode */ 277 rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift); 278 } 279 280 static void rkclk_init(struct rk3328_cru *cru) 281 { 282 u32 aclk_div; 283 u32 hclk_div; 284 u32 pclk_div; 285 286 /* configure gpll cpll */ 287 rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); 288 rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); 289 290 /* configure perihp aclk, hclk, pclk */ 291 aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; 292 hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; 293 pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; 294 295 rk_clrsetreg(&cru->clksel_con[28], 296 ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, 297 ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | 298 aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); 299 rk_clrsetreg(&cru->clksel_con[29], 300 PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK, 301 pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | 302 hclk_div << HCLK_PERIHP_DIV_CON_SHIFT); 303 } 304 305 void rk3328_configure_cpu(struct rk3328_cru *cru, 306 enum apll_frequencies apll_freq) 307 { 308 u32 clk_core_div; 309 u32 aclkm_div; 310 u32 pclk_dbg_div; 311 312 rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]); 313 314 clk_core_div = APLL_HZ / CLK_CORE_HZ - 1; 315 aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1; 316 pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1; 317 318 rk_clrsetreg(&cru->clksel_con[0], 319 CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK, 320 CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT | 321 clk_core_div << CLK_CORE_DIV_SHIFT); 322 323 rk_clrsetreg(&cru->clksel_con[1], 324 PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK, 325 pclk_dbg_div << PCLK_DBG_DIV_SHIFT | 326 aclkm_div << ACLKM_CORE_DIV_SHIFT); 327 } 328 329 330 static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id) 331 { 332 u32 div, con; 333 334 switch (clk_id) { 335 case SCLK_I2C0: 336 con = readl(&cru->clksel_con[34]); 337 div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 338 break; 339 case SCLK_I2C1: 340 con = readl(&cru->clksel_con[34]); 341 div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 342 break; 343 case SCLK_I2C2: 344 con = readl(&cru->clksel_con[35]); 345 div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 346 break; 347 case SCLK_I2C3: 348 con = readl(&cru->clksel_con[35]); 349 div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 350 break; 351 default: 352 printf("do not support this i2c bus\n"); 353 return -EINVAL; 354 } 355 356 return DIV_TO_RATE(GPLL_HZ, div); 357 } 358 359 static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz) 360 { 361 int src_clk_div; 362 363 src_clk_div = GPLL_HZ / hz; 364 assert(src_clk_div - 1 < 127); 365 366 switch (clk_id) { 367 case SCLK_I2C0: 368 rk_clrsetreg(&cru->clksel_con[34], 369 CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | 370 CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, 371 (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 372 CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); 373 break; 374 case SCLK_I2C1: 375 rk_clrsetreg(&cru->clksel_con[34], 376 CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | 377 CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, 378 (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 379 CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 380 break; 381 case SCLK_I2C2: 382 rk_clrsetreg(&cru->clksel_con[35], 383 CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | 384 CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, 385 (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 386 CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 387 break; 388 case SCLK_I2C3: 389 rk_clrsetreg(&cru->clksel_con[35], 390 CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | 391 CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, 392 (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 393 CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 394 break; 395 default: 396 printf("do not support this i2c bus\n"); 397 return -EINVAL; 398 } 399 400 return DIV_TO_RATE(GPLL_HZ, src_clk_div); 401 } 402 403 static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) 404 { 405 struct rk3328_grf_regs *grf; 406 ulong ret; 407 408 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 409 410 /* 411 * The RGMII CLK can be derived either from an external "clkin" 412 * or can be generated from internally by a divider from SCLK_MAC. 413 */ 414 if (readl(&grf->mac_con[1]) & BIT(10) && 415 readl(&grf->soc_con[4]) & BIT(14)) { 416 /* An external clock will always generate the right rate... */ 417 ret = rate; 418 } else { 419 u32 con = readl(&cru->clksel_con[27]); 420 ulong pll_rate; 421 u8 div; 422 423 if ((con >> GMAC2IO_PLL_SEL_SHIFT) & GMAC2IO_PLL_SEL_GPLL) 424 pll_rate = GPLL_HZ; 425 else 426 pll_rate = CPLL_HZ; 427 428 div = DIV_ROUND_UP(pll_rate, rate) - 1; 429 if (div <= 0x1f) 430 rk_clrsetreg(&cru->clksel_con[27], GMAC2IO_CLK_DIV_MASK, 431 div << GMAC2IO_CLK_DIV_SHIFT); 432 else 433 debug("Unsupported div for gmac:%d\n", div); 434 435 return DIV_TO_RATE(pll_rate, div); 436 } 437 438 return ret; 439 } 440 441 static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) 442 { 443 u32 div, con, con_id; 444 445 switch (clk_id) { 446 case HCLK_SDMMC: 447 case SCLK_SDMMC: 448 con_id = 30; 449 break; 450 case HCLK_EMMC: 451 case SCLK_EMMC: 452 con_id = 32; 453 break; 454 default: 455 return -EINVAL; 456 } 457 con = readl(&cru->clksel_con[con_id]); 458 div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 459 460 if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 461 == CLK_EMMC_PLL_SEL_24M) 462 return DIV_TO_RATE(OSC_HZ, div) / 2; 463 else 464 return DIV_TO_RATE(GPLL_HZ, div) / 2; 465 } 466 467 static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru, 468 ulong clk_id, ulong set_rate) 469 { 470 int src_clk_div; 471 u32 con_id; 472 473 switch (clk_id) { 474 case HCLK_SDMMC: 475 case SCLK_SDMMC: 476 con_id = 30; 477 break; 478 case HCLK_EMMC: 479 case SCLK_EMMC: 480 con_id = 32; 481 break; 482 default: 483 return -EINVAL; 484 } 485 /* Select clk_sdmmc/emmc source from GPLL by default */ 486 /* mmc clock defaulg div 2 internal, need provide double in cru */ 487 src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); 488 489 if (src_clk_div > 127) { 490 /* use 24MHz source for 400KHz clock */ 491 src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); 492 rk_clrsetreg(&cru->clksel_con[con_id], 493 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 494 CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 495 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 496 } else { 497 rk_clrsetreg(&cru->clksel_con[con_id], 498 CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 499 CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 500 (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 501 } 502 503 return rk3328_mmc_get_clk(cru, clk_id); 504 } 505 506 static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru) 507 { 508 u32 div, con; 509 510 con = readl(&cru->clksel_con[24]); 511 div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; 512 513 return DIV_TO_RATE(GPLL_HZ, div); 514 } 515 516 static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz) 517 { 518 u32 div = GPLL_HZ / hz; 519 520 rk_clrsetreg(&cru->clksel_con[24], 521 CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 522 CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT | 523 (div - 1) << CLK_PWM_DIV_CON_SHIFT); 524 525 return DIV_TO_RATE(GPLL_HZ, div); 526 } 527 528 static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru) 529 { 530 u32 div, val; 531 532 val = readl(&cru->clksel_con[23]); 533 div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT, 534 CLK_SARADC_DIV_CON_WIDTH); 535 536 return DIV_TO_RATE(OSC_HZ, div); 537 } 538 539 static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz) 540 { 541 int src_clk_div; 542 543 src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; 544 assert(src_clk_div < 128); 545 546 rk_clrsetreg(&cru->clksel_con[23], 547 CLK_SARADC_DIV_CON_MASK, 548 src_clk_div << CLK_SARADC_DIV_CON_SHIFT); 549 550 return rk3328_saradc_get_clk(cru); 551 } 552 553 static ulong rk3328_clk_get_rate(struct clk *clk) 554 { 555 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 556 ulong rate = 0; 557 558 switch (clk->id) { 559 case 0 ... 29: 560 return 0; 561 case HCLK_SDMMC: 562 case HCLK_EMMC: 563 case SCLK_SDMMC: 564 case SCLK_EMMC: 565 rate = rk3328_mmc_get_clk(priv->cru, clk->id); 566 break; 567 case SCLK_I2C0: 568 case SCLK_I2C1: 569 case SCLK_I2C2: 570 case SCLK_I2C3: 571 rate = rk3328_i2c_get_clk(priv->cru, clk->id); 572 break; 573 case SCLK_PWM: 574 rate = rk3328_pwm_get_clk(priv->cru); 575 break; 576 case SCLK_SARADC: 577 rate = rk3328_saradc_get_clk(priv->cru); 578 break; 579 default: 580 return -ENOENT; 581 } 582 583 return rate; 584 } 585 586 static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 587 { 588 struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 589 ulong ret = 0; 590 591 switch (clk->id) { 592 case 0 ... 29: 593 return 0; 594 case HCLK_SDMMC: 595 case HCLK_EMMC: 596 case SCLK_SDMMC: 597 case SCLK_EMMC: 598 ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate); 599 break; 600 case SCLK_I2C0: 601 case SCLK_I2C1: 602 case SCLK_I2C2: 603 case SCLK_I2C3: 604 ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate); 605 break; 606 case SCLK_MAC2IO: 607 ret = rk3328_gmac2io_set_clk(priv->cru, rate); 608 break; 609 case SCLK_PWM: 610 ret = rk3328_pwm_set_clk(priv->cru, rate); 611 break; 612 case SCLK_SARADC: 613 ret = rk3328_saradc_set_clk(priv->cru, rate); 614 break; 615 case DCLK_LCDC: 616 case SCLK_PDM: 617 case SCLK_RTC32K: 618 case SCLK_UART0: 619 case SCLK_UART1: 620 case SCLK_UART2: 621 case SCLK_SDIO: 622 case SCLK_TSP: 623 case SCLK_WIFI: 624 case ACLK_BUS_PRE: 625 case HCLK_BUS_PRE: 626 case PCLK_BUS_PRE: 627 case ACLK_PERI_PRE: 628 case HCLK_PERI: 629 case PCLK_PERI: 630 case ACLK_VIO_PRE: 631 case HCLK_VIO_PRE: 632 case ACLK_RGA_PRE: 633 case SCLK_RGA: 634 case ACLK_VOP_PRE: 635 case ACLK_RKVDEC_PRE: 636 case ACLK_RKVENC: 637 case ACLK_VPU_PRE: 638 case SCLK_VDEC_CABAC: 639 case SCLK_VDEC_CORE: 640 case SCLK_VENC_CORE: 641 case SCLK_VENC_DSP: 642 case SCLK_EFUSE: 643 case PCLK_DDR: 644 case ACLK_GMAC: 645 case PCLK_GMAC: 646 case SCLK_USB3OTG_SUSPEND: 647 return 0; 648 default: 649 return -ENOENT; 650 } 651 652 return ret; 653 } 654 655 static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) 656 { 657 struct rk3328_grf_regs *grf; 658 const char *clock_output_name; 659 int ret; 660 661 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 662 663 /* 664 * If the requested parent is in the same clock-controller and the id 665 * is SCLK_MAC2IO_SRC ("clk_mac2io_src"), switch to the internal clock. 666 */ 667 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO_SRC)) { 668 debug("%s: switching RGMII to SCLK_MAC2IO_SRC\n", __func__); 669 rk_clrreg(&grf->mac_con[1], BIT(10)); 670 return 0; 671 } 672 673 /* 674 * Otherwise, we need to check the clock-output-names of the 675 * requested parent to see if the requested id is "gmac_clkin". 676 */ 677 ret = dev_read_string_index(parent->dev, "clock-output-names", 678 parent->id, &clock_output_name); 679 if (ret < 0) 680 return -ENODATA; 681 682 /* If this is "gmac_clkin", switch to the external clock input */ 683 if (!strcmp(clock_output_name, "gmac_clkin")) { 684 debug("%s: switching RGMII to CLKIN\n", __func__); 685 rk_setreg(&grf->mac_con[1], BIT(10)); 686 return 0; 687 } 688 689 return -EINVAL; 690 } 691 692 static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) 693 { 694 struct rk3328_grf_regs *grf; 695 const char *clock_output_name; 696 int ret; 697 698 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 699 700 /* 701 * If the requested parent is in the same clock-controller and the id 702 * is SCLK_MAC2IO ("clk_mac2io"), switch to the internal clock. 703 */ 704 if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2IO)) { 705 debug("%s: switching RGMII to SCLK_MAC2IO\n", __func__); 706 rk_clrreg(&grf->soc_con[4], BIT(14)); 707 return 0; 708 } 709 710 /* 711 * Otherwise, we need to check the clock-output-names of the 712 * requested parent to see if the requested id is "gmac_clkin". 713 */ 714 ret = dev_read_string_index(parent->dev, "clock-output-names", 715 parent->id, &clock_output_name); 716 if (ret < 0) 717 return -ENODATA; 718 719 /* If this is "gmac_clkin", switch to the external clock input */ 720 if (!strcmp(clock_output_name, "gmac_clkin")) { 721 debug("%s: switching RGMII to CLKIN\n", __func__); 722 rk_setreg(&grf->soc_con[4], BIT(14)); 723 return 0; 724 } 725 726 return -EINVAL; 727 } 728 729 static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) 730 { 731 switch (clk->id) { 732 case SCLK_MAC2IO: 733 return rk3328_gmac2io_set_parent(clk, parent); 734 case SCLK_MAC2IO_EXT: 735 return rk3328_gmac2io_ext_set_parent(clk, parent); 736 case DCLK_LCDC: 737 case SCLK_PDM: 738 case SCLK_RTC32K: 739 case SCLK_UART0: 740 case SCLK_UART1: 741 case SCLK_UART2: 742 return 0; 743 } 744 745 debug("%s: unsupported clk %ld\n", __func__, clk->id); 746 return -ENOENT; 747 } 748 749 static struct clk_ops rk3328_clk_ops = { 750 .get_rate = rk3328_clk_get_rate, 751 .set_rate = rk3328_clk_set_rate, 752 .set_parent = rk3328_clk_set_parent, 753 }; 754 755 static int rk3328_clk_probe(struct udevice *dev) 756 { 757 struct rk3328_clk_priv *priv = dev_get_priv(dev); 758 759 rkclk_init(priv->cru); 760 761 return 0; 762 } 763 764 static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 765 { 766 struct rk3328_clk_priv *priv = dev_get_priv(dev); 767 768 priv->cru = dev_read_addr_ptr(dev); 769 770 return 0; 771 } 772 773 static int rk3328_clk_bind(struct udevice *dev) 774 { 775 int ret; 776 struct udevice *sys_child; 777 struct sysreset_reg *priv; 778 779 /* The reset driver does not have a device node, so bind it here */ 780 ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", 781 &sys_child); 782 if (ret) { 783 debug("Warning: No sysreset driver: ret=%d\n", ret); 784 } else { 785 priv = malloc(sizeof(struct sysreset_reg)); 786 priv->glb_srst_fst_value = offsetof(struct rk3328_cru, 787 glb_srst_fst_value); 788 priv->glb_srst_snd_value = offsetof(struct rk3328_cru, 789 glb_srst_snd_value); 790 sys_child->priv = priv; 791 } 792 793 #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP) 794 ret = offsetof(struct rk3328_cru, softrst_con[0]); 795 ret = rockchip_reset_bind(dev, ret, 12); 796 if (ret) 797 debug("Warning: software reset driver bind faile\n"); 798 #endif 799 800 return ret; 801 } 802 803 static const struct udevice_id rk3328_clk_ids[] = { 804 { .compatible = "rockchip,rk3328-cru" }, 805 { } 806 }; 807 808 U_BOOT_DRIVER(rockchip_rk3328_cru) = { 809 .name = "rockchip_rk3328_cru", 810 .id = UCLASS_CLK, 811 .of_match = rk3328_clk_ids, 812 .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 813 .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 814 .ops = &rk3328_clk_ops, 815 .bind = rk3328_clk_bind, 816 .probe = rk3328_clk_probe, 817 }; 818