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