1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2010 Samsung Electronics 4 * Minkyu Kang <mk7.kang@samsung.com> 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <asm/arch/clock.h> 10 #include <asm/arch/clk.h> 11 #include <asm/arch/periph.h> 12 13 #define PLL_DIV_1024 1024 14 #define PLL_DIV_65535 65535 15 #define PLL_DIV_65536 65536 16 /* * 17 * This structure is to store the src bit, div bit and prediv bit 18 * positions of the peripheral clocks of the src and div registers 19 */ 20 struct clk_bit_info { 21 enum periph_id id; 22 int32_t src_mask; 23 int32_t div_mask; 24 int32_t prediv_mask; 25 int8_t src_bit; 26 int8_t div_bit; 27 int8_t prediv_bit; 28 }; 29 30 static struct clk_bit_info exynos5_bit_info[] = { 31 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ 32 {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1}, 33 {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1}, 34 {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1}, 35 {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1}, 36 {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0}, 37 {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0}, 38 {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0}, 39 {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0}, 40 {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0}, 41 {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0}, 42 {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0}, 43 {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0}, 44 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8}, 45 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24}, 46 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8}, 47 {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8}, 48 {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24}, 49 {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8}, 50 {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24}, 51 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, 52 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, 53 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4}, 54 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16}, 55 {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8}, 56 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1}, 57 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1}, 58 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1}, 59 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1}, 60 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1}, 61 62 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, 63 }; 64 65 static struct clk_bit_info exynos542x_bit_info[] = { 66 /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ 67 {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1}, 68 {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1}, 69 {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1}, 70 {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1}, 71 {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1}, 72 {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1}, 73 {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1}, 74 {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1}, 75 {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1}, 76 {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1}, 77 {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1}, 78 {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1}, 79 {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8}, 80 {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16}, 81 {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24}, 82 {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1}, 83 {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1}, 84 {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1}, 85 {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1}, 86 {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1}, 87 {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, 88 {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, 89 {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0}, 90 {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8}, 91 {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1}, 92 {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1}, 93 {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1}, 94 {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1}, 95 {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1}, 96 {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1}, 97 98 {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, 99 }; 100 101 /* Epll Clock division values to achive different frequency output */ 102 static struct set_epll_con_val exynos5_epll_div[] = { 103 { 192000000, 0, 48, 3, 1, 0 }, 104 { 180000000, 0, 45, 3, 1, 0 }, 105 { 73728000, 1, 73, 3, 3, 47710 }, 106 { 67737600, 1, 90, 4, 3, 20762 }, 107 { 49152000, 0, 49, 3, 3, 9961 }, 108 { 45158400, 0, 45, 3, 3, 10381 }, 109 { 180633600, 0, 45, 3, 1, 10381 } 110 }; 111 112 /* exynos: return pll clock frequency */ 113 static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k) 114 { 115 unsigned long m, p, s = 0, mask, fout; 116 unsigned int div; 117 unsigned int freq; 118 /* 119 * APLL_CON: MIDV [25:16] 120 * MPLL_CON: MIDV [25:16] 121 * EPLL_CON: MIDV [24:16] 122 * VPLL_CON: MIDV [24:16] 123 * BPLL_CON: MIDV [25:16]: Exynos5 124 */ 125 if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL || 126 pllreg == SPLL) 127 mask = 0x3ff; 128 else 129 mask = 0x1ff; 130 131 m = (r >> 16) & mask; 132 133 /* PDIV [13:8] */ 134 p = (r >> 8) & 0x3f; 135 /* SDIV [2:0] */ 136 s = r & 0x7; 137 138 freq = CONFIG_SYS_CLK_FREQ; 139 140 if (pllreg == EPLL || pllreg == RPLL) { 141 k = k & 0xffff; 142 /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ 143 fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s))); 144 } else if (pllreg == VPLL) { 145 k = k & 0xfff; 146 147 /* 148 * Exynos4210 149 * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) 150 * 151 * Exynos4412 152 * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV) 153 * 154 * Exynos5250 155 * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) 156 */ 157 if (proid_is_exynos4210()) 158 div = PLL_DIV_1024; 159 else if (proid_is_exynos4412()) 160 div = PLL_DIV_65535; 161 else if (proid_is_exynos5250() || proid_is_exynos5420() || 162 proid_is_exynos5422()) 163 div = PLL_DIV_65536; 164 else 165 return 0; 166 167 fout = (m + k / div) * (freq / (p * (1 << s))); 168 } else { 169 /* 170 * Exynos4412 / Exynos5250 171 * FOUT = MDIV * FIN / (PDIV * 2^SDIV) 172 * 173 * Exynos4210 174 * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1)) 175 */ 176 if (proid_is_exynos4210()) 177 fout = m * (freq / (p * (1 << (s - 1)))); 178 else 179 fout = m * (freq / (p * (1 << s))); 180 } 181 return fout; 182 } 183 184 /* exynos4: return pll clock frequency */ 185 static unsigned long exynos4_get_pll_clk(int pllreg) 186 { 187 struct exynos4_clock *clk = 188 (struct exynos4_clock *)samsung_get_base_clock(); 189 unsigned long r, k = 0; 190 191 switch (pllreg) { 192 case APLL: 193 r = readl(&clk->apll_con0); 194 break; 195 case MPLL: 196 r = readl(&clk->mpll_con0); 197 break; 198 case EPLL: 199 r = readl(&clk->epll_con0); 200 k = readl(&clk->epll_con1); 201 break; 202 case VPLL: 203 r = readl(&clk->vpll_con0); 204 k = readl(&clk->vpll_con1); 205 break; 206 default: 207 printf("Unsupported PLL (%d)\n", pllreg); 208 return 0; 209 } 210 211 return exynos_get_pll_clk(pllreg, r, k); 212 } 213 214 /* exynos4x12: return pll clock frequency */ 215 static unsigned long exynos4x12_get_pll_clk(int pllreg) 216 { 217 struct exynos4x12_clock *clk = 218 (struct exynos4x12_clock *)samsung_get_base_clock(); 219 unsigned long r, k = 0; 220 221 switch (pllreg) { 222 case APLL: 223 r = readl(&clk->apll_con0); 224 break; 225 case MPLL: 226 r = readl(&clk->mpll_con0); 227 break; 228 case EPLL: 229 r = readl(&clk->epll_con0); 230 k = readl(&clk->epll_con1); 231 break; 232 case VPLL: 233 r = readl(&clk->vpll_con0); 234 k = readl(&clk->vpll_con1); 235 break; 236 default: 237 printf("Unsupported PLL (%d)\n", pllreg); 238 return 0; 239 } 240 241 return exynos_get_pll_clk(pllreg, r, k); 242 } 243 244 /* exynos5: return pll clock frequency */ 245 static unsigned long exynos5_get_pll_clk(int pllreg) 246 { 247 struct exynos5_clock *clk = 248 (struct exynos5_clock *)samsung_get_base_clock(); 249 unsigned long r, k = 0, fout; 250 unsigned int pll_div2_sel, fout_sel; 251 252 switch (pllreg) { 253 case APLL: 254 r = readl(&clk->apll_con0); 255 break; 256 case MPLL: 257 r = readl(&clk->mpll_con0); 258 break; 259 case EPLL: 260 r = readl(&clk->epll_con0); 261 k = readl(&clk->epll_con1); 262 break; 263 case VPLL: 264 r = readl(&clk->vpll_con0); 265 k = readl(&clk->vpll_con1); 266 break; 267 case BPLL: 268 r = readl(&clk->bpll_con0); 269 break; 270 default: 271 printf("Unsupported PLL (%d)\n", pllreg); 272 return 0; 273 } 274 275 fout = exynos_get_pll_clk(pllreg, r, k); 276 277 /* According to the user manual, in EVT1 MPLL and BPLL always gives 278 * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ 279 if (pllreg == MPLL || pllreg == BPLL) { 280 pll_div2_sel = readl(&clk->pll_div2_sel); 281 282 switch (pllreg) { 283 case MPLL: 284 fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) 285 & MPLL_FOUT_SEL_MASK; 286 break; 287 case BPLL: 288 fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT) 289 & BPLL_FOUT_SEL_MASK; 290 break; 291 default: 292 fout_sel = -1; 293 break; 294 } 295 296 if (fout_sel == 0) 297 fout /= 2; 298 } 299 300 return fout; 301 } 302 303 /* exynos542x: return pll clock frequency */ 304 static unsigned long exynos542x_get_pll_clk(int pllreg) 305 { 306 struct exynos5420_clock *clk = 307 (struct exynos5420_clock *)samsung_get_base_clock(); 308 unsigned long r, k = 0; 309 310 switch (pllreg) { 311 case APLL: 312 r = readl(&clk->apll_con0); 313 break; 314 case MPLL: 315 r = readl(&clk->mpll_con0); 316 break; 317 case EPLL: 318 r = readl(&clk->epll_con0); 319 k = readl(&clk->epll_con1); 320 break; 321 case VPLL: 322 r = readl(&clk->vpll_con0); 323 k = readl(&clk->vpll_con1); 324 break; 325 case BPLL: 326 r = readl(&clk->bpll_con0); 327 break; 328 case RPLL: 329 r = readl(&clk->rpll_con0); 330 k = readl(&clk->rpll_con1); 331 break; 332 case SPLL: 333 r = readl(&clk->spll_con0); 334 break; 335 default: 336 printf("Unsupported PLL (%d)\n", pllreg); 337 return 0; 338 } 339 340 return exynos_get_pll_clk(pllreg, r, k); 341 } 342 343 static struct clk_bit_info *get_clk_bit_info(int peripheral) 344 { 345 int i; 346 struct clk_bit_info *info; 347 348 if (proid_is_exynos5420() || proid_is_exynos5422()) 349 info = exynos542x_bit_info; 350 else 351 info = exynos5_bit_info; 352 353 for (i = 0; info[i].id != PERIPH_ID_NONE; i++) { 354 if (info[i].id == peripheral) 355 break; 356 } 357 358 if (info[i].id == PERIPH_ID_NONE) 359 debug("ERROR: Peripheral ID %d not found\n", peripheral); 360 361 return &info[i]; 362 } 363 364 static unsigned long exynos5_get_periph_rate(int peripheral) 365 { 366 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); 367 unsigned long sclk = 0; 368 unsigned int src = 0, div = 0, sub_div = 0; 369 struct exynos5_clock *clk = 370 (struct exynos5_clock *)samsung_get_base_clock(); 371 372 switch (peripheral) { 373 case PERIPH_ID_UART0: 374 case PERIPH_ID_UART1: 375 case PERIPH_ID_UART2: 376 case PERIPH_ID_UART3: 377 src = readl(&clk->src_peric0); 378 div = readl(&clk->div_peric0); 379 break; 380 case PERIPH_ID_PWM0: 381 case PERIPH_ID_PWM1: 382 case PERIPH_ID_PWM2: 383 case PERIPH_ID_PWM3: 384 case PERIPH_ID_PWM4: 385 src = readl(&clk->src_peric0); 386 div = readl(&clk->div_peric3); 387 break; 388 case PERIPH_ID_I2S0: 389 src = readl(&clk->src_mau); 390 div = sub_div = readl(&clk->div_mau); 391 case PERIPH_ID_SPI0: 392 case PERIPH_ID_SPI1: 393 src = readl(&clk->src_peric1); 394 div = sub_div = readl(&clk->div_peric1); 395 break; 396 case PERIPH_ID_SPI2: 397 src = readl(&clk->src_peric1); 398 div = sub_div = readl(&clk->div_peric2); 399 break; 400 case PERIPH_ID_SPI3: 401 case PERIPH_ID_SPI4: 402 src = readl(&clk->sclk_src_isp); 403 div = sub_div = readl(&clk->sclk_div_isp); 404 break; 405 case PERIPH_ID_SDMMC0: 406 case PERIPH_ID_SDMMC1: 407 src = readl(&clk->src_fsys); 408 div = sub_div = readl(&clk->div_fsys1); 409 break; 410 case PERIPH_ID_SDMMC2: 411 case PERIPH_ID_SDMMC3: 412 src = readl(&clk->src_fsys); 413 div = sub_div = readl(&clk->div_fsys2); 414 break; 415 case PERIPH_ID_I2C0: 416 case PERIPH_ID_I2C1: 417 case PERIPH_ID_I2C2: 418 case PERIPH_ID_I2C3: 419 case PERIPH_ID_I2C4: 420 case PERIPH_ID_I2C5: 421 case PERIPH_ID_I2C6: 422 case PERIPH_ID_I2C7: 423 src = EXYNOS_SRC_MPLL; 424 div = readl(&clk->div_top1); 425 sub_div = readl(&clk->div_top0); 426 break; 427 default: 428 debug("%s: invalid peripheral %d", __func__, peripheral); 429 return -1; 430 }; 431 432 if (bit_info->src_bit >= 0) 433 src = (src >> bit_info->src_bit) & bit_info->src_mask; 434 435 switch (src) { 436 case EXYNOS_SRC_MPLL: 437 sclk = exynos5_get_pll_clk(MPLL); 438 break; 439 case EXYNOS_SRC_EPLL: 440 sclk = exynos5_get_pll_clk(EPLL); 441 break; 442 case EXYNOS_SRC_VPLL: 443 sclk = exynos5_get_pll_clk(VPLL); 444 break; 445 default: 446 debug("%s: EXYNOS_SRC %d not supported\n", __func__, src); 447 return 0; 448 } 449 450 /* Clock divider ratio for this peripheral */ 451 if (bit_info->div_bit >= 0) 452 div = (div >> bit_info->div_bit) & bit_info->div_mask; 453 454 /* Clock pre-divider ratio for this peripheral */ 455 if (bit_info->prediv_bit >= 0) 456 sub_div = (sub_div >> bit_info->prediv_bit) 457 & bit_info->prediv_mask; 458 459 /* Calculate and return required clock rate */ 460 return (sclk / (div + 1)) / (sub_div + 1); 461 } 462 463 static unsigned long exynos542x_get_periph_rate(int peripheral) 464 { 465 struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); 466 unsigned long sclk = 0; 467 unsigned int src = 0, div = 0, sub_div = 0; 468 struct exynos5420_clock *clk = 469 (struct exynos5420_clock *)samsung_get_base_clock(); 470 471 switch (peripheral) { 472 case PERIPH_ID_UART0: 473 case PERIPH_ID_UART1: 474 case PERIPH_ID_UART2: 475 case PERIPH_ID_UART3: 476 case PERIPH_ID_PWM0: 477 case PERIPH_ID_PWM1: 478 case PERIPH_ID_PWM2: 479 case PERIPH_ID_PWM3: 480 case PERIPH_ID_PWM4: 481 src = readl(&clk->src_peric0); 482 div = readl(&clk->div_peric0); 483 break; 484 case PERIPH_ID_SPI0: 485 case PERIPH_ID_SPI1: 486 case PERIPH_ID_SPI2: 487 src = readl(&clk->src_peric1); 488 div = readl(&clk->div_peric1); 489 sub_div = readl(&clk->div_peric4); 490 break; 491 case PERIPH_ID_SPI3: 492 case PERIPH_ID_SPI4: 493 src = readl(&clk->src_isp); 494 div = readl(&clk->div_isp1); 495 sub_div = readl(&clk->div_isp1); 496 break; 497 case PERIPH_ID_SDMMC0: 498 case PERIPH_ID_SDMMC1: 499 case PERIPH_ID_SDMMC2: 500 case PERIPH_ID_SDMMC3: 501 src = readl(&clk->src_fsys); 502 div = readl(&clk->div_fsys1); 503 break; 504 case PERIPH_ID_I2C0: 505 case PERIPH_ID_I2C1: 506 case PERIPH_ID_I2C2: 507 case PERIPH_ID_I2C3: 508 case PERIPH_ID_I2C4: 509 case PERIPH_ID_I2C5: 510 case PERIPH_ID_I2C6: 511 case PERIPH_ID_I2C7: 512 case PERIPH_ID_I2C8: 513 case PERIPH_ID_I2C9: 514 case PERIPH_ID_I2C10: 515 src = EXYNOS542X_SRC_MPLL; 516 div = readl(&clk->div_top1); 517 break; 518 default: 519 debug("%s: invalid peripheral %d", __func__, peripheral); 520 return -1; 521 }; 522 523 if (bit_info->src_bit >= 0) 524 src = (src >> bit_info->src_bit) & bit_info->src_mask; 525 526 switch (src) { 527 case EXYNOS542X_SRC_MPLL: 528 sclk = exynos542x_get_pll_clk(MPLL); 529 break; 530 case EXYNOS542X_SRC_SPLL: 531 sclk = exynos542x_get_pll_clk(SPLL); 532 break; 533 case EXYNOS542X_SRC_EPLL: 534 sclk = exynos542x_get_pll_clk(EPLL); 535 break; 536 case EXYNOS542X_SRC_RPLL: 537 sclk = exynos542x_get_pll_clk(RPLL); 538 break; 539 default: 540 debug("%s: EXYNOS542X_SRC %d not supported", __func__, src); 541 return 0; 542 } 543 544 /* Clock divider ratio for this peripheral */ 545 if (bit_info->div_bit >= 0) 546 div = (div >> bit_info->div_bit) & bit_info->div_mask; 547 548 /* Clock pre-divider ratio for this peripheral */ 549 if (bit_info->prediv_bit >= 0) 550 sub_div = (sub_div >> bit_info->prediv_bit) 551 & bit_info->prediv_mask; 552 553 /* Calculate and return required clock rate */ 554 return (sclk / (div + 1)) / (sub_div + 1); 555 } 556 557 unsigned long clock_get_periph_rate(int peripheral) 558 { 559 if (cpu_is_exynos5()) { 560 if (proid_is_exynos5420() || proid_is_exynos5422()) 561 return exynos542x_get_periph_rate(peripheral); 562 return exynos5_get_periph_rate(peripheral); 563 } else { 564 return 0; 565 } 566 } 567 568 /* exynos4: return ARM clock frequency */ 569 static unsigned long exynos4_get_arm_clk(void) 570 { 571 struct exynos4_clock *clk = 572 (struct exynos4_clock *)samsung_get_base_clock(); 573 unsigned long div; 574 unsigned long armclk; 575 unsigned int core_ratio; 576 unsigned int core2_ratio; 577 578 div = readl(&clk->div_cpu0); 579 580 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ 581 core_ratio = (div >> 0) & 0x7; 582 core2_ratio = (div >> 28) & 0x7; 583 584 armclk = get_pll_clk(APLL) / (core_ratio + 1); 585 armclk /= (core2_ratio + 1); 586 587 return armclk; 588 } 589 590 /* exynos4x12: return ARM clock frequency */ 591 static unsigned long exynos4x12_get_arm_clk(void) 592 { 593 struct exynos4x12_clock *clk = 594 (struct exynos4x12_clock *)samsung_get_base_clock(); 595 unsigned long div; 596 unsigned long armclk; 597 unsigned int core_ratio; 598 unsigned int core2_ratio; 599 600 div = readl(&clk->div_cpu0); 601 602 /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ 603 core_ratio = (div >> 0) & 0x7; 604 core2_ratio = (div >> 28) & 0x7; 605 606 armclk = get_pll_clk(APLL) / (core_ratio + 1); 607 armclk /= (core2_ratio + 1); 608 609 return armclk; 610 } 611 612 /* exynos5: return ARM clock frequency */ 613 static unsigned long exynos5_get_arm_clk(void) 614 { 615 struct exynos5_clock *clk = 616 (struct exynos5_clock *)samsung_get_base_clock(); 617 unsigned long div; 618 unsigned long armclk; 619 unsigned int arm_ratio; 620 unsigned int arm2_ratio; 621 622 div = readl(&clk->div_cpu0); 623 624 /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */ 625 arm_ratio = (div >> 0) & 0x7; 626 arm2_ratio = (div >> 28) & 0x7; 627 628 armclk = get_pll_clk(APLL) / (arm_ratio + 1); 629 armclk /= (arm2_ratio + 1); 630 631 return armclk; 632 } 633 634 /* exynos4: return pwm clock frequency */ 635 static unsigned long exynos4_get_pwm_clk(void) 636 { 637 struct exynos4_clock *clk = 638 (struct exynos4_clock *)samsung_get_base_clock(); 639 unsigned long pclk, sclk; 640 unsigned int sel; 641 unsigned int ratio; 642 643 if (s5p_get_cpu_rev() == 0) { 644 /* 645 * CLK_SRC_PERIL0 646 * PWM_SEL [27:24] 647 */ 648 sel = readl(&clk->src_peril0); 649 sel = (sel >> 24) & 0xf; 650 651 if (sel == 0x6) 652 sclk = get_pll_clk(MPLL); 653 else if (sel == 0x7) 654 sclk = get_pll_clk(EPLL); 655 else if (sel == 0x8) 656 sclk = get_pll_clk(VPLL); 657 else 658 return 0; 659 660 /* 661 * CLK_DIV_PERIL3 662 * PWM_RATIO [3:0] 663 */ 664 ratio = readl(&clk->div_peril3); 665 ratio = ratio & 0xf; 666 } else if (s5p_get_cpu_rev() == 1) { 667 sclk = get_pll_clk(MPLL); 668 ratio = 8; 669 } else 670 return 0; 671 672 pclk = sclk / (ratio + 1); 673 674 return pclk; 675 } 676 677 /* exynos4x12: return pwm clock frequency */ 678 static unsigned long exynos4x12_get_pwm_clk(void) 679 { 680 unsigned long pclk, sclk; 681 unsigned int ratio; 682 683 sclk = get_pll_clk(MPLL); 684 ratio = 8; 685 686 pclk = sclk / (ratio + 1); 687 688 return pclk; 689 } 690 691 /* exynos4: return uart clock frequency */ 692 static unsigned long exynos4_get_uart_clk(int dev_index) 693 { 694 struct exynos4_clock *clk = 695 (struct exynos4_clock *)samsung_get_base_clock(); 696 unsigned long uclk, sclk; 697 unsigned int sel; 698 unsigned int ratio; 699 700 /* 701 * CLK_SRC_PERIL0 702 * UART0_SEL [3:0] 703 * UART1_SEL [7:4] 704 * UART2_SEL [8:11] 705 * UART3_SEL [12:15] 706 * UART4_SEL [16:19] 707 * UART5_SEL [23:20] 708 */ 709 sel = readl(&clk->src_peril0); 710 sel = (sel >> (dev_index << 2)) & 0xf; 711 712 if (sel == 0x6) 713 sclk = get_pll_clk(MPLL); 714 else if (sel == 0x7) 715 sclk = get_pll_clk(EPLL); 716 else if (sel == 0x8) 717 sclk = get_pll_clk(VPLL); 718 else 719 return 0; 720 721 /* 722 * CLK_DIV_PERIL0 723 * UART0_RATIO [3:0] 724 * UART1_RATIO [7:4] 725 * UART2_RATIO [8:11] 726 * UART3_RATIO [12:15] 727 * UART4_RATIO [16:19] 728 * UART5_RATIO [23:20] 729 */ 730 ratio = readl(&clk->div_peril0); 731 ratio = (ratio >> (dev_index << 2)) & 0xf; 732 733 uclk = sclk / (ratio + 1); 734 735 return uclk; 736 } 737 738 /* exynos4x12: return uart clock frequency */ 739 static unsigned long exynos4x12_get_uart_clk(int dev_index) 740 { 741 struct exynos4x12_clock *clk = 742 (struct exynos4x12_clock *)samsung_get_base_clock(); 743 unsigned long uclk, sclk; 744 unsigned int sel; 745 unsigned int ratio; 746 747 /* 748 * CLK_SRC_PERIL0 749 * UART0_SEL [3:0] 750 * UART1_SEL [7:4] 751 * UART2_SEL [8:11] 752 * UART3_SEL [12:15] 753 * UART4_SEL [16:19] 754 */ 755 sel = readl(&clk->src_peril0); 756 sel = (sel >> (dev_index << 2)) & 0xf; 757 758 if (sel == 0x6) 759 sclk = get_pll_clk(MPLL); 760 else if (sel == 0x7) 761 sclk = get_pll_clk(EPLL); 762 else if (sel == 0x8) 763 sclk = get_pll_clk(VPLL); 764 else 765 return 0; 766 767 /* 768 * CLK_DIV_PERIL0 769 * UART0_RATIO [3:0] 770 * UART1_RATIO [7:4] 771 * UART2_RATIO [8:11] 772 * UART3_RATIO [12:15] 773 * UART4_RATIO [16:19] 774 */ 775 ratio = readl(&clk->div_peril0); 776 ratio = (ratio >> (dev_index << 2)) & 0xf; 777 778 uclk = sclk / (ratio + 1); 779 780 return uclk; 781 } 782 783 static unsigned long exynos4_get_mmc_clk(int dev_index) 784 { 785 struct exynos4_clock *clk = 786 (struct exynos4_clock *)samsung_get_base_clock(); 787 unsigned long uclk, sclk; 788 unsigned int sel, ratio, pre_ratio; 789 int shift = 0; 790 791 sel = readl(&clk->src_fsys); 792 sel = (sel >> (dev_index << 2)) & 0xf; 793 794 if (sel == 0x6) 795 sclk = get_pll_clk(MPLL); 796 else if (sel == 0x7) 797 sclk = get_pll_clk(EPLL); 798 else if (sel == 0x8) 799 sclk = get_pll_clk(VPLL); 800 else 801 return 0; 802 803 switch (dev_index) { 804 case 0: 805 case 1: 806 ratio = readl(&clk->div_fsys1); 807 pre_ratio = readl(&clk->div_fsys1); 808 break; 809 case 2: 810 case 3: 811 ratio = readl(&clk->div_fsys2); 812 pre_ratio = readl(&clk->div_fsys2); 813 break; 814 case 4: 815 ratio = readl(&clk->div_fsys3); 816 pre_ratio = readl(&clk->div_fsys3); 817 break; 818 default: 819 return 0; 820 } 821 822 if (dev_index == 1 || dev_index == 3) 823 shift = 16; 824 825 ratio = (ratio >> shift) & 0xf; 826 pre_ratio = (pre_ratio >> (shift + 8)) & 0xff; 827 uclk = (sclk / (ratio + 1)) / (pre_ratio + 1); 828 829 return uclk; 830 } 831 832 /* exynos4: set the mmc clock */ 833 static void exynos4_set_mmc_clk(int dev_index, unsigned int div) 834 { 835 struct exynos4_clock *clk = 836 (struct exynos4_clock *)samsung_get_base_clock(); 837 unsigned int addr, clear_bit, set_bit; 838 839 /* 840 * CLK_DIV_FSYS1 841 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] 842 * CLK_DIV_FSYS2 843 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] 844 * CLK_DIV_FSYS3 845 * MMC4_RATIO [3:0] 846 */ 847 if (dev_index < 2) { 848 addr = (unsigned int)&clk->div_fsys1; 849 clear_bit = MASK_PRE_RATIO(dev_index); 850 set_bit = SET_PRE_RATIO(dev_index, div); 851 } else if (dev_index == 4) { 852 addr = (unsigned int)&clk->div_fsys3; 853 dev_index -= 4; 854 /* MMC4 is controlled with the MMC4_RATIO value */ 855 clear_bit = MASK_RATIO(dev_index); 856 set_bit = SET_RATIO(dev_index, div); 857 } else { 858 addr = (unsigned int)&clk->div_fsys2; 859 dev_index -= 2; 860 clear_bit = MASK_PRE_RATIO(dev_index); 861 set_bit = SET_PRE_RATIO(dev_index, div); 862 } 863 864 clrsetbits_le32(addr, clear_bit, set_bit); 865 } 866 867 /* exynos5: set the mmc clock */ 868 static void exynos5_set_mmc_clk(int dev_index, unsigned int div) 869 { 870 struct exynos5_clock *clk = 871 (struct exynos5_clock *)samsung_get_base_clock(); 872 unsigned int addr; 873 874 /* 875 * CLK_DIV_FSYS1 876 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] 877 * CLK_DIV_FSYS2 878 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] 879 */ 880 if (dev_index < 2) { 881 addr = (unsigned int)&clk->div_fsys1; 882 } else { 883 addr = (unsigned int)&clk->div_fsys2; 884 dev_index -= 2; 885 } 886 887 clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8), 888 (div & 0xff) << ((dev_index << 4) + 8)); 889 } 890 891 /* exynos5: set the mmc clock */ 892 static void exynos5420_set_mmc_clk(int dev_index, unsigned int div) 893 { 894 struct exynos5420_clock *clk = 895 (struct exynos5420_clock *)samsung_get_base_clock(); 896 unsigned int addr; 897 unsigned int shift; 898 899 /* 900 * CLK_DIV_FSYS1 901 * MMC0_RATIO [9:0] 902 * MMC1_RATIO [19:10] 903 * MMC2_RATIO [29:20] 904 */ 905 addr = (unsigned int)&clk->div_fsys1; 906 shift = dev_index * 10; 907 908 clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift); 909 } 910 911 /* get_lcd_clk: return lcd clock frequency */ 912 static unsigned long exynos4_get_lcd_clk(void) 913 { 914 struct exynos4_clock *clk = 915 (struct exynos4_clock *)samsung_get_base_clock(); 916 unsigned long pclk, sclk; 917 unsigned int sel; 918 unsigned int ratio; 919 920 /* 921 * CLK_SRC_LCD0 922 * FIMD0_SEL [3:0] 923 */ 924 sel = readl(&clk->src_lcd0); 925 sel = sel & 0xf; 926 927 /* 928 * 0x6: SCLK_MPLL 929 * 0x7: SCLK_EPLL 930 * 0x8: SCLK_VPLL 931 */ 932 if (sel == 0x6) 933 sclk = get_pll_clk(MPLL); 934 else if (sel == 0x7) 935 sclk = get_pll_clk(EPLL); 936 else if (sel == 0x8) 937 sclk = get_pll_clk(VPLL); 938 else 939 return 0; 940 941 /* 942 * CLK_DIV_LCD0 943 * FIMD0_RATIO [3:0] 944 */ 945 ratio = readl(&clk->div_lcd0); 946 ratio = ratio & 0xf; 947 948 pclk = sclk / (ratio + 1); 949 950 return pclk; 951 } 952 953 /* get_lcd_clk: return lcd clock frequency */ 954 static unsigned long exynos5_get_lcd_clk(void) 955 { 956 struct exynos5_clock *clk = 957 (struct exynos5_clock *)samsung_get_base_clock(); 958 unsigned long pclk, sclk; 959 unsigned int sel; 960 unsigned int ratio; 961 962 /* 963 * CLK_SRC_LCD0 964 * FIMD0_SEL [3:0] 965 */ 966 sel = readl(&clk->src_disp1_0); 967 sel = sel & 0xf; 968 969 /* 970 * 0x6: SCLK_MPLL 971 * 0x7: SCLK_EPLL 972 * 0x8: SCLK_VPLL 973 */ 974 if (sel == 0x6) 975 sclk = get_pll_clk(MPLL); 976 else if (sel == 0x7) 977 sclk = get_pll_clk(EPLL); 978 else if (sel == 0x8) 979 sclk = get_pll_clk(VPLL); 980 else 981 return 0; 982 983 /* 984 * CLK_DIV_LCD0 985 * FIMD0_RATIO [3:0] 986 */ 987 ratio = readl(&clk->div_disp1_0); 988 ratio = ratio & 0xf; 989 990 pclk = sclk / (ratio + 1); 991 992 return pclk; 993 } 994 995 static unsigned long exynos5420_get_lcd_clk(void) 996 { 997 struct exynos5420_clock *clk = 998 (struct exynos5420_clock *)samsung_get_base_clock(); 999 unsigned long pclk, sclk; 1000 unsigned int sel; 1001 unsigned int ratio; 1002 1003 /* 1004 * CLK_SRC_DISP10 1005 * FIMD1_SEL [4] 1006 * 0: SCLK_RPLL 1007 * 1: SCLK_SPLL 1008 */ 1009 sel = readl(&clk->src_disp10); 1010 sel &= (1 << 4); 1011 1012 if (sel) 1013 sclk = get_pll_clk(SPLL); 1014 else 1015 sclk = get_pll_clk(RPLL); 1016 1017 /* 1018 * CLK_DIV_DISP10 1019 * FIMD1_RATIO [3:0] 1020 */ 1021 ratio = readl(&clk->div_disp10); 1022 ratio = ratio & 0xf; 1023 1024 pclk = sclk / (ratio + 1); 1025 1026 return pclk; 1027 } 1028 1029 static unsigned long exynos5800_get_lcd_clk(void) 1030 { 1031 struct exynos5420_clock *clk = 1032 (struct exynos5420_clock *)samsung_get_base_clock(); 1033 unsigned long sclk; 1034 unsigned int sel; 1035 unsigned int ratio; 1036 1037 /* 1038 * CLK_SRC_DISP10 1039 * CLKMUX_FIMD1 [6:4] 1040 */ 1041 sel = (readl(&clk->src_disp10) >> 4) & 0x7; 1042 1043 if (sel) { 1044 /* 1045 * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into 1046 * PLLs. The first element is a placeholder to bypass the 1047 * default settig. 1048 */ 1049 const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL, 1050 RPLL}; 1051 sclk = get_pll_clk(reg_map[sel]); 1052 } else 1053 sclk = CONFIG_SYS_CLK_FREQ; 1054 /* 1055 * CLK_DIV_DISP10 1056 * FIMD1_RATIO [3:0] 1057 */ 1058 ratio = readl(&clk->div_disp10) & 0xf; 1059 1060 return sclk / (ratio + 1); 1061 } 1062 1063 void exynos4_set_lcd_clk(void) 1064 { 1065 struct exynos4_clock *clk = 1066 (struct exynos4_clock *)samsung_get_base_clock(); 1067 1068 /* 1069 * CLK_GATE_BLOCK 1070 * CLK_CAM [0] 1071 * CLK_TV [1] 1072 * CLK_MFC [2] 1073 * CLK_G3D [3] 1074 * CLK_LCD0 [4] 1075 * CLK_LCD1 [5] 1076 * CLK_GPS [7] 1077 */ 1078 setbits_le32(&clk->gate_block, 1 << 4); 1079 1080 /* 1081 * CLK_SRC_LCD0 1082 * FIMD0_SEL [3:0] 1083 * MDNIE0_SEL [7:4] 1084 * MDNIE_PWM0_SEL [8:11] 1085 * MIPI0_SEL [12:15] 1086 * set lcd0 src clock 0x6: SCLK_MPLL 1087 */ 1088 clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6); 1089 1090 /* 1091 * CLK_GATE_IP_LCD0 1092 * CLK_FIMD0 [0] 1093 * CLK_MIE0 [1] 1094 * CLK_MDNIE0 [2] 1095 * CLK_DSIM0 [3] 1096 * CLK_SMMUFIMD0 [4] 1097 * CLK_PPMULCD0 [5] 1098 * Gating all clocks for FIMD0 1099 */ 1100 setbits_le32(&clk->gate_ip_lcd0, 1 << 0); 1101 1102 /* 1103 * CLK_DIV_LCD0 1104 * FIMD0_RATIO [3:0] 1105 * MDNIE0_RATIO [7:4] 1106 * MDNIE_PWM0_RATIO [11:8] 1107 * MDNIE_PWM_PRE_RATIO [15:12] 1108 * MIPI0_RATIO [19:16] 1109 * MIPI0_PRE_RATIO [23:20] 1110 * set fimd ratio 1111 */ 1112 clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1); 1113 } 1114 1115 void exynos5_set_lcd_clk(void) 1116 { 1117 struct exynos5_clock *clk = 1118 (struct exynos5_clock *)samsung_get_base_clock(); 1119 1120 /* 1121 * CLK_GATE_BLOCK 1122 * CLK_CAM [0] 1123 * CLK_TV [1] 1124 * CLK_MFC [2] 1125 * CLK_G3D [3] 1126 * CLK_LCD0 [4] 1127 * CLK_LCD1 [5] 1128 * CLK_GPS [7] 1129 */ 1130 setbits_le32(&clk->gate_block, 1 << 4); 1131 1132 /* 1133 * CLK_SRC_LCD0 1134 * FIMD0_SEL [3:0] 1135 * MDNIE0_SEL [7:4] 1136 * MDNIE_PWM0_SEL [8:11] 1137 * MIPI0_SEL [12:15] 1138 * set lcd0 src clock 0x6: SCLK_MPLL 1139 */ 1140 clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6); 1141 1142 /* 1143 * CLK_GATE_IP_LCD0 1144 * CLK_FIMD0 [0] 1145 * CLK_MIE0 [1] 1146 * CLK_MDNIE0 [2] 1147 * CLK_DSIM0 [3] 1148 * CLK_SMMUFIMD0 [4] 1149 * CLK_PPMULCD0 [5] 1150 * Gating all clocks for FIMD0 1151 */ 1152 setbits_le32(&clk->gate_ip_disp1, 1 << 0); 1153 1154 /* 1155 * CLK_DIV_LCD0 1156 * FIMD0_RATIO [3:0] 1157 * MDNIE0_RATIO [7:4] 1158 * MDNIE_PWM0_RATIO [11:8] 1159 * MDNIE_PWM_PRE_RATIO [15:12] 1160 * MIPI0_RATIO [19:16] 1161 * MIPI0_PRE_RATIO [23:20] 1162 * set fimd ratio 1163 */ 1164 clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0); 1165 } 1166 1167 void exynos5420_set_lcd_clk(void) 1168 { 1169 struct exynos5420_clock *clk = 1170 (struct exynos5420_clock *)samsung_get_base_clock(); 1171 unsigned int cfg; 1172 1173 /* 1174 * CLK_SRC_DISP10 1175 * FIMD1_SEL [4] 1176 * 0: SCLK_RPLL 1177 * 1: SCLK_SPLL 1178 */ 1179 cfg = readl(&clk->src_disp10); 1180 cfg &= ~(0x1 << 4); 1181 cfg |= (0 << 4); 1182 writel(cfg, &clk->src_disp10); 1183 1184 /* 1185 * CLK_DIV_DISP10 1186 * FIMD1_RATIO [3:0] 1187 */ 1188 cfg = readl(&clk->div_disp10); 1189 cfg &= ~(0xf << 0); 1190 cfg |= (0 << 0); 1191 writel(cfg, &clk->div_disp10); 1192 } 1193 1194 void exynos5800_set_lcd_clk(void) 1195 { 1196 struct exynos5420_clock *clk = 1197 (struct exynos5420_clock *)samsung_get_base_clock(); 1198 unsigned int cfg; 1199 1200 /* 1201 * Use RPLL for pixel clock 1202 * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] 1203 * ================== 1204 * 111: SCLK_RPLL 1205 */ 1206 cfg = readl(&clk->src_disp10) | (0x7 << 4); 1207 writel(cfg, &clk->src_disp10); 1208 1209 /* 1210 * CLK_DIV_DISP10 1211 * FIMD1_RATIO [3:0] 1212 */ 1213 clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0); 1214 } 1215 1216 void exynos4_set_mipi_clk(void) 1217 { 1218 struct exynos4_clock *clk = 1219 (struct exynos4_clock *)samsung_get_base_clock(); 1220 1221 /* 1222 * CLK_SRC_LCD0 1223 * FIMD0_SEL [3:0] 1224 * MDNIE0_SEL [7:4] 1225 * MDNIE_PWM0_SEL [8:11] 1226 * MIPI0_SEL [12:15] 1227 * set mipi0 src clock 0x6: SCLK_MPLL 1228 */ 1229 clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12); 1230 1231 /* 1232 * CLK_SRC_MASK_LCD0 1233 * FIMD0_MASK [0] 1234 * MDNIE0_MASK [4] 1235 * MDNIE_PWM0_MASK [8] 1236 * MIPI0_MASK [12] 1237 * set src mask mipi0 0x1: Unmask 1238 */ 1239 setbits_le32(&clk->src_mask_lcd0, 0x1 << 12); 1240 1241 /* 1242 * CLK_GATE_IP_LCD0 1243 * CLK_FIMD0 [0] 1244 * CLK_MIE0 [1] 1245 * CLK_MDNIE0 [2] 1246 * CLK_DSIM0 [3] 1247 * CLK_SMMUFIMD0 [4] 1248 * CLK_PPMULCD0 [5] 1249 * Gating all clocks for MIPI0 1250 */ 1251 setbits_le32(&clk->gate_ip_lcd0, 1 << 3); 1252 1253 /* 1254 * CLK_DIV_LCD0 1255 * FIMD0_RATIO [3:0] 1256 * MDNIE0_RATIO [7:4] 1257 * MDNIE_PWM0_RATIO [11:8] 1258 * MDNIE_PWM_PRE_RATIO [15:12] 1259 * MIPI0_RATIO [19:16] 1260 * MIPI0_PRE_RATIO [23:20] 1261 * set mipi ratio 1262 */ 1263 clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16); 1264 } 1265 1266 int exynos5_set_epll_clk(unsigned long rate) 1267 { 1268 unsigned int epll_con, epll_con_k; 1269 unsigned int i; 1270 unsigned int lockcnt; 1271 unsigned int start; 1272 struct exynos5_clock *clk = 1273 (struct exynos5_clock *)samsung_get_base_clock(); 1274 1275 epll_con = readl(&clk->epll_con0); 1276 epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK << 1277 EPLL_CON0_LOCK_DET_EN_SHIFT) | 1278 EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT | 1279 EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT | 1280 EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT); 1281 1282 for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) { 1283 if (exynos5_epll_div[i].freq_out == rate) 1284 break; 1285 } 1286 1287 if (i == ARRAY_SIZE(exynos5_epll_div)) 1288 return -1; 1289 1290 epll_con_k = exynos5_epll_div[i].k_dsm << 0; 1291 epll_con |= exynos5_epll_div[i].en_lock_det << 1292 EPLL_CON0_LOCK_DET_EN_SHIFT; 1293 epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT; 1294 epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT; 1295 epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT; 1296 1297 /* 1298 * Required period ( in cycles) to genarate a stable clock output. 1299 * The maximum clock time can be up to 3000 * PDIV cycles of PLLs 1300 * frequency input (as per spec) 1301 */ 1302 lockcnt = 3000 * exynos5_epll_div[i].p_div; 1303 1304 writel(lockcnt, &clk->epll_lock); 1305 writel(epll_con, &clk->epll_con0); 1306 writel(epll_con_k, &clk->epll_con1); 1307 1308 start = get_timer(0); 1309 1310 while (!(readl(&clk->epll_con0) & 1311 (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) { 1312 if (get_timer(start) > TIMEOUT_EPLL_LOCK) { 1313 debug("%s: Timeout waiting for EPLL lock\n", __func__); 1314 return -1; 1315 } 1316 } 1317 return 0; 1318 } 1319 1320 int exynos5_set_i2s_clk_source(unsigned int i2s_id) 1321 { 1322 struct exynos5_clock *clk = 1323 (struct exynos5_clock *)samsung_get_base_clock(); 1324 unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass(); 1325 1326 if (i2s_id == 0) { 1327 setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL); 1328 clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK, 1329 (CLK_SRC_SCLK_EPLL)); 1330 setbits_le32(audio_ass, AUDIO_CLKMUX_ASS); 1331 } else if (i2s_id == 1) { 1332 clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK, 1333 (CLK_SRC_SCLK_EPLL)); 1334 } else { 1335 return -1; 1336 } 1337 return 0; 1338 } 1339 1340 int exynos5_set_i2s_clk_prescaler(unsigned int src_frq, 1341 unsigned int dst_frq, 1342 unsigned int i2s_id) 1343 { 1344 struct exynos5_clock *clk = 1345 (struct exynos5_clock *)samsung_get_base_clock(); 1346 unsigned int div; 1347 1348 if ((dst_frq == 0) || (src_frq == 0)) { 1349 debug("%s: Invalid requency input for prescaler\n", __func__); 1350 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1351 return -1; 1352 } 1353 1354 div = (src_frq / dst_frq); 1355 if (i2s_id == 0) { 1356 if (div > AUDIO_0_RATIO_MASK) { 1357 debug("%s: Frequency ratio is out of range\n", 1358 __func__); 1359 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1360 return -1; 1361 } 1362 clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK, 1363 (div & AUDIO_0_RATIO_MASK)); 1364 } else if (i2s_id == 1) { 1365 if (div > AUDIO_1_RATIO_MASK) { 1366 debug("%s: Frequency ratio is out of range\n", 1367 __func__); 1368 debug("src frq = %d des frq = %d ", src_frq, dst_frq); 1369 return -1; 1370 } 1371 clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK, 1372 (div & AUDIO_1_RATIO_MASK)); 1373 } else { 1374 return -1; 1375 } 1376 return 0; 1377 } 1378 1379 /** 1380 * Linearly searches for the most accurate main and fine stage clock scalars 1381 * (divisors) for a specified target frequency and scalar bit sizes by checking 1382 * all multiples of main_scalar_bits values. Will always return scalars up to or 1383 * slower than target. 1384 * 1385 * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32 1386 * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32 1387 * @param input_freq Clock frequency to be scaled in Hz 1388 * @param target_freq Desired clock frequency in Hz 1389 * @param best_fine_scalar Pointer to store the fine stage divisor 1390 * 1391 * @return best_main_scalar Main scalar for desired frequency or -1 if none 1392 * found 1393 */ 1394 static int clock_calc_best_scalar(unsigned int main_scaler_bits, 1395 unsigned int fine_scalar_bits, unsigned int input_rate, 1396 unsigned int target_rate, unsigned int *best_fine_scalar) 1397 { 1398 int i; 1399 int best_main_scalar = -1; 1400 unsigned int best_error = target_rate; 1401 const unsigned int cap = (1 << fine_scalar_bits) - 1; 1402 const unsigned int loops = 1 << main_scaler_bits; 1403 1404 debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate, 1405 target_rate, cap); 1406 1407 assert(best_fine_scalar != NULL); 1408 assert(main_scaler_bits <= fine_scalar_bits); 1409 1410 *best_fine_scalar = 1; 1411 1412 if (input_rate == 0 || target_rate == 0) 1413 return -1; 1414 1415 if (target_rate >= input_rate) 1416 return 1; 1417 1418 for (i = 1; i <= loops; i++) { 1419 const unsigned int effective_div = 1420 max(min(input_rate / i / target_rate, cap), 1U); 1421 const unsigned int effective_rate = input_rate / i / 1422 effective_div; 1423 const int error = target_rate - effective_rate; 1424 1425 debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div, 1426 effective_rate, error); 1427 1428 if (error >= 0 && error <= best_error) { 1429 best_error = error; 1430 best_main_scalar = i; 1431 *best_fine_scalar = effective_div; 1432 } 1433 } 1434 1435 return best_main_scalar; 1436 } 1437 1438 static int exynos5_set_spi_clk(enum periph_id periph_id, 1439 unsigned int rate) 1440 { 1441 struct exynos5_clock *clk = 1442 (struct exynos5_clock *)samsung_get_base_clock(); 1443 int main; 1444 unsigned int fine; 1445 unsigned shift, pre_shift; 1446 unsigned mask = 0xff; 1447 u32 *reg; 1448 1449 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); 1450 if (main < 0) { 1451 debug("%s: Cannot set clock rate for periph %d", 1452 __func__, periph_id); 1453 return -1; 1454 } 1455 main = main - 1; 1456 fine = fine - 1; 1457 1458 switch (periph_id) { 1459 case PERIPH_ID_SPI0: 1460 reg = &clk->div_peric1; 1461 shift = 0; 1462 pre_shift = 8; 1463 break; 1464 case PERIPH_ID_SPI1: 1465 reg = &clk->div_peric1; 1466 shift = 16; 1467 pre_shift = 24; 1468 break; 1469 case PERIPH_ID_SPI2: 1470 reg = &clk->div_peric2; 1471 shift = 0; 1472 pre_shift = 8; 1473 break; 1474 case PERIPH_ID_SPI3: 1475 reg = &clk->sclk_div_isp; 1476 shift = 0; 1477 pre_shift = 4; 1478 break; 1479 case PERIPH_ID_SPI4: 1480 reg = &clk->sclk_div_isp; 1481 shift = 12; 1482 pre_shift = 16; 1483 break; 1484 default: 1485 debug("%s: Unsupported peripheral ID %d\n", __func__, 1486 periph_id); 1487 return -1; 1488 } 1489 clrsetbits_le32(reg, mask << shift, (main & mask) << shift); 1490 clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift); 1491 1492 return 0; 1493 } 1494 1495 static int exynos5420_set_spi_clk(enum periph_id periph_id, 1496 unsigned int rate) 1497 { 1498 struct exynos5420_clock *clk = 1499 (struct exynos5420_clock *)samsung_get_base_clock(); 1500 int main; 1501 unsigned int fine; 1502 unsigned shift, pre_shift; 1503 unsigned div_mask = 0xf, pre_div_mask = 0xff; 1504 u32 *reg; 1505 u32 *pre_reg; 1506 1507 main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); 1508 if (main < 0) { 1509 debug("%s: Cannot set clock rate for periph %d", 1510 __func__, periph_id); 1511 return -1; 1512 } 1513 main = main - 1; 1514 fine = fine - 1; 1515 1516 switch (periph_id) { 1517 case PERIPH_ID_SPI0: 1518 reg = &clk->div_peric1; 1519 shift = 20; 1520 pre_reg = &clk->div_peric4; 1521 pre_shift = 8; 1522 break; 1523 case PERIPH_ID_SPI1: 1524 reg = &clk->div_peric1; 1525 shift = 24; 1526 pre_reg = &clk->div_peric4; 1527 pre_shift = 16; 1528 break; 1529 case PERIPH_ID_SPI2: 1530 reg = &clk->div_peric1; 1531 shift = 28; 1532 pre_reg = &clk->div_peric4; 1533 pre_shift = 24; 1534 break; 1535 case PERIPH_ID_SPI3: 1536 reg = &clk->div_isp1; 1537 shift = 16; 1538 pre_reg = &clk->div_isp1; 1539 pre_shift = 0; 1540 break; 1541 case PERIPH_ID_SPI4: 1542 reg = &clk->div_isp1; 1543 shift = 20; 1544 pre_reg = &clk->div_isp1; 1545 pre_shift = 8; 1546 break; 1547 default: 1548 debug("%s: Unsupported peripheral ID %d\n", __func__, 1549 periph_id); 1550 return -1; 1551 } 1552 1553 clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift); 1554 clrsetbits_le32(pre_reg, pre_div_mask << pre_shift, 1555 (fine & pre_div_mask) << pre_shift); 1556 1557 return 0; 1558 } 1559 1560 static unsigned long exynos4_get_i2c_clk(void) 1561 { 1562 struct exynos4_clock *clk = 1563 (struct exynos4_clock *)samsung_get_base_clock(); 1564 unsigned long sclk, aclk_100; 1565 unsigned int ratio; 1566 1567 sclk = get_pll_clk(APLL); 1568 1569 ratio = (readl(&clk->div_top)) >> 4; 1570 ratio &= 0xf; 1571 aclk_100 = sclk / (ratio + 1); 1572 return aclk_100; 1573 } 1574 1575 unsigned long get_pll_clk(int pllreg) 1576 { 1577 if (cpu_is_exynos5()) { 1578 if (proid_is_exynos5420() || proid_is_exynos5422()) 1579 return exynos542x_get_pll_clk(pllreg); 1580 return exynos5_get_pll_clk(pllreg); 1581 } else if (cpu_is_exynos4()) { 1582 if (proid_is_exynos4412()) 1583 return exynos4x12_get_pll_clk(pllreg); 1584 return exynos4_get_pll_clk(pllreg); 1585 } 1586 1587 return 0; 1588 } 1589 1590 unsigned long get_arm_clk(void) 1591 { 1592 if (cpu_is_exynos5()) { 1593 return exynos5_get_arm_clk(); 1594 } else if (cpu_is_exynos4()) { 1595 if (proid_is_exynos4412()) 1596 return exynos4x12_get_arm_clk(); 1597 return exynos4_get_arm_clk(); 1598 } 1599 1600 return 0; 1601 } 1602 1603 unsigned long get_i2c_clk(void) 1604 { 1605 if (cpu_is_exynos5()) 1606 return clock_get_periph_rate(PERIPH_ID_I2C0); 1607 else if (cpu_is_exynos4()) 1608 return exynos4_get_i2c_clk(); 1609 1610 return 0; 1611 } 1612 1613 unsigned long get_pwm_clk(void) 1614 { 1615 if (cpu_is_exynos5()) { 1616 return clock_get_periph_rate(PERIPH_ID_PWM0); 1617 } else if (cpu_is_exynos4()) { 1618 if (proid_is_exynos4412()) 1619 return exynos4x12_get_pwm_clk(); 1620 return exynos4_get_pwm_clk(); 1621 } 1622 1623 return 0; 1624 } 1625 1626 unsigned long get_uart_clk(int dev_index) 1627 { 1628 enum periph_id id; 1629 1630 switch (dev_index) { 1631 case 0: 1632 id = PERIPH_ID_UART0; 1633 break; 1634 case 1: 1635 id = PERIPH_ID_UART1; 1636 break; 1637 case 2: 1638 id = PERIPH_ID_UART2; 1639 break; 1640 case 3: 1641 id = PERIPH_ID_UART3; 1642 break; 1643 default: 1644 debug("%s: invalid UART index %d", __func__, dev_index); 1645 return -1; 1646 } 1647 1648 if (cpu_is_exynos5()) { 1649 return clock_get_periph_rate(id); 1650 } else if (cpu_is_exynos4()) { 1651 if (proid_is_exynos4412()) 1652 return exynos4x12_get_uart_clk(dev_index); 1653 return exynos4_get_uart_clk(dev_index); 1654 } 1655 1656 return 0; 1657 } 1658 1659 unsigned long get_mmc_clk(int dev_index) 1660 { 1661 enum periph_id id; 1662 1663 if (cpu_is_exynos4()) 1664 return exynos4_get_mmc_clk(dev_index); 1665 1666 switch (dev_index) { 1667 case 0: 1668 id = PERIPH_ID_SDMMC0; 1669 break; 1670 case 1: 1671 id = PERIPH_ID_SDMMC1; 1672 break; 1673 case 2: 1674 id = PERIPH_ID_SDMMC2; 1675 break; 1676 case 3: 1677 id = PERIPH_ID_SDMMC3; 1678 break; 1679 default: 1680 debug("%s: invalid MMC index %d", __func__, dev_index); 1681 return -1; 1682 } 1683 1684 return clock_get_periph_rate(id); 1685 } 1686 1687 void set_mmc_clk(int dev_index, unsigned int div) 1688 { 1689 /* If want to set correct value, it needs to substract one from div.*/ 1690 if (div > 0) 1691 div -= 1; 1692 1693 if (cpu_is_exynos5()) { 1694 if (proid_is_exynos5420() || proid_is_exynos5422()) 1695 exynos5420_set_mmc_clk(dev_index, div); 1696 else 1697 exynos5_set_mmc_clk(dev_index, div); 1698 } else if (cpu_is_exynos4()) { 1699 exynos4_set_mmc_clk(dev_index, div); 1700 } 1701 } 1702 1703 unsigned long get_lcd_clk(void) 1704 { 1705 if (cpu_is_exynos4()) { 1706 return exynos4_get_lcd_clk(); 1707 } else if (cpu_is_exynos5()) { 1708 if (proid_is_exynos5420()) 1709 return exynos5420_get_lcd_clk(); 1710 else if (proid_is_exynos5422()) 1711 return exynos5800_get_lcd_clk(); 1712 else 1713 return exynos5_get_lcd_clk(); 1714 } 1715 1716 return 0; 1717 } 1718 1719 void set_lcd_clk(void) 1720 { 1721 if (cpu_is_exynos4()) { 1722 exynos4_set_lcd_clk(); 1723 } else if (cpu_is_exynos5()) { 1724 if (proid_is_exynos5250()) 1725 exynos5_set_lcd_clk(); 1726 else if (proid_is_exynos5420()) 1727 exynos5420_set_lcd_clk(); 1728 else 1729 exynos5800_set_lcd_clk(); 1730 } 1731 } 1732 1733 void set_mipi_clk(void) 1734 { 1735 if (cpu_is_exynos4()) 1736 exynos4_set_mipi_clk(); 1737 } 1738 1739 int set_spi_clk(int periph_id, unsigned int rate) 1740 { 1741 if (cpu_is_exynos5()) { 1742 if (proid_is_exynos5420() || proid_is_exynos5422()) 1743 return exynos5420_set_spi_clk(periph_id, rate); 1744 return exynos5_set_spi_clk(periph_id, rate); 1745 } 1746 1747 return 0; 1748 } 1749 1750 int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, 1751 unsigned int i2s_id) 1752 { 1753 if (cpu_is_exynos5()) 1754 return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id); 1755 1756 return 0; 1757 } 1758 1759 int set_i2s_clk_source(unsigned int i2s_id) 1760 { 1761 if (cpu_is_exynos5()) 1762 return exynos5_set_i2s_clk_source(i2s_id); 1763 1764 return 0; 1765 } 1766 1767 int set_epll_clk(unsigned long rate) 1768 { 1769 if (cpu_is_exynos5()) 1770 return exynos5_set_epll_clk(rate); 1771 1772 return 0; 1773 } 1774